Module infotheo.lib.poly_ext
From mathcomp Require Import all_ssreflect fingroup perm ssralg zmodp.From mathcomp Require Import matrix mxalgebra poly polydiv mxpoly.
Require Import ssralg_ext.
# Additional lemmas about polynomials
Set Implicit Arguments.
Set SsrOldRewriteGoalsOrder.
Unset Strict Implicit.
Import Prenex Implicits.
Import GRing.Theory.
Local Open Scope ring_scope.
Section AboutPoly.
Variable R : idomainType.
Lemma size_quot_eq0 : forall q d r : {poly R},
d \is monic -> size r < size d -> (size (q * d + r) < size d) = (q == 0).
Proof.
move=> q d r mon sz; apply/eqP/eqP => [sz0 | ->]; apply/eqP.
- apply/negPn; apply/negP=> ab_absurdo; move: sz0.
rewrite size_polyDl; last first.
rewrite mulrC size_monicM //.
have Htmp : 0 < size q by rewrite lt0n size_poly_eq0.
rewrite -subn1 -addnBA //.
apply: (@leq_trans (size d)) => //.
by rewrite leq_addr.
rewrite mulrC size_monicM // prednK; last first.
rewrite addn_gt0.
apply/orP; left.
exact: (@leq_ltn_trans (size r)).
move/eqP.
rewrite addnC -addnBA // subnn addn0 size_poly_eq0; by apply/negP.
- by rewrite mul0r add0r subn_eq0.
Qed.
- apply/negPn; apply/negP=> ab_absurdo; move: sz0.
rewrite size_polyDl; last first.
rewrite mulrC size_monicM //.
have Htmp : 0 < size q by rewrite lt0n size_poly_eq0.
rewrite -subn1 -addnBA //.
apply: (@leq_trans (size d)) => //.
by rewrite leq_addr.
rewrite mulrC size_monicM // prednK; last first.
rewrite addn_gt0.
apply/orP; left.
exact: (@leq_ltn_trans (size r)).
move/eqP.
rewrite addnC -addnBA // subnn addn0 size_poly_eq0; by apply/negP.
- by rewrite mul0r add0r subn_eq0.
Qed.
Lemma poly_def_lead_coef : forall p : {poly R},
p = \sum_(i < (size p).-1) p`_i *: 'X^i + lead_coef p *: 'X^((size p).-1).
Proof.
Lemma size_lead_coefK : forall n (p : {poly R}), size p <= n.+1 ->
size (p - lead_coef p *: 'X^((size p).-1)) <= n.
Proof.
elim=> [|n IHn] p sz_p.
- rewrite (size1_polyC sz_p) lead_coefC size_polyC.
set t := (_ != _); have -> : t.-1 = O by case: t.
by rewrite expr0 alg_polyC subrr size_poly0.
- rewrite {1}(poly_def_lead_coef p) -addrA subrr addr0; apply/leq_trans.
+ by rewrite -poly_def; apply: size_poly.
+ by move: sz_p; case: (size _).
Qed.
- rewrite (size1_polyC sz_p) lead_coefC size_polyC.
set t := (_ != _); have -> : t.-1 = O by case: t.
by rewrite expr0 alg_polyC subrr size_poly0.
- rewrite {1}(poly_def_lead_coef p) -addrA subrr addr0; apply/leq_trans.
+ by rewrite -poly_def; apply: size_poly.
+ by move: sz_p; case: (size _).
Qed.
Lemma size_sub (p q : {poly R}) : p <> 0 -> size p = size q ->
lead_coef p = lead_coef q -> size (p - q) < size p.
Proof.
move=> p0 pq lc_pq.
move: (size_polyD p (-q)); rewrite pq size_polyN (maxn_idPr _) //.
rewrite leq_eqVlt; case/orP => // abs.
rewrite (@leq_ltn_trans (size q).-1) //; last first.
by rewrite -pq prednK // lt0n size_poly_eq0; apply/eqP.
rewrite (poly_def_lead_coef p) {1}(poly_def_lead_coef q) lc_pq pq.
rewrite opprD addrCA addrK addrC.
rewrite (_ : _ - _ = \poly_(i < (size q).-1) (p`_i - q`_i)) ?size_poly //.
rewrite -sumrB poly_def; apply: eq_bigr => i _; by rewrite scalerBl.
Qed.
move: (size_polyD p (-q)); rewrite pq size_polyN (maxn_idPr _) //.
rewrite leq_eqVlt; case/orP => // abs.
rewrite (@leq_ltn_trans (size q).-1) //; last first.
by rewrite -pq prednK // lt0n size_poly_eq0; apply/eqP.
rewrite (poly_def_lead_coef p) {1}(poly_def_lead_coef q) lc_pq pq.
rewrite opprD addrCA addrK addrC.
rewrite (_ : _ - _ = \poly_(i < (size q).-1) (p`_i - q`_i)) ?size_poly //.
rewrite -sumrB poly_def; apply: eq_bigr => i _; by rewrite scalerBl.
Qed.
Lemma rVpoly0 n (p : 'rV[R]_n) : (rVpoly p == 0) = (p == 0).
Proof.
Lemma poly_rV_0_inv n (p : {poly R}) : size p <= n ->
poly_rV p == (0 : 'rV[R]_n) -> p == 0.
Proof.
Lemma poly_rV_0 n (p : {poly R}) : p == 0 -> poly_rV p == (0 : 'rV[R]_n).
End AboutPoly.
Lemma morph_modp (F : fieldType) (p : {poly F}) :
{morph (fun x : {poly F} => x %% p) : x y / x + y}.