rw
Summary
The rw or rewrite tactic is a “substitute in” tactic. If h : x = y is a hypothesis then rw [h] changes all of the x s in the goal to y s. rw also works with iff statements: if h : P ↔ Q then rw [h] will replace all the P s in the goal with Q s.
Notes
rw works up to syntactic equality, i.e. if h : x = y then rw [h] will only work if the goal contains something which is literally the same as x.
A common mistake I see is people trying rw [h] when h is not an equality, or an iff statement; most commonly people try it when h has type P → Q. This won’t work; you use the apply tactic in this situation.
Examples
Faced with
h : x = y
⊢ x ^ 2 = 1369
the tactic rw [h] will turn the goal into y ^ 2 = 1369.
rwworks with↔statements as well. Faced with
h : P ↔ Q
⊢ P ∧ R
the tactic rw [h] will turn the goal into ⊢ Q ∧ R.
rwcan also be used to rewrite in hypotheses. For example givenh : x = yandh2 : x ^ 2 = 289, the tacticrw [h] at h2will turnh2intoh2 : y ^ 2 = 289. You can rewrite in multiple places at once – for examplerw [h] at h1 h2 h3will change all occurrences of the left hand side ofhinto the right hand side, in all ofh1,h2andh3. If you want to rewrite in a hypothesis and a goal at the same time, tryrw [h] at h1 ⊢(type the turnstile⊢symbol with\|-).rwdoesn’t just eat hypotheses – the theoremzero_addsays∀ x, 0 + x = x, so if you have a goal⊢ 0 + t = 37thenrw [zero_add]will change it tot = 37. Note thatrwis smart enough to fill in the value ofxfor you.If you want to replace the right hand side of a hypothesis
hwith the left hand side, thenrw [← h]will do it. Type←with\l, noting thatlis a small letterLfor left, and not a number1.You can chain rewrites in one tactic. Equivalent to
rw [h1],rw [h2],rw [h3]isrw [h1, h2, h3].rwwill match on the first thing it finds. For example,add_commis the theorem that∀ x y, x + y = y + x. If the goal is⊢ a + b + c = 0thenrw add_commwill change it to⊢ c + (a + b) = 0, because if we strip away the notation thena + b + c = add (add a b) c, which gets changed toadd c (add a b). If you wanted to switchaandbthen you can tell Lean to do this explicitly withrw add_comm a b.
Further notes
rwtries a weak version ofrflwhen it’s finished. Beginners can find this confusing; indeed I disabled this in the natural number game because users found it confusing. As an example, if your tactic state is
h : P ↔ Q
⊢ P ∧ R ↔ Q ∧ R
then rw [h] will close the goal, because after the rewrite the goal becomes ⊢ Q ∧ R ↔ Q ∧ R and rfl closes this goal.
A variant of
rwisrwa, which isrwfollowed by theassumptiontactic. For example if your tactic state is
h1 : P ↔ Q
h2 : Q ↔ R
⊢ P ↔ R
then rwa [h1] closes the goal, because it turns the goal into Q ↔ R which is one of our assumptions.
If
h : x = yand your goal is⊢ x * 2 + z = x, thenrw [h]will turn bothx``s into ``y``s. If you only want to turn one of the ``x``s into a ``ythen you can usenth_rw 1 [h](for the first one) ornth_rw 2 [h](for the second one).rwworks up to syntactic equality. This means that ifh : (P → False) ↔ Qand the goal is⊢ ¬Pthenrw [h]will fail, even thoughP → Falseand¬Pare definitionally equal. The left hand side has to match on the nose.rwdoes not work under binders. Examples of binders are∀and∃. For example, if your goal is⊢ ∀ (x : ℕ), x + 0 = 0 + xthenrw [add_zero]will not work. In situations like this you can either dointro xfirst, or you can use the more powerfulsimp_rwtactic;simp_rw [add_zero]works and changes the goal to∀ (x : ℕ), x = 0 + x.