(** 2) For Euclid's algorithm, the worst-case situation corresponds
    to Fibonacci numbers. Let's define them: *)

 Fixpoint fibonacci (n:nat) : Z :=
   match n with
     | O => 1
     | S O => 1
     | S (S n as p) => fibonacci p + fibonacci n
   end.

(* Specifications: *)
Lemma fibonacci_pos : forall n, 0 <= fibonacci n.
Lemma fibonacci_incr : forall n m, (n<=m)%nat -> fibonacci n <= fibonacci m.
Lemma Zgcdn_worst_is_fibonacci : forall n a b, 0 < a < b -> Zis_gcd a b (Zgcdn (S n) a b) -> Zgcdn n a b <> Zgcdn (S n) a b -> fibonacci (S n) <= a /\ fibonacci (S (S n)) <= b.
Lemma Zgcdn_ok_before_fibonacci : forall n a b, 0 < a < b -> a < fibonacci (S n) -> Zis_gcd a b (Zgcdn n a b).
Lemma Zgcd_bound_fibonacci : forall a, 0 < a -> a < fibonacci (Zgcd_bound a).
Lemma Zgcd_bound_opp a : Zgcd_bound (-a) = Zgcd_bound a.
Lemma Zgcdn_opp n a b : Zgcdn n (-a) b = Zgcdn n a b.
Lemma Zgcdn_is_gcd_pos n a b : (Zgcd_bound (Zpos a) <= n)%nat -> Zis_gcd (Zpos a) b (Zgcdn n (Zpos a) b).
Lemma Zgcdn_is_gcd n a b : (Zgcd_bound a <= n)%nat -> Zis_gcd a b (Zgcdn n a b).
Lemma Zgcd_is_gcd : forall a b, Zis_gcd a b (Zgcd_alt a b).