(* Zmodule structure for polynomial *)
Fact add_poly_key : unit. Proof. by []. Qed.
Definition add_poly := locked_with add_poly_key add_poly_def.
Canonical add_poly_unlockable := [unlockable fun add_poly].
Definition opp_poly_def p := \poly_(i < size p) - p`_i.
Fact opp_poly_key : unit. Proof. by []. Qed.
Definition opp_poly := locked_with opp_poly_key opp_poly_def.
Canonical opp_poly_unlockable := [unlockable fun opp_poly].
Fact coef_add_poly p q i : (add_poly p q)`_i = p`_i + q`_i.
Fact coef_opp_poly p i : (opp_poly p)`_i = - p`_i.
Fact add_polyA : associative add_poly.
Fact add_polyN : left_inverse 0%:P opp_poly add_poly.
Definition poly_zmodMixin :=
ZmodMixin add_polyA add_polyC add_poly0 add_polyN.
Canonical poly_zmodType := Eval hnf in ZmodType {poly R} poly_zmodMixin.
Canonical polynomial_zmodType :=
Eval hnf in ZmodType (polynomial R) poly_zmodMixin.

(* Specifications: *)
(* Properties of the zero polynomial *)
Lemma polyC0 : 0%:P = 0 :> {poly R}. Proof. by []. Qed.
Lemma polyseq0 : (0 : {poly R}) = [::] :> seq R.
Lemma polyC_eq0 (c : R) : (c%:P == 0) = (c == 0).
Lemma size_polyC_leq1 (c : R) : (size c%:P <= 1)%N.
(* Size, leading coef, morphism properties of coef *)
Lemma coefD p q i : (p + q)`_i = p`_i + q`_i.
Lemma lead_coef_opp p : lead_coef (- p) = - lead_coef p.
Lemma size_sum I (r : seq I) (P : pred I) (F : I -> {poly R}) :
size (\sum_(i <- r | P i) F i) <= \max_(i <- r | P i) size (F i).
Lemma lead_coefDl p q : size p > size q -> lead_coef (p + q) = lead_coef p.
Lemma lead_coefDr p q : size q > size p -> lead_coef (p + q) = lead_coef q.
Fact coef_mul_poly_rev p q i :
(mul_poly p q)`_i = \sum_(j < i.+1) p`_(i - j)%N * q`_j.