(* Extended gcd, which computes Bezout coefficients. *)

Fixpoint Bezout_rec km kn qs :=
  if qs is q :: qs' then Bezout_rec kn (NatTrec.add_mul q kn km) qs'
  else (km, kn).

(* Specifications: *)
Lemma egcd0n n : egcdn 0 n = (1, 0).
Lemma egcdnP m n : m > 0 -> egcdn_spec m n (egcdn m n).
Lemma gcdnAC : right_commutative gcdn.
Lemma gcdnA : associative gcdn.
Lemma gcdnCA : left_commutative gcdn.
Lemma gcdnACA : interchange gcdn gcdn.
Lemma muln_gcdr : right_distributive muln gcdn.
Lemma muln_gcdl : left_distributive muln gcdn.
Lemma lcmnC : commutative lcmn.
Lemma lcm0n : left_zero 0 lcmn.
Lemma lcmn0 : right_zero 0 lcmn.
Lemma lcm1n : left_id 1 lcmn.
Lemma lcmn1 : right_id 1 lcmn.
Lemma muln_lcm_gcd m n : lcmn m n * gcdn m n = m * n.
Lemma lcmn_gt0 m n : (0 < lcmn m n) = (0 < m) && (0 < n).
Lemma muln_lcmr : right_distributive muln lcmn.
Lemma muln_lcml : left_distributive muln lcmn.
Lemma lcmnA : associative lcmn.
Lemma lcmnCA : left_commutative lcmn.
Lemma lcmnAC : right_commutative lcmn.
Lemma lcmnACA : interchange lcmn lcmn.
Lemma lcmnMl m n : lcmn m (m * n) = m * n.
Lemma lcmnMr m n : lcmn n (m * n) = m * n.
Lemma expn_max e m n : e ^ maxn m n = lcmn (e ^ m) (e ^ n).
Lemma coprime1n n : coprime 1 n.
Lemma coprimen1 n : coprime n 1.
Lemma coprime_sym m n : coprime m n = coprime n m.
Lemma coprime2n n : coprime 2 n = odd n.
Lemma coprimen2 n : coprime n 2 = odd n.
Lemma Gauss_gcdr p m n : coprime p m -> gcdn p (m * n) = gcdn p n.
Lemma Gauss_gcdl p m n : coprime p n -> gcdn p (m * n) = gcdn p m.
Lemma coprime_mulr p m n : coprime p (m * n) = coprime p m && coprime p n.
Lemma coprime_mull p m n : coprime (m * n) p = coprime m p && coprime n p.
Lemma coprime_pexpl k m n : 0 < k -> coprime (m ^ k) n = coprime m n.
Lemma coprime_pexpr k m n : 0 < k -> coprime m (n ^ k) = coprime m n.
Lemma coprime_expl k m n : coprime m n -> coprime (m ^ k) n.
Lemma coprime_expr k m n : coprime m n -> coprime m (n ^ k).