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.
26 lines
800 B
Text
26 lines
800 B
Text
import Std.Do
|
||
|
||
/-
|
||
Section variables should not be included.
|
||
-/
|
||
variable {Q : Std.Do.PostCond α ps}
|
||
def Id.instLawfulMonad' : LawfulMonad Id := by
|
||
apply LawfulMonad.mk' <;> (simp only [Id.instMonad]; grind)
|
||
|
||
/-- info: Id.instLawfulMonad'.{u_1} : LawfulMonad Id -/
|
||
#guard_msgs in
|
||
#check Id.instLawfulMonad'
|
||
|
||
/-
|
||
Note that they are included when using `grind +revert`.
|
||
The problem is that the idiom `revert` and then re-`intro` while simplifying creates the
|
||
illusion that the section variables are needed.
|
||
-/
|
||
def Id.instLawfulMonad'' : LawfulMonad Id := by
|
||
apply LawfulMonad.mk' <;> (simp only [Id.instMonad]; grind +revert)
|
||
|
||
/--
|
||
info: Id.instLawfulMonad''.{u_1, u_2} {α : Type u_2} {ps : Std.Do.PostShape} {Q : Std.Do.PostCond α ps} : LawfulMonad Id
|
||
-/
|
||
#guard_msgs in
|
||
#check Id.instLawfulMonad''
|