Zulip Chat Archive
Stream: new members
Topic: Idiom
Richard Copley (Jul 23 2023 at 10:50):
Is there a more idiomatic way to do rewrite [(by ring : (a + b) * (a + b) = a * a + b * b + 2 * (a * b))]
in Lean 4?
The context is below (line 22). This is just a trivial learning example that I set for myself, from a question which came up on Libera IRC ##math. I'd appreciate any other hints on how a more experienced user of Lean 4 would write this proof.
import Mathlib.Data.Nat.Basic
import Mathlib.Data.Nat.GCD.Basic
import Mathlib.Tactic.Ring
theorem toy (a b : ℕ) : a * b ∣ (a + b)^2 → a = b := by
have C : ∀ {a b : ℕ}, a * b ∣ a * a + b * b → a ∣ b * b := by
intro a b h
rewrite [Nat.dvd_add_iff_right (Nat.dvd_mul_right a a)]
exact Nat.dvd_trans (Nat.dvd_mul_right a b) h
rewrite [Nat.pow_two]
if hz : a = 0 then
rewrite [hz, Nat.zero_add, Nat.zero_mul, ← Nat.mul_self_inj, Nat.zero_mul]
exact symm ∘ Nat.eq_zero_of_zero_dvd
else
let d := Nat.gcd a b
have dpos : 0 < d := Nat.gcd_pos_of_pos_left b (Nat.pos_of_ne_zero hz)
have ⟨⟨a', (h₁ : a = d * a')⟩, ⟨b', (h₂ : b = d * b')⟩⟩ := Nat.gcd_dvd a b
have hcoprime : Nat.coprime a' b' := by
rewrite [← (Nat.div_eq_iff_eq_mul_right dpos ⟨a', h₁⟩).mpr h₁]
rewrite [← (Nat.div_eq_iff_eq_mul_right dpos ⟨b', h₂⟩).mpr h₂]
exact Nat.coprime_div_gcd_div_gcd dpos
rewrite [(by ring : (a + b) * (a + b) = a * a + b * b + 2 * (a * b))]
rewrite [← Nat.dvd_add_iff_left (Nat.dvd_mul_left _ _)]
rewrite [h₁, h₂]
repeat rewrite [(by intro x y ; ring :
∀ (x y : ℕ), d * x * (d * y) = d * d * (x * y))]
rewrite [← Nat.mul_add, Nat.mul_dvd_mul_iff_left (Nat.mul_pos dpos dpos)]
intro h
apply congr_arg (fun x => d * x)
apply Nat.dvd_antisymm
. rewrite [← Nat.coprime.dvd_mul_right hcoprime]
exact C h
. rewrite [← Nat.coprime.dvd_mul_right hcoprime.symm]
exact C ((Nat.add_comm ..) ▸ (Nat.mul_comm ..) ▸ h)
Alex J. Best (Jul 23 2023 at 12:36):
At the moment, not really, some people like using the similar rw [show (a + b) * (a + b) = a * a + b * b + 2 * (a * b) by ring]
more but that is basically the same. Seeing as you are rewriting a subterm you can't use convert_to
which would be a more idiomatic way if you wanted to change the whole goal.
Richard Copley (Jul 23 2023 at 12:38):
Thank you. That is nice to know.
Ruben Van de Velde (Jul 23 2023 at 12:54):
How about rw [add_mul_self_eq]
Richard Copley (Jul 23 2023 at 22:00):
Ruben Van de Velde said:
How about
rw [add_mul_self_eq]
Thanks! Followed by rewrite [(by ring : a * a + 2 * a * b + b * b = a * a + b * b + 2 * (a * b)]
? Or rewrite [add_rotate, mul_assoc, add_assoc]
?
Eric Wieser (Jul 23 2023 at 22:00):
add_right_comm
should be enough
Richard Copley (Jul 23 2023 at 22:02):
Great! But not quite. Still need the mul_assoc
.
Do you think that's better?
Yury G. Kudryashov (Jul 24 2023 at 00:25):
Another option is to use calc
with ring
.
Last updated: Dec 20 2023 at 11:08 UTC