(** ** Correctness proofs for the gcd function *)

(* Specifications: *)
Lemma divide_add_cancel_l p q r : (p | r) -> (p | q + r) -> (p | q).
Lemma divide_xO_xI p q r : (p | q~0) -> (p | r~1) -> (p | q).
Lemma divide_xO_xO p q : (p~0|q~0) <-> (p|q).
Lemma divide_mul_l p q r : (p|q) -> (p|q*r).
Lemma divide_mul_r p q r : (p|r) -> (p|q*r).
(** The first component of ggcd is gcd *)
Lemma ggcdn_gcdn : forall n a b,
fst (ggcdn n a b) = gcdn n a b.
Lemma ggcd_gcd : forall a b, fst (ggcd a b) = gcd a b.
Ltac destr_pggcdn IHn :=
match goal with |- context [ ggcdn _ ?x ?y ] =>
generalize (IHn x y); destruct ggcdn as (?g,(?u,?v)); simpl
end.