This PR implements the option `revert`, which is set to `false` by default. To recover the old `grind` behavior, you should use `grind +revert`. Previously, `grind` used the `RevSimpIntro` idiom, i.e., it would revert all hypotheses and then re-introduce them while simplifying and applying eager `cases`. This idiom created several problems: * Users reported that `grind` would include unnecessary parameters. See [here](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/Grind.20aggressively.20includes.20local.20hypotheses.2E/near/554887715). * Unnecessary section variables were also being introduced. See the new test contributed by Sebastian Graf. * Finally, it prevented us from supporting arbitrary parameters as we do in `simp`. In `simp`, I implemented a mechanism that simulates local universe-polymorphic theorems, but this approach could not be used in `grind` because there is no mechanism for reverting (and re-introducing) local universe-polymorphic theorems. Adding such a mechanism would require substantial work: I would need to modify the local context object. I considered maintaining a substitution from the original variables to the new ones, but this is also tricky, because the mapping would have to be stored in the `grind` goal objects, and it is not just a simple mapping. After reverting everything, I would need to keep a sequence of original variables that must be added to the mapping as we re-introduce them, but eager case splits complicate this quite a bit. The whole approach felt overly messy. The new behavior `grind -revert` addresses all these issues. None of the `grind` proofs in our test suite broke after we fixed the bugs exposed by the new feature. That said, the traces and counterexamples produced by `grind` are different. The new proof terms are also different.
85 lines
1.4 KiB
Text
85 lines
1.4 KiB
Text
module
|
|
reset_grind_attrs%
|
|
|
|
attribute [grind] List.map_append
|
|
|
|
def a := 10
|
|
|
|
example : a = 5 + 5 := by
|
|
grind [a]
|
|
|
|
/--
|
|
error: `grind` failed
|
|
case grind
|
|
h : ¬a = 10
|
|
⊢ False
|
|
[grind] Goal diagnostics
|
|
[facts] Asserted facts
|
|
[prop] ¬a = 10
|
|
[eqc] False propositions
|
|
[prop] a = 10
|
|
[cutsat] Assignment satisfying linear constraints
|
|
[assign] a := 1
|
|
-/
|
|
#guard_msgs (error) in
|
|
example : a = 5 + 5 := by
|
|
grind
|
|
|
|
section
|
|
attribute [local grind] a
|
|
|
|
example : a = 5 + 5 := by
|
|
grind
|
|
end
|
|
|
|
def f (x : Nat) := x + 1
|
|
|
|
theorem fa : f a = 11 := rfl
|
|
|
|
example : f a = 10 + 1 := by
|
|
grind [fa]
|
|
|
|
/--
|
|
error: `grind` failed
|
|
case grind
|
|
h : ¬f a = 11
|
|
⊢ False
|
|
[grind] Goal diagnostics
|
|
[facts] Asserted facts
|
|
[prop] ¬f a = 11
|
|
[eqc] False propositions
|
|
[prop] f a = 11
|
|
[cutsat] Assignment satisfying linear constraints
|
|
[assign] a := 2
|
|
[assign] f a := 1
|
|
-/
|
|
#guard_msgs (error) in
|
|
example : f a = 10 + 1 := by
|
|
grind
|
|
|
|
attribute [grind] fa
|
|
|
|
example : f a = 10 + 1 := by
|
|
grind
|
|
|
|
/--
|
|
error: `grind` failed
|
|
case grind
|
|
x : Nat
|
|
h : ¬f x = 11
|
|
⊢ False
|
|
[grind] Goal diagnostics
|
|
[facts] Asserted facts
|
|
[prop] ¬f x = 11
|
|
[eqc] False propositions
|
|
[prop] f x = 11
|
|
[ematch] E-matching patterns
|
|
[thm] fa: [f `[a]]
|
|
[cutsat] Assignment satisfying linear constraints
|
|
[assign] x := 1
|
|
[assign] a := 3
|
|
[assign] f x := 2
|
|
-/
|
|
#guard_msgs (error) in
|
|
example : f x = 10 + 1 := by
|
|
grind
|