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.
69 lines
2.1 KiB
Text
69 lines
2.1 KiB
Text
module
|
||
def Set (α : Type) := α → Bool
|
||
|
||
def insertElem [DecidableEq α] (s : Set α) (a : α) : Set α :=
|
||
fun x => a = x || s x
|
||
|
||
def contains (s : Set α) (a : α) : Bool :=
|
||
s a
|
||
|
||
theorem contains_insert [DecidableEq α] (s : Set α) (a : α) : contains (insertElem s a) a := by
|
||
simp [contains, insertElem]
|
||
|
||
grind_pattern contains_insert => contains (insertElem s a) a
|
||
|
||
-- TheoremPattern activation test
|
||
|
||
set_option trace.grind.ematch true
|
||
set_option trace.grind.ematch.pattern true
|
||
|
||
/-- trace: [grind.ematch] activated `contains_insert`, [@contains #3 (@insertElem _ #2 #1 #0) #0] -/
|
||
#guard_msgs (trace) in
|
||
example [DecidableEq α] (s₁ s₂ : Set α) (a₁ a₂ : α) :
|
||
s₂ = insertElem s₁ a₁ → a₁ = a₂ → contains s₂ a₂ := by
|
||
grind
|
||
|
||
/-- trace: [grind.ematch] activated `contains_insert`, [@contains #3 (@insertElem _ #2 #1 #0) #0] -/
|
||
#guard_msgs (trace) in
|
||
example [DecidableEq α] (s₁ s₂ : Set α) (a₁ a₂ : α) :
|
||
¬ contains s₂ a₂ → s₂ = insertElem s₁ a₁ → a₁ = a₂ → False := by
|
||
grind
|
||
|
||
def a := 10
|
||
def b := 20
|
||
def foo (x : List Nat) (y : List Nat) := x ++ y ++ x
|
||
|
||
theorem fooThm : foo x [a, b] = x ++ [a, b] ++ x := rfl
|
||
|
||
/-- trace: [grind.ematch.pattern] fooThm: [foo #0 `[[a, b]]] -/
|
||
#guard_msgs in
|
||
grind_pattern fooThm => foo x [a, b]
|
||
|
||
|
||
/--
|
||
trace: [grind.internalize] [0] x
|
||
[grind.internalize] [0] y
|
||
[grind.internalize] [0] z
|
||
[grind.internalize] [0] foo x y
|
||
[grind.internalize] [0] [a, b]
|
||
[grind.internalize] [0] Nat
|
||
[grind.internalize] [0] a
|
||
[grind.internalize] [0] [b]
|
||
[grind.internalize] [0] b
|
||
[grind.internalize] [0] []
|
||
[grind.ematch] activated `fooThm`, [foo #0 `[[a, b]]]
|
||
-/
|
||
#guard_msgs (trace) in
|
||
set_option trace.grind.internalize true in
|
||
example : foo x y = z → False := by
|
||
fail_if_success grind
|
||
sorry
|
||
|
||
theorem arrEx [Add α] (as : Array α) (h₁ : i < as.size) (h₂ : i = j) : as[i]+as[j] = as[i] + as[i] := by sorry
|
||
|
||
|
||
/--
|
||
trace: [grind.ematch.pattern] arrEx: [@HAdd.hAdd #6 _ _ _ (@getElem (Array _) `[Nat] _ _ _ #2 #5 _) (@getElem (Array _) `[Nat] _ _ _ #2 #4 _)]
|
||
-/
|
||
#guard_msgs in
|
||
grind_pattern arrEx => as[i]+as[j]'(h₂▸h₁)
|