Library Coq.Numbers.Integer.Abstract.ZLcm
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.
The two notions of division are equal on non-negative numbers
We can use the sign rule to have an relation between divisions.
Modulo and remainder are null at the same place,
and this correspond to the divisibility relation.
When division is exact, div and quot agree
Gcd of divided elements, for exact divisions
The following equality is crucial for Euclid algorithm
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 garantee with the third equation above.
Definition lcm a b :=
abs (
a*(b/gcd a b)).
Instance lcm_wd :
Proper (
eq==>eq==>eq)
lcm.
Lemma lcm_equiv1 :
forall a b,
gcd a b ~= 0 ->
a * (b / gcd a b) == (a*b)/gcd a b.
Lemma lcm_equiv2 :
forall a b,
gcd a b ~= 0 ->
(a / gcd a b) * b == (a*b)/gcd a b.
Lemma gcd_div_swap :
forall a b,
(a / gcd a b) * b == a * (b / gcd a b).
Lemma divide_lcm_l :
forall a b,
(a | lcm a b).
Lemma divide_lcm_r :
forall a b,
(b | lcm a b).
Lemma divide_div :
forall a b c,
a~=0 ->
(a|b) ->
(b|c) ->
(b/a|c/a).
Lemma lcm_least :
forall a b c,
(a | c) ->
(b | c) ->
(lcm a b | c).
Lemma lcm_nonneg :
forall a b, 0
<= lcm a b.
Lemma lcm_comm :
forall a b,
lcm a b == lcm b a.
Lemma lcm_divide_iff :
forall n m p,
(lcm n m | p) <-> (n | p) /\ (m | p).
Lemma lcm_unique :
forall n m p,
0
<=p ->
(n|p) ->
(m|p) ->
(
forall q,
(n|q) ->
(m|q) ->
(p|q)) ->
lcm n m == p.
Lemma lcm_unique_alt :
forall n m p, 0
<=p ->
(
forall q,
(p|q) <-> (n|q) /\ (m|q)) ->
lcm n m == p.
Lemma lcm_assoc :
forall n m p,
lcm n (
lcm m p)
== lcm (
lcm n m)
p.
Lemma lcm_0_l :
forall n,
lcm 0
n == 0.
Lemma lcm_0_r :
forall n,
lcm n 0
== 0.
Lemma lcm_1_l_nonneg :
forall n, 0
<=n ->
lcm 1
n == n.
Lemma lcm_1_r_nonneg :
forall n, 0
<=n ->
lcm n 1
== n.
Lemma lcm_diag_nonneg :
forall n, 0
<=n ->
lcm n n == n.
Lemma lcm_eq_0 :
forall n m,
lcm n m == 0
<-> n == 0
\/ m == 0.
Lemma divide_lcm_eq_r :
forall n m, 0
<=m ->
(n|m) ->
lcm n m == m.
Lemma divide_lcm_iff :
forall n m, 0
<=m -> (
(n|m) <-> lcm n m == m).
Lemma lcm_opp_l :
forall n m,
lcm (
-n)
m == lcm n m.
Lemma lcm_opp_r :
forall n m,
lcm n (
-m)
== lcm n m.
Lemma lcm_abs_l :
forall n m,
lcm (
abs n)
m == lcm n m.
Lemma lcm_abs_r :
forall n m,
lcm n (
abs m)
== lcm n m.
Lemma lcm_1_l :
forall n,
lcm 1
n == abs n.
Lemma lcm_1_r :
forall n,
lcm n 1
== abs n.
Lemma lcm_diag :
forall n,
lcm n n == abs n.
Lemma lcm_mul_mono_l :
forall n m p,
lcm (
p * n) (
p * m)
== abs p * lcm n m.
Lemma lcm_mul_mono_l_nonneg :
forall n m p, 0
<=p ->
lcm (
p*n) (
p*m)
== p * lcm n m.
Lemma lcm_mul_mono_r :
forall n m p,
lcm (
n * p) (
m * p)
== lcm n m * abs p.
Lemma lcm_mul_mono_r_nonneg :
forall n m p, 0
<=p ->
lcm (
n*p) (
m*p)
== lcm n m * p.
Lemma gcd_1_lcm_mul :
forall n m,
n~=0 ->
m~=0 ->
(
gcd n m == 1
<-> lcm n m == abs (
n*m)).
End ZLcmProp.