fix: unfold should not create an auxiliary declaration when result is definitionally equal
This commit fixes an issue reported on Zulip https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Unfolding.20the.20type.20of.20a.20variable.20creates.20a.20new.20variable
This commit is contained in:
parent
7cf4642d1b
commit
fb64a4ccc0
4 changed files with 28 additions and 5 deletions
|
|
@ -680,9 +680,9 @@ def applySimpResultToProp (mvarId : MVarId) (proof : Expr) (prop : Expr) (r : Si
|
|||
else
|
||||
return some (proof, r.expr)
|
||||
|
||||
def applySimpResultToFVarId (mvarId : MVarId) (fvarId : FVarId) (r : Simp.Result) : MetaM (Option (Expr × Expr)) := do
|
||||
def applySimpResultToFVarId (mvarId : MVarId) (fvarId : FVarId) (r : Simp.Result) (mayCloseGoal : Bool) : MetaM (Option (Expr × Expr)) := do
|
||||
let localDecl ← getLocalDecl fvarId
|
||||
applySimpResultToProp mvarId (mkFVar fvarId) localDecl.type r
|
||||
applySimpResultToProp mvarId (mkFVar fvarId) localDecl.type r mayCloseGoal
|
||||
|
||||
/--
|
||||
Simplify `prop` (which is inhabited by `proof`). Return `none` if the goal was closed. Return `some (proof', prop')`
|
||||
|
|
@ -709,8 +709,17 @@ def applySimpResultToLocalDeclCore (mvarId : MVarId) (fvarId : FVarId) (r : Opti
|
|||
/--
|
||||
Simplify `simp` result to the given local declaration. Return `none` if the goal was closed.
|
||||
This method assumes `mvarId` is not assigned, and we are already using `mvarId`s local context. -/
|
||||
def applySimpResultToLocalDecl (mvarId : MVarId) (fvarId : FVarId) (r : Simp.Result) : MetaM (Option (FVarId × MVarId)) := do
|
||||
applySimpResultToLocalDeclCore mvarId fvarId (← applySimpResultToFVarId mvarId fvarId r)
|
||||
def applySimpResultToLocalDecl (mvarId : MVarId) (fvarId : FVarId) (r : Simp.Result) (mayCloseGoal : Bool) : MetaM (Option (FVarId × MVarId)) := do
|
||||
if r.proof?.isNone then
|
||||
-- New result is definitionally equal to input. Thus, we can avoid creating a new variable if there are dependencies
|
||||
let mvarId ← replaceLocalDeclDefEq mvarId fvarId r.expr
|
||||
if mayCloseGoal && r.expr.isConstOf ``False then
|
||||
assignExprMVar mvarId (← mkFalseElim (← getMVarType mvarId) (mkFVar fvarId))
|
||||
return none
|
||||
else
|
||||
return some (fvarId, mvarId)
|
||||
else
|
||||
applySimpResultToLocalDeclCore mvarId fvarId (← applySimpResultToFVarId mvarId fvarId r mayCloseGoal)
|
||||
|
||||
def simpLocalDecl (mvarId : MVarId) (fvarId : FVarId) (ctx : Simp.Context) (discharge? : Option Simp.Discharge := none) (mayCloseGoal := true) : MetaM (Option (FVarId × MVarId)) := do
|
||||
withMVarContext mvarId do
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def unfoldTarget (mvarId : MVarId) (declName : Name) : MetaM MVarId := withMVarC
|
|||
def unfoldLocalDecl (mvarId : MVarId) (fvarId : FVarId) (declName : Name) : MetaM MVarId := withMVarContext mvarId do
|
||||
let localDecl ← getLocalDecl fvarId
|
||||
let r ← unfold (← instantiateMVars localDecl.type) declName
|
||||
let some (_, mvarId) ← applySimpResultToLocalDecl mvarId fvarId r | unreachable!
|
||||
let some (_, mvarId) ← applySimpResultToLocalDecl mvarId fvarId r (mayCloseGoal := false) | unreachable!
|
||||
return mvarId
|
||||
|
||||
end Lean.Meta
|
||||
|
|
|
|||
9
tests/lean/unfoldDefEq.lean
Normal file
9
tests/lean/unfoldDefEq.lean
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
def Wrapper (n : Nat) : Type × Type :=
|
||||
(Fin n, Fin n)
|
||||
|
||||
def some_property {n} (x : Fin n) : Prop :=
|
||||
True
|
||||
|
||||
example (x : (Wrapper n).1) (h : some_property x) : True := by
|
||||
unfold Wrapper at x
|
||||
done
|
||||
5
tests/lean/unfoldDefEq.lean.expected.out
Normal file
5
tests/lean/unfoldDefEq.lean.expected.out
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
unfoldDefEq.lean:9:2-9:6: error: unsolved goals
|
||||
n : Nat
|
||||
x : (Fin n, Fin n).fst
|
||||
h : some_property x
|
||||
⊢ True
|
||||
Loading…
Add table
Reference in a new issue