(** For stating the fully general result, let's give a short name
    to the condition on the remainder. *)

Definition Remainder r b :=  0 <= r < b \/ b < r <= 0.(** Another equivalent formulation: *)

Definition Remainder_alt r b :=  Z.abs r < Z.abs b /\ Z.sgn r <> - Z.sgn b.

(* Specifications: *)
Lemma Remainder_equiv : forall r b, Remainder r b <-> Remainder_alt r b.
Theorem Z_div_mod_full a b : b <> 0 -> let (q, r) := Z.div_eucl a b in a = b * q + r /\ Remainder r b.
Lemma Z_mod_remainder a b : b<>0 -> Remainder (a mod b) b.
Lemma Z_mod_lt a b : b > 0 -> 0 <= a mod b < b.
Lemma Z_mod_neg a b : b < 0 -> b < a mod b <= 0.
Lemma Z_div_mod_eq_full a b : a = b*(a/b) + (a mod b).
Lemma Zmod_eq_full a b : b<>0 -> a mod b = a - (a/b)*b.
Lemma Zmod_eq a b : b>0 -> a mod b = a - (a/b)*b.
Theorem Zdiv_eucl_exist : forall (b:Z)(Hb:b>0)(a:Z), {qr : Z * Z | let (q, r) := qr in a = b * q + r /\ 0 <= r < b}.
Theorem Zdiv_mod_unique b q1 q2 r1 r2 : 0 <= r1 < Z.abs b -> 0 <= r2 < Z.abs b -> b*q1+r1 = b*q2+r2 -> q1=q2 /\ r1=r2.
Theorem Zdiv_mod_unique_2 : forall b q1 q2 r1 r2:Z, Remainder r1 b -> Remainder r2 b -> b*q1+r1 = b*q2+r2 -> q1=q2 /\ r1=r2.
Theorem Zdiv_unique_full: forall a b q r, Remainder r b -> a = b*q + r -> q = a/b.
Theorem Zdiv_unique: forall a b q r, 0 <= r < b -> a = b*q + r -> q = a/b.
Theorem Zmod_unique_full: forall a b q r, Remainder r b -> a = b*q + r -> r = a mod b.
Theorem Zmod_unique: forall a b q r, 0 <= r < b -> a = b*q + r -> r = a mod b.
Lemma Zmod_0_l: forall a, 0 mod a = 0.
Lemma Zmod_0_r: forall a, a mod 0 = a.
Lemma Zdiv_0_l: forall a, 0/a = 0.
Lemma Zdiv_0_r: forall a, a/0 = 0.