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 *)
(** 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 guarantee 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_unique : forall n m p,
0<=p -> (n|p) -> (m|p) ->
(forall q, (n|q) -> (m|q) -> (p|q)) ->
lcm n m == p.