(* Monic predicate *)
Fact monic_key : pred_key monic. Proof. by []. Qed.
Canonical monic_keyed := KeyedQualifier monic_key.

(* Specifications: *)
Lemma monicE p : (p \is monic) = (lead_coef p == 1). Proof. by []. Qed.
Lemma monicP p : reflect (lead_coef p = 1) (p \is monic).
Lemma lead_coef_Mmonic p q : q \is monic -> lead_coef (p * q) = lead_coef p.
Lemma size_monicM p q :
p \is monic -> q != 0 -> size (p * q) = (size p + size q).-1.
Lemma size_Mmonic p q :
p != 0 -> q \is monic -> size (p * q) = (size p + size q).-1.
Lemma monicMl p q : p \is monic -> (p * q \is monic) = (q \is monic).
Lemma size_exp_XsubC n a : size (('X - a%:P) ^+ n) = n.+1.
Lemma rreg_lead p : GRing.rreg (lead_coef p) -> GRing.rreg p.
Lemma lreg_lead0 p : GRing.lreg (lead_coef p) -> p != 0.
Lemma lreg_polyZ_eq0 c p : GRing.lreg c -> (c *: p == 0) = (p == 0).
Lemma rreg_polyMC_eq0 c p : GRing.rreg c -> (p * c%:P == 0) = (p == 0).
Lemma monic_comreg p :
p \is monic -> GRing.comm p (lead_coef p)%:P /\ GRing.rreg (lead_coef p).
Lemma horner_coef0 p : p.[0] = p`_0.
Lemma horner_coef_wide n p x :
size p <= n -> p.[x] = \sum_(i < n) p`_i * x ^+ i.
Lemma horner_poly n E x : (\poly_(i < n) E i).[x] = \sum_(i < n) E i * x ^+ i.
Lemma hornerN p x : (- p).[x] = - p.[x].
Lemma hornerD p q x : (p + q).[x] = p.[x] + q.[x].
Lemma hornerXsubC a x : ('X - a%:P).[x] = x - a.
Lemma hornerZ c p x : (c *: p).[x] = c * p.[x].
Lemma comm_poly0 x : comm_poly 0 x.
Lemma horner_exp_comm p x n : comm_poly p x -> (p ^+ n).[x] = p.[x] ^+ n.
Lemma hornerXn x n : ('X^n).[x] = x ^+ n.
Lemma root_XsubC a x : root ('X - a%:P) x = (x == a).
Lemma multiplicity_XsubC p a :
{m | exists2 q, (p != 0) ==> ~~ root q a & p = q * ('X - a%:P) ^+ m}.