(** In Coq, we need to control the number of iteration of modulo.
   For that, we use an explicit measure in [nat], and we prove later
   that using [2*d] is enough, where [d] is the number of binary
   digits of the first argument. *)

 Fixpoint Zgcdn (n:nat) : Z -> Z -> Z := fun a b =>
   match n with
     | O => 1 (* arbitrary, since n should be big enough *)
     | S n => match a with
                | Z0 => Z.abs b
                | Zpos _ => Zgcdn n (Z.modulo b a) a
                | Zneg a => Zgcdn n (Z.modulo b (Zpos a)) (Zpos a)
              end
   end.Definition Zgcd_bound (a:Z) :=
   match a with
     | Z0 => S O
     | Zpos p => let n := Pos.size_nat p in (n+n)%nat
     | Zneg p => let n := Pos.size_nat p in (n+n)%nat
   end.Definition Zgcd_alt a b := Zgcdn (Zgcd_bound a) a b.

(* Specifications: *)
Lemma Zgcdn_pos : forall n a b, 0 <= Zgcdn n a b.
Lemma Zgcd_alt_pos : forall a b, 0 <= Zgcd_alt a b.
Lemma Zgcdn_linear_bound : forall n a b, Z.abs a < Z.of_nat n -> Zis_gcd a b (Zgcdn n a b).