This PR adds support for interactivity to the combined "try this" messages that were introduced in #9966. In doing so, it moves the link to apply a suggestion to a separate `[apply]` button in front of the suggestion. Hints with diffs remain unchanged, as they did not previously support interacting with terms in the diff, either. <img width="379" height="256" alt="Suggestion with interactive message" src="https://github.com/user-attachments/assets/7838ebf6-0613-46e7-bc88-468a05acbf51" />
403 lines
11 KiB
Text
403 lines
11 KiB
Text
set_option linter.unusedSimpArgs false
|
||
|
||
axiom testSorry : α
|
||
|
||
opaque a : Nat
|
||
opaque b : Nat
|
||
|
||
theorem ab : a = b := testSorry
|
||
theorem ba : b = a := testSorry
|
||
theorem aa : a = id a := testSorry
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `aa`
|
||
|
||
Note: Possibly caused by: `id`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : id a = 23 := by simp -failIfUnchanged only [aa, id]
|
||
|
||
-- also simp_all
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `aa`
|
||
|
||
Note: Possibly caused by: `id`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : id a = 23 := by simp_all -failIfUnchanged only [aa, id]
|
||
|
||
|
||
-- Other exceptions do not trigger the loop check
|
||
|
||
/--
|
||
error: unsolved goals
|
||
⊢ b = 23
|
||
-/
|
||
#guard_msgs in
|
||
example : id b = 23 := by simp -failIfUnchanged only [aa, id]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `aa`
|
||
|
||
Note: Possibly caused by: `id`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
|
||
Note: This linter can be disabled with `set_option linter.loopingSimpArgs false`
|
||
---
|
||
error: unsolved goals
|
||
⊢ b = 23
|
||
-/
|
||
#guard_msgs in
|
||
set_option linter.loopingSimpArgs true in
|
||
example : id b = 23 := by simp -failIfUnchanged only [aa, id]
|
||
|
||
/-- error: `simp` made no progress -/
|
||
#guard_msgs in
|
||
example : b = 23 := by simp only [aa, id]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `ab`
|
||
|
||
Note: Possibly caused by: `ba`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `ba`
|
||
|
||
Note: Possibly caused by: `ab`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : a = 23 := by simp -failIfUnchanged [ab, ba]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `ab`
|
||
|
||
Note: Possibly caused by: `ba`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `ba`
|
||
|
||
Note: Possibly caused by: `ab`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : a = 2*b := by simp -failIfUnchanged [ab, ba]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `← ab`
|
||
|
||
Note: Possibly caused by: `← ba`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `← ba`
|
||
|
||
Note: Possibly caused by: `← ab`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : a = 23 := by simp -failIfUnchanged [← ab, ← ba]
|
||
|
||
-- Local theorems are not checked for loops,
|
||
-- but are still applied when checking other rules
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `ab`
|
||
|
||
Note: Possibly caused by: `h`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example (h : b = a) : a = 23 := by simp -failIfUnchanged [ab, h]
|
||
|
||
/-! Examples from the original RFC -/
|
||
|
||
variable (P : Nat → Prop)
|
||
/--
|
||
warning: Possibly looping simp theorem: `Nat.add_assoc`
|
||
|
||
Note: Possibly caused by: `(Nat.add_assoc _ _ _).symm`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `(Nat.add_assoc _ _ _).symm`
|
||
|
||
Note: Possibly caused by: `Nat.add_assoc`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example (a b c : Nat) : P (a + b + c) := by simp [Nat.add_assoc, (Nat.add_assoc _ _ _).symm]
|
||
|
||
inductive Tree (α : Type) where | node : α → List (Tree α) → Tree α
|
||
def Tree.children : Tree α → List (Tree α) | .node _ ts => ts
|
||
def Tree.size (t : Tree α) := 1 + List.sum (t.children.attach.map (fun ⟨c,_⟩ => c.size))
|
||
decreasing_by simp_wf; cases t; simp_all [Tree.children]; decreasing_trivial
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `Tree.size.eq_1`
|
||
|
||
Note: Possibly caused by: `Tree.size`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example (t : Tree α) : 0 < t.size := by simp [Tree.size]
|
||
|
||
|
||
/--
|
||
Identifiyng looping theorems by their origin is not enough,
|
||
as the elements of conjunctions would clash, as shown by these:
|
||
|
||
(The error message isn't great yet, but it's a corner case)
|
||
-/
|
||
|
||
theorem b1ab : b = 1 ∧ a = b := testSorry
|
||
theorem baab : b = a ∧ a = b := testSorry
|
||
|
||
/--
|
||
error: unsolved goals
|
||
P : Nat → Prop
|
||
⊢ 1 > 0
|
||
-/
|
||
#guard_msgs in
|
||
example : a > 0 := by simp only [b1ab]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `baab`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `baab`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : a > 0 := by simp only [baab]
|
||
|
||
-- Same, with local theorems (should we ever support them):
|
||
|
||
/--
|
||
error: unsolved goals
|
||
P : Nat → Prop
|
||
a b : Nat
|
||
h1 : b = 1 ∧ a = b
|
||
h2 : 1 > 0
|
||
⊢ True
|
||
-/
|
||
#guard_msgs in
|
||
example
|
||
(a b : Nat)
|
||
(h1 : b = 1 ∧ a = b )
|
||
(h2 : a > 0) : True := by
|
||
simp only [h1] at h2
|
||
|
||
|
||
/-!
|
||
Unfolding should not confuse it.
|
||
(Error message is not optimal as it does not mention the unfolded definition.)
|
||
-/
|
||
|
||
def c := a
|
||
def ac : a = c := rfl
|
||
def ca : c = a := rfl
|
||
def d := c
|
||
def dc : d = c := rfl
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `c.eq_1`
|
||
|
||
Note: Possibly caused by: `ac` and `c`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `ac`
|
||
|
||
Note: Possibly caused by: `c`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : c > 0 := by simp only [c, ac]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `dc`
|
||
|
||
Note: Possibly caused by: `c` and `ac`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `c.eq_1`
|
||
|
||
Note: Possibly caused by: `ac` and `c`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `ac`
|
||
|
||
Note: Possibly caused by: `c`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : d > 0 := by simp only [dc, c, ac]
|
||
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `c.eq_1`
|
||
|
||
Note: Possibly caused by: `ac` and `c`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
warning: Possibly looping simp theorem: `ac`
|
||
|
||
Note: Possibly caused by: `c`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : a > 0 := by simp only [c, ac]
|
||
|
||
example (h : c = 1) : d > 0 := by simp only [dc, h, ca, ac, Nat.one_pos]
|
||
|
||
|
||
/-!
|
||
Simp? does not print the warnings for now. Let’s see if users find that helpful or confusing.
|
||
-/
|
||
|
||
/--
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : d > 0 := by simp? only [dc, ca, ac]; exact testSorry
|
||
|
||
/-!
|
||
But we can turn it on:
|
||
-/
|
||
set_option linter.loopingSimpArgs true in
|
||
/--
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : d > 0 := by simp? only [dc, ca, ac]; exact testSorry
|
||
|
||
/--
|
||
info: Try this:
|
||
[apply] simp only [dc, h, Nat.one_pos]
|
||
-/
|
||
#guard_msgs in
|
||
example (h : c = 1) : d > 0 := by simp? only [dc, h, ca, ac, Nat.one_pos]
|
||
|
||
|
||
/-! An example where a second rewrite rules makes the looping rule looping,
|
||
without being itself looping.
|
||
-/
|
||
|
||
opaque f : Nat → Nat
|
||
theorem fbfa : f b = f a := testSorry
|
||
theorem fbffa : f b = f (f a) := testSorry
|
||
|
||
-- This one doesn't actually trigger because `simpLoop` does not recurse when
|
||
-- the expression is the same after `post`. Also see issue #8864
|
||
|
||
/--
|
||
error: unsolved goals
|
||
P : Nat → Prop
|
||
⊢ 0 < f a
|
||
-/
|
||
#guard_msgs in
|
||
example : 0 < f a := by simp -failIfUnchanged [fbfa, ab]
|
||
|
||
/--
|
||
warning: Possibly looping simp theorem: `fbffa`
|
||
|
||
Note: Possibly caused by: `ab`
|
||
|
||
Hint: You can disable a simp theorem from the default simp set by passing `- theoremName` to `simp`.
|
||
---
|
||
error: Tactic `simp` failed with a nested error:
|
||
maximum recursion depth has been reached
|
||
use `set_option maxRecDepth <num>` to increase limit
|
||
use `set_option diagnostics true` to get diagnostic information
|
||
-/
|
||
#guard_msgs in
|
||
example : 0 < f a := by simp -failIfUnchanged [fbffa, ab]
|