|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Eric Wieser. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Eric Wieser |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module data.mv_polynomial.division |
| 7 | +! leanprover-community/mathlib commit 72c366d0475675f1309d3027d3d7d47ee4423951 |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Algebra.MonoidAlgebra.Division |
| 12 | +import Mathlib.Data.MvPolynomial.Basic |
| 13 | + |
| 14 | +/-! |
| 15 | +# Division of `MvPolynomial` by monomials |
| 16 | +
|
| 17 | +## Main definitions |
| 18 | +
|
| 19 | +* `MvPolynomial.divMonomial x s`: divides `x` by the monomial `MvPolynomial.monomial 1 s` |
| 20 | +* `MvPolynomial.modMonomial x s`: the remainder upon dividing `x` by the monomial |
| 21 | + `MvPolynomial.monomial 1 s`. |
| 22 | +
|
| 23 | +## Main results |
| 24 | +
|
| 25 | +* `MvPolynomial.divMonomial_add_modMonomial`, `MvPolynomial.modMonomial_add_divMonomial`: |
| 26 | + `divMonomial` and `modMonomial` are well-behaved as quotient and remainder operators. |
| 27 | +
|
| 28 | +## Implementation notes |
| 29 | +
|
| 30 | +Where possible, the results in this file should be first proved in the generality of |
| 31 | +`AddMonoidAlgebra`, and then the versions specialized to `MvPolynomial` proved in terms of these. |
| 32 | +
|
| 33 | +-/ |
| 34 | + |
| 35 | + |
| 36 | +variable {σ R : Type _} [CommSemiring R] |
| 37 | + |
| 38 | +namespace MvPolynomial |
| 39 | + |
| 40 | +section CopiedDeclarations |
| 41 | + |
| 42 | +/-! Please ensure the declarations in this section are direct translations of `AddMonoidAlgebra` |
| 43 | +results. -/ |
| 44 | + |
| 45 | + |
| 46 | +/-- Divide by `monomial 1 s`, discarding terms not divisible by this. -/ |
| 47 | +noncomputable def divMonomial (p : MvPolynomial σ R) (s : σ →₀ ℕ) : MvPolynomial σ R := |
| 48 | + AddMonoidAlgebra.divOf p s |
| 49 | +#align mv_polynomial.div_monomial MvPolynomial.divMonomial |
| 50 | + |
| 51 | +local infixl:70 " /ᵐᵒⁿᵒᵐⁱᵃˡ " => divMonomial |
| 52 | + |
| 53 | +@[simp] |
| 54 | +theorem coeff_divMonomial (s : σ →₀ ℕ) (x : MvPolynomial σ R) (s' : σ →₀ ℕ) : |
| 55 | + coeff s' (x /ᵐᵒⁿᵒᵐⁱᵃˡ s) = coeff (s + s') x := |
| 56 | + rfl |
| 57 | +#align mv_polynomial.coeff_div_monomial MvPolynomial.coeff_divMonomial |
| 58 | + |
| 59 | +@[simp] |
| 60 | +theorem support_divMonomial (s : σ →₀ ℕ) (x : MvPolynomial σ R) : |
| 61 | + (x /ᵐᵒⁿᵒᵐⁱᵃˡ s).support = x.support.preimage _ ((add_right_injective s).injOn _) := |
| 62 | + rfl |
| 63 | +#align mv_polynomial.support_div_monomial MvPolynomial.support_divMonomial |
| 64 | + |
| 65 | +@[simp] |
| 66 | +theorem zero_divMonomial (s : σ →₀ ℕ) : (0 : MvPolynomial σ R) /ᵐᵒⁿᵒᵐⁱᵃˡ s = 0 := |
| 67 | + AddMonoidAlgebra.zero_divOf _ |
| 68 | +#align mv_polynomial.zero_div_monomial MvPolynomial.zero_divMonomial |
| 69 | + |
| 70 | +theorem divMonomial_zero (x : MvPolynomial σ R) : x /ᵐᵒⁿᵒᵐⁱᵃˡ 0 = x := |
| 71 | + x.divOf_zero |
| 72 | +#align mv_polynomial.div_monomial_zero MvPolynomial.divMonomial_zero |
| 73 | + |
| 74 | +theorem add_divMonomial (x y : MvPolynomial σ R) (s : σ →₀ ℕ) : |
| 75 | + (x + y) /ᵐᵒⁿᵒᵐⁱᵃˡ s = x /ᵐᵒⁿᵒᵐⁱᵃˡ s + y /ᵐᵒⁿᵒᵐⁱᵃˡ s := |
| 76 | + map_add _ _ _ |
| 77 | +#align mv_polynomial.add_div_monomial MvPolynomial.add_divMonomial |
| 78 | + |
| 79 | +theorem divMonomial_add (a b : σ →₀ ℕ) (x : MvPolynomial σ R) : |
| 80 | + x /ᵐᵒⁿᵒᵐⁱᵃˡ (a + b) = x /ᵐᵒⁿᵒᵐⁱᵃˡ a /ᵐᵒⁿᵒᵐⁱᵃˡ b := |
| 81 | + x.divOf_add _ _ |
| 82 | +#align mv_polynomial.div_monomial_add MvPolynomial.divMonomial_add |
| 83 | + |
| 84 | +@[simp] |
| 85 | +theorem divMonomial_monomial_mul (a : σ →₀ ℕ) (x : MvPolynomial σ R) : |
| 86 | + monomial a 1 * x /ᵐᵒⁿᵒᵐⁱᵃˡ a = x := |
| 87 | + x.of'_mul_divOf _ |
| 88 | +#align mv_polynomial.div_monomial_monomial_mul MvPolynomial.divMonomial_monomial_mul |
| 89 | + |
| 90 | +@[simp] |
| 91 | +theorem divMonomial_mul_monomial (a : σ →₀ ℕ) (x : MvPolynomial σ R) : |
| 92 | + x * monomial a 1 /ᵐᵒⁿᵒᵐⁱᵃˡ a = x := |
| 93 | + x.mul_of'_divOf _ |
| 94 | +#align mv_polynomial.div_monomial_mul_monomial MvPolynomial.divMonomial_mul_monomial |
| 95 | + |
| 96 | +@[simp] |
| 97 | +theorem divMonomial_monomial (a : σ →₀ ℕ) : monomial a 1 /ᵐᵒⁿᵒᵐⁱᵃˡ a = (1 : MvPolynomial σ R) := |
| 98 | + AddMonoidAlgebra.of'_divOf _ |
| 99 | +#align mv_polynomial.div_monomial_monomial MvPolynomial.divMonomial_monomial |
| 100 | + |
| 101 | +/-- The remainder upon division by `monomial 1 s`. -/ |
| 102 | +noncomputable def modMonomial (x : MvPolynomial σ R) (s : σ →₀ ℕ) : MvPolynomial σ R := |
| 103 | + x.modOf s |
| 104 | +#align mv_polynomial.mod_monomial MvPolynomial.modMonomial |
| 105 | + |
| 106 | +local infixl:70 " %ᵐᵒⁿᵒᵐⁱᵃˡ " => modMonomial |
| 107 | + |
| 108 | +@[simp] |
| 109 | +theorem coeff_modMonomial_of_not_le {s' s : σ →₀ ℕ} (x : MvPolynomial σ R) (h : ¬s ≤ s') : |
| 110 | + coeff s' (x %ᵐᵒⁿᵒᵐⁱᵃˡ s) = coeff s' x := |
| 111 | + x.modOf_apply_of_not_exists_add s s' |
| 112 | + (by |
| 113 | + rintro ⟨d, rfl⟩ |
| 114 | + exact h le_self_add) |
| 115 | +#align mv_polynomial.coeff_mod_monomial_of_not_le MvPolynomial.coeff_modMonomial_of_not_le |
| 116 | + |
| 117 | +@[simp] |
| 118 | +theorem coeff_modMonomial_of_le {s' s : σ →₀ ℕ} (x : MvPolynomial σ R) (h : s ≤ s') : |
| 119 | + coeff s' (x %ᵐᵒⁿᵒᵐⁱᵃˡ s) = 0 := |
| 120 | + x.modOf_apply_of_exists_add _ _ <| exists_add_of_le h |
| 121 | +#align mv_polynomial.coeff_mod_monomial_of_le MvPolynomial.coeff_modMonomial_of_le |
| 122 | + |
| 123 | +@[simp] |
| 124 | +theorem monomial_mul_modMonomial (s : σ →₀ ℕ) (x : MvPolynomial σ R) : |
| 125 | + monomial s 1 * x %ᵐᵒⁿᵒᵐⁱᵃˡ s = 0 := |
| 126 | + x.of'_mul_modOf _ |
| 127 | +#align mv_polynomial.monomial_mul_mod_monomial MvPolynomial.monomial_mul_modMonomial |
| 128 | + |
| 129 | +@[simp] |
| 130 | +theorem mul_monomial_modMonomial (s : σ →₀ ℕ) (x : MvPolynomial σ R) : |
| 131 | + x * monomial s 1 %ᵐᵒⁿᵒᵐⁱᵃˡ s = 0 := |
| 132 | + x.mul_of'_modOf _ |
| 133 | +#align mv_polynomial.mul_monomial_mod_monomial MvPolynomial.mul_monomial_modMonomial |
| 134 | + |
| 135 | +@[simp] |
| 136 | +theorem monomial_modMonomial (s : σ →₀ ℕ) : monomial s (1 : R) %ᵐᵒⁿᵒᵐⁱᵃˡ s = 0 := |
| 137 | + AddMonoidAlgebra.of'_modOf _ |
| 138 | +#align mv_polynomial.monomial_mod_monomial MvPolynomial.monomial_modMonomial |
| 139 | + |
| 140 | +theorem divMonomial_add_modMonomial (x : MvPolynomial σ R) (s : σ →₀ ℕ) : |
| 141 | + monomial s 1 * (x /ᵐᵒⁿᵒᵐⁱᵃˡ s) + x %ᵐᵒⁿᵒᵐⁱᵃˡ s = x := |
| 142 | + AddMonoidAlgebra.divOf_add_modOf x s |
| 143 | +#align mv_polynomial.div_monomial_add_mod_monomial MvPolynomial.divMonomial_add_modMonomial |
| 144 | + |
| 145 | +theorem modMonomial_add_divMonomial (x : MvPolynomial σ R) (s : σ →₀ ℕ) : |
| 146 | + x %ᵐᵒⁿᵒᵐⁱᵃˡ s + monomial s 1 * (x /ᵐᵒⁿᵒᵐⁱᵃˡ s) = x := |
| 147 | + AddMonoidAlgebra.modOf_add_divOf x s |
| 148 | +#align mv_polynomial.mod_monomial_add_div_monomial MvPolynomial.modMonomial_add_divMonomial |
| 149 | + |
| 150 | +theorem monomial_one_dvd_iff_modMonomial_eq_zero {i : σ →₀ ℕ} {x : MvPolynomial σ R} : |
| 151 | + monomial i (1 : R) ∣ x ↔ x %ᵐᵒⁿᵒᵐⁱᵃˡ i = 0 := |
| 152 | + AddMonoidAlgebra.of'_dvd_iff_modOf_eq_zero |
| 153 | +#align mv_polynomial.monomial_one_dvd_iff_mod_monomial_eq_zero MvPolynomial.monomial_one_dvd_iff_modMonomial_eq_zero |
| 154 | + |
| 155 | +end CopiedDeclarations |
| 156 | + |
| 157 | +section XLemmas |
| 158 | + |
| 159 | +local infixl:70 " /ᵐᵒⁿᵒᵐⁱᵃˡ " => divMonomial |
| 160 | + |
| 161 | +local infixl:70 " %ᵐᵒⁿᵒᵐⁱᵃˡ " => modMonomial |
| 162 | + |
| 163 | +@[simp] |
| 164 | +theorem x_mul_divMonomial (i : σ) (x : MvPolynomial σ R) : |
| 165 | + X i * x /ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = x := |
| 166 | + divMonomial_monomial_mul _ _ |
| 167 | +set_option linter.uppercaseLean3 false in |
| 168 | +#align mv_polynomial.X_mul_div_monomial MvPolynomial.x_mul_divMonomial |
| 169 | + |
| 170 | +@[simp] |
| 171 | +theorem x_divMonomial (i : σ) : (X i : MvPolynomial σ R) /ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = 1 := |
| 172 | + divMonomial_monomial (Finsupp.single i 1) |
| 173 | +set_option linter.uppercaseLean3 false in |
| 174 | +#align mv_polynomial.X_div_monomial MvPolynomial.x_divMonomial |
| 175 | + |
| 176 | +@[simp] |
| 177 | +theorem mul_x_divMonomial (x : MvPolynomial σ R) (i : σ) : |
| 178 | + x * X i /ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = x := |
| 179 | + divMonomial_mul_monomial _ _ |
| 180 | +set_option linter.uppercaseLean3 false in |
| 181 | +#align mv_polynomial.mul_X_div_monomial MvPolynomial.mul_x_divMonomial |
| 182 | + |
| 183 | +@[simp] |
| 184 | +theorem x_mul_modMonomial (i : σ) (x : MvPolynomial σ R) : |
| 185 | + X i * x %ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = 0 := |
| 186 | + monomial_mul_modMonomial _ _ |
| 187 | +set_option linter.uppercaseLean3 false in |
| 188 | +#align mv_polynomial.X_mul_mod_monomial MvPolynomial.x_mul_modMonomial |
| 189 | + |
| 190 | +@[simp] |
| 191 | +theorem mul_x_modMonomial (x : MvPolynomial σ R) (i : σ) : |
| 192 | + x * X i %ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = 0 := |
| 193 | + mul_monomial_modMonomial _ _ |
| 194 | +set_option linter.uppercaseLean3 false in |
| 195 | +#align mv_polynomial.mul_X_mod_monomial MvPolynomial.mul_x_modMonomial |
| 196 | + |
| 197 | +@[simp] |
| 198 | +theorem modMonomial_x (i : σ) : (X i : MvPolynomial σ R) %ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = 0 := |
| 199 | + monomial_modMonomial _ |
| 200 | +set_option linter.uppercaseLean3 false in |
| 201 | +#align mv_polynomial.mod_monomial_X MvPolynomial.modMonomial_x |
| 202 | + |
| 203 | +theorem divMonomial_add_modMonomial_single (x : MvPolynomial σ R) (i : σ) : |
| 204 | + X i * (x /ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1) + x %ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = x := |
| 205 | + divMonomial_add_modMonomial _ _ |
| 206 | +#align mv_polynomial.div_monomial_add_mod_monomial_single MvPolynomial.divMonomial_add_modMonomial_single |
| 207 | + |
| 208 | +theorem modMonomial_add_divMonomial_single (x : MvPolynomial σ R) (i : σ) : |
| 209 | + x %ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 + X i * (x /ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1) = x := |
| 210 | + modMonomial_add_divMonomial _ _ |
| 211 | +#align mv_polynomial.mod_monomial_add_div_monomial_single MvPolynomial.modMonomial_add_divMonomial_single |
| 212 | + |
| 213 | +theorem x_dvd_iff_modMonomial_eq_zero {i : σ} {x : MvPolynomial σ R} : |
| 214 | + X i ∣ x ↔ x %ᵐᵒⁿᵒᵐⁱᵃˡ Finsupp.single i 1 = 0 := |
| 215 | + monomial_one_dvd_iff_modMonomial_eq_zero |
| 216 | +set_option linter.uppercaseLean3 false in |
| 217 | +#align mv_polynomial.X_dvd_iff_mod_monomial_eq_zero MvPolynomial.x_dvd_iff_modMonomial_eq_zero |
| 218 | + |
| 219 | +end XLemmas |
| 220 | + |
| 221 | +/-! ### Some results about dvd (`∣`) on `monomial` and `X` -/ |
| 222 | + |
| 223 | + |
| 224 | +theorem monomial_dvd_monomial {r s : R} {i j : σ →₀ ℕ} : |
| 225 | + monomial i r ∣ monomial j s ↔ (s = 0 ∨ i ≤ j) ∧ r ∣ s := by |
| 226 | + constructor |
| 227 | + · rintro ⟨x, hx⟩ |
| 228 | + rw [MvPolynomial.ext_iff] at hx |
| 229 | + have hj := hx j |
| 230 | + have hi := hx i |
| 231 | + classical |
| 232 | + simp_rw [coeff_monomial, if_pos] at hj hi |
| 233 | + simp_rw [coeff_monomial_mul', if_pos] at hi hj |
| 234 | + split_ifs at hi hj with hi hi |
| 235 | + · exact ⟨Or.inr hi, _, hj⟩ |
| 236 | + · exact ⟨Or.inl hj, hj.symm ▸ dvd_zero _⟩ |
| 237 | + -- Porting note: two goals remain at this point in Lean 4 |
| 238 | + · simp_all only [or_true, dvd_mul_right] |
| 239 | + · simp_all only [ite_self, le_refl, ite_true, dvd_mul_right] |
| 240 | + · rintro ⟨h | hij, d, rfl⟩ |
| 241 | + · simp_rw [h, monomial_zero, dvd_zero] |
| 242 | + · refine' ⟨monomial (j - i) d, _⟩ |
| 243 | + rw [monomial_mul, add_tsub_cancel_of_le hij] |
| 244 | +#align mv_polynomial.monomial_dvd_monomial MvPolynomial.monomial_dvd_monomial |
| 245 | + |
| 246 | +@[simp] |
| 247 | +theorem monomial_one_dvd_monomial_one [Nontrivial R] {i j : σ →₀ ℕ} : |
| 248 | + monomial i (1 : R) ∣ monomial j 1 ↔ i ≤ j := by |
| 249 | + rw [monomial_dvd_monomial] |
| 250 | + simp_rw [one_ne_zero, false_or_iff, dvd_rfl, and_true_iff] |
| 251 | +#align mv_polynomial.monomial_one_dvd_monomial_one MvPolynomial.monomial_one_dvd_monomial_one |
| 252 | + |
| 253 | +@[simp] |
| 254 | +theorem x_dvd_x [Nontrivial R] {i j : σ} : |
| 255 | + (X i : MvPolynomial σ R) ∣ (X j : MvPolynomial σ R) ↔ i = j := by |
| 256 | + refine' monomial_one_dvd_monomial_one.trans _ |
| 257 | + simp_rw [Finsupp.single_le_iff, Nat.one_le_iff_ne_zero, Finsupp.single_apply_ne_zero, Ne.def, |
| 258 | + one_ne_zero, not_false_iff, and_true_iff] |
| 259 | +set_option linter.uppercaseLean3 false in |
| 260 | +#align mv_polynomial.X_dvd_X MvPolynomial.x_dvd_x |
| 261 | + |
| 262 | +@[simp] |
| 263 | +theorem x_dvd_monomial {i : σ} {j : σ →₀ ℕ} {r : R} : |
| 264 | + (X i : MvPolynomial σ R) ∣ monomial j r ↔ r = 0 ∨ j i ≠ 0 := by |
| 265 | + refine' monomial_dvd_monomial.trans _ |
| 266 | + simp_rw [one_dvd, and_true_iff, Finsupp.single_le_iff, Nat.one_le_iff_ne_zero] |
| 267 | +set_option linter.uppercaseLean3 false in |
| 268 | +#align mv_polynomial.X_dvd_monomial MvPolynomial.x_dvd_monomial |
| 269 | + |
| 270 | +end MvPolynomial |
0 commit comments