@@ -8,6 +8,7 @@ import Mathlib.Algebra.GradedMonoid
8
8
import Mathlib.Algebra.MvPolynomial.CommRing
9
9
import Mathlib.Algebra.MvPolynomial.Equiv
10
10
import Mathlib.Algebra.MvPolynomial.Variables
11
+ import Mathlib.RingTheory.MvPolynomial.WeightedHomogeneous
11
12
import Mathlib.Algebra.Polynomial.RingDivision
12
13
13
14
#align_import ring_theory.mv_polynomial.homogeneous from "leanprover-community/mathlib" @"2f5b500a507264de86d666a5f87ddb976e2d8de4"
@@ -37,19 +38,34 @@ variable {σ : Type*} {τ : Type*} {R : Type*} {S : Type*}
37
38
38
39
/-
39
40
TODO
40
- * create definition for `∑ i in d.support, d i`
41
41
* show that `MvPolynomial σ R ≃ₐ[R] ⨁ i, homogeneousSubmodule σ R i`
42
42
-/
43
+
44
+ /-- The degree of a monomial. -/
45
+ def degree (d : σ →₀ ℕ) := ∑ i in d.support, d i
46
+
47
+ theorem weightedDegree_one (d : σ →₀ ℕ) :
48
+ weightedDegree 1 d = degree d := by
49
+ simp [weightedDegree, degree, Finsupp.total, Finsupp.sum]
50
+
43
51
/-- A multivariate polynomial `φ` is homogeneous of degree `n`
44
52
if all monomials occurring in `φ` have degree `n`. -/
45
53
def IsHomogeneous [CommSemiring R] (φ : MvPolynomial σ R) (n : ℕ) :=
46
- ∀ ⦃d⦄, coeff d φ ≠ 0 → ∑ i in d.support, d i = n
54
+ IsWeightedHomogeneous 1 φ n
47
55
#align mv_polynomial.is_homogeneous MvPolynomial.IsHomogeneous
48
56
57
+ variable [CommSemiring R]
58
+
59
+ theorem weightedTotalDegree_one (φ : MvPolynomial σ R) :
60
+ weightedTotalDegree (1 : σ → ℕ) φ = φ.totalDegree := by
61
+ simp only [totalDegree, weightedTotalDegree, weightedDegree, LinearMap.toAddMonoidHom_coe,
62
+ Finsupp.total, Pi.one_apply, Finsupp.coe_lsum, LinearMap.coe_smulRight, LinearMap.id_coe,
63
+ id.def, Algebra.id.smul_eq_mul, mul_one]
64
+
49
65
variable (σ R)
50
66
51
67
/-- The submodule of homogeneous `MvPolynomial`s of degree `n`. -/
52
- def homogeneousSubmodule [CommSemiring R] (n : ℕ) : Submodule R (MvPolynomial σ R) where
68
+ def homogeneousSubmodule (n : ℕ) : Submodule R (MvPolynomial σ R) where
53
69
carrier := { x | x.IsHomogeneous n }
54
70
smul_mem' r a ha c hc := by
55
71
rw [coeff_smul] at hc
@@ -68,6 +84,10 @@ def homogeneousSubmodule [CommSemiring R] (n : ℕ) : Submodule R (MvPolynomial
68
84
· exact hb h
69
85
#align mv_polynomial.homogeneous_submodule MvPolynomial.homogeneousSubmodule
70
86
87
+ @[simp]
88
+ lemma weightedHomogeneousSubmodule_one (n : ℕ) :
89
+ weightedHomogeneousSubmodule R 1 n = homogeneousSubmodule σ R n := rfl
90
+
71
91
variable {σ R}
72
92
73
93
@[simp]
@@ -79,66 +99,41 @@ variable (σ R)
79
99
80
100
/-- While equal, the former has a convenient definitional reduction. -/
81
101
theorem homogeneousSubmodule_eq_finsupp_supported [CommSemiring R] (n : ℕ) :
82
- homogeneousSubmodule σ R n = Finsupp.supported _ R { d | ∑ i in d.support, d i = n } := by
83
- ext
84
- rw [Finsupp.mem_supported, Set.subset_def]
85
- simp only [Finsupp.mem_support_iff, Finset.mem_coe]
86
- rfl
102
+ homogeneousSubmodule σ R n = Finsupp.supported _ R { d | degree d = n } := by
103
+ simp_rw [← weightedDegree_one]
104
+ exact weightedHomogeneousSubmodule_eq_finsupp_supported R 1 n
87
105
#align mv_polynomial.homogeneous_submodule_eq_finsupp_supported MvPolynomial.homogeneousSubmodule_eq_finsupp_supported
88
106
89
107
variable {σ R}
90
108
91
109
theorem homogeneousSubmodule_mul [CommSemiring R] (m n : ℕ) :
92
- homogeneousSubmodule σ R m * homogeneousSubmodule σ R n ≤ homogeneousSubmodule σ R (m + n) := by
93
- rw [Submodule.mul_le]
94
- intro φ hφ ψ hψ c hc
95
- classical
96
- rw [coeff_mul] at hc
97
- obtain ⟨⟨d, e⟩, hde, H⟩ := Finset.exists_ne_zero_of_sum_ne_zero hc
98
- have aux : coeff d φ ≠ 0 ∧ coeff e ψ ≠ 0 := by
99
- contrapose! H
100
- by_cases h : coeff d φ = 0 <;>
101
- simp_all only [Ne, not_false_iff, zero_mul, mul_zero]
102
- specialize hφ aux.1
103
- specialize hψ aux.2
104
- rw [Finset.mem_antidiagonal] at hde
105
- classical
106
- have hd' : d.support ⊆ d.support ∪ e.support := Finset.subset_union_left _ _
107
- have he' : e.support ⊆ d.support ∪ e.support := Finset.subset_union_right _ _
108
- rw [← hde, ← hφ, ← hψ, Finset.sum_subset Finsupp.support_add, Finset.sum_subset hd',
109
- Finset.sum_subset he', ← Finset.sum_add_distrib]
110
- · congr
111
- all_goals intro _ _; apply Finsupp.not_mem_support_iff.mp
110
+ homogeneousSubmodule σ R m * homogeneousSubmodule σ R n ≤ homogeneousSubmodule σ R (m + n) :=
111
+ weightedHomogeneousSubmodule_mul 1 m n
112
112
#align mv_polynomial.homogeneous_submodule_mul MvPolynomial.homogeneousSubmodule_mul
113
113
114
114
section
115
115
116
116
variable [CommSemiring R]
117
117
118
- theorem isHomogeneous_monomial ( d : σ →₀ ℕ) (r : R) ( n : ℕ) (hn : ∑ i in d.support, d i = n) :
118
+ theorem isHomogeneous_monomial { d : σ →₀ ℕ} (r : R) { n : ℕ} (hn : degree d = n) :
119
119
IsHomogeneous (monomial d r) n := by
120
- intro c hc
121
- classical
122
- rw [coeff_monomial] at hc
123
- split_ifs at hc with h
124
- · subst c
125
- exact hn
126
- · contradiction
120
+ simp_rw [← weightedDegree_one] at hn
121
+ exact isWeightedHomogeneous_monomial 1 d r hn
127
122
#align mv_polynomial.is_homogeneous_monomial MvPolynomial.isHomogeneous_monomial
128
123
129
124
variable (σ)
130
125
131
- theorem isHomogeneous_of_totalDegree_zero {p : MvPolynomial σ R} (hp : p.totalDegree = 0 ) :
132
- IsHomogeneous p 0 := by
133
- erw [totalDegree, Finset.sup_eq_bot_iff] at hp
134
- -- we have to do this in two steps to stop simp changing bot to zero
135
- simp_rw [mem_support_iff] at hp
136
- exact hp
126
+ theorem totalDegree_zero_iff_isHomogeneous {p : MvPolynomial σ R} :
127
+ p.totalDegree = 0 ↔ IsHomogeneous p 0 := by
128
+ rw [← weightedTotalDegree_one,
129
+ ← isWeightedHomogeneous_zero_iff_weightedTotalDegree_eq_zero, IsHomogeneous]
130
+
131
+ alias ⟨isHomogeneous_of_totalDegree_zero, _⟩ := totalDegree_zero_iff_isHomogeneous
137
132
#align mv_polynomial.is_homogeneous_of_total_degree_zero MvPolynomial.isHomogeneous_of_totalDegree_zero
138
133
139
134
theorem isHomogeneous_C (r : R) : IsHomogeneous (C r : MvPolynomial σ R) 0 := by
140
135
apply isHomogeneous_monomial
141
- simp only [Finsupp.zero_apply, Finset.sum_const_zero]
136
+ simp only [degree, Finsupp.zero_apply, Finset.sum_const_zero]
142
137
set_option linter.uppercaseLean3 false in
143
138
#align mv_polynomial.is_homogeneous_C MvPolynomial.isHomogeneous_C
144
139
@@ -156,7 +151,7 @@ variable {σ}
156
151
157
152
theorem isHomogeneous_X (i : σ) : IsHomogeneous (X i : MvPolynomial σ R) 1 := by
158
153
apply isHomogeneous_monomial
159
- rw [Finsupp.support_single_ne_zero _ one_ne_zero, Finset.sum_singleton]
154
+ rw [degree, Finsupp.support_single_ne_zero _ one_ne_zero, Finset.sum_singleton]
160
155
exact Finsupp.single_eq_same
161
156
set_option linter.uppercaseLean3 false in
162
157
#align mv_polynomial.is_homogeneous_X MvPolynomial.isHomogeneous_X
@@ -167,11 +162,10 @@ namespace IsHomogeneous
167
162
168
163
variable [CommSemiring R] [CommSemiring S] {φ ψ : MvPolynomial σ R} {m n : ℕ}
169
164
170
- theorem coeff_eq_zero (hφ : IsHomogeneous φ n) ( d : σ →₀ ℕ) (hd : ∑ i in d.support, d i ≠ n) :
165
+ theorem coeff_eq_zero (hφ : IsHomogeneous φ n) { d : σ →₀ ℕ} (hd : degree d ≠ n) :
171
166
coeff d φ = 0 := by
172
- have aux := mt (@hφ d) hd
173
- classical
174
- rwa [Classical.not_not] at aux
167
+ simp_rw [← weightedDegree_one] at hd
168
+ exact IsWeightedHomogeneous.coeff_eq_zero hφ d hd
175
169
#align mv_polynomial.is_homogeneous.coeff_eq_zero MvPolynomial.IsHomogeneous.coeff_eq_zero
176
170
177
171
theorem inj_right (hm : IsHomogeneous φ m) (hn : IsHomogeneous φ n) (hφ : φ ≠ 0 ) : m = n := by
@@ -239,7 +233,8 @@ lemma eval₂ (hφ : φ.IsHomogeneous m) (f : R →+* MvPolynomial τ S) (g : σ
239
233
apply IsHomogeneous.mul (hf _) _
240
234
convert IsHomogeneous.prod _ _ (fun k ↦ n * i k) _
241
235
· rw [Finsupp.mem_support_iff] at hi
242
- rw [← Finset.mul_sum, hφ hi]
236
+ rw [← Finset.mul_sum, ← hφ hi, weightedDegree_apply]
237
+ simp_rw [smul_eq_mul, Finsupp.sum, Pi.one_apply, mul_one]
243
238
· rintro k -
244
239
apply (hg k).pow
245
240
@@ -271,38 +266,48 @@ lemma totalDegree_le (hφ : IsHomogeneous φ n) : φ.totalDegree ≤ n := by
271
266
apply Finset.sup_le
272
267
intro d hd
273
268
rw [mem_support_iff] at hd
274
- rw [Finsupp.sum, hφ hd]
269
+ rw [Finsupp.sum, ← hφ hd, weightedDegree_apply]
270
+ simp only [Pi.one_apply, smul_eq_mul, mul_one]
271
+ exact Nat.le.refl
275
272
276
273
theorem totalDegree (hφ : IsHomogeneous φ n) (h : φ ≠ 0 ) : totalDegree φ = n := by
277
274
apply le_antisymm hφ.totalDegree_le
278
275
obtain ⟨d, hd⟩ : ∃ d, coeff d φ ≠ 0 := exists_coeff_ne_zero h
279
276
simp only [← hφ hd, MvPolynomial.totalDegree, Finsupp.sum]
280
277
replace hd := Finsupp.mem_support_iff.mpr hd
278
+ simp only [weightedDegree_apply,Pi.one_apply, smul_eq_mul, mul_one, ge_iff_le]
281
279
-- Porting note: Original proof did not define `f`
282
280
exact Finset.le_sup (f := fun s ↦ ∑ x in s.support, s x) hd
283
281
#align mv_polynomial.is_homogeneous.total_degree MvPolynomial.IsHomogeneous.totalDegree
284
282
285
283
theorem rename_isHomogeneous {f : σ → τ} (h : φ.IsHomogeneous n):
286
284
(rename f φ).IsHomogeneous n := by
287
285
rw [← φ.support_sum_monomial_coeff, map_sum]; simp_rw [rename_monomial]
288
- exact IsHomogeneous.sum _ _ _ fun d hd ↦ isHomogeneous_monomial _ _ _
289
- ((Finsupp.sum_mapDomain_index_addMonoidHom fun _ ↦ .id ℕ).trans <| h <| mem_support_iff.mp hd)
286
+ apply IsHomogeneous.sum _ _ _ fun d hd ↦ isHomogeneous_monomial _ _
287
+ intro d hd
288
+ apply (Finsupp.sum_mapDomain_index_addMonoidHom fun _ ↦ .id ℕ).trans
289
+ convert h (mem_support_iff.mp hd)
290
+ simp only [weightedDegree_apply, AddMonoidHom.id_apply, Pi.one_apply, smul_eq_mul, mul_one]
290
291
291
292
theorem rename_isHomogeneous_iff {f : σ → τ} (hf : f.Injective) :
292
293
(rename f φ).IsHomogeneous n ↔ φ.IsHomogeneous n := by
293
294
refine ⟨fun h d hd ↦ ?_, rename_isHomogeneous⟩
294
295
convert ← @h (d.mapDomain f) _
295
- · exact Finsupp.sum_mapDomain_index_inj (h := fun _ ↦ id) hf
296
+ · simp only [weightedDegree_apply, Pi.one_apply, smul_eq_mul, mul_one]
297
+ exact Finsupp.sum_mapDomain_index_inj (h := fun _ ↦ id) hf
296
298
· rwa [coeff_rename_mapDomain f hf]
297
299
298
300
lemma finSuccEquiv_coeff_isHomogeneous {N : ℕ} {φ : MvPolynomial (Fin (N+1 )) R} {n : ℕ}
299
301
(hφ : φ.IsHomogeneous n) (i j : ℕ) (h : i + j = n) :
300
302
((finSuccEquiv _ _ φ).coeff i).IsHomogeneous j := by
301
303
intro d hd
302
304
rw [finSuccEquiv_coeff_coeff] at hd
303
- have aux : 0 ∉ Finset.map (Fin.succEmb N).toEmbedding d.support := by simp [Fin.succ_ne_zero]
304
- simpa [Finset.sum_subset_zero_on_sdiff (g := d.cons i)
305
- (d.cons_support (y := i)) (by simp) (fun _ _ ↦ rfl), Finset.sum_insert aux, ← h] using hφ hd
305
+ have h' : (weightedDegree 1 ) (Finsupp.cons i d) = i + j := by
306
+ simpa [Finset.sum_subset_zero_on_sdiff (g := d.cons i)
307
+ (d.cons_support (y := i)) (by simp) (fun _ _ ↦ rfl), ← h] using hφ hd
308
+ simp only [weightedDegree_apply, Pi.one_apply, smul_eq_mul, mul_one, Finsupp.sum_cons,
309
+ add_right_inj] at h' ⊢
310
+ exact h'
306
311
307
312
-- TODO: develop API for `optionEquivLeft` and get rid of the `[Fintype σ]` assumption
308
313
lemma coeff_isHomogeneous_of_optionEquivLeft_symm
@@ -336,7 +341,7 @@ lemma exists_eval_ne_zero_of_coeff_finSuccEquiv_ne_zero_aux
336
341
intro i hi
337
342
rw [Finset.mem_range] at hi
338
343
apply (hF.finSuccEquiv_coeff_isHomogeneous i (n-i) (by omega)).coeff_eq_zero
339
- simp only [Finsupp.support_zero, Finsupp.coe_zero, Pi.zero_apply, Finset.sum_const_zero]
344
+ simp only [degree, Finsupp.support_zero, Finsupp.coe_zero, Pi.zero_apply, Finset.sum_const_zero]
340
345
omega
341
346
simp_rw [eval_eq_eval_mv_eval', eval_one_map, Polynomial.eval_eq_sum_range' hdeg,
342
347
eval_zero, one_pow, mul_one, map_sum, Finset.sum_range_succ, Finset.sum_eq_zero aux, zero_add]
@@ -350,6 +355,7 @@ lemma exists_eval_ne_zero_of_coeff_finSuccEquiv_ne_zero_aux
350
355
rw [Finsupp.coe_zero, Pi.zero_apply]
351
356
by_cases hi : i ∈ d.support
352
357
· have := hF.finSuccEquiv_coeff_isHomogeneous n 0 (add_zero _) hd
358
+ simp only [weightedDegree_apply, Pi.one_apply, smul_eq_mul, mul_one, Finsupp.sum] at this
353
359
rw [Finset.sum_eq_zero_iff_of_nonneg (fun _ _ ↦ zero_le')] at this
354
360
exact this i hi
355
361
· simpa using hi
@@ -468,7 +474,7 @@ open Finset
468
474
See `sum_homogeneousComponent` for the statement that `φ` is equal to the sum
469
475
of all its homogeneous components. -/
470
476
def homogeneousComponent [CommSemiring R] (n : ℕ) : MvPolynomial σ R →ₗ[R] MvPolynomial σ R :=
471
- (Submodule.subtype _).comp <| Finsupp.restrictDom _ _ { d | ∑ i in d.support, d i = n }
477
+ weightedHomogeneousComponent 1 n
472
478
#align mv_polynomial.homogeneous_component MvPolynomial.homogeneousComponent
473
479
474
480
section HomogeneousComponent
@@ -478,54 +484,45 @@ open Finset
478
484
variable [CommSemiring R] (n : ℕ) (φ ψ : MvPolynomial σ R)
479
485
480
486
theorem coeff_homogeneousComponent (d : σ →₀ ℕ) :
481
- coeff d (homogeneousComponent n φ) = if (∑ i in d.support, d i) = n then coeff d φ else 0 :=
482
- Finsupp.filter_apply (fun d : σ →₀ ℕ => ∑ i in d.support, d i = n) φ d
487
+ coeff d (homogeneousComponent n φ) = if (degree d) = n then coeff d φ else 0 := by
488
+ simp_rw [← weightedDegree_one]
489
+ convert coeff_weightedHomogeneousComponent n φ d
483
490
#align mv_polynomial.coeff_homogeneous_component MvPolynomial.coeff_homogeneousComponent
484
491
485
492
theorem homogeneousComponent_apply :
486
493
homogeneousComponent n φ =
487
- ∑ d in φ.support.filter fun d => ∑ i in d.support, d i = n, monomial d (coeff d φ) :=
488
- Finsupp.filter_eq_sum (fun d : σ →₀ ℕ => ∑ i in d.support, d i = n) φ
494
+ ∑ d in φ.support.filter fun d => degree d = n, monomial d (coeff d φ) := by
495
+ simp_rw [← weightedDegree_one]
496
+ convert weightedHomogeneousComponent_apply n φ
489
497
#align mv_polynomial.homogeneous_component_apply MvPolynomial.homogeneousComponent_apply
490
498
491
- theorem homogeneousComponent_isHomogeneous : (homogeneousComponent n φ).IsHomogeneous n := by
492
- intro d hd
493
- contrapose! hd
494
- rw [coeff_homogeneousComponent, if_neg hd]
499
+ theorem homogeneousComponent_isHomogeneous : (homogeneousComponent n φ).IsHomogeneous n :=
500
+ weightedHomogeneousComponent_isWeightedHomogeneous n φ
495
501
#align mv_polynomial.homogeneous_component_is_homogeneous MvPolynomial.homogeneousComponent_isHomogeneous
496
502
497
503
@[simp]
498
- theorem homogeneousComponent_zero : homogeneousComponent 0 φ = C (coeff 0 φ) := by
499
- ext1 d
500
- rcases em (d = 0 ) with (rfl | hd)
501
- classical
502
- · simp only [coeff_homogeneousComponent, sum_eq_zero_iff, Finsupp.zero_apply, if_true, coeff_C,
503
- eq_self_iff_true, forall_true_iff]
504
- · rw [coeff_homogeneousComponent, if_neg, coeff_C, if_neg (Ne.symm hd)]
505
- simp only [DFunLike.ext_iff, Finsupp.zero_apply] at hd
506
- simp [hd]
504
+ theorem homogeneousComponent_zero : homogeneousComponent 0 φ = C (coeff 0 φ) :=
505
+ weightedHomogeneousComponent_zero φ (fun _ => Nat.succ_ne_zero Nat.zero)
507
506
#align mv_polynomial.homogeneous_component_zero MvPolynomial.homogeneousComponent_zero
508
507
509
508
@[simp]
510
509
theorem homogeneousComponent_C_mul (n : ℕ) (r : R) :
511
- homogeneousComponent n (C r * φ) = C r * homogeneousComponent n φ := by
512
- simp only [C_mul', LinearMap.map_smul]
510
+ homogeneousComponent n (C r * φ) = C r * homogeneousComponent n φ :=
511
+ weightedHomogeneousComponent_C_mul φ n r
513
512
set_option linter.uppercaseLean3 false in
514
513
#align mv_polynomial.homogeneous_component_C_mul MvPolynomial.homogeneousComponent_C_mul
515
514
516
515
theorem homogeneousComponent_eq_zero'
517
- (h : ∀ d : σ →₀ ℕ, d ∈ φ.support → ∑ i in d.support, d i ≠ n) :
516
+ (h : ∀ d : σ →₀ ℕ, d ∈ φ.support → degree d ≠ n) :
518
517
homogeneousComponent n φ = 0 := by
519
- rw [homogeneousComponent_apply, sum_eq_zero]
520
- intro d hd; rw [mem_filter] at hd
521
- exfalso; exact h _ hd.1 hd.2
518
+ simp_rw [← weightedDegree_one] at h
519
+ exact weightedHomogeneousComponent_eq_zero' n φ h
522
520
#align mv_polynomial.homogeneous_component_eq_zero' MvPolynomial.homogeneousComponent_eq_zero'
523
521
524
522
theorem homogeneousComponent_eq_zero (h : φ.totalDegree < n) : homogeneousComponent n φ = 0 := by
525
523
apply homogeneousComponent_eq_zero'
526
524
rw [totalDegree, Finset.sup_lt_iff] at h
527
- · intro d hd
528
- exact ne_of_lt (h d hd)
525
+ · intro d hd; exact ne_of_lt (h d hd)
529
526
· exact lt_of_le_of_lt (Nat.zero_le _) h
530
527
#align mv_polynomial.homogeneous_component_eq_zero MvPolynomial.homogeneousComponent_eq_zero
531
528
@@ -539,17 +536,7 @@ theorem sum_homogeneousComponent :
539
536
540
537
theorem homogeneousComponent_homogeneous_polynomial (m n : ℕ) (p : MvPolynomial σ R)
541
538
(h : p ∈ homogeneousSubmodule σ R n) : homogeneousComponent m p = if m = n then p else 0 := by
542
- simp only [mem_homogeneousSubmodule] at h
543
- ext x
544
- rw [coeff_homogeneousComponent]
545
- by_cases zero_coeff : coeff x p = 0
546
- · split_ifs
547
- all_goals simp only [zero_coeff, coeff_zero]
548
- · rw [h zero_coeff]
549
- simp only [show n = m ↔ m = n from eq_comm]
550
- split_ifs with h1
551
- · rfl
552
- · simp only [coeff_zero]
539
+ convert weightedHomogeneousComponent_weighted_homogeneous_polynomial m n p h
553
540
#align mv_polynomial.homogeneous_component_homogeneous_polynomial MvPolynomial.homogeneousComponent_homogeneous_polynomial
554
541
555
542
end HomogeneousComponent
0 commit comments