(************************************************************************)
(*         *      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)         *)
(************************************************************************)
(** * An light axiomatization of integers (used in MSetAVL). *)
(** We define a signature for an integer datatype based on [Z]. The goal is to allow a switch after extraction to ocaml's [big_int] or even [int] when finiteness isn't a problem (typically : when measuring the height of an AVL tree). *)
Declare Scope Int_scope.
Delimit Scope Int_scope with I.
Local Open Scope Int_scope.
Local Ltac Tauto.intuition_solver ::= auto with bool.
(** * A specification of integers *)
Module Type Int.
Parameter t : Set.
Bind Scope Int_scope with t.
Parameter i2z : t -> Z.
Parameter _0 : t.
Parameter _1 : t.
Parameter _2 : t.
Parameter _3 : t.
Parameter add : t -> t -> t.
Parameter opp : t -> t.
Parameter sub : t -> t -> t.
Parameter mul : t -> t -> t.
Parameter max : t -> t -> t.
Notation "0" := _0 : Int_scope.
Notation "1" := _1 : Int_scope.
Notation "2" := _2 : Int_scope.
Notation "3" := _3 : Int_scope.
Infix "+" := add : Int_scope.
Infix "-" := sub : Int_scope.
Infix "*" := mul : Int_scope.
Notation "- x" := (opp x) : Int_scope.
(** For logical relations, we can rely on their counterparts in Z, since they don't appear after extraction. Moreover, using tactics like omega is easier this way. *)
Notation "x == y" := (i2z x = i2z y)
(at level 70, y at next level, no associativity) : Int_scope.
Notation "x <= y" := (i2z x <= i2z y)%Z : Int_scope.
Notation "x < y" := (i2z x < i2z y)%Z : Int_scope.
Notation "x >= y" := (i2z x >= i2z y)%Z : Int_scope.
Notation "x > y" := (i2z x > i2z y)%Z : Int_scope.
Notation "x <= y <= z" := (x <= y /\ y <= z) : Int_scope.
Notation "x <= y < z" := (x <= y /\ y < z) : Int_scope.
Notation "x < y < z" := (x < y /\ y < z) : Int_scope.
Notation "x < y <= z" := (x < y /\ y <= z) : Int_scope.
(** Informative comparisons. *)

(* Specifications: *)
Axiom eqb : t -> t -> bool.
Axiom ltb : t -> t -> bool.
Axiom leb : t -> t -> bool.
Infix "=?" := eqb.