Zulip Chat Archive
Stream: new members
Topic: my attempt proving gcd(a, b) = gcd(b, a)
agro1986 (Nov 08 2019 at 05:29):
Hi everyone. I tried defining gcd and then proving that gcd(a, b) implies gcd(b, a):
variables {a b c d: ℤ}
def divides (a b: ℤ): Prop := ∃(d: ℤ), b = a * d
def gcd (a b d: ℤ): Prop :=
¬(a = 0 ∧ b = 0) ∧
divides d a ∧
divides d b ∧
∀ (c: ℤ), divides c a ∧ divides c b → c ≤ d
theorem gcd_sym (h: gcd a b d): gcd b a d :=
begin
let hnonzero := h.left, -- ¬(a = 0 ∧ b = 0)
let hda := h.right.left, -- divides d a ∧
let hdb := h.right.right.left, -- divides d b ∧
let hgreatest := h.right.right.right,
apply and.intro,
exact (assume hzero: b = 0 ∧ a = 0,
hnonzero ⟨hzero.right, hzero.left⟩),
apply and.intro,
assumption,
apply and.intro,
assumption,
assume c,
let hc_lt_d := hgreatest c,
assume hc_divides,
exact hc_lt_d ⟨hc_divides.right, hc_divides.left⟩
end
Would you define gcd differently? (e.g., something that means the same thing but is more canonical to write in Lean)
Also, the proof is a bit long for basically flipping some terms. Any way you would streamline it? Thanks a lot!
Anne Baanen (Nov 08 2019 at 07:14):
My instinct would be to define gcd : ℤ → ℤ → ℤ using Euclid's algorithm (and prove it is the unique number that satisfies the condition in your gcd proposition). The proof would then state gcd a b = gcd b a.
Anne Baanen (Nov 08 2019 at 07:16):
But I'm pretty much an intuitionist, so take that as you want :P
Johan Commelin (Nov 08 2019 at 09:01):
@agro1986 Could you explain a bit of your background/motivation/goal? Such a bigger picture could help us with answering more specific questions. Are these training exercises, or do you want to formalise a particular piece of maths, or do you have another goal?
Kevin Buzzard (Nov 08 2019 at 09:17):
Here's a more compressed tactic mode proof:
theorem gcd_sym (h: gcd a b d): gcd b a d := begin rcases h with ⟨hne0, hda, hdb, hdmin⟩, split, exact mt and.comm.mp hne0, split, assumption, split, assumption, rintros c ⟨ha, hb⟩, exact hdmin c ⟨hb, ha⟩ end
Kevin Buzzard (Nov 08 2019 at 09:20):
and here's a term mode proof:
theorem gcd_sym (h: gcd a b d): gcd b a d := ⟨mt and.comm.mp h.1, h.2.2.1, h.2.1, λ c hc, h.2.2.2 _ ⟨hc.2, hc.1⟩⟩
agro1986 (Nov 08 2019 at 11:11):
@Johan Commelin for now, training exercise to familiarize myself with the language :). I'm rereading an elementary number theory textbook while challenging myself to write the definitions and proofs using Lean
agro1986 (Nov 08 2019 at 11:29):
@Tim Baanen hmm, that's an interesting way to think about it. Write the algorithm for it, and then using Lean prove that it satisfies certain properties...
However when I try something like this:
def add (a: ℤ) (b: ℤ): ℤ := a + b
def add_sym (a: ℤ) (b: ℤ): add a b = add b a :=
begin
-- ???
end
I don't have any idea to first prove the super obvious definitionally 100% correct fact that h: add a b = a + b :(. Any pointers?
Mario Carneiro (Nov 08 2019 at 11:36):
rfl
Mario Carneiro (Nov 08 2019 at 11:36):
in tactic mode, unfold add will change the goal to a + b = b + a
Kevin Buzzard (Nov 08 2019 at 11:39):
Because it's true by definition, you can use the change tactic. For example change a + b = b + a should work.
agro1986 (Nov 08 2019 at 11:41):
@Mario Carneiro Great!
def add_sym (a: ℤ) (b: ℤ): add a b = add b a :=
begin
unfold add,
ring,
end
change tactic also works! Thanks @Kevin Buzzard
agro1986 (Nov 08 2019 at 12:06):
@Kevin Buzzard Thank you for the compressed tactic mode proof also. It's kind of a magical experience that with Lean, you can just paste the proof and then I can interactively walk through it while seeing how the state changes. rcases and rintros with their pattern matching is so useful.
Reid Barton (Nov 08 2019 at 13:21):
I think a better definition would conclude ∀ (c: ℤ), divides c a ∧ divides c b → divides c d. Then asssume d >= 0. You don't need the ¬(a = 0 ∧ b = 0) part.
Last updated: May 02 2025 at 03:31 UTC