Module Type NZDomainSig :=
EqualityType <+ ZeroSuccPred <+ IsNZDomain <+ OneTwo <+ IsOneTwo.
Module Type NZDomainSig' :=
EqualityType' <+ ZeroSuccPred' <+ IsNZDomain <+ OneTwo' <+ IsOneTwo.
(** At this point, a module implementing [NZDomainSig] has : - two unary operators [pred] and [succ] such that [forall n, pred (succ n) = n]. - a bidirectional induction principle - three constants [0], [1 = S 0], [2 = S 1] *)
(** ** Axiomatization of basic operations : [+] [-] [*] *)
Module Type AddSubMul (Import T:Typ).
Parameters Inline add sub mul : t -> t -> t.
End AddSubMul.
Module Type AddSubMulNotation (T:Typ)(Import NZ:AddSubMul T).
Notation "x + y" := (add x y).
Notation "x - y" := (sub x y).
Notation "x * y" := (mul x y).
End AddSubMulNotation.
Module Type AddSubMul' (T:Typ) := AddSubMul T <+ AddSubMulNotation T.
Module Type IsAddSubMul (Import E:NZDomainSig')(Import NZ:AddSubMul' E).
#[global]
Declare Instance add_wd : Proper (eq ==> eq ==> eq) add.
#[global]
Declare Instance sub_wd : Proper (eq ==> eq ==> eq) sub.
#[global]
Declare Instance mul_wd : Proper (eq ==> eq ==> eq) mul.

(* Specifications: *)
Axiom add_0_l : forall n, 0 + n == n.
Axiom add_succ_l : forall n m, (S n) + m == S (n + m).
Axiom sub_0_r : forall n, n - 0 == n.
Axiom sub_succ_r : forall n m, n - (S m) == P (n - m).
Axiom mul_0_l : forall n, 0 * n == 0.
Axiom mul_succ_l : forall n m, S n * m == n * m + m.
End IsAddSubMul.