Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import NAxioms NSub NDiv NGcd.
Unlike other functions around, we will define lcm below instead of
axiomatizing it. Indeed, there is no "prior art" about lcm in the
standard library to be compliant with, and the generic definition
of lcm via gcd is quite reasonable.
By the way, we also state here some combined properties of div/mod
and gcd.
Module Type NLcmProp
(Import A : NAxiomsSig')
(Import B : NSubProp A)
(Import C : NDivProp A B)
(Import D : NGcdProp A B).
Divibility and modulo
forall a b : t, b ~= 0 -> a mod b == 0 <-> (b | a)forall a b : t, b ~= 0 -> a mod b == 0 <-> (b | a)a, b:tHb:b ~= 0a mod b == 0 <-> (b | a)a, b:tHb:b ~= 0a mod b == 0 -> (b | a)a, b:tHb:b ~= 0(b | a) -> a mod b == 0a, b:tHb:b ~= 0Hab:a mod b == 0(b | a)a, b:tHb:b ~= 0(b | a) -> a mod b == 0a, b:tHb:b ~= 0Hab:a mod b == 0a == a / b * ba, b:tHb:b ~= 0(b | a) -> a mod b == 0a, b:tHb:b ~= 0Hab:a mod b == 0a == b * (a / b)a, b:tHb:b ~= 0(b | a) -> a mod b == 0a, b:tHb:b ~= 0Hab:a mod b == 0b * (a / b) + a mod b == b * (a / b)a, b:tHb:b ~= 0(b | a) -> a mod b == 0a, b:tHb:b ~= 0(b | a) -> a mod b == 0a, b:tHb:b ~= 0c:tHc:a == c * ba mod b == 0now apply mod_mul. Qed.a, b:tHb:b ~= 0c:tHc:a == c * b(c * b) mod b == 0forall a b c : t, b ~= 0 -> (b | a) -> c * a / b == c * (a / b)forall a b c : t, b ~= 0 -> (b | a) -> c * a / b == c * (a / b)a, b, c:tHb:b ~= 0H:(b | a)c * a / b == c * (a / b)a, b, c:tHb:b ~= 0H:(b | a)b * (c * a / b) == b * (c * (a / b))a, b, c:tHb:b ~= 0H:(b | a)b * (c * a / b) == b * (a / b) * ca, b, c:tHb:b ~= 0H, H':(b | a)b * (c * a / b) == b * (a / b) * ca, b, c:tHb:b ~= 0H:(b | a)H':a == b * (a / b)b * (c * a / b) == b * (a / b) * ca, b, c:tHb:b ~= 0H:(b | a)H':a == b * (a / b)b * (c * a / b) == c * aa, b, c:tHb:b ~= 0H:(b | a)H':a == b * (a / b)c * a == b * (c * a / b)a, b, c:tHb:b ~= 0H:(b | a)H':a == b * (a / b)(c * a) mod b == 0now apply divide_mul_r. Qed.a, b, c:tHb:b ~= 0H:(b | a)H':a == b * (a / b)(b | c * a)
Gcd of divided elements, for exact divisions
forall a b c : t, c ~= 0 -> (c | a) -> (c | b) -> gcd (a / c) (b / c) == gcd a b / cforall a b c : t, c ~= 0 -> (c | a) -> (c | b) -> gcd (a / c) (b / c) == gcd a b / ca, b, c:tHc:c ~= 0Ha:(c | a)Hb:(c | b)gcd (a / c) (b / c) == gcd a b / ca, b, c:tHc:c ~= 0Ha:(c | a)Hb:(c | b)c * gcd (a / c) (b / c) == c * (gcd a b / c)a, b, c:tHc:c ~= 0Ha:(c | a)Hb:(c | b)H:(c | gcd a b)c * gcd (a / c) (b / c) == c * (gcd a b / c)a, b, c:tHc:c ~= 0Ha:(c | a)Hb:(c | b)H:gcd a b == c * (gcd a b / c)c * gcd (a / c) (b / c) == c * (gcd a b / c)a, b, c:tHc:c ~= 0Ha:(c | a)Hb:(c | b)H:gcd a b == c * (gcd a b / c)c * gcd (a / c) (b / c) == gcd a bf_equiv; symmetry; apply div_exact; try order; apply mod_divide; trivial; try order. Qed.a, b, c:tHc:c ~= 0Ha:(c | a)Hb:(c | b)H:gcd a b == c * (gcd a b / c)gcd (c * (a / c)) (c * (b / c)) == gcd a bforall a b g : t, g ~= 0 -> g == gcd a b -> gcd (a / g) (b / g) == 1forall a b g : t, g ~= 0 -> g == gcd a b -> gcd (a / g) (b / g) == 1a, b, g:tNZ:g ~= 0EQ:g == gcd a bgcd (a / g) (b / g) == 1a, b, g:tNZ:g ~= 0EQ:g == gcd a bgcd a b / g == 1a, b, g:tNZ:g ~= 0EQ:g == gcd a bg ~= 0a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | a)a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | b)a, b, g:tNZ:g ~= 0EQ:g == gcd a bg ~= 0a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | a)a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | b)a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | a)a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | b)rewrite EQ; apply gcd_divide_r. Qed.a, b, g:tNZ:g ~= 0EQ:g == gcd a b(g | b)
The following equality is crucial for Euclid algorithm
forall a b : t, b ~= 0 -> gcd (a mod b) b == gcd b aforall a b : t, b ~= 0 -> gcd (a mod b) b == gcd b aa, b:tHb:b ~= 0gcd (a mod b) b == gcd b aa, b:tHb:b ~= 0gcd b (a mod b) == gcd b anow rewrite add_comm, mul_comm, <- div_mod. Qed.a, b:tHb:b ~= 0gcd b (a mod b + a / b * b) == gcd b a
We now define lcm thanks to gcd:
lcm a b = a * (b / gcd a b)
= (a / gcd a b) * b
= (a*b) / gcd a b
Nota: lcm 0 0 should be 0, which isn't guarantee with the third
equation above.
Definition lcm a b := a*(b/gcd a b).Proper (eq ==> eq ==> eq) lcmProper (eq ==> eq ==> eq) lcmsolve_proper. Qed.Proper (eq ==> eq ==> eq) (fun a b : t => a * (b / gcd a b))forall a b : t, gcd a b ~= 0 -> a * (b / gcd a b) == a * b / gcd a bforall a b : t, gcd a b ~= 0 -> a * (b / gcd a b) == a * b / gcd a ba, b:tH:gcd a b ~= 0a * (b / gcd a b) == a * b / gcd a bapply gcd_divide_r. Qed.a, b:tH:gcd a b ~= 0(gcd a b | b)forall a b : t, gcd a b ~= 0 -> a / gcd a b * b == a * b / gcd a bforall a b : t, gcd a b ~= 0 -> a / gcd a b * b == a * b / gcd a ba, b:tH:gcd a b ~= 0a / gcd a b * b == a * b / gcd a ba, b:tH:gcd a b ~= 0b * (a / gcd a b) == b * a / gcd a bapply gcd_divide_l. Qed.a, b:tH:gcd a b ~= 0(gcd a b | a)forall a b : t, a / gcd a b * b == a * (b / gcd a b)forall a b : t, a / gcd a b * b == a * (b / gcd a b)a, b:ta / gcd a b * b == a * (b / gcd a b)a, b:tEQ:gcd a b == 0a / gcd a b * b == a * (b / gcd a b)a, b:tNEQ:gcd a b ~= 0a / gcd a b * b == a * (b / gcd a b)a, b:tEQ:a == 0 /\ b == 0a / gcd a b * b == a * (b / gcd a b)a, b:tNEQ:gcd a b ~= 0a / gcd a b * b == a * (b / gcd a b)a, b:tEQ:a == 0EQ':b == 0a / gcd a b * b == a * (b / gcd a b)a, b:tNEQ:gcd a b ~= 0a / gcd a b * b == a * (b / gcd a b)a, b:tEQ:a == 0EQ':b == 00 / gcd 0 0 * 0 == 0 * (0 / gcd 0 0)a, b:tNEQ:gcd a b ~= 0a / gcd a b * b == a * (b / gcd a b)now rewrite lcm_equiv1, <-lcm_equiv2. Qed.a, b:tNEQ:gcd a b ~= 0a / gcd a b * b == a * (b / gcd a b)forall a b : t, (a | lcm a b)forall a b : t, (a | lcm a b)forall a b : t, (a | a * (b / gcd a b))apply divide_factor_l. Qed.a, b:t(a | a * (b / gcd a b))forall a b : t, (b | lcm a b)forall a b : t, (b | lcm a b)forall a b : t, (b | a * (b / gcd a b))a, b:t(b | a * (b / gcd a b))apply divide_factor_r. Qed.a, b:t(b | a / gcd a b * b)forall a b c : t, a ~= 0 -> (a | b) -> (b | c) -> (b / a | c / a)forall a b c : t, a ~= 0 -> (a | b) -> (b | c) -> (b / a | c / a)a, b, c:tHa:a ~= 0Hb:(a | b)c':tHc:c == c' * b(b / a | c / a)now rewrite <- divide_div_mul_exact, Hc. Qed.a, b, c:tHa:a ~= 0Hb:(a | b)c':tHc:c == c' * bc / a == c' * (b / a)forall a b c : t, (a | c) -> (b | c) -> (lcm a b | c)forall a b c : t, (a | c) -> (b | c) -> (lcm a b | c)a, b, c:tHa:(a | c)Hb:(b | c)(lcm a b | c)a, b, c:tHa:(a | c)Hb:(b | c)(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)EQ:gcd a b == 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)EQ:a == 0 /\ b == 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)EQ:a == 0EQ':b == 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0(a * (b / gcd a b) | c)a, b, c:tHa:(0 | c)Hb:(b | c)EQ:a == 0EQ':b == 0(0 * (b / gcd 0 b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0Ga:(gcd a b | a)(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)NEQ:gcd a b ~= 0Ga:(gcd a b | a)Gb:(gcd a b | b)(a * (b / gcd a b) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)Ha':(a / g | c / g)(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)Ha':(a / g | c / g)Hb':(b / g | c / g)(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)Hb':(b / g | c / g)(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)Hb':(b / g | a / g * a')(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)Hb':(b / g | a')(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)(a * (b / g) | c)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c == b' * (a * (b / g))a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c == a * a'a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)g * (c / g) == a * a'a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c mod g == 0a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)a' * (g * (a / g)) == a' * aa, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c mod g == 0a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)g * (a / g) == aa, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c mod g == 0a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)a == g * (a / g)a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c mod g == 0a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)a mod g == 0a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c mod g == 0a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)c mod g == 0transitivity a; trivial. Qed.a, b, c:tHa:(a | c)Hb:(b | c)g:=gcd a b:tNEQ:g ~= 0Ga:(g | a)Gb:(g | b)a':tHa':c / g == a' * (a / g)b':tHb':a' == b' * (b / g)(g | c)forall a b : t, lcm a b == lcm b aforall a b : t, lcm a b == lcm b aa, b:tlcm a b == lcm b aa, b:ta * (b / gcd a b) == b * (a / gcd b a)now rewrite <- gcd_div_swap. Qed.a, b:ta * (b / gcd a b) == a / gcd a b * bforall n m p : t, (lcm n m | p) <-> (n | p) /\ (m | p)forall n m p : t, (lcm n m | p) <-> (n | p) /\ (m | p)n, m, p:t(lcm n m | p) <-> (n | p) /\ (m | p)n, m, p:t(lcm n m | p) -> (n | p) /\ (m | p)n, m, p:t(n | p) /\ (m | p) -> (lcm n m | p)n, m, p:tH:(lcm n m | p)(n | p)n, m, p:tH:(lcm n m | p)(m | p)n, m, p:t(n | p) /\ (m | p) -> (lcm n m | p)n, m, p:tH:(lcm n m | p)(m | p)n, m, p:t(n | p) /\ (m | p) -> (lcm n m | p)n, m, p:t(n | p) /\ (m | p) -> (lcm n m | p)now apply lcm_least. Qed.n, m, p:tH:(n | p)H':(m | p)(lcm n m | p)forall n m p : t, 0 <= p -> (n | p) -> (m | p) -> (forall q : t, (n | q) -> (m | q) -> (p | q)) -> lcm n m == pforall n m p : t, 0 <= p -> (n | p) -> (m | p) -> (forall q : t, (n | q) -> (m | q) -> (p | q)) -> lcm n m == pn, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)lcm n m == pn, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)(lcm n m | p)n, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)(p | lcm n m)n, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)(p | lcm n m)n, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)(n | lcm n m)n, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)(m | lcm n m)apply divide_lcm_r. Qed.n, m, p:tHp:0 <= pHn:(n | p)Hm:(m | p)H:forall q : t, (n | q) -> (m | q) -> (p | q)(m | lcm n m)forall n m p : t, 0 <= p -> (forall q : t, (p | q) <-> (n | q) /\ (m | q)) -> lcm n m == pforall n m p : t, 0 <= p -> (forall q : t, (p | q) <-> (n | q) /\ (m | q)) -> lcm n m == pn, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)lcm n m == pn, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)(n | p)n, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)(m | p)n, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)forall q : t, (n | q) -> (m | q) -> (p | q)n, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)(m | p)n, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)forall q : t, (n | q) -> (m | q) -> (p | q)n, m, p:tHp:0 <= pH:forall q : t, (p | q) <-> (n | q) /\ (m | q)forall q : t, (n | q) -> (m | q) -> (p | q)n, m, p:tHp:0 <= pH:forall q0 : t, (p | q0) <-> (n | q0) /\ (m | q0)q:tH0:(n | q)H1:(m | q)(p | q)now split. Qed.n, m, p:tHp:0 <= pH:forall q0 : t, (p | q0) <-> (n | q0) /\ (m | q0)q:tH0:(n | q)H1:(m | q)(n | q) /\ (m | q)forall n m p : t, lcm n (lcm m p) == lcm (lcm n m) pforall n m p : t, lcm n (lcm m p) == lcm (lcm n m) pn, m, p:tlcm n (lcm m p) == lcm (lcm n m) pn, m, p:t0 <= lcm (lcm n m) pn, m, p:tforall q : t, (lcm (lcm n m) p | q) <-> (n | q) /\ (lcm m p | q)n, m, p:tforall q : t, (lcm (lcm n m) p | q) <-> (n | q) /\ (lcm m p | q)now rewrite !lcm_divide_iff, and_assoc. Qed.n, m, p, q:t(lcm (lcm n m) p | q) <-> (n | q) /\ (lcm m p | q)forall n : t, lcm 0 n == 0forall n : t, lcm 0 n == 0n:tlcm 0 n == 0n:t0 <= 0n:t(0 | 0)n:t(n | 0)n:t(0 | 0)n:t(n | 0)apply divide_0_r. Qed.n:t(n | 0)forall n : t, lcm n 0 == 0forall n : t, lcm n 0 == 0now rewrite lcm_comm, lcm_0_l. Qed.n:tlcm n 0 == 0forall n : t, lcm 1 n == nforall n : t, lcm 1 n == napply lcm_unique; trivial using divide_1_l, le_0_l, divide_refl. Qed.n:tlcm 1 n == nforall n : t, lcm n 1 == nforall n : t, lcm n 1 == nnow rewrite lcm_comm, lcm_1_l. Qed.n:tlcm n 1 == nforall n : t, lcm n n == nforall n : t, lcm n n == napply lcm_unique; trivial using divide_refl, le_0_l. Qed.n:tlcm n n == nforall n m : t, lcm n m == 0 <-> n == 0 \/ m == 0forall n m : t, lcm n m == 0 <-> n == 0 \/ m == 0n, m:tlcm n m == 0 <-> n == 0 \/ m == 0n, m:tlcm n m == 0 -> n == 0 \/ m == 0n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:lcm n m == 0n == 0 \/ m == 0n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:lcm n m == 0n * m == 0n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:lcm n m == 0(0 | n * m)n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:lcm n m == 0(lcm n m | n * m)n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:lcm n m == 0(n | n * m)n, m:tEQ:lcm n m == 0(m | n * m)n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:lcm n m == 0(m | n * m)n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tn == 0 \/ m == 0 -> lcm n m == 0n, m:tEQ:n == 0lcm 0 m == 0n, m:tEQ:m == 0lcm n 0 == 0apply lcm_0_r. Qed.n, m:tEQ:m == 0lcm n 0 == 0forall n m : t, (n | m) -> lcm n m == mforall n m : t, (n | m) -> lcm n m == mn, m:tH:(n | m)lcm n m == mn, m:tH:(n | m)forall q : t, (m | q) <-> (n | q) /\ (m | q)n, m:tH:(n | m)q:t(m | q) <-> (n | q) /\ (m | q)n, m:tH:(n | m)q:t(m | q) -> (n | q) /\ (m | q)n, m:tH:(n | m)q:t(n | q) /\ (m | q) -> (m | q)n, m:tH:(n | m)q:tH0:(m | q)(n | q)n, m:tH:(n | m)q:t(n | q) /\ (m | q) -> (m | q)now destruct 1. Qed.n, m:tH:(n | m)q:t(n | q) /\ (m | q) -> (m | q)forall n m : t, (n | m) <-> lcm n m == mforall n m : t, (n | m) <-> lcm n m == mn, m:t(n | m) <-> lcm n m == mn, m:t(n | m) -> lcm n m == mn, m:tlcm n m == m -> (n | m)n, m:tlcm n m == m -> (n | m)n, m:tEQ:lcm n m == m(n | m)apply divide_lcm_l. Qed.n, m:tEQ:lcm n m == m(n | lcm n m)forall n m p : t, lcm (p * n) (p * m) == p * lcm n mforall n m p : t, lcm (p * n) (p * m) == p * lcm n mn, m, p:tlcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p == 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p == 0lcm (0 * n) (0 * m) == 0 * lcm n mn, m, p:tHp:p ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p == 0lcm 0 0 == 0n, m, p:tHp:p ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p == 00 == 0n, m, p:tHp:p ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hg:gcd n m == 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hg:gcd n m ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hg:n == 0 /\ m == 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hg:gcd n m ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hn:n == 0Hm:m == 0lcm (p * 0) (p * 0) == p * lcm 0 0n, m, p:tHp:p ~= 0Hg:gcd n m ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hn:n == 0Hm:m == 0lcm 0 0 == p * lcm 0 0n, m, p:tHp:p ~= 0Hg:gcd n m ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hn:n == 0Hm:m == 00 == p * 0n, m, p:tHp:p ~= 0Hg:gcd n m ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hg:gcd n m ~= 0lcm (p * n) (p * m) == p * lcm n mn, m, p:tHp:p ~= 0Hg:gcd n m ~= 0p * n * (p * m / gcd (p * n) (p * m)) == p * (n * (m / gcd n m))n, m, p:tHp:p ~= 0Hg:gcd n m ~= 0p * n * (p * m / (p * gcd n m)) == p * (n * (m / gcd n m))n, m, p:tHp:p ~= 0Hg:gcd n m ~= 0p * n * (p * m / (p * gcd n m)) == p * n * (m / gcd n m)now rewrite div_mul_cancel_l. Qed.n, m, p:tHp:p ~= 0Hg:gcd n m ~= 0p * m / (p * gcd n m) == m / gcd n mforall n m p : t, lcm (n * p) (m * p) == lcm n m * pforall n m p : t, lcm (n * p) (m * p) == lcm n m * pnow rewrite !(mul_comm _ p), lcm_mul_mono_l, mul_comm. Qed.n, m, p:tlcm (n * p) (m * p) == lcm n m * pforall n m : t, n ~= 0 -> m ~= 0 -> gcd n m == 1 <-> lcm n m == n * mforall n m : t, n ~= 0 -> m ~= 0 -> gcd n m == 1 <-> lcm n m == n * mn, m:tHn:n ~= 0Hm:m ~= 0gcd n m == 1 <-> lcm n m == n * mn, m:tHn:n ~= 0Hm:m ~= 0H:gcd n m == 1lcm n m == n * mn, m:tHn:n ~= 0Hm:m ~= 0H:lcm n m == n * mgcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:gcd n m == 1n * (m / gcd n m) == n * mn, m:tHn:n ~= 0Hm:m ~= 0H:lcm n m == n * mgcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:gcd n m == 1n * (m / 1) == n * mn, m:tHn:n ~= 0Hm:m ~= 0H:lcm n m == n * mgcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:lcm n m == n * mgcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:n * (m / gcd n m) == n * mgcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mgcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mHg:gcd n m ~= 0gcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mHg:gcd n m ~= 0H':(gcd n m | m)gcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mHg:gcd n m ~= 0H':m mod gcd n m == 0gcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mHg:gcd n m ~= 0H':m == gcd n m * (m / gcd n m)gcd n m == 1n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mHg:gcd n m ~= 0H':m == gcd n m * mgcd n m == 1now apply mul_cancel_r in H'. Qed. End NLcmProp.n, m:tHn:n ~= 0Hm:m ~= 0H:m / gcd n m == mHg:gcd n m ~= 0H':1 * m == gcd n m * mgcd n m == 1