fix: equational theorem generation for structural recursion
This commit is contained in:
parent
233a262c03
commit
82f3042fa4
2 changed files with 34 additions and 2 deletions
|
|
@ -24,6 +24,12 @@ def deltaLHS (mvarId : MVarId) : MetaM MVarId := withMVarContext mvarId do
|
|||
let some lhs ← delta? lhs | throwTacticEx `deltaLHS mvarId "failed to delta reduce lhs"
|
||||
replaceTargetDefEq mvarId (← mkEq lhs rhs)
|
||||
|
||||
def deltaRHS? (mvarId : MVarId) (declName : Name) : MetaM (Option MVarId) := withMVarContext mvarId do
|
||||
let target ← getMVarType' mvarId
|
||||
let some (_, lhs, rhs) ← target.eq? | throwTacticEx `deltaRHS mvarId "equality expected"
|
||||
let some rhs ← delta? rhs (. == declName) | return none
|
||||
replaceTargetDefEq mvarId (← mkEq lhs rhs)
|
||||
|
||||
private partial def whnfAux (e : Expr) : MetaM Expr := do
|
||||
let e ← whnfR e
|
||||
match e with
|
||||
|
|
@ -77,6 +83,10 @@ private def simpMatch? (mvarId : MVarId) : MetaM (Option MVarId) := do
|
|||
let mvarId' ← Split.simpMatchTarget mvarId
|
||||
if mvarId != mvarId' then return some mvarId' else return none
|
||||
|
||||
private def simpIf? (mvarId : MVarId) : MetaM (Option MVarId) := do
|
||||
let mvarId' ← simpIfTarget mvarId (useDecide := true)
|
||||
if mvarId != mvarId' then return some mvarId' else return none
|
||||
|
||||
/--
|
||||
Auxiliary method for `mkEqnTypes`. We should "keep going"/"processing" the goal
|
||||
`... |- f ... = rhs` at `mkEqnTypes` IF `rhs` contains a `f` application containing loose bound
|
||||
|
|
@ -124,7 +134,8 @@ private partial def mkEqnTypes (mvarId : MVarId) : ReaderT EqnInfo (StateRefT (A
|
|||
private def mkBaseNameFor (env : Environment) (declName : Name) : Name :=
|
||||
Lean.mkBaseNameFor env declName `eq_1 `_eqns
|
||||
|
||||
private partial def mkProof (declName : Name) (type : Expr) : MetaM Expr :=
|
||||
private partial def mkProof (declName : Name) (type : Expr) : MetaM Expr := do
|
||||
trace[Elab.definition.structural.eqns] "proving: {type}"
|
||||
withNewMCtxDepth do
|
||||
let main ← mkFreshExprSyntheticOpaqueMVar type
|
||||
let (_, mvarId) ← intros main.mvarId!
|
||||
|
|
@ -138,9 +149,13 @@ where
|
|||
return ()
|
||||
else if (← tryContradiction mvarId) then
|
||||
return ()
|
||||
else if let some mvarId ← simpMatch? mvarId then
|
||||
go mvarId
|
||||
else if let some mvarId ← simpIf? mvarId then
|
||||
go mvarId
|
||||
else if let some mvarId ← whnfReducibleLHS? mvarId then
|
||||
go mvarId
|
||||
else if let some mvarId ← simpMatch? mvarId then
|
||||
else if let some mvarId ← deltaRHS? mvarId declName then
|
||||
go mvarId
|
||||
else if let some mvarIds ← casesOnStuckLHS? mvarId then
|
||||
mvarIds.forM go
|
||||
|
|
|
|||
17
tests/lean/run/structuralEqns2.lean
Normal file
17
tests/lean/run/structuralEqns2.lean
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import Lean
|
||||
|
||||
open Lean
|
||||
open Lean.Meta
|
||||
def tst (declName : Name) : MetaM Unit := do
|
||||
IO.println (← getEqnsFor? declName)
|
||||
|
||||
def g (i j : Nat) : Nat :=
|
||||
if i < 5 then 0 else
|
||||
match j with
|
||||
| Nat.zero => 1
|
||||
| Nat.succ j => g i j
|
||||
|
||||
#eval tst ``g
|
||||
#check g.eq_1
|
||||
#check g.eq_2
|
||||
#check g.eq_3
|
||||
Loading…
Add table
Reference in a new issue