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.

Least Common Multiple

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:t
Hb:b ~= 0

a mod b == 0 <-> (b | a)
a, b:t
Hb:b ~= 0

a mod b == 0 -> (b | a)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

(b | a)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

a == a / b * b
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

a == b * (a / b)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
Hab:a mod b == 0

b * (a / b) + a mod b == b * (a / b)
a, b:t
Hb:b ~= 0
(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0

(b | a) -> a mod b == 0
a, b:t
Hb:b ~= 0
c:t
Hc:a == c * b

a mod b == 0
a, b:t
Hb:b ~= 0
c:t
Hc:a == c * b

(c * b) mod b == 0
now apply mod_mul. Qed.

forall 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:t
Hb:b ~= 0
H:(b | a)

c * a / b == c * (a / b)
a, b, c:t
Hb:b ~= 0
H:(b | a)

b * (c * a / b) == b * (c * (a / b))
a, b, c:t
Hb:b ~= 0
H:(b | a)

b * (c * a / b) == b * (a / b) * c
a, b, c:t
Hb:b ~= 0
H, H':(b | a)

b * (c * a / b) == b * (a / b) * c
a, b, c:t
Hb:b ~= 0
H:(b | a)
H':a == b * (a / b)

b * (c * a / b) == b * (a / b) * c
a, b, c:t
Hb:b ~= 0
H:(b | a)
H':a == b * (a / b)

b * (c * a / b) == c * a
a, b, c:t
Hb:b ~= 0
H:(b | a)
H':a == b * (a / b)

c * a == b * (c * a / b)
a, b, c:t
Hb:b ~= 0
H:(b | a)
H':a == b * (a / b)

(c * a) mod b == 0
a, b, c:t
Hb:b ~= 0
H:(b | a)
H':a == b * (a / b)

(b | c * a)
now apply divide_mul_r. Qed.
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 / c

forall a b c : t, c ~= 0 -> (c | a) -> (c | b) -> gcd (a / c) (b / c) == gcd a b / c
a, b, c:t
Hc:c ~= 0
Ha:(c | a)
Hb:(c | b)

gcd (a / c) (b / c) == gcd a b / c
a, b, c:t
Hc:c ~= 0
Ha:(c | a)
Hb:(c | b)

c * gcd (a / c) (b / c) == c * (gcd a b / c)
a, b, c:t
Hc:c ~= 0
Ha:(c | a)
Hb:(c | b)
H:(c | gcd a b)

c * gcd (a / c) (b / c) == c * (gcd a b / c)
a, b, c:t
Hc:c ~= 0
Ha:(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:t
Hc:c ~= 0
Ha:(c | a)
Hb:(c | b)
H:gcd a b == c * (gcd a b / c)

c * gcd (a / c) (b / c) == gcd a b
a, b, c:t
Hc:c ~= 0
Ha:(c | a)
Hb:(c | b)
H:gcd a b == c * (gcd a b / c)

gcd (c * (a / c)) (c * (b / c)) == gcd a b
f_equiv; symmetry; apply div_exact; try order; apply mod_divide; trivial; try order. Qed.

forall a b g : t, g ~= 0 -> g == gcd a b -> gcd (a / g) (b / g) == 1

forall a b g : t, g ~= 0 -> g == gcd a b -> gcd (a / g) (b / g) == 1
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b

gcd (a / g) (b / g) == 1
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b

gcd a b / g == 1
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b
g ~= 0
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b
(g | a)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b
(g | b)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b

g ~= 0
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b
(g | a)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b
(g | b)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b

(g | a)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b
(g | b)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b

(g | b)
rewrite EQ; apply gcd_divide_r. Qed.
The following equality is crucial for Euclid algorithm

forall a b : t, b ~= 0 -> gcd (a mod b) b == gcd b a

forall a b : t, b ~= 0 -> gcd (a mod b) b == gcd b a
a, b:t
Hb:b ~= 0

gcd (a mod b) b == gcd b a
a, b:t
Hb:b ~= 0

gcd b (a mod b) == gcd b a
a, b:t
Hb:b ~= 0

gcd b (a mod b + a / b * b) == gcd b a
now rewrite add_comm, mul_comm, <- div_mod. Qed.
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) lcm

Proper (eq ==> eq ==> eq) lcm

Proper (eq ==> eq ==> eq) (fun a b : t => a * (b / gcd a b))
solve_proper. Qed.

forall a b : t, gcd a b ~= 0 -> a * (b / gcd a b) == a * b / gcd a b

forall a b : t, gcd a b ~= 0 -> a * (b / gcd a b) == a * b / gcd a b
a, b:t
H:gcd a b ~= 0

a * (b / gcd a b) == a * b / gcd a b
a, b:t
H:gcd a b ~= 0

(gcd a b | b)
apply gcd_divide_r. Qed.

forall a b : t, gcd a b ~= 0 -> a / gcd a b * b == a * b / gcd a b

forall a b : t, gcd a b ~= 0 -> a / gcd a b * b == a * b / gcd a b
a, b:t
H:gcd a b ~= 0

a / gcd a b * b == a * b / gcd a b
a, b:t
H:gcd a b ~= 0

b * (a / gcd a b) == b * a / gcd a b
a, b:t
H:gcd a b ~= 0

(gcd a b | a)
apply gcd_divide_l. Qed.

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:t

a / gcd a b * b == a * (b / gcd a b)
a, b:t
EQ:gcd a b == 0

a / gcd a b * b == a * (b / gcd a b)
a, b:t
NEQ:gcd a b ~= 0
a / gcd a b * b == a * (b / gcd a b)
a, b:t
EQ:a == 0 /\ b == 0

a / gcd a b * b == a * (b / gcd a b)
a, b:t
NEQ:gcd a b ~= 0
a / gcd a b * b == a * (b / gcd a b)
a, b:t
EQ:a == 0
EQ':b == 0

a / gcd a b * b == a * (b / gcd a b)
a, b:t
NEQ:gcd a b ~= 0
a / gcd a b * b == a * (b / gcd a b)
a, b:t
EQ:a == 0
EQ':b == 0

0 / gcd 0 0 * 0 == 0 * (0 / gcd 0 0)
a, b:t
NEQ:gcd a b ~= 0
a / gcd a b * b == a * (b / gcd a b)
a, b:t
NEQ:gcd a b ~= 0

a / gcd a b * b == a * (b / gcd a b)
now rewrite lcm_equiv1, <-lcm_equiv2. Qed.

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))
a, b:t

