move=> pn0 qn0; apply: (iffP idP); last first.
case=> [[u v] /= /andP [/andP [ps1 s1] /andP [ps2 s2]] e].
have: ~~(size (q * p) <= size (u * p)).
rewrite -ltnNge !size_mul // -?size_poly_gt0 // (polySpred pn0) !addnS.
by rewrite ltn_add2r.
apply: contra => ?; apply: dvdp_leq; rewrite ?mulf_neq0 // -?size_poly_gt0 //.
by rewrite mulrC Gauss_dvdp // dvdp_mull // e dvdp_mull.
rewrite coprimep_def neq_ltn.
case/orP; first by rewrite ltnS leqn0 size_poly_eq0 gcdp_eq0 -[p == 0]negbK pn0.
case sg: (size (gcdp p q)) => [|n] //; case: n sg=> [|n] // sg _.
move: (dvdp_gcdl p q); rewrite dvdp_eq; set c1 := _ ^+ _; move/eqP=> hu1.
move: (dvdp_gcdr p q); rewrite dvdp_eq; set c2 := _ ^+ _; move/eqP=> hv1.
exists (c1 *: (q %/ gcdp p q), c2 *: (p %/ gcdp p q)); last first.
by rewrite -!{1}scalerAl !scalerAr hu1 hv1 mulrCA.
rewrite !{1}size_scale ?lc_expn_scalp_neq0 //= !size_poly_gt0 !divp_eq0.
rewrite gcdp_eq0 !(negPf pn0) !(negPf qn0) /= -!leqNgt leq_gcdpl //.
rewrite leq_gcdpr //= !ltn_divpl -?size_poly_eq0 ?sg //.
rewrite !size_mul // -?size_poly_eq0 ?sg // ![(_ + n.+2)%N]addnS /=.
by rewrite -{1}(addn0 (size p)) -{1}(addn0 (size q)) !ltn_add2l.
Qed.

(* Specifications: *)
Lemma dvdp_pexp2r m n k : k > 0 -> (m ^+ k %| n ^+ k) = (m %| n).
Lemma root_gcd p q x : root (gcdp p q) x = root p x && root q x.
Lemma root_biggcd : forall x (ps : seq {poly R}),
root (\big[gcdp/0]_(p <- ps) p) x = all (fun p => root p x) ps.