import Lean.Meta.Tactic.Simp.Simproc /-! # Behavior of `simp?` -/ /-! `simp?` lists the lemmas in order of being applied and not in the order of being declared. Note: This is not always desirable, see #4615 -/ def x1 := 1 def x2 := 1 def x3 := 1 def x4 := 1 @[simp] theorem x2_eq_x3 : x2 = x3 := rfl @[simp] theorem x3_eq_x4 : x3 = x4 := rfl @[simp] theorem x1_eq_x2 : x1 = x2 := rfl /-- info: Try this: [apply] simp only [x1_eq_x2, x2_eq_x3, x3_eq_x4] -/ #guard_msgs in example : x1 = x4 := by simp? /-! `simp?` lists every theorem being used only once. -/ /-- info: Try this: [apply] simp only [x1_eq_x2, x2_eq_x3, x3_eq_x4] -/ #guard_msgs in example : x1 * x1 = x4 * x4 := by simp? @[simp] def test : Nat → Nat | 0 => 3 | 1 => 5 | 2 => 9 | 3 => 4 | 4 => 16 | _ => 0 /-! `simp?` mentions the name of the definition instead of the names of the equation lemmas. -/ /-- info: Try this: [apply] simp only [test] -/ #guard_msgs in example : [test 3, test 2, test 4, test 5, test 0] = [4, 9, 16, 0, 3] := by simp? /-! `simp?` records names of `let` declarations being unfolded. -/ /-- info: Try this: [apply] simp only [a] -/ #guard_msgs in example : let a := 5; a = 5 := by intro a simp? [a] /-! `simp?` shouldn't mention matcher equations. -/ /-- info: Try this: [apply] simp only [h] --- error: unsolved goals a b : Nat h : a = 3 ⊢ 9 = b -/ #guard_msgs in example (h : a = 3) : (match (generalizing := false) a with | 0 => 7 | _ + 1 => 9) = b := by simp? [h] /-! `simp?` also mentions simprocs (builtin and non-builtin) but only if they succeeded. -/ def y1 := 1 def y2 := 1 simproc rewriteY1 (y1) := fun _ => do return .done { expr := Lean.mkConst ``y2 } simproc dontRewriteY2 (y2) := fun _ => do Lean.logInfo "was run" return .continue /-- info: was run --- info: Try this: [apply] simp only [rewriteY1] -/ #guard_msgs in example : y1 = y2 := by simp? -- rewriteY1 succeeds, dontRewriteY2 doesn't /-- info: Try this: [apply] simp only [Nat.reduceAdd] -/ #guard_msgs in example : 1 + 1 = 2 := by simp? /-! The left arrow (`←`) should be grouped together with the lemma name. -/ def z1 := 1 def z2 := 1 def z3 := 1 theorem very_long_lemma_oh_no_can_you_please_stop_we're_getting_to_the_limit : z1 = z2 := rfl theorem wait_this_is_rewritten_backwards_and_wow_it's_very_clear_and_obvious : z3 = z2 := rfl /-- info: Try this: [apply] simp only [very_long_lemma_oh_no_can_you_please_stop_we're_getting_to_the_limit, ← wait_this_is_rewritten_backwards_and_wow_it's_very_clear_and_obvious] -/ #guard_msgs in example : z1 = z3 := by simp? [very_long_lemma_oh_no_can_you_please_stop_we're_getting_to_the_limit, ← wait_this_is_rewritten_backwards_and_wow_it's_very_clear_and_obvious]