(a | a * (b / gcd a b))
apply divide_factor_l. Qed.

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))
a, b:t

(b | a / gcd a b * b)
apply divide_factor_r. Qed.

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:t
Ha:a ~= 0
Hb:(a | b)
c':t
Hc:c == c' * b

(b / a | c / a)
a, b, c:t
Ha:a ~= 0
Hb:(a | b)
c':t
Hc:c == c' * b

c / a == c' * (b / a)
now rewrite <- divide_div_mul_exact, Hc. Qed.

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:t
Ha:(a | c)
Hb:(b | c)

(lcm a b | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
EQ:gcd a b == 0

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0
(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
EQ:a == 0 /\ b == 0

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0
(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
EQ:a == 0
EQ':b == 0

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0
(a * (b / gcd a b) | c)
a, b, c:t
Ha:(0 | c)
Hb:(b | c)
EQ:a == 0
EQ':b == 0

(0 * (b / gcd 0 b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0
(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0
Ga:(gcd a b | a)

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
NEQ:gcd a b ~= 0
Ga:(gcd a b | a)
Gb:(gcd a b | b)

(a * (b / gcd a b) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
Ha':(a / g | c / g)

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
Ha':(a / g | c / g)
Hb':(b / g | c / g)

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
Hb':(b / g | c / g)

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
Hb':(b / g | a / g * a')

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
Hb':(b / g | a')

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

(a * (b / g) | c)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

c == b' * (a * (b / g))
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

c == a * a'
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

g * (c / g) == a * a'
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)
c mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

a' * (g * (a / g)) == a' * a
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)
c mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

g * (a / g) == a
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)
c mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

a == g * (a / g)
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)
c mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

a mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)
c mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

c mod g == 0
a, b, c:t
Ha:(a | c)
Hb:(b | c)
g:=gcd a b:t
NEQ:g ~= 0
Ga:(g | a)
Gb:(g | b)
a':t
Ha':c / g == a' * (a / g)
b':t
Hb':a' == b' * (b / g)

(g | c)
transitivity a; trivial. Qed.

forall a b : t, lcm a b == lcm b a

forall a b : t, lcm a b == lcm b a
a, b:t

lcm a b == lcm b a
a, b:t

a * (b / gcd a b) == b * (a / gcd b a)
a, b:t

a * (b / gcd a b) == a / gcd a b * b
now rewrite <- gcd_div_swap. Qed.

forall 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:t
H:(lcm n m | p)

(n | p)
n, m, p:t
H:(lcm n m | p)
(m | p)
n, m, p:t
(n | p) /\ (m | p) -> (lcm n m | p)
n, m, p:t
H:(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)
n, m, p:t
H:(n | p)
H':(m | p)

