(** A division by itself returns 1 *)

(* Specifications: *)
Lemma div_same : forall a, 0<a -> a/a == 1.
Lemma mod_same : forall a, 0<a -> 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.
(** Same situation, in term of modulo: *)
Theorem mod_small: forall a b, 0<=a<b -> a mod b == a.
(** * Basic values of divisions and modulo. *)
Lemma div_0_l: forall a, 0<a -> 0/a == 0.
Lemma mod_0_l: forall a, 0<a -> 0 mod a == 0.
Lemma div_1_r: forall a, 0<=a -> a/1 == a.
Lemma mod_1_r: forall a, 0<=a -> a mod 1 == 0.
Lemma div_1_l: forall a, 1<a -> 1/a == 0.
Lemma mod_1_l: forall a, 1<a -> 1 mod a == 1.
Lemma div_mul : forall a b, 0<=a -> 0<b -> (a*b)/b == a.
Lemma mod_mul : forall a b, 0<=a -> 0<b -> (a*b) mod b == 0.
(** * 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.
(* Division of positive numbers is positive. *)
Lemma div_pos: forall a b, 0<=a -> 0<b -> 0 <= a/b.
Lemma div_str_pos : forall a b, 0<b<=a -> 0 < a/b.
Lemma div_small_iff : forall a b, 0<=a -> 0<b -> (a/b==0 <-> a<b).
Lemma mod_small_iff : forall a b, 0<=a -> 0<b -> (a mod b == a <-> a<b).
Lemma div_str_pos_iff : forall a b, 0<=a -> 0<b -> (0<a/b <-> b<=a).
(** 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.
(** [le] is compatible with a positive division. *)
Lemma div_le_mono : forall a b c, 0<c -> 0<=a<=b -> a/c <= b/c.
(** The following two properties could be used as specification of div *)
Lemma mul_div_le : forall a b, 0<=a -> 0<b -> b*(a/b) <= a.
Lemma mul_succ_div_gt : forall a b, 0<=a -> 0<b -> a < b*(S (a/b)).
(** The previous inequality is exact iff the modulo is zero. *)
Lemma div_exact : forall a b, 0<=a -> 0<b -> (a == b*(a/b) <-> a mod b == 0).
(** Some additional inequalities about div. *)
Theorem div_lt_upper_bound:
forall a b q, 0<=a -> 0<b -> a < b*q -> a/b < q.
Theorem div_le_upper_bound:
forall a b q, 0<=a -> 0<b -> a <= b*q -> a/b <= q.
Theorem div_le_lower_bound:
forall a b q, 0<=a -> 0<b -> b*q <= a -> q <= a/b.
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 -> b~=0 -> a mod b <= a.
Theorem div_pos : forall a b, 0<=a -> 0<b -> 0<= a/b.
Lemma mod_small_iff : forall a b, b~=0 -> (a mod b == a <-> 0<=a<abs b).
(** 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 when divisor is positive, and Rounding-Toward-Top otherwise.  Since we cannot speak of rational values here, we express this fact by multiplying back by [b], and this leads to a nice unique statement. *)
Lemma mul_div_le : forall a b, b~=0 -> b*(a/b) <= a.
(** Giving a reversed bound is slightly more complex *)
Lemma mul_succ_div_gt: forall a b, 0<b -> a < b*(S (a/b)).
Lemma mul_pred_div_gt: forall a b, b<0 -> a < b*(P (a/b)).
(** NB: The three 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.