@@ -9,17 +9,33 @@ public import Lean.Meta.Tactic.Grind.Types
99import Lean.Util.ForEachExpr
1010public section
1111namespace Lean.Meta.Grind
12+
13+ /-- Helper type for implementing `finish?` and `grind?` -/
14+ inductive ProofStep where
15+ | solver (id : Nat)
16+ | lookahead | mbtc
17+ | instantiate (thms : List EMatchTheorem) (usedThms : List EMatchTheorem)
18+ deriving Inhabited
19+
20+ /-- Helper type for implementing `finish?` and `grind?` -/
21+ inductive ProofTrace where
22+ | done
23+ | sep (s : ProofStep) (k : ProofTrace)
24+ | cases (info : SplitInfo) (alts : List ProofTrace)
25+ deriving Inhabited
26+
1227/--
1328A `choice` (aka backtracking) point in the search tree.
1429-/
1530structure Choice where
31+ info? : Option SplitInfo
1632 /--
1733 Goal where the case-split was performed.
18- Invariant: `goalOld .mvarId` is not assigned.
34+ Invariant: `goalPending .mvarId` is not assigned.
1935 -/
2036 goalPending : Goal
2137 /--
22- Expression to be assigned to `goalOld .mvarId` if it is not possible to perform
38+ Expression to be assigned to `goalPending .mvarId` if it is not possible to perform
2339 non-chronological backtracking.
2440 `proof` is often a `casesOn` application containing meta-variables.
2541 -/
@@ -28,11 +44,14 @@ structure Choice where
2844 Subgoals that still need to be processed.
2945 -/
3046 todo : List Goal
47+ traces : Array ProofTrace := #[]
3148 generation : Nat
3249 deriving Inhabited
3350
3451structure SearchM.State where
35- goal : Goal
52+ goal : Goal
53+ steps : Array ProofStep := #[]
54+ trace? : Option ProofTrace := none
3655 choiceStack : List Choice := []
3756
3857abbrev SearchM := StateRefT SearchM.State GrindM
@@ -66,7 +85,7 @@ update current goal using `s`.
6685- If there are more than one `s :: ss`, we create a choice point using the current
6786 goal as the pending goal, and update the current goal with `s`.
6887-/
69- def mkChoice (proof : Expr) (subgoals : List Goal) (generation : Nat) : SearchM Unit := do
88+ def mkChoice (proof : Expr) (subgoals : List Goal) (generation : Nat) (info? : Option SplitInfo := none) : SearchM Unit := do
7089 assert! !(← isInconsistent)
7190 match subgoals with
7291 | [] =>
@@ -79,7 +98,7 @@ def mkChoice (proof : Expr) (subgoals : List Goal) (generation : Nat) : SearchM
7998 let goalPending ← getGoal
8099 modify fun s => { s with
81100 goal := subgoal
82- choiceStack := { goalPending, proof, generation, todo := subgoals } :: s.choiceStack
101+ choiceStack := { info?, goalPending, proof, generation, todo := subgoals } :: s.choiceStack
83102 }
84103
85104/--
@@ -94,6 +113,9 @@ def mkAuxMVarForCurrGoal : SearchM MVarId := withCurrGoalContext do
94113 let mvarNew ← mkFreshExprSyntheticOpaqueMVar type tag
95114 return mvarNew.mvarId!
96115
116+ /--
117+ Returns the maximum free variable id occurring in `e`
118+ -/
97119private def findMaxFVarIdx? (e : Expr) : MetaM (Option Nat) := do
98120 let go (e : Expr) : StateT (Option Nat) MetaM Bool := do
99121 unless e.hasFVar do return false
@@ -187,14 +209,14 @@ def nextGoal? : SearchM (Option Nat) := do
187209 let mvarDecl ← choice.goalPending.mvarId.getDecl
188210 let numIndices := mvarDecl.lctx.numIndices
189211 if maxFVarIdx < numIndices then
190- -- `falseProof` can close `choice.goalOld ` since all its free-variables are in scope.
212+ -- `falseProof` can close `choice.goalPending ` since all its free-variables are in scope.
191213 choice.goalPending.mvarId.assignFalseProof falseProof
192214 -- keep looking at next choice point
193215 -- Remark: we may be able to find other choice points using falseProof.
194216 choices := choices'
195217 else match choice.todo with
196218 | [] =>
197- -- All subgoals have been solved. We can finally assign `choice.proof` to `goalOld .mvarId`.
219+ -- All subgoals have been solved. We can finally assign `choice.proof` to `goalPending .mvarId`.
198220 let proof ← instantiateMVars choice.proof
199221 choice.goalPending.mvarId.assign proof
200222 if (← isTargetFalse choice.goalPending.mvarId) then
0 commit comments