(* A d *)
elim H0; intros; elim H2; intros. split. exact H1. clear H0 H2.
(* A (-a) *)
elim H; intros; elim H2; intros; elim H5; intros; elim H8; intros.
elim H10; intros; elim (H12 a H3); intros; elim H14; intros.
split. exact H15. clear H0 H2 H3 H6 H7 H8 H9 H10 H13 H14 H15 H16.
(* (-a) = 0 or d <> 0 and (-a)= d*q *)
(* a = 0 *)
elim H4; intros. rewrite H0. left. exact (opp_neutral S A Add O Opp H5).
clear H4 H11.
(* a <> 0 *)
right.
elim H0; intros; elim H3; intros; elim H4; intros.
split. exact H2. clear H0 H2 H3 H4.
exists (Opp x).
elim (H12 x H6); intros; elim H2; intros. split. exact H3.
clear H3 H4 H5 H6 H12.
rewrite (mult_opp_r H d x H1 H0). elim H7; reflexivity.
Qed.
(***************)
Definition is_gcd (a b d : S) :=
divide d a /\
divide d b /\ (forall q : S, divide q a -> divide q b -> divide q d).

(* Specifications: *)
(**************)
Lemma gcd_null : forall a b : S, is_gcd a b O -> a = O /\ b = O.
unfold is_gcd in |- *; intros.