(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
Local Open Scope Z_scope.
(** This file provides results about the Round-Toward-Zero Euclidean division [Z.quotrem], whose projections are [Z.quot] (noted ÷) and [Z.rem].  This division and [Z.div] agree only on positive numbers. Otherwise, [Z.div] performs Round-Toward-Bottom (a.k.a Floor).  This [Z.quot] is compatible with the division of usual programming languages such as Ocaml. In addition, it has nicer properties with respect to opposite and other usual operations.  The definition of this division is now in file [BinIntDef], while most of the results about here are now in the main module [BinInt.Z], thanks to the generic "Numbers" layer. Remain here:  - some compatibility notation for old names.  - some extra results with less preconditions (in particular exploiting the arbitrary value of division by 0). *)
Notation Ndiv_Zquot := N2Z.inj_quot (only parsing).
Notation Nmod_Zrem := N2Z.inj_rem (only parsing).
Notation Z_quot_rem_eq := Z.quot_rem' (only parsing).
Notation Zrem_lt := Z.rem_bound_abs (only parsing).
Notation Z_quot_mult := Z.quot_mul (only parsing).
(** Particular values taken for [a÷0] and [(Z.rem a 0)]. We avise to not rely on these arbitrary values. *)

(* Specifications: *)
Lemma Zquot_0_r a : a ÷ 0 = 0.
(** This can also be said in a simpler way: *)
Theorem Zrem_sgn2 a b : 0 <= (Z.rem a b) * a.
(** Reformulation of [Z.rem_bound_abs] in 2 then 4 particular cases. *)
Theorem Zrem_lt_pos a b : 0<=a -> b<>0 -> 0 <= Z.rem a b < Z.abs b.
Theorem Zrem_lt_neg a b : a<=0 -> b<>0 -> -Z.abs b < Z.rem a b <= 0.
Theorem Zrem_lt_pos_pos a b : 0<=a -> 0<b -> 0 <= Z.rem a b < b.
Theorem Zrem_lt_pos_neg a b : 0<=a -> b<0 -> 0 <= Z.rem a b < -b.
Theorem Zrem_lt_neg_pos a b : a<=0 -> 0<b -> -b < Z.rem a b <= 0.
Theorem Zrem_lt_neg_neg a b : a<=0 -> b<0 -> b < Z.rem a b <= 0.
Definition Remainder a b r :=
(0 <= a /\ 0 <= r < Z.abs b) \/ (a <= 0 /\ -Z.abs b < r <= 0).