Skip to content

Commit 4eccb5b

Browse files
authored
fix: grind diagnostics at maxHeartbeats (#8438)
This PR ensures that `grind` diagnostics are obtained even when `maxHeartbeats` is reached. This PR also removes some dead code.
1 parent 0a43c13 commit 4eccb5b

File tree

6 files changed

+51
-51
lines changed

6 files changed

+51
-51
lines changed

src/Lean/Meta/Tactic/Grind/Combinators.lean

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,6 @@ TODO: a proper tactic language for `grind`.
1515

1616
def GrindTactic := Goal → GrindM (Option (List Goal))
1717

18-
def GrindTactic.try (x : GrindTactic) : GrindTactic := fun g => do
19-
let some gs ← x g | return some [g]
20-
return some gs
21-
22-
def applyToAll (x : GrindTactic) (goals : List Goal) : GrindM (List Goal) := do
23-
go goals []
24-
where
25-
go (goals : List Goal) (acc : List Goal) : GrindM (List Goal) := do
26-
match goals with
27-
| [] => return acc.reverse
28-
| goal :: goals => match (← x goal) with
29-
| none => go goals (goal :: acc)
30-
| some goals' => go goals (goals' ++ acc)
31-
32-
partial def GrindTactic.andThen (x y : GrindTactic) : GrindTactic := fun goal => do
33-
let some goals ← x goal | return none
34-
applyToAll y goals
35-
36-
instance : AndThen GrindTactic where
37-
andThen a b := GrindTactic.andThen a (b ())
38-
3918
partial def GrindTactic.iterate (x : GrindTactic) : GrindTactic := fun goal => do
4019
go [goal] []
4120
where
@@ -48,13 +27,6 @@ where
4827
else
4928
go todo (goal :: result)
5029

51-
partial def GrindTactic.orElse (x y : GrindTactic) : GrindTactic := fun goal => do
52-
let some goals ← x goal | y goal
53-
return goals
54-
55-
instance : OrElse GrindTactic where
56-
orElse a b := GrindTactic.andThen a (b ())
57-
5830
def toGrindTactic (f : GoalM Unit) : GrindTactic := fun goal => do
5931
let goal ← GoalM.run' goal f
6032
if goal.inconsistent then

src/Lean/Meta/Tactic/Grind/EMatch.lean

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ end EMatch
474474
open EMatch
475475

476476
/-- Performs one round of E-matching, and returns new instances. -/
477-
def ematch : GoalM Unit := do
477+
private def ematchCore : GoalM Unit := do
478478
let go (thms newThms : PArray EMatchTheorem) : EMatch.M Unit := do
479479
withReader (fun ctx => { ctx with useMT := true }) <| ematchTheorems thms
480480
withReader (fun ctx => { ctx with useMT := false }) <| ematchTheorems newThms
@@ -489,12 +489,13 @@ def ematch : GoalM Unit := do
489489
ematch.num := s.ematch.num + 1
490490
}
491491

492-
/-- Performs one round of E-matching, and assert new instances. -/
493-
def ematchAndAssert : GrindTactic := fun goal => do
492+
/-- Performs one round of E-matching. -/
493+
def ematch : GrindTactic := fun goal => do
494494
let numInstances := goal.ematch.numInstances
495-
let goal ← GoalM.run' goal ematch
495+
let goal ← GoalM.run' goal ematchCore
496496
if goal.ematch.numInstances == numInstances then
497497
return none
498-
assertAll goal
498+
else
499+
return [goal]
499500

500501
end Lean.Meta.Grind

src/Lean/Meta/Tactic/Grind/Intro.lean

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,10 @@ def assertNext : GrindTactic := fun goal => do
263263
assertAt fact.proof fact.prop fact.generation { goal with newRawFacts }
264264

265265
/-- Asserts all facts in the `goal` fact queue. -/
266-
partial def assertAll : GrindTactic :=
267-
assertNext.iterate
266+
partial def assertAll : GrindTactic := fun goal =>
267+
if goal.newRawFacts.isEmpty then
268+
return none
269+
else
270+
assertNext.iterate goal
268271

