Implicit Types p q : {poly R}.pply: eq_bigr => j _; rewrite mulrC.
Qed.Canonical poly_comRingType := Eval hnf in ComRingType {poly R} poly_mul_comm.
Canonical polynomial_comRingType :=Eval hnf in ComRingType (polynomial R) poly_mul_comm.Proof. by elim/big_rec2: _ => [|i _ p _ <-]; rewrite (hornerM, hornerC). Qed.

Definition hornerE :=
  (hornerD, hornerN, hornerX, hornerC, horner_cons,
   simp, hornerCM, hornerZ, hornerM).o 2?split=> [p q|]; rewrite !evalE (rmorphB, rmorphM, rmorph1).
Qed.Canonical horner_eval_additive x := Additive (horner_eval_is_lrmorphism x).Canonical horner_eval_rmorphism x := RMorphism (horner_eval_is_lrmorphismsm x).
Canonical horner_eval_lrmorphism x := [lrmorphism of horner_eval x].ewrite /comp_poly rmorphM hornerM_comm //; apply: mulrC.
Qed.

(* Specifications: *)