lean4-htt/tests/lean/run/substlet.lean
Kyle Miller 3af9ab64ed
feat: subst tactic can substitute let values (#8450)
This PR adds a feature to the `subst` tactic so that when `x : X := v`
is a local definition, `subst x` substitutes `v` for `x` in the goal and
removes `x`. Previously the tactic would throw an error.
2025-05-27 06:06:35 +00:00

112 lines
1.8 KiB
Text

/-!
# Tests of the `subst` tactic when `let`s are present.
-/
/-!
Eliminates `a` even though `e : id a = m`.
-/
/--
trace: case intro
n : Nat
m : Nat := n
a : Nat
e : id a = m
⊢ 0 + n = n
---
trace: case intro
a : Nat
m : Nat := id a
⊢ 0 + id a = id a
-/
#guard_msgs in
theorem ex1 (n : Nat) : 0 + n = n := by
let m := n
have h : ∃ k, id k = m := ⟨m, rfl⟩
cases h with
| intro a e =>
trace_state
subst e
trace_state
apply Nat.zero_add
/-!
Eliminates `a` even though `e : m = id a`.
-/
/--
trace: case intro
n : Nat
m : Nat := n
a : Nat
e : m = id a
⊢ 0 + n = n
---
trace: case intro
n : Nat
m : Nat := n
⊢ 0 + n = n
-/
#guard_msgs in
theorem ex2 (n : Nat) : 0 + n = n := by
let m := n
have h : ∃ k, m = id k := ⟨m, rfl⟩
cases h with
| intro a e =>
trace_state
subst e
trace_state
apply Nat.zero_add
/-!
Since `v` is a let binding, the `subst v` tactic instead
zeta delta reduces it everywhere and then clears it.
-/
/--
trace: n : Nat
h : n = 0
m : Nat := n + 1
v : Nat := m + 1
this : v = n + 2
⊢ 0 + n = 0
---
trace: n : Nat
h : n = 0
m : Nat := n + 1
this : m + 1 = n + 2
⊢ 0 + n = 0
---
trace: m : Nat := 0 + 1
this : m + 1 = 0 + 2
⊢ 0 + 0 = 0
-/
#guard_msgs in
theorem ex3 (n : Nat) (h : n = 0) : 0 + n = 0 := by
let m := n + 1
let v := m + 1
have : v = n + 2 := rfl
trace_state
subst v
trace_state
subst n
trace_state
rfl
/-!
Can't do `subst this` with `this : v = n + 2` since `v` is a let binding.
The tactic sees `m + 1 = n + 2` and fails.
-/
/--
error: tactic 'subst' failed, invalid equality proof, it is not of the form (x = t) or (t = x)
v = n + 2
n : Nat
h : n = 0
m : Nat := n + 1
v : Nat := m + 1
this : v = n + 2
⊢ 0 + n = 0
-/
#guard_msgs in
theorem ex4 (n : Nat) (h : n = 0) : 0 + n = 0 := by
let m := n + 1
let v := m + 1
have : v = n + 2 := rfl
subst this