(lcm n m | p)
now apply lcm_least. Qed.

forall n m p : t, 0 <= p -> (n | p) -> (m | p) -> (forall q : t, (n | q) -> (m | q) -> (p | q)) -> 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 == p
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)

lcm n m == p
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)

(lcm n m | p)
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)
(p | lcm n m)
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)

(p | lcm n m)
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)

(n | lcm n m)
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)
(m | lcm n m)
n, m, p:t
Hp:0 <= p
Hn:(n | p)
Hm:(m | p)
H:forall q : t, (n | q) -> (m | q) -> (p | q)

(m | lcm n m)
apply divide_lcm_r. Qed.

forall n m p : t, 0 <= p -> (forall q : t, (p | q) <-> (n | q) /\ (m | q)) -> lcm n m == p

forall n m p : t, 0 <= p -> (forall q : t, (p | q) <-> (n | q) /\ (m | q)) -> lcm n m == p
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)

lcm n m == p
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)

(n | p)
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)
(m | p)
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)
forall q : t, (n | q) -> (m | q) -> (p | q)
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)

(m | p)
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)
forall q : t, (n | q) -> (m | q) -> (p | q)
n, m, p:t
Hp:0 <= p
H:forall q : t, (p | q) <-> (n | q) /\ (m | q)

forall q : t, (n | q) -> (m | q) -> (p | q)
n, m, p:t
Hp:0 <= p
H:forall q0 : t, (p | q0) <-> (n | q0) /\ (m | q0)
q:t
H0:(n | q)
H1:(m | q)

(p | q)
n, m, p:t
Hp:0 <= p
H:forall q0 : t, (p | q0) <-> (n | q0) /\ (m | q0)
q:t
H0:(n | q)
H1:(m | q)

(n | q) /\ (m | q)
now split. Qed.

forall n m p : t, lcm n (lcm m p) == lcm (lcm n m) p

forall n m p : t, lcm n (lcm m p) == lcm (lcm n m) p
n, m, p:t

lcm n (lcm m p) == lcm (lcm n m) p
n, m, p:t

0 <= lcm (lcm n m) p
n, m, p:t
forall q : t, (lcm (lcm n m) p | q) <-> (n | q) /\ (lcm m p | q)
n, m, p:t

forall q : t, (lcm (lcm n m) p | q) <-> (n | q) /\ (lcm m p | q)
n, m, p, q:t

(lcm (lcm n m) p | q) <-> (n | q) /\ (lcm m p | q)
now rewrite !lcm_divide_iff, and_assoc. Qed.

forall n : t, lcm 0 n == 0

forall n : t, lcm 0 n == 0
n:t

lcm 0 n == 0
n:t

0 <= 0
n:t
(0 | 0)
n:t
(n | 0)
n:t

(0 | 0)
n:t
(n | 0)
n:t

(n | 0)
apply divide_0_r. Qed.

forall n : t, lcm n 0 == 0

forall n : t, lcm n 0 == 0
n:t

lcm n 0 == 0
now rewrite lcm_comm, lcm_0_l. Qed.

forall n : t, lcm 1 n == n

forall n : t, lcm 1 n == n
n:t

lcm 1 n == n
apply lcm_unique; trivial using divide_1_l, le_0_l, divide_refl. Qed.

forall n : t, lcm n 1 == n

forall n : t, lcm n 1 == n
n:t

lcm n 1 == n
now rewrite lcm_comm, lcm_1_l. Qed.

forall n : t, lcm n n == n

forall n : t, lcm n n == n
n:t

lcm n n == n
apply lcm_unique; trivial using divide_refl, le_0_l. Qed.

forall n m : t, lcm n m == 0 <-> n == 0 \/ m == 0

forall n m : t, lcm n m == 0 <-> n == 0 \/ m == 0
n, m:t

lcm n m == 0 <-> n == 0 \/ m == 0
n, m:t

lcm n m == 0 -> n == 0 \/ m == 0
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:lcm n m == 0

n == 0 \/ m == 0
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:lcm n m == 0

n * m == 0
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:lcm n m == 0

(0 | n * m)
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:lcm n m == 0

(lcm n m | n * m)
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:lcm n m == 0

(n | n * m)
n, m:t
EQ:lcm n m == 0
(m | n * m)
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:lcm n m == 0

(m | n * m)
n, m:t
n == 0 \/ m == 0 -> lcm n m == 0
n, m:t