269272
end Lean.Meta.Grind

src/Lean/Meta/Tactic/Grind/Lookahead.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ where
2424
loop (goal : Goal) : GrindM Bool := withIncRecDepth do
2525
if goal.inconsistent then
2626
return true
27-
else if let some goals ← assertNext goal then
27+
else if let some goals ← assertAll goal then
2828
cont goals
2929
else if let some goals ← Arith.check goal then
3030
cont goals
3131
else if let some goals ← splitNext goal then
3232
cont goals
33-
else if let some goals ← ematchAndAssert goal then
33+
else if let some goals ← ematch goal then
3434
cont goals
3535
else
3636
return false

src/Lean/Meta/Tactic/Grind/Solve.lean

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ def setFailure (goal : Goal) : M Unit := do
3535
modify fun s => { s with failure? := some goal }
3636

3737
@[inline] def stepGuard (x : Goal → M Bool) (goal : Goal) : M Bool := do
38-
try
39-
x goal
40-
catch ex =>
41-
if ex.isMaxHeartbeat || ex.isMaxRecDepth then
42-
reportIssue! ex.toMessageData
43-
setFailure goal
44-
return true
45-
else
46-
throw ex
38+
tryCatchRuntimeEx
39+
(x goal)
40+
fun ex => do
41+
if ex.isMaxHeartbeat || ex.isMaxRecDepth then
42+
reportIssue! ex.toMessageData
43+
setFailure goal
44+
return true
45+
else
46+
throw ex
4747

4848
def applyTac (x : GrindTactic) (goal : Goal) : M Bool := do
4949
let go (goal : Goal) : M Bool := do
@@ -52,18 +52,18 @@ def applyTac (x : GrindTactic) (goal : Goal) : M Bool := do
5252
return true
5353
stepGuard go goal
5454

55-
def tryAssertNext : Goal → M Bool := applyTac assertNext
55+
def tryAssertAll : Goal → M Bool := applyTac assertAll
5656

57-
def tryEmatch : Goal → M Bool := applyTac ematchAndAssert
58-
59-
def trySplit : Goal → M Bool := applyTac splitNext
57+
def tryEmatch : Goal → M Bool := applyTac ematch
6058

6159
def tryArith : Goal → M Bool := applyTac Arith.check
6260

6361
def tryLookahead : Goal → M Bool := applyTac lookahead
6462

6563
def tryMBTC : Goal → M Bool := applyTac Arith.Cutsat.mbtcTac
6664

65+
def trySplit : Goal → M Bool := applyTac splitNext
66+
6767
partial def main (fallback : Fallback) : M Unit := do
6868
repeat do
6969
if (← get).failure?.isSome then
@@ -72,7 +72,7 @@ partial def main (fallback : Fallback) : M Unit := do
7272
return ()
7373
if goal.inconsistent then
7474
continue
75-
if (← tryAssertNext goal) then
75+
if (← tryAssertAll goal) then
7676
continue
7777
if (← tryArith goal) then
7878
continue
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
set_option grind.warning false
2+
3+
opaque f : Nat → Nat
4+
opaque op : Nat → Nat → Nat
5+
@[grind] theorem op_comm : op x y = op y x := sorry
6+
@[grind] theorem op_assoc : op (op x y) z = op x (op y z) := sorry
7+
8+
syntax "gen! " num : term
9+
10+
macro_rules
11+
| `(gen! 0) => `(f 0)
12+
| `(gen! $n:num) => `(op (f $n) (gen! $(Lean.quote (n.getNat - 1))))
13+
14+
/--
15+
trace: [grind.issues] (deterministic) timeout at `isDefEq`, maximum number of heartbeats (5000) has been reached
16+
Use `set_option maxHeartbeats <num>` to set the limit.
17+
18+
Additional diagnostic information may be available using the `set_option diagnostics true` command.
19+
-/
20+
#guard_msgs (trace, drop error) in
21+
set_option trace.grind.issues true in
22+
set_option maxHeartbeats 5000 in
23+
example : gen! 10 = 0 ∧ True := by
24+
grind (instances := 10000)

0 commit comments

Comments
 (0)