Section IDomainPseudoDivision.
Variable R : idomainType.
Implicit Type p q r d m n : {poly R}.
Hint Resolve divp0 divp1 mod0p modp0 modp1 : core.
Hint Resolve dvdp0 : core.
Hint Resolve dvdpp : core.
Hint Resolve eqpxx : core.
suff Hmn m n: m %= n -> (m %| p) -> (n %| p).
by move=> ?; apply/idP/idP; apply: Hmn; rewrite // eqp_sym.
by rewrite /eqp; case/andP=> dd' d'd dp; apply: (dvdp_trans d'd).
Qed.
Definition gcdp_rec p q :=
let: (p1, q1) := if size p < size q then (q, p) else (p, q) in
if p1 == 0 then q1 else
let fix loop (n : nat) (pp qq : {poly R}) {struct n} :=
let rr := modp pp qq in
if rr == 0 then qq else
if n is n1.+1 then loop n1 qq rr else rr in
loop (size p1) p1 q1.
Definition gcdp := nosimpl gcdp_rec.

Lemma gcdp_def d m n :
d %| m -> d %| n -> (forall d', d' %| m -> d' %| n -> d' %| d) ->
gcdp m n %= d.