This PR improves the `grind` tactic generated by the `instantiate`
action in tracing mode. It also updates the syntax for the `instantiate`
tactic, making it similar to `simp`. For example:
* `instantiate only [thm1, thm2]` instantiates only theorems `thm1` and
`thm2`.
* `instantiate [thm1, thm2]` instantiates theorems marked with the
`@[grind]` attribute **and** theorems `thm1` and `thm2`.
The action produces `instantiate only [...]` tactics. Example:
```lean
/--
info: Try this:
[apply] ⏎
instantiate only [= Array.getElem_set]
instantiate only [= Array.getElem_set]
-/
#guard_msgs in
example (as bs cs : Array α) (v₁ v₂ : α)
(i₁ i₂ j : Nat)
(h₁ : i₁ < as.size)
(h₂ : bs = as.set i₁ v₁)
(h₃ : i₂ < bs.size)
(h₄ : cs = bs.set i₂ v₂)
(h₅ : i₁ ≠ j ∧ i₂ ≠ j)
(h₆ : j < cs.size)
(h₇ : j < as.size) :
cs[j] = as[j] := by
grind => finish?
```
Recall that `finish?` replays generated tactics before suggesting them.
The `instantiate` action inspects the generated proof term to decide
which theorems to include as parameters in the `instantiate only [...]`
tactic. However, in some cases, a theorem contributes only by adding a
term to the state. In such cases, the generated tactic cannot be fully
replayed, and the action uses
`instantiate approx [<thms instantiated>]` to indicate which parts of
the tactic script are approximate. The `approx` is just a hint for
users.
62 lines
1.5 KiB
Text
62 lines
1.5 KiB
Text
open Lean Grind
|
||
|
||
/--
|
||
info: Try this:
|
||
[apply] cases #c4b6 <;> ring <;> cases #4c68 <;> ring
|
||
-/
|
||
#guard_msgs in
|
||
example {α : Type} [CommRing α] (a b c d e : α) :
|
||
(a * a = b * c ∨ a^2 = c * b) →
|
||
(a^2 = c * b ∨ e^2 = d * c) →
|
||
(b^2 = d*c ∨ b^2 = c*d) →
|
||
a*b*(b*a) = c^2*b*d := by
|
||
grind => finish?
|
||
|
||
|
||
/--
|
||
info: Try this:
|
||
[apply] ⏎
|
||
cases #b0f4
|
||
next => cases #50fc
|
||
next => cases #50fc <;> lia
|
||
-/
|
||
#guard_msgs in
|
||
example (p : Nat → Prop) (x y z w : Int) :
|
||
(x = 1 ∨ x = 2) →
|
||
(w = 1 ∨ w = 4) →
|
||
(y = 1 ∨ (∃ x : Nat, y = 3 - x ∧ p x)) →
|
||
(z = 1 ∨ z = 0) → x + y ≤ 6 := by
|
||
grind => finish?
|
||
|
||
/--
|
||
info: Try this:
|
||
[apply] ⏎
|
||
ac
|
||
cases #5c4b <;> cases #896f <;> ac
|
||
-/
|
||
#guard_msgs in
|
||
example {α : Type} (op : α → α → α) [Std.Associative op] [Std.Commutative op] (a b c d e : α) :
|
||
(op a a = op b c ∨ op a a = op c b) →
|
||
(op a a = op c b ∨ op e e = op d c) →
|
||
(op b b = op d c ∨ op b b = op c d) →
|
||
op (op a b) (op b a) = op (op c c) (op b d) := by
|
||
grind => finish?
|
||
|
||
/--
|
||
info: Try this:
|
||
[apply] ⏎
|
||
instantiate only [= Array.getElem_set]
|
||
instantiate only [= Array.getElem_set]
|
||
-/
|
||
#guard_msgs in
|
||
example (as bs cs : Array α) (v₁ v₂ : α)
|
||
(i₁ i₂ j : Nat)
|
||
(h₁ : i₁ < as.size)
|
||
(h₂ : bs = as.set i₁ v₁)
|
||
(h₃ : i₂ < bs.size)
|
||
(h₃ : cs = bs.set i₂ v₂)
|
||
(h₄ : i₁ ≠ j ∧ i₂ ≠ j)
|
||
(h₅ : j < cs.size)
|
||
(h₆ : j < as.size)
|
||
: cs[j] = as[j] := by
|
||
grind => finish?
|