(*************)
Definition oppZ (x : Z) :=
  match x return Z with
  | OZ =>
      (* OZ *)  OZ
      (* pos n *) 
  | pos n => neg n
      (* neg n *) 
  | neg n => pos n
  end.

(* Specifications: *)
Lemma opp_succZ : forall x : Z, oppZ (succZ x) = predZ (oppZ x).
Lemma opp_predZ : forall x : Z, oppZ (predZ x) = succZ (oppZ x).
Lemma tech_add_pos_negZ : forall n : nat, addZ (pos n) (neg n) = OZ.
Lemma tech_add_neg_posZ : forall n : nat, addZ (neg n) (pos n) = OZ.
Lemma tech_add_pos_posZ : forall n m : nat, addZ (pos n) (pos m) = pos (S (n + m)).
Lemma tech_add_neg_negZ : forall n m : nat, addZ (neg n) (neg m) = neg (S (n + m)).
Theorem addZ_opposite : opposite Z IdZ addZ OZ oppZ.
Theorem Z_group : is_group Z IdZ addZ OZ oppZ.
Theorem abs_eq_or_oppZ : forall x : Z, {absZ x = x} + {absZ x = oppZ x}.
Lemma tech_opp_pos_negZ : forall n : nat, oppZ (pos n) = neg n /\ oppZ (neg n) = pos n.