fix: whnfCore not expanding delayed assignments
This commit is contained in:
parent
f57c184dbd
commit
83775b08cb
2 changed files with 37 additions and 0 deletions
|
|
@ -307,6 +307,31 @@ def reduceProj? (e : Expr) : MetaM (Option Expr) := do
|
||||||
| Expr.proj _ i c _ => project? c i
|
| Expr.proj _ i c _ => project? c i
|
||||||
| _ => return none
|
| _ => return none
|
||||||
|
|
||||||
|
/-
|
||||||
|
Auxiliary method for reducing terms of the form `?m t_1 ... t_n` where `?m` is delayed assigned.
|
||||||
|
Recall that we can only expand a delayed assignment when all holes/metavariables in the assigned value have been "filled".
|
||||||
|
-/
|
||||||
|
private def whnfDelayedAssigned? (f' : Expr) (e : Expr) : MetaM (Option Expr) := do
|
||||||
|
if f'.isMVar then
|
||||||
|
match (← getDelayedAssignment? f'.mvarId!) with
|
||||||
|
| none => return none
|
||||||
|
| some { fvars := fvars, val := val, .. } =>
|
||||||
|
let args := e.getAppArgs
|
||||||
|
if fvars.size > args.size then
|
||||||
|
-- Insufficient number of argument to expand delayed assignment
|
||||||
|
return none
|
||||||
|
else
|
||||||
|
let newVal ← instantiateMVars val
|
||||||
|
if newVal.hasExprMVar then
|
||||||
|
-- Delayed assignment still contains metavariables
|
||||||
|
return none
|
||||||
|
else
|
||||||
|
let newVal := newVal.abstract fvars
|
||||||
|
let result := newVal.instantiateRevRange 0 fvars.size args
|
||||||
|
return mkAppRange result fvars.size args.size args
|
||||||
|
else
|
||||||
|
return none
|
||||||
|
|
||||||
/--
|
/--
|
||||||
Apply beta-reduction, zeta-reduction (i.e., unfold let local-decls), iota-reduction,
|
Apply beta-reduction, zeta-reduction (i.e., unfold let local-decls), iota-reduction,
|
||||||
expand let-expressions, expand assigned meta-variables. -/
|
expand let-expressions, expand assigned meta-variables. -/
|
||||||
|
|
@ -322,6 +347,8 @@ partial def whnfCore (e : Expr) : MetaM Expr :=
|
||||||
if f'.isLambda then
|
if f'.isLambda then
|
||||||
let revArgs := e.getAppRevArgs
|
let revArgs := e.getAppRevArgs
|
||||||
whnfCore <| f'.betaRev revArgs
|
whnfCore <| f'.betaRev revArgs
|
||||||
|
else if let some eNew ← whnfDelayedAssigned? f' e then
|
||||||
|
whnfCore eNew
|
||||||
else
|
else
|
||||||
let e := if f == f' then e else e.updateFn f'
|
let e := if f == f' then e else e.updateFn f'
|
||||||
match (← reduceMatcher? e) with
|
match (← reduceMatcher? e) with
|
||||||
|
|
|
||||||
10
tests/lean/run/whnfDelayedMVarIssue.lean
Normal file
10
tests/lean/run/whnfDelayedMVarIssue.lean
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
def Nat.isZero (n : Nat) :=
|
||||||
|
n == 0
|
||||||
|
|
||||||
|
def test (preDefs : Array (Array Nat)) : IO Unit := do
|
||||||
|
for preDefs in preDefs do
|
||||||
|
let preDef := preDefs[0]
|
||||||
|
if preDef.isZero then
|
||||||
|
pure ()
|
||||||
|
else
|
||||||
|
IO.println "error"
|
||||||
Loading…
Add table
Reference in a new issue