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 ZAxioms ZMulOrder ZSgnAbs ZGcd ZDivTrunc ZDivFloor.

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 quot/rem and gcd.
Module Type ZLcmProp
 (Import A : ZAxiomsSig')
 (Import B : ZMulOrderProp A)
 (Import C : ZSgnAbsProp A B)
 (Import D : ZDivProp A B C)
 (Import E : ZQuotProp A B C)
 (Import F : ZGcdProp A B C).
The two notions of division are equal on non-negative numbers

forall a b : t, 0 <= a -> 0 < b -> a ÷ b == a / b

forall a b : t, 0 <= a -> 0 < b -> a ÷ b == a / b
a, b:t
H:0 <= a
H0:0 < b

a ÷ b == a / b
a, b:t
H:0 <= a
H0:0 < b

0 <= a rem b < b
a, b:t
H:0 <= a
H0:0 < b
a == b * (a ÷ b) + a rem b
a, b:t
H:0 <= a
H0:0 < b

a == b * (a ÷ b) + a rem b
a, b:t
H:0 <= a
H0:0 < b

b ~= 0
order. Qed.

forall a b : t, 0 <= a -> 0 < b -> a rem b == a mod b

forall a b : t, 0 <= a -> 0 < b -> a rem b == a mod b
a, b:t
H:0 <= a
H0:0 < b

a rem b == a mod b
a, b:t
H:0 <= a
H0:0 < b

0 <= a rem b < b
a, b:t
H:0 <= a
H0:0 < b
a == b * (a ÷ b) + a rem b
a, b:t
H:0 <= a
H0:0 < b

a == b * (a ÷ b) + a rem b
a, b:t
H:0 <= a
H0:0 < b

b ~= 0
order. Qed.
We can use the sign rule to have an relation between divisions.

forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)

forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)

forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b

