(* Contribution to the Coq Library   V6.3 (July 1999)                    *)
(****************************************************************************)
(*                 The Calculus of Inductive Constructions                  *)
(*                                                                          *)
(*                                Projet Coq                                *)
(*                                                                          *)
(*                     INRIA                        ENS-CNRS                *)
(*              Rocquencourt                        Lyon                    *)
(*                                                                          *)
(*                                Coq V5.10                                 *)
(*                              Nov 25th 1994                               *)
(*                                                                          *)
(****************************************************************************)
(*                                  Zgcd.v                                  *)
(****************************************************************************)
Require Export misc.
Require Export Zadd.
Require Export Zle.
Require Export Euclid.
Require Export Peano_dec.
Require Export Zrec.
Require Export Zmult.
Require Export Zdiv.
Unset Standard Proposition Elimination Names.
intros.
elim
(gcd_unicity_apart_unities Z IdZ addZ multZ OZ IZ oppZ
Z_unitary_commutative_ring integrityZ a b d1 d2 H H0).
intros.
elim (inversibleZ x); intros.
left. elim H1; intros; elim H4; intros. rewrite H6. rewrite H2.
exact (mult_IZ d1).
right. elim H1; intros; elim H4; intros. rewrite H6. rewrite H2.
simpl in |- *; exact (mult_mIZ d1).
elim H1; intros; exact H2.
Qed.
intros. elim (abs_eq_or_oppZ b); intro y.
(* |b|=b *)
rewrite y.
unfold is_gcd in |- *; split.
unfold divide in |- *; unfold IdZ in |- *; split. exact I. split. exact I. left; reflexivity.
split; unfold divide in |- *; unfold IdZ in |- *. split. exact I. split. exact I.
elim (eq_OZ_dec b); intro y0.
left; exact y0.
right. split. exact y0. exists IZ. split. exact I. symmetry  in |- *; exact (mult_IZ b).
intros; exact H0.
(* |b|=(-b) *)
rewrite y.
unfold is_gcd in |- *; split.
unfold divide in |- *; unfold IdZ in |- *; split. exact I. split. exact I. left; reflexivity.
split; unfold divide in |- *; unfold IdZ in |- *; split. exact I. split. exact I.
elim (eq_OZ_dec b); intro y0.
left; exact y0.
right. split.
unfold not in |- *; intros; elim y0.
exact (opp_O Z IdZ addZ multZ OZ oppZ Z_ring b I H).
exists (oppZ IZ); split. exact I.
rewrite (mult_opp_opp Z IdZ addZ multZ OZ oppZ Z_ring b IZ I I).
symmetry  in |- *; exact (mult_IZ b). exact I. split. exact I.
elim H0; intros; elim H2; intros; elim H4; intros. rewrite H5.
left; reflexivity.
right; split. elim H5; intros; exact H6. elim H5; intros; elim H7; intros.
exists (oppZ x). split. exact I. elim H8; intros; rewrite H10.
symmetry  in |- *; exact (mult_opp_r Z IdZ addZ multZ OZ oppZ Z_ring q x I I).
Qed.
(******************)
Inductive is_gcdZ : Z -> Z -> Z -> Prop :=
| gcd_OZ : forall b : Z, is_gcdZ OZ b (absZ b)
| gcd_mod :
forall b a d q r : Z,
b <> OZ -> is_diveuclZ a b q r -> is_gcdZ r b d -> is_gcdZ b a d.
(******************)
Definition have_gcdZ (a b : Z) := {d : Z | is_gcdZ a b d}.
Definition gcdZ_i (a b : Z) := exist (is_gcdZ a b).
(* Inductive have_gcdZ [a, b: Z]: Set := gcdZ_i: (d: Z) (is_gcdZ a b d) -> (have_gcdZ a b). *)
(*******************)
Definition P (a : Z) := forall b : Z, have_gcdZ a b.

(****************)
Lemma gcdZ_is_gcd :
forall a b d : Z, is_gcdZ a b d -> is_gcd Z IdZ multZ OZ a b d.