rw — Rewriting
rw replaces one term with an equal term in your goal. It's how you use equalities to transform what you're proving.
The Basic Idea
If you know a = b, you can replace awith b anywhere:
lean
1example (a b : Nat) (h : a = b) : a + 1 = b + 1 := by2 rw [h]3 -- Goal was: a + 1 = b + 14 -- After rw: b + 1 = b + 15 rflThe rw [h] tactic finds a in the goal and replaces it with b (because h : a = b).
Direction Matters
By default, rw replaces left with right. Use ←to go the other direction:
lean
1example (a b : Nat) (h : a = b) : b = a := by2 rw [h] -- Replaces a with b... but there's no 'a' in goal!3 -- Actually: replaces 'a' in goal. Goal: b = b. Works!45example (a b : Nat) (h : a = b) : b + 1 = a + 1 := by6 rw [← h] -- h : a = b, but ← h replaces b with a7 -- Goal becomes: a + 1 = a + 18 rflKey Takeaway
rw [h] replaces left→right: if h : a = b, it replaces a with b.rw [← h] replaces right→left: replaces bwith a.Using Library Lemmas
You can rewrite with named lemmas from the library:
lean
1example (n : Nat) : n + 0 = n := by2 rw [Nat.add_zero]3 -- Nat.add_zero : ∀ n, n + 0 = n4 -- Replaces n + 0 with n56example (a b : Nat) : a + b = b + a := by7 rw [Nat.add_comm]8 -- Nat.add_comm : ∀ a b, a + b = b + a9 -- Goal becomes: b + a = b + a1011example (n : Nat) : 0 + n = n := by12 rw [Nat.zero_add]13 -- Nat.zero_add : ∀ n, 0 + n = nMultiple Rewrites
Chain rewrites in a single rw:
lean
1example (a b c : Nat) (h1 : a = b) (h2 : b = c) : a = c := by2 rw [h1, h2]3 -- First: replace a with b4 -- Then: replace b with c5 -- Goal: c = c67example (n : Nat) : n + 0 + 0 = n := by8 rw [Nat.add_zero, Nat.add_zero]9 -- Apply twice to remove both zerosRewriting in Hypotheses
Use rw [...] at h to rewrite in a hypothesis instead of the goal:
lean
1example (a b : Nat) (h1 : a = b) (h2 : a + 1 = 5) : b + 1 = 5 := by2 rw [h1] at h23 -- Before: h2 : a + 1 = 54 -- After: h2 : b + 1 = 55 exact h267example (n : Nat) (h : n + 0 = 5) : n = 5 := by8 rw [Nat.add_zero] at h9 -- h becomes: n = 510 exact hRewriting Everywhere
lean
1example (a b : Nat) (h : a = b) (h2 : a + a = 10) : b + b = 10 := by2 rw [h] at *3 -- Rewrites in ALL hypotheses and the goal4 exact h2Common Lemmas for Rewriting
Addition
lean
1#check Nat.add_zero -- n + 0 = n2#check Nat.zero_add -- 0 + n = n3#check Nat.add_comm -- a + b = b + a4#check Nat.add_assoc -- (a + b) + c = a + (b + c)5#check Nat.succ_add -- (n + 1) + m = (n + m) + 16#check Nat.add_succ -- n + (m + 1) = (n + m) + 1Multiplication
lean
1#check Nat.mul_zero -- n * 0 = 02#check Nat.zero_mul -- 0 * n = 03#check Nat.mul_one -- n * 1 = n4#check Nat.one_mul -- 1 * n = n5#check Nat.mul_comm -- a * b = b * a6#check Nat.mul_assoc -- (a * b) * c = a * (b * c)Lists
lean
1#check List.append_nil -- xs ++ [] = xs2#check List.nil_append -- [] ++ xs = xs3#check List.append_assoc -- (xs ++ ys) ++ zs = xs ++ (ys ++ zs)💡
Use
#check to see a lemma's type. The type tells you exactly what it can rewrite.rw vs rfl
Sometimes rw and rfl can both close a goal:
lean
1example : 2 + 0 = 2 := by rfl -- Computes directly2example : 2 + 0 = 2 := by rw [Nat.add_zero] -- Uses lemma34-- rfl works here because + is defined to compute n + 0 = n5-- But for general n, you need the lemma:6example (n : Nat) : n + 0 = n := by7 -- rfl -- Fails! n is a variable8 rw [Nat.add_zero] -- WorksDeep Dive: How rw Finds Subterms
rw searches the goal for the left-hand side of the equality and replaces the first match. If there are multiple matches, you can control which one:
lean
1example (a : Nat) : a + a = a + a := by2 rw [Nat.add_comm] -- Rewrites first a + a to a + a (no visible change!)3 rfl45-- Use nth_rewrite to target specific occurrences6example (a b : Nat) : a + b + (a + b) = (b + a) + (a + b) := by7 nth_rewrite 1 [Nat.add_comm] -- Only rewrite the first a + b8 rflCombining with Other Tactics
lean
1example (a b c : Nat) (h : a = b + c) : a + a = (b + c) + (b + c) := by2 rw [h] -- Replace a with b + c34example (n m : Nat) (h : n = m) : n + n = m + m := by5 rw [h] -- Both n's become m67example (a b : Nat) : (a + b) + 0 = b + a := by8 rw [Nat.add_zero] -- Remove the + 09 rw [Nat.add_comm] -- Swap a + b to b + a