(** Operations modulo. *)

(* Specifications: *)
Theorem mod_mod: forall a n, 0<=a -> 0<n ->
(a mod n) mod n == a mod n.
Lemma mul_mod_idemp_l : forall a b n, 0<=a -> 0<=b -> 0<n ->
((a mod n)*b) mod n == (a*b) mod n.
Lemma mul_mod_idemp_r : forall a b n, 0<=a -> 0<=b -> 0<n ->
(a*(b mod n)) mod n == (a*b) mod n.
Theorem mul_mod: forall a b n, 0<=a -> 0<=b -> 0<n ->
(a * b) mod n == ((a mod n) * (b mod n)) mod n.
Lemma add_mod_idemp_l : forall a b n, 0<=a -> 0<=b -> 0<n ->
((a mod n)+b) mod n == (a+b) mod n.
Lemma add_mod_idemp_r : forall a b n, 0<=a -> 0<=b -> 0<n ->
(a+(b mod n)) mod n == (a+b) mod n.
Theorem add_mod: forall a b n, 0<=a -> 0<=b -> 0<n ->
(a+b) mod n == (a mod n + b mod n) mod n.
Lemma div_div : forall a b c, 0<=a -> 0<b -> 0<c ->
(a/b)/c == a/(b*c).
Lemma mod_mul_r : forall a b c, 0<=a -> 0<b -> 0<c ->
a mod (b*c) == a mod b + b*((a/b) mod c).
Lemma add_mul_mod_distr_l: forall a b c d, 0<=a -> 0<b -> 0<=d<c ->
(c*a+d) mod (c*b) == c*(a mod b)+d.
Lemma add_mul_mod_distr_r: forall a b c d, 0<=a -> 0<b -> 0<=d<c ->
(a*c+d) mod (b*c) == (a mod b)*c+d.
Lemma mul_mod_distr_l: forall a b c, 0<=a -> 0<b -> 0<c ->
(c*a) mod (c*b) == c * (a mod b).
Lemma mul_mod_distr_r: forall a b c, 0<=a -> 0<b -> 0<c ->
(a*c) mod (b*c) == (a mod b) * c.
Theorem mod_mod: forall a n, n~=0 ->
(a mod n) mod n == a mod n.
Lemma mul_mod_idemp_l : forall a b n, n~=0 ->
((a mod n)*b) mod n == (a*b) mod n.
Lemma mul_mod_idemp_r : forall a b n, n~=0 ->
(a*(b mod n)) mod n == (a*b) mod n.
Theorem mul_mod: forall a b n, n~=0 ->
(a * b) mod n == ((a mod n) * (b mod n)) mod n.
Lemma add_mod_idemp_l : forall a b n, n~=0 ->
((a mod n)+b) mod n == (a+b) mod n.
Lemma add_mod_idemp_r : forall a b n, n~=0 ->
(a+(b mod n)) mod n == (a+b) mod n.
Theorem add_mod: forall a b n, n~=0 ->
(a+b) mod n == (a mod n + b mod n) mod n.
Theorem mod_mod: forall a n, n~=0 ->
(a mod n) mod n == a mod n.
Lemma mul_mod_idemp_l : forall a b n, n~=0 ->
((a mod n)*b) mod n == (a*b) mod n.
Lemma mul_mod_idemp_r : forall a b n, n~=0 ->
(a*(b mod n)) mod n == (a*b) mod n.
Theorem mul_mod: forall a b n, n~=0 ->
(a * b) mod n == ((a mod n) * (b mod n)) mod n.
Lemma add_mod_idemp_l : forall a b n, n~=0 ->
((a mod n)+b) mod n == (a+b) mod n.
Lemma add_mod_idemp_r : forall a b n, n~=0 ->
(a+(b mod n)) mod n == (a+b) mod n.
Theorem add_mod: forall a b n, n~=0 ->
(a+b) mod n == (a mod n + b mod n) mod n.
Theorem rem_rem: forall a n, n~=0 ->
(a rem n) rem n == a rem n.
Lemma mul_rem_idemp_l : forall a b n, n~=0 ->
((a rem n)*b) rem n == (a*b) rem n.
Lemma mul_rem_idemp_r : forall a b n, n~=0 ->
(a*(b rem n)) rem n == (a*b) rem n.
Theorem mul_rem: forall a b n, n~=0 ->
(a * b) rem n == ((a rem n) * (b rem n)) rem n.
Theorem Zmod_mod: forall a n, (a mod n) mod n = a mod n.
Lemma Zplus_mod_idemp_l: forall a b n, (a mod n + b) mod n = (a + b) mod n.
Lemma Zplus_mod_idemp_r: forall a b n, (b + a mod n) mod n = (b + a) mod n.
Lemma Zminus_mod_idemp_l: forall a b n, (a mod n - b) mod n = (a - b) mod n.
Lemma Zminus_mod_idemp_r: forall a b n, (a - b mod n) mod n = (a - b) mod n.
Lemma Zmult_mod_idemp_l: forall a b n, (a mod n * b) mod n = (a * b) mod n.
Lemma Zmult_mod_idemp_r: forall a b n, (b * (a mod n)) mod n = (b * a) mod n.
Section EqualityModulo.
Theorem Zrem_rem: forall a n, Z.rem (Z.rem a n) n = Z.rem a n.
Lemma Zmult_rem_idemp_l: forall a b n, Z.rem (Z.rem a n * b) n = Z.rem (a * b) n.
(** A last inequality: *)
Theorem Zquot_mult_le:
forall a b c, 0<=a -> 0<=b -> 0<=c -> c*(a÷b) <= (c*a)÷b.