@@ -9,10 +9,79 @@ import Lean.Meta.Tactic.Grind.Intro
99import Lean.Meta.Tactic.Grind.Arith
1010import Lean.Meta.Tactic.Grind.Split
1111import Lean.Meta.Tactic.Grind.EMatch
12+ import Lean.Meta.Tactic.Grind.SearchM
1213
1314namespace Lean.Meta.Grind
1415
15- private partial def solve (generation : Nat) (goal : Goal) : GrindM Bool := do
16+ private partial def solve (generation : Nat) : SearchM Bool := withIncRecDepth do
17+ unless (← get).choiceStack.isEmpty do
18+ return false -- `splitNext` should have been configured to not create choice points
19+ if (← getGoal).inconsistent then
20+ return true
21+ if (← intros' generation <||> assertAll <||> Arith.check <||> splitNext <||> ematch) then
22+ solve generation
23+ else
24+ return false
25+
26+ private def tryLookahead (e : Expr) : GoalM Bool :=
27+ withTheReader Grind.Context
28+ (fun ctx => { ctx with config.qlia := true , cheapCases := true }) do
29+ -- TODO: if `e` is an arithmetic expression, we can avoid creating an auxiliary goal.
30+ -- We can assert it directly to the arithmetic module.
31+ -- Remark: We can simplify this code because the lookahead only really worked for arithmetic.
32+ trace_goal[grind.lookahead.try] "{e}"
33+ let goal ← get
34+ let proof? ← withoutModifyingMCtx do
35+ let tag ← goal.mvarId.getTag
36+ let target ← mkArrow (mkNot e) (← getFalseExpr)
37+ let mvar ← mkFreshExprSyntheticOpaqueMVar target tag
38+ let goalAux := { goal with mvarId := mvar.mvarId!, newFacts := {} }
39+ let gen ← getGeneration e
40+ let (ok, _) ← (solve gen).run goalAux
41+ if ok then
42+ return some (← instantiateMVars mvar)
43+ else
44+ return none
45+ if let some proof := proof? then
46+ trace[grind.lookahead.assert] "{e}"
47+ pushEqTrue e <| mkApp2 (mkConst ``Grind.of_lookahead) e proof
48+ processNewFacts
49+ return true
50+ else
51+ return false
52+
53+ def lookahead : GoalM Bool := do
54+ unless (← getConfig).lookahead do
55+ return false
56+ if (← get).split.lookaheads.isEmpty then
57+ return false
58+ let mut postponed := []
59+ let mut progress := false
60+ let infos := (← get).split.lookaheads
61+ modify fun s => { s with split.lookaheads := [] }
62+ for info in infos do
63+ if (← isInconsistent) then
64+ return true
65+ match (← checkSplitStatus info) with
66+ | .resolved => progress := true
67+ | .ready _ _ true
68+ | .notReady => postponed := info :: postponed
69+ | .ready _ _ false =>
70+ if (← tryLookahead info.getExpr) then
71+ progress := true
72+ else
73+ postponed := info :: postponed
74+ if progress then
75+ modify fun s => { s with
76+ split.lookaheads := s.split.lookaheads ++ postponed.reverse
77+ }
78+ return true
79+ else
80+ return false
81+
82+ /-! TODO: delete rest of the file. -/
83+
84+ private partial def solveOld (generation : Nat) (goal : Goal) : GrindM Bool := do
1685 cont (← introsOld generation goal)
1786where
1887 cont (goals : List Goal) : GrindM Bool := do
35104 else
36105 return false
37106
38- private def tryLookahead (e : Expr) : GoalM Bool := do
107+ private def tryLookaheadOld (e : Expr) : GoalM Bool := do
39108 -- TODO: if `e` is an arithmetic expression, we can avoid creating an auxiliary goal.
40109 -- We can assert it directly to the arithmetic module.
41110 -- Remark: We can simplify this code because the lookahead only really worked for arithmetic.
@@ -46,7 +115,7 @@ private def tryLookahead (e : Expr) : GoalM Bool := do
46115 let target ← mkArrow (mkNot e) (← getFalseExpr)
47116 let mvar ← mkFreshExprMVar target .syntheticOpaque tag
48117 let gen ← getGeneration e
49- if (← solve gen { goal with mvarId := mvar.mvarId! }) then
118+ if (← solveOld gen { goal with mvarId := mvar.mvarId! }) then
50119 return some (← instantiateMVars mvar)
51120 else
52121 return none
@@ -63,7 +132,7 @@ private def withLookaheadConfig (x : GrindM α) : GrindM α := do
63132 (fun ctx => { ctx with config.qlia := true , cheapCases := true })
64133 x
65134
66- def lookahead : GrindTactic := fun goal => do
135+ def lookaheadOld : GrindTactic := fun goal => do
67136 unless (← getConfig).lookahead do
68137 return none
69138 if goal.split.lookaheads.isEmpty then
@@ -82,7 +151,7 @@ def lookahead : GrindTactic := fun goal => do
82151 | .ready _ _ true
83152 | .notReady => postponed := info :: postponed
84153 | .ready _ _ false =>
85- if (← tryLookahead info.getExpr) then
154+ if (← tryLookaheadOld info.getExpr) then
86155 progress := true
87156 else
88157 postponed := info :: postponed
0 commit comments