|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Damiano Testa. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Damiano Testa |
| 5 | +-/ |
| 6 | +import data.polynomial.degree.basic |
| 7 | +import data.polynomial.degree.trailing_degree |
| 8 | + |
| 9 | +/-! |
| 10 | +# Erase the leading term of a univariate polynomial |
| 11 | +
|
| 12 | +## Definition |
| 13 | +
|
| 14 | +* `erase_lead f`: the polynomial `f - leading term of f` |
| 15 | +
|
| 16 | +`erase_lead` serves as reduction step in an induction, shaving off one monomial from a polynomial. |
| 17 | +The definition is set up so that it does not mention subtraction in the definition, |
| 18 | +and thus works for polynomials over semirings as well as rings. |
| 19 | +-/ |
| 20 | + |
| 21 | +noncomputable theory |
| 22 | +open_locale classical |
| 23 | + |
| 24 | +open polynomial finsupp finset |
| 25 | + |
| 26 | +namespace polynomial |
| 27 | + |
| 28 | +variables {R : Type*} [semiring R] {f : polynomial R} |
| 29 | + |
| 30 | +/-- `erase_lead f` for a polynomial `f` is the polynomial obtained by |
| 31 | +subtracting from `f` the leading term of `f`. -/ |
| 32 | +def erase_lead (f : polynomial R) : polynomial R := |
| 33 | +finsupp.erase f.nat_degree f |
| 34 | + |
| 35 | +section erase_lead |
| 36 | + |
| 37 | +lemma erase_lead_support (f : polynomial R) : |
| 38 | + f.erase_lead.support = f.support.erase f.nat_degree := |
| 39 | +-- `rfl` fails because LHS uses `nat.decidable_eq` but RHS is classical. |
| 40 | +by convert rfl |
| 41 | + |
| 42 | +lemma erase_lead_coeff (i : ℕ) : |
| 43 | + f.erase_lead.coeff i = if i = f.nat_degree then 0 else f.coeff i := |
| 44 | +-- `rfl` fails because LHS uses `nat.decidable_eq` but RHS is classical. |
| 45 | +by convert rfl |
| 46 | + |
| 47 | +@[simp] lemma erase_lead_coeff_nat_degree : f.erase_lead.coeff f.nat_degree = 0 := |
| 48 | +finsupp.erase_same |
| 49 | + |
| 50 | +lemma erase_lead_coeff_of_ne (i : ℕ) (hi : i ≠ f.nat_degree) : |
| 51 | + f.erase_lead.coeff i = f.coeff i := |
| 52 | +finsupp.erase_ne hi |
| 53 | + |
| 54 | +@[simp] lemma erase_lead_zero : erase_lead (0 : polynomial R) = 0 := |
| 55 | +finsupp.erase_zero _ |
| 56 | + |
| 57 | +@[simp] lemma erase_lead_add_monomial_nat_degree_leading_coeff (f : polynomial R) : |
| 58 | + f.erase_lead + monomial f.nat_degree f.leading_coeff = f := |
| 59 | +begin |
| 60 | + ext i, |
| 61 | + simp only [erase_lead_coeff, coeff_monomial, coeff_add, @eq_comm _ _ i], |
| 62 | + split_ifs with h, |
| 63 | + { subst i, simp only [leading_coeff, zero_add] }, |
| 64 | + { exact add_zero _ } |
| 65 | +end |
| 66 | + |
| 67 | +@[simp] lemma erase_lead_add_C_mul_X_pow (f : polynomial R) : |
| 68 | + f.erase_lead + (C f.leading_coeff) * X ^ f.nat_degree = f := |
| 69 | +by rw [C_mul_X_pow_eq_monomial, erase_lead_add_monomial_nat_degree_leading_coeff] |
| 70 | + |
| 71 | +@[simp] lemma self_sub_monomial_nat_degree_leading_coeff {R : Type*} [ring R] (f : polynomial R) : |
| 72 | + f - monomial f.nat_degree f.leading_coeff = f.erase_lead := |
| 73 | +(eq_sub_iff_add_eq.mpr (erase_lead_add_monomial_nat_degree_leading_coeff f)).symm |
| 74 | + |
| 75 | +@[simp] lemma self_sub_C_mul_X_pow {R : Type*} [ring R] (f : polynomial R) : |
| 76 | + f - (C f.leading_coeff) * X ^ f.nat_degree = f.erase_lead := |
| 77 | +by rw [C_mul_X_pow_eq_monomial, self_sub_monomial_nat_degree_leading_coeff] |
| 78 | + |
| 79 | +lemma erase_lead_ne_zero (f0 : 2 ≤ f.support.card) : erase_lead f ≠ 0 := |
| 80 | +begin |
| 81 | + rw [ne.def, ← finsupp.card_support_eq_zero, erase_lead_support], |
| 82 | + exact (zero_lt_one.trans_le $ (nat.sub_le_sub_right f0 1).trans |
| 83 | + finset.pred_card_le_card_erase).ne.symm |
| 84 | +end |
| 85 | + |
| 86 | +@[simp] lemma nat_degree_not_mem_erase_lead_support : f.nat_degree ∉ (erase_lead f).support := |
| 87 | +by convert not_mem_erase _ _ |
| 88 | + |
| 89 | +lemma ne_nat_degree_of_mem_erase_lead_support {a : ℕ} (h : a ∈ (erase_lead f).support) : |
| 90 | + a ≠ f.nat_degree := |
| 91 | +by { rintro rfl, exact nat_degree_not_mem_erase_lead_support h } |
| 92 | + |
| 93 | +lemma erase_lead_support_card_lt (h : f ≠ 0) : (erase_lead f).support.card < f.support.card := |
| 94 | +begin |
| 95 | + rw erase_lead_support, |
| 96 | + exact card_lt_card (erase_ssubset $ nat_degree_mem_support_of_nonzero h) |
| 97 | +end |
| 98 | + |
| 99 | +@[simp] lemma erase_lead_monomial (i : ℕ) (r : R) : |
| 100 | + erase_lead (monomial i r) = 0 := |
| 101 | +begin |
| 102 | + by_cases hr : r = 0, |
| 103 | + { subst r, simp only [monomial_zero_right, erase_lead_zero] }, |
| 104 | + { rw [erase_lead, nat_degree_monomial _ _ hr, monomial, erase_single] } |
| 105 | +end |
| 106 | + |
| 107 | +@[simp] lemma erase_lead_C (r : R) : erase_lead (C r) = 0 := |
| 108 | +erase_lead_monomial _ _ |
| 109 | + |
| 110 | +@[simp] lemma erase_lead_X : erase_lead (X : polynomial R) = 0 := |
| 111 | +erase_lead_monomial _ _ |
| 112 | + |
| 113 | +@[simp] lemma erase_lead_X_pow (n : ℕ) : erase_lead (X ^ n : polynomial R) = 0 := |
| 114 | +by rw [X_pow_eq_monomial, erase_lead_monomial] |
| 115 | + |
| 116 | +@[simp] lemma erase_lead_C_mul_X_pow (r : R) (n : ℕ) : erase_lead (C r * X ^ n) = 0 := |
| 117 | +by rw [C_mul_X_pow_eq_monomial, erase_lead_monomial] |
| 118 | + |
| 119 | +lemma erase_lead_degree_le : (erase_lead f).degree ≤ f.degree := |
| 120 | +begin |
| 121 | + rw degree_le_iff_coeff_zero, |
| 122 | + intros i hi, |
| 123 | + rw erase_lead_coeff, |
| 124 | + split_ifs with h, { refl }, |
| 125 | + apply coeff_eq_zero_of_degree_lt hi |
| 126 | +end |
| 127 | + |
| 128 | +lemma erase_lead_nat_degree_le : (erase_lead f).nat_degree ≤ f.nat_degree := |
| 129 | +nat_degree_le_nat_degree erase_lead_degree_le |
| 130 | + |
| 131 | +lemma erase_lead_nat_degree_lt (f0 : 2 ≤ f.support.card) : |
| 132 | + (erase_lead f).nat_degree < f.nat_degree := |
| 133 | +lt_of_le_of_ne erase_lead_nat_degree_le $ ne_nat_degree_of_mem_erase_lead_support $ |
| 134 | + nat_degree_mem_support_of_nonzero $ erase_lead_ne_zero f0 |
| 135 | + |
| 136 | +end erase_lead |
| 137 | + |
| 138 | +end polynomial |
0 commit comments