(** We can deduce a [sgn] function from a [compare] function *)
Module Type ZDecAxiomsSig := ZAxiomsMiniSig <+ HasCompare.
Module Type ZDecAxiomsSig' := ZAxiomsMiniSig' <+ HasCompare.
Module Type GenericSgn (Import Z : ZDecAxiomsSig')
(Import ZP : ZMulOrderProp Z) <: HasSgn Z.
Definition sgn n :=
match compare 0 n with Eq => 0 | Lt => 1 | Gt => -1 end.

(* Specifications: *)
Lemma sgn_null n : n==0 -> sgn n == 0.
Lemma abs_max : forall n, abs n == max n (-n).
Lemma abs_neq' : forall n, 0<=-n -> abs n == -n.
Lemma abs_nonneg : forall n, 0 <= abs n.
Lemma abs_eq_iff : forall n, abs n == n <-> 0<=n.
Lemma abs_neq_iff : forall n, abs n == -n <-> n<=0.
Lemma abs_opp : forall n, abs (-n) == abs n.
Lemma abs_0 : abs 0 == 0.
Lemma abs_0_iff : forall n, abs n == 0 <-> n==0.
Lemma abs_pos : forall n, 0 < abs n <-> n~=0.
Lemma abs_eq_or_opp : forall n, abs n == n \/ abs n == -n.
Lemma abs_or_opp_abs : forall n, n == abs n \/ n == - abs n.
Lemma abs_idemp : forall n, abs (abs n) == abs n.
#[deprecated(since="8.19", note="Use abs_idemp")]
Notation abs_involutive := abs_idemp.
Lemma abs_spec : forall n,
(0 <= n /\ abs n == n) \/ (n < 0 /\ abs n == -n).
Lemma abs_case_strong :
forall (P:t->Prop) n, Proper (eq==>iff) P ->
(0<=n -> P n) -> (n<=0 -> P (-n)) -> P (abs n).
Lemma abs_case : forall (P:t->Prop) n, Proper (eq==>iff) P ->
P n -> P (-n) -> P (abs n).
Lemma abs_lt : forall a b, abs a < b <-> -b < a < b.
Lemma abs_le : forall a b, abs a <= b <-> -b <= a <= b.
(** Triangular inequality *)
Lemma abs_triangle : forall n m, abs (n + m) <= abs n + abs m.
Lemma abs_sub_triangle : forall n m, abs n - abs m <= abs (n-m).
(** Absolute value and multiplication *)
Lemma abs_mul : forall n m, abs (n * m) == abs n * abs m.
Lemma abs_square : forall n, abs n * abs n == n * n.
Ltac destruct_sgn n :=
let LT := fresh "LT" in
let EQ := fresh "EQ" in
let GT := fresh "GT" in
destruct (lt_trichotomy 0 n) as [LT|[EQ|GT]];
[rewrite (sgn_pos n) by auto|
rewrite (sgn_null n) by auto with relations|
rewrite (sgn_neg n) by auto].