a ÷ b == sgn a * sgn b * (abs a / abs b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b

a ÷ b == sgn a * (abs a / b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b
Ha:0 < a

a ÷ b == sgn a * (abs a / b)
a, b:t
Hb:0 < b
Ha:0 == a
a ÷ b == sgn a * (abs a / b)
a, b:t
Hb:0 < b
Ha:a < 0
a ÷ b == sgn a * (abs a / b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b
Ha:0 == a

a ÷ b == sgn a * (abs a / b)
a, b:t
Hb:0 < b
Ha:a < 0
a ÷ b == sgn a * (abs a / b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b
Ha:a < 0

a ÷ b == sgn a * (abs a / b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b
Ha:a < 0

- a ÷ b == - a / b
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
a, b:t
Hb:0 < b
Ha:a < 0

0 <= - a
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)
forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
AUX:forall a b : t, 0 < b -> a ÷ b == sgn a * sgn b * (abs a / abs b)

forall a b : t, b ~= 0 -> a ÷ b == sgn a * sgn b * (abs a / abs b)
(* main *)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b ~= 0

a ÷ b == sgn a * sgn b * (abs a / abs b)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0 \/ 0 < b

a ÷ b == sgn a * sgn b * (abs a / abs b)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0

a ÷ b == sgn a * sgn b * (abs a / abs b)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0

a ÷ - - b == sgn a * sgn b * (abs a / abs b)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0

- (a ÷ - b) == sgn a * sgn b * (abs a / abs b)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0
- b ~= 0
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0

sgn a * sgn b * (abs a / abs b) == sgn a * sgn b * (abs a / abs b)
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0
0 < - b
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0
- b ~= 0
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0

0 < - b
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0
- b ~= 0
AUX:forall a0 b0 : t, 0 < b0 -> a0 ÷ b0 == sgn a0 * sgn b0 * (abs a0 / abs b0)
a, b:t
Hb:b < 0

- b ~= 0
rewrite eq_opp_l, opp_0; order. Qed.

forall a b : t, b ~= 0 -> a rem b == sgn a * (abs a mod abs b)

forall a b : t, b ~= 0 -> a rem b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0

a rem b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0

a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b

a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:0 < a

a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:0 == a
a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:a < 0
a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:0 == a

a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:a < 0
a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:a < 0

a rem abs b == sgn a * (abs a mod abs b)
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:a < 0

- a rem abs b == - a mod abs b
a, b:t
Hb:b ~= 0
Hb':0 < abs b
Ha:a < 0

0 <= - a
apply opp_nonneg_nonpos; order. Qed.
Modulo and remainder are null at the same place, and this correspond to the divisibility relation.

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 : t, b ~= 0 -> a rem b == 0 <-> (b | a)

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

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

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

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

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

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

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

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

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

(c * b) rem b == 0
now apply rem_mul. Qed.

forall a b : t, b ~= 0 -> a rem b == 0 <-> a mod b == 0

forall a b : t, b ~= 0 -> a rem b == 0 <-> a mod b == 0
a, b:t
Hb:b ~= 0

a rem b == 0 <-> a mod b == 0
now rewrite mod_divide, rem_divide. Qed.
When division is exact, div and quot agree

forall a b : t, b ~= 0 -> (b | a) -> a ÷ b == a / b

forall a b : t, b ~= 0 -> (b | a) -> a ÷ b == a / b
a, b:t
Hb:b ~= 0
H:(b | a)

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

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

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

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

b * (a ÷ b) == b * (a / b)
now rewrite <-H,<-H'. 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.

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)

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

(b | c * a)
now apply divide_mul_r. Qed.
Gcd of divided elements, for exact divisions

forall a b c : t, 0 < c -> (c | a) -> (c | b) -> gcd (a / c) (b / c) == gcd a b / c

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

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

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

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

gcd (a ÷ c) (b ÷ c) == gcd a b ÷ c
a, b, c:t
Hc:0 < c
Ha:(c | a)
Hb:(c | b)

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

(c | gcd a b)
now apply gcd_greatest. 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
0 < g
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

0 < g
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.

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 / g) (b / g) == 1
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 | a)
a, b, g:t
NZ:g ~= 0
EQ:g == gcd a b

(g | a)
rewrite EQ; apply gcd_divide_l. 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 (a - b * (a / b)) b == gcd b a
a, b:t
Hb:b ~= 0

gcd (a + - (a / b) * b) b == gcd b a
a, b:t
Hb:b ~= 0

gcd b (a + - (a / b) * b) == gcd b a
apply gcd_add_mult_diag_r. Qed.

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

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

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

gcd (a - b * (a ÷ b)) b == gcd b a
a, b:t
Hb:b ~= 0

gcd (a + - (a ÷ b) * b) b == gcd b a
a, b:t
Hb:b ~= 0

gcd b (a + - (a ÷ b) * b) == gcd b a
apply gcd_add_mult_diag_r. 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
We had an abs in order to have an always-nonnegative lcm, in the spirit of gcd. Nota: lcm 0 0 should be 0, which isn't guarantee with the third equation above.
Definition lcm a b := abs (a*(b/gcd a b)).


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

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

Proper (eq ==> eq ==> eq) (fun a b : t => abs (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 | abs (a * (b / gcd a b)))
a, b:t

(a | abs (a * (b / gcd a b)))
apply divide_abs_r, 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 | abs (a * (b / gcd a b)))
a, b:t

(b | abs (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)

(abs (a * (b / gcd 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, 0 <= lcm a b

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

0 <= lcm a b
a, b:t

0 <= abs (a * (b / gcd a b))
apply abs_nonneg. 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

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

abs (a * (b / gcd a b)) == abs (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)

0 <= 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)
(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)

(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

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, 0 <= n -> lcm 1 n == n

forall n : t, 0 <= n -> lcm 1 n == n
n:t
H:0 <= n

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

forall n : t, 0 <= n -> lcm n 1 == n

forall n : t, 0 <= n -> lcm n 1 == n
n:t
H:0 <= n

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

forall n : t, 0 <= n -> lcm n n == n

forall n : t, 0 <= n -> lcm n n == n
n:t
H:0 <= n

lcm n n == n
apply lcm_unique; trivial using divide_refl. 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, 0 <= m -> (n | m) -> lcm n m == m

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

lcm n m == m
n, m:t
Hm:0 <= m
H:(n | m)

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

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

(m | q) -> (n | q) /\ (m | q)
n, m:t
Hm:0 <= m
H:(n | m)
q:t
(n | q) /\ (m | q) -> (m | q)
n, m:t
Hm:0 <= m
H:(n | m)
q:t
H0:(m | q)

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

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

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

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

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

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

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

(n | m)
n, m:t
Hn:0 <= m
EQ:lcm n m == m

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

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

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

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

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

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

(lcm n m | q) <-> (n | q) /\ (m | q)
apply lcm_divide_iff. Qed.

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

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

lcm n (- m) == lcm n m
now rewrite lcm_comm, lcm_opp_l, lcm_comm. Qed.

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

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

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

lcm n m == lcm n m
n, m:t
H:abs n == - n
lcm (- n) m == lcm n m
n, m:t
H:abs n == - n

lcm (- n) m == lcm n m
apply lcm_opp_l. Qed.

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

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

lcm n (abs m) == lcm n m
now rewrite lcm_comm, lcm_abs_l, lcm_comm. Qed.

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

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

lcm 1 n == abs n
n:t

lcm 1 (abs n) == abs n
apply lcm_1_l_nonneg, abs_nonneg. Qed.

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

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

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

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

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

lcm n n == abs n
n:t

lcm (abs n) (abs n) == abs n
apply lcm_diag_nonneg, abs_nonneg. Qed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == 1

sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:0 == p
sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == -1
sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == 1

1 * 1 * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:0 == p
sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == -1
sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:0 == p

sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == -1
sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == -1

sgn p * sgn p * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == -1

-1 * -1 * abs (m / gcd n m) == abs (m / gcd n m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
EQ:sgn p == -1

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

(gcd n m | m)
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0
abs p ~= 0
n, m, p:t
Hp:p ~= 0
Hg:gcd n m ~= 0

abs p ~= 0
n, m, p:t
Hg:gcd n m ~= 0
Hp:abs p == 0

p == 0
now apply abs_0_iff. Qed.

forall n m p : t, 0 <= p -> lcm (p * n) (p * m) == p * lcm n m

forall n m p : t, 0 <= p -> lcm (p * n) (p * m) == p * lcm n m
n, m, p:t
H:0 <= p

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

lcm (p * n) (p * m) == abs p * lcm n m
apply lcm_mul_mono_l. Qed.

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

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

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

forall n m p : t, 0 <= p -> lcm (n * p) (m * p) == lcm n m * p

forall n m p : t, 0 <= p -> lcm (n * p) (m * p) == lcm n m * p
n, m, p:t
H:0 <= p

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

lcm (n * p) (m * p) == lcm n m * abs p
apply lcm_mul_mono_r. Qed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

0 <= gcd n m
apply gcd_nonneg. Qed. End ZLcmProp.