Skip to content

Commit 7c5a533

Browse files
committed
feat: port Data.MvPolynomial.Division (#3100)
Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>
1 parent 3266301 commit 7c5a533

File tree

2 files changed

+271
-0
lines changed

2 files changed

+271
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ import Mathlib.Data.MvPolynomial.Cardinal
777777
import Mathlib.Data.MvPolynomial.Comap
778778
import Mathlib.Data.MvPolynomial.CommRing
779779
import Mathlib.Data.MvPolynomial.Counit
780+
import Mathlib.Data.MvPolynomial.Division
780781
import Mathlib.Data.MvPolynomial.Equiv
781782
import Mathlib.Data.MvPolynomial.Invertible
782783
import Mathlib.Data.MvPolynomial.Rename
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
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

Comments
 (0)