(* -*- coding: utf-8 -*- *)
(************************************************************************)
(*         *      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)         *)
(************************************************************************)
Require Export BinNums BinPos Pnat.
OrdersFacts ZAxioms ZProperties DecidableClass.
Require BinIntDef.
(***********************************************************)
(** * Binary Integers *)
(***********************************************************)
(** Initial author: Pierre Crégut, CNET, Lannion, France *)
(** The type [Z] and its constructors [Z0] and [Zpos] and [Zneg] are now defined in [BinNums.v] *)
Local Open Scope Z_scope.
(** Every definitions and early properties about binary integers are placed in a module [Z] for qualification purpose. *)
Module Z
<: ZAxiomsSig
<: UsualOrderedTypeFull
<: UsualDecidableTypeFull
<: TotalOrder.
(** * Definitions of operations, now in a separate file *)
Include BinIntDef.Z.
Register add as num.Z.add.
Register opp as num.Z.opp.
Register succ as num.Z.succ.
Register pred as num.Z.pred.
Register sub as num.Z.sub.
Register mul as num.Z.mul.
Register pow as num.Z.pow.
Register of_nat as num.Z.of_nat.
(** When including property functors, only inline t eq zero one two *)
Set Inline Level 30.
(** * Logic Predicates *)
Definition eq := @Logic.eq Z.
Definition eq_equiv := @eq_equivalence Z.
Notation "x <= y <= z" := (x <= y /\ y <= z) : Z_scope.
Notation "x <= y < z" := (x <= y /\ y < z) : Z_scope.
Notation "x < y < z" := (x < y /\ y < z) : Z_scope.
Notation "x < y <= z" := (x < y /\ y <= z) : Z_scope.
Definition divide x y := exists z, y = z*x.
Notation "( x | y )" := (divide x y) (at level 0).
Definition Even a := exists b, a = 2*b.
Definition Odd a := exists b, a = 2*b+1.
Register le as num.Z.le.
Register lt as num.Z.lt.
Register ge as num.Z.ge.
Register gt as num.Z.gt.
Register leb as num.Z.leb.
Register ltb as num.Z.ltb.
Register geb as num.Z.geb.
Register gtb as num.Z.gtb.
Register eqb as num.Z.eqb.
(** * Decidability of equality. *)
Definition eq_dec (x y : Z) : {x = y} + {x <> y}.

Lemma pos_sub_discr p q :
match pos_sub p q with
| Z0 => p = q
| pos k => p = q + k
| neg k => q = p + k
end%positive.