n == 0 \/ m == 0 -> lcm n m == 0
n, m:t
EQ:n == 0

lcm 0 m == 0
n, m:t
EQ:m == 0
lcm n 0 == 0
n, m:t
EQ:m == 0

lcm n 0 == 0
apply lcm_0_r. Qed.

forall n m : t, (n | m) -> lcm n m == m

forall n m : t, (n | m) -> lcm n m == m
n, m:t
H:(n | m)

lcm n m == m
n, m:t
H:(n | m)

forall q : t, (m | q) <-> (n | q) /\ (m | q)
n, m:t
H:(n | m)
q:t

(m | q) <-> (n | q) /\ (m | q)
n, m:t
H:(n | m)
q:t

(m | q) -> (n | q) /\ (m | q)
n, m:t
H:(n | m)
q:t
(n | q) /\ (m | q) -> (m | q)
n, m:t
H:(n | m)
q:t
H0:(m | q)

(n | q)
n, m:t
H:(n | m)
q:t
(n | q) /\ (m | q) -> (m | q)
n, m:t
H:(n | m)
q:t

(n | q) /\ (m | q) -> (m | q)
now destruct 1. Qed.

forall n m : t, (n | m) <-> lcm n m == m

forall n m : t, (n | m) <-> lcm n m == m
n, m:t

(n | m) <-> lcm n m == m
n, m:t

(n | m) -> lcm n m == m
n, m:t
lcm n m == m -> (n | m)
n, m:t

lcm n m == m -> (n | m)
n, m:t
EQ:lcm n m == m

(n | m)
n, m:t
EQ:lcm n m == m

(n | lcm n m)
apply divide_lcm_l. Qed.

forall n m p : t, lcm (p * n) (p * m) == p * lcm n m

forall n m p : t, lcm (p * n) (p * m) == p * lcm n m
n, m, p:t

lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p == 0

lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p == 0

lcm (0 * n) (0 * m) == 0 * lcm n m
n, m, p:t
Hp:p ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p == 0

lcm 0 0 == 0
n, m, p:t
Hp:p ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p == 0

0 == 0
n, m, p:t
Hp:p ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0

lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hg:gcd n m == 0

lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hg:n == 0 /\ m == 0

lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hn:n == 0
Hm:m == 0

lcm (p * 0) (p * 0) == p * lcm 0 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hn:n == 0
Hm:m == 0

lcm 0 0 == p * lcm 0 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hn:n == 0
Hm:m == 0

0 == p * 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0

lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0

p * n * (p * m / gcd (p * n) (p * m)) == p * (n * (m / gcd n m))
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0

p * n * (p * m / (p * gcd n m)) == p * (n * (m / gcd n m))
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0

p * n * (p * m / (p * gcd n m)) == p * n * (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0

p * m / (p * gcd n m) == m / gcd n m
now rewrite div_mul_cancel_l. Qed.

forall n m p : t, lcm (n * p) (m * p) == lcm n m * p

forall n m p : t, lcm (n * p) (m * p) == lcm n m * p
n, m, p:t

lcm (n * p) (m * p) == lcm n m * p
now rewrite !(mul_comm _ p), lcm_mul_mono_l, mul_comm. Qed.

forall n m : t, n ~= 0 -> m ~= 0 -> gcd n m == 1 <-> lcm n m == n * m

forall n m : t, n ~= 0 -> m ~= 0 -> gcd n m == 1 <-> lcm n m == n * m
n, m:t
Hn:n ~= 0
Hm:m ~= 0

gcd n m == 1 <-> lcm n m == n * m
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:gcd n m == 1

lcm n m == n * m
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:lcm n m == n * m
gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:gcd n m == 1

n * (m / gcd n m) == n * m
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:lcm n m == n * m
gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:gcd n m == 1

n * (m / 1) == n * m
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:lcm n m == n * m
gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:lcm n m == n * m

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:n * (m / gcd n m) == n * m

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m
Hg:gcd n m ~= 0

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m
Hg:gcd n m ~= 0
H':(gcd n m | m)

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m
Hg:gcd n m ~= 0
H':m mod gcd n m == 0

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m
Hg:gcd n m ~= 0
H':m == gcd n m * (m / gcd n m)

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m
Hg:gcd n m ~= 0
H':m == gcd n m * m

gcd n m == 1
n, m:t
Hn:n ~= 0
Hm:m ~= 0
H:m / gcd n m == m
Hg:gcd n m ~= 0
H':1 * m == gcd n m * m

gcd n m == 1
now apply mul_cancel_r in H'. Qed. End NLcmProp.