refactor: no need for simpMatchWF? (#4153)

Despite what it said in its docstring, `simpMatchWF?` seems to behave
like `simpMatch?`, so let’s just use that.
This commit is contained in:
Joachim Breitner 2024-05-13 21:33:23 +02:00 committed by GitHub
parent 842280321b
commit 7c4284aa91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 36 deletions

View file

@ -9,6 +9,7 @@ import Lean.Meta.Tactic.Split
import Lean.Elab.PreDefinition.Basic
import Lean.Elab.PreDefinition.Eqns
import Lean.Meta.ArgsPacker.Basic
import Init.Data.Array.Basic
namespace Lean.Elab.WF
open Meta
@ -39,41 +40,6 @@ private def rwFixEq (mvarId : MVarId) : MetaM MVarId := mvarId.withContext do
mvarId.assign (← mkEqTrans h mvarNew)
return mvarNew.mvarId!
/--
Simplify `match`-expressions when trying to prove equation theorems for a recursive declaration defined using well-founded recursion.
It is similar to `simpMatch?`, but is also tries to fold `WellFounded.fix` applications occurring in discriminants.
See comment at `tryToFoldWellFoundedFix`.
-/
def simpMatchWF? (mvarId : MVarId) : MetaM (Option MVarId) :=
mvarId.withContext do
let target ← instantiateMVars (← mvarId.getType)
let discharge? ← mvarId.withContext do SplitIf.mkDischarge?
let (targetNew, _) ← Simp.main target (← Split.getSimpMatchContext) (methods := { pre, discharge? })
let mvarIdNew ← applySimpResultToTarget mvarId target targetNew
if mvarId != mvarIdNew then return some mvarIdNew else return none
where
pre (e : Expr) : SimpM Simp.Step := do
let some app ← matchMatcherApp? e
| return Simp.Step.continue
-- First try to reduce matcher
match (← reduceRecMatcher? e) with
| some e' => return Simp.Step.done { expr := e' }
| none => Simp.simpMatchCore app.matcherName e
/--
Given a goal of the form `|- f.{us} a_1 ... a_n b_1 ... b_m = ...`, return `(us, #[a_1, ..., a_n])`
where `f` is a constant named `declName`, and `n = info.fixedPrefixSize`.
-/
private def getFixedPrefix (declName : Name) (info : EqnInfo) (mvarId : MVarId) : MetaM (List Level × Array Expr) := mvarId.withContext do
let target ← mvarId.getType'
let some (_, lhs, _) := target.eq? | unreachable!
let lhsArgs := lhs.getAppArgs
if lhsArgs.size < info.fixedPrefixSize || !lhs.getAppFn matches .const .. then
throwError "failed to generate equational theorem for '{declName}', unexpected number of arguments in the equation left-hand-side\n{mvarId}"
let result := lhsArgs[:info.fixedPrefixSize]
trace[Elab.definition.wf.eqns] "fixedPrefix: {result}"
return (lhs.getAppFn.constLevels!, result)
private partial def mkProof (declName : Name) (type : Expr) : MetaM Expr := do
trace[Elab.definition.wf.eqns] "proving: {type}"
withNewMCtxDepth do
@ -85,7 +51,7 @@ private partial def mkProof (declName : Name) (type : Expr) : MetaM Expr := do
return ()
else if (← tryContradiction mvarId) then
return ()
else if let some mvarId ← simpMatchWF? mvarId then
else if let some mvarId ← simpMatch? mvarId then
go mvarId
else if let some mvarId ← simpIf? mvarId then
go mvarId

View file

@ -35,6 +35,32 @@ def f.eq_2_ := 10 -- Should be ok
#guard_msgs in
#check f.eq_def
def nonrecfun : Bool → Nat
| false => 0
| true => 0
/--
info: nonrecfun.eq_def :
∀ (x : Bool),
nonrecfun x =
match x with
| false => 0
| true => 0
-/
#guard_msgs in
#check nonrecfun.eq_def
/--
info: nonrecfun.eq_1 :
∀ (x : Bool),
nonrecfun x =
match x with
| false => 0
| true => 0
-/
#guard_msgs in
#check nonrecfun.eq_1
def fact : Nat → Nat
| 0 => 1
| n+1 => (n+1) * fact n