(** The sign of [a mod b] is the one of [b] (when it isn't null) *)

(* Specifications: *)
Lemma mod_sign_nz : forall a b, b~=0 -> a mod b ~= 0 ->
sgn (a mod b) == sgn b.
Lemma mod_sign : forall a b, b~=0 -> sgn (a mod b) ~= -sgn b.
Lemma mod_sign_mul : forall a b, b~=0 -> 0 <= (a mod b) * b.
(** A division by itself returns 1 *)
Lemma div_same : forall a, a~=0 -> a/a == 1.
Lemma mod_same : forall a, a~=0 -> a mod a == 0.
(** A division of a small number by a bigger one yields zero. *)
Theorem div_small: forall a b, 0<=a<b -> a/b == 0.
Lemma mod_0_l: forall a, a~=0 -> 0 mod a == 0.
Lemma div_1_r: forall a, a/1 == a.
Lemma mod_1_r: forall a, a mod 1 == 0.
Lemma div_1_l: forall a, 1<a -> 1/a == 0.
Lemma mod_mul : forall a b, b~=0 -> (a*b) mod b == 0.
Theorem div_unique_exact a b q: b~=0 -> a == b*q -> q == a/b.
(** * Order results about mod and div *)
(** A modulo cannot grow beyond its starting point. *)
Theorem mod_le: forall a b, 0<=a -> 0<b -> a mod b <= a.
Lemma mod_small_iff : forall a b, b~=0 -> (a mod b == a <-> 0<=a<b \/ b<a<=0).
(** As soon as the divisor is strictly greater than 1, the division is strictly decreasing. *)
Lemma div_lt : forall a b, 0<a -> 1<b -> a/b < a.
(** In this convention, [div] performs Rounding-Toward-Bottom.  Since we cannot speak of rational values here, we express this fact by multiplying back by [b], and this leads to separates statements according to the sign of [b].  First, [a/b] is below the exact fraction ... *)
Lemma mul_div_le : forall a b, 0<b -> b*(a/b) <= a.
Lemma mul_div_ge : forall a b, b<0 -> a <= b*(a/b).
(** ... and moreover it is the larger such integer, since [S(a/b)] is strictly above the exact fraction. *)
Lemma mul_succ_div_gt: forall a b, 0<b -> a < b*(S (a/b)).
Lemma mul_succ_div_lt: forall a b, b<0 -> b*(S (a/b)) < a.
(** NB: The four previous properties could be used as specifications for [div]. *)
(** Inequality [mul_div_le] is exact iff the modulo is zero. *)
Lemma div_exact : forall a b, b~=0 -> (a == b*(a/b) <-> a mod b == 0).
(** Some additional inequalities about div. *)
Theorem div_lt_upper_bound:
forall a b q, 0<b -> a < b*q -> a/b < q.
Theorem div_le_upper_bound:
forall a b q, 0<b -> a <= b*q -> a/b <= q.
Theorem div_le_lower_bound:
forall a b q, 0<b -> b*q <= a -> q <= a/b.