Skip to content

Commit bec5207

Browse files
committed
refactor(RingTheory.MvPolynomial.Homogeneous): refactor in terms of weightedHomogeneous (#7609)
We rewrite the definition of homogeneous polynomial as a special case of weighted homogeneous polynomial. Question: should all uses of `∑ i in d.support, d i` be replaced by `degree d`? Co-authored-by: Antoine Chambert-Loir <antoine.chambert-loir@u-paris.fr> Co-authored-by: María Inés de Frutos-Fernández <88536493+mariainesdff@users.noreply.github.com>
1 parent 28bea03 commit bec5207

File tree

2 files changed

+199
-119
lines changed

2 files changed

+199
-119
lines changed

Mathlib/RingTheory/MvPolynomial/Homogeneous.lean

Lines changed: 81 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Mathlib.Algebra.GradedMonoid
88
import Mathlib.Algebra.MvPolynomial.CommRing
99
import Mathlib.Algebra.MvPolynomial.Equiv
1010
import Mathlib.Algebra.MvPolynomial.Variables
11+
import Mathlib.RingTheory.MvPolynomial.WeightedHomogeneous
1112
import Mathlib.Algebra.Polynomial.RingDivision
1213

1314
#align_import ring_theory.mv_polynomial.homogeneous from "leanprover-community/mathlib"@"2f5b500a507264de86d666a5f87ddb976e2d8de4"
@@ -37,19 +38,34 @@ variable {σ : Type*} {τ : Type*} {R : Type*} {S : Type*}
3738

3839
/-
3940
TODO
40-
* create definition for `∑ i in d.support, d i`
4141
* show that `MvPolynomial σ R ≃ₐ[R] ⨁ i, homogeneousSubmodule σ R i`
4242
-/
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+
4351
/-- A multivariate polynomial `φ` is homogeneous of degree `n`
4452
if all monomials occurring in `φ` have degree `n`. -/
4553
def IsHomogeneous [CommSemiring R] (φ : MvPolynomial σ R) (n : ℕ) :=
46-
∀ ⦃d⦄, coeff d φ ≠ 0 → ∑ i in d.support, d i = n
54+
IsWeightedHomogeneous 1 φ n
4755
#align mv_polynomial.is_homogeneous MvPolynomial.IsHomogeneous
4856

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+
4965
variable (σ R)
5066

5167
/-- 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
5369
carrier := { x | x.IsHomogeneous n }
5470
smul_mem' r a ha c hc := by
5571
rw [coeff_smul] at hc
@@ -68,6 +84,10 @@ def homogeneousSubmodule [CommSemiring R] (n : ℕ) : Submodule R (MvPolynomial
6884
· exact hb h
6985
#align mv_polynomial.homogeneous_submodule MvPolynomial.homogeneousSubmodule
7086

87+
@[simp]
88+
lemma weightedHomogeneousSubmodule_one (n : ℕ) :
89+
weightedHomogeneousSubmodule R 1 n = homogeneousSubmodule σ R n := rfl
90+
7191
variable {σ R}
7292

7393
@[simp]
@@ -79,66 +99,41 @@ variable (σ R)
7999

80100
/-- While equal, the former has a convenient definitional reduction. -/
81101
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
87105
#align mv_polynomial.homogeneous_submodule_eq_finsupp_supported MvPolynomial.homogeneousSubmodule_eq_finsupp_supported
88106

89107
variable {σ R}
90108

91109
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
112112
#align mv_polynomial.homogeneous_submodule_mul MvPolynomial.homogeneousSubmodule_mul
113113

114114
section
115115

116116
variable [CommSemiring R]
117117

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) :
119119
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
127122
#align mv_polynomial.is_homogeneous_monomial MvPolynomial.isHomogeneous_monomial
128123

129124
variable (σ)
130125

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 = 0IsHomogeneous 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
137132
#align mv_polynomial.is_homogeneous_of_total_degree_zero MvPolynomial.isHomogeneous_of_totalDegree_zero
138133

139134
theorem isHomogeneous_C (r : R) : IsHomogeneous (C r : MvPolynomial σ R) 0 := by
140135
apply isHomogeneous_monomial
141-
simp only [Finsupp.zero_apply, Finset.sum_const_zero]
136+
simp only [degree, Finsupp.zero_apply, Finset.sum_const_zero]
142137
set_option linter.uppercaseLean3 false in
143138
#align mv_polynomial.is_homogeneous_C MvPolynomial.isHomogeneous_C
144139

@@ -156,7 +151,7 @@ variable {σ}
156151

157152
theorem isHomogeneous_X (i : σ) : IsHomogeneous (X i : MvPolynomial σ R) 1 := by
158153
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]
160155
exact Finsupp.single_eq_same
161156
set_option linter.uppercaseLean3 false in
162157
#align mv_polynomial.is_homogeneous_X MvPolynomial.isHomogeneous_X
@@ -167,11 +162,10 @@ namespace IsHomogeneous
167162

168163
variable [CommSemiring R] [CommSemiring S] {φ ψ : MvPolynomial σ R} {m n : ℕ}
169164

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) :
171166
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
175169
#align mv_polynomial.is_homogeneous.coeff_eq_zero MvPolynomial.IsHomogeneous.coeff_eq_zero
176170

177171
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 : σ
239233
apply IsHomogeneous.mul (hf _) _
240234
convert IsHomogeneous.prod _ _ (fun k ↦ n * i k) _
241235
· 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]
243238
· rintro k -
244239
apply (hg k).pow
245240

@@ -271,38 +266,48 @@ lemma totalDegree_le (hφ : IsHomogeneous φ n) : φ.totalDegree ≤ n := by
271266
apply Finset.sup_le
272267
intro d hd
273268
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
275272

276273
theorem totalDegree (hφ : IsHomogeneous φ n) (h : φ ≠ 0) : totalDegree φ = n := by
277274
apply le_antisymm hφ.totalDegree_le
278275
obtain ⟨d, hd⟩ : ∃ d, coeff d φ ≠ 0 := exists_coeff_ne_zero h
279276
simp only [← hφ hd, MvPolynomial.totalDegree, Finsupp.sum]
280277
replace hd := Finsupp.mem_support_iff.mpr hd
278+
simp only [weightedDegree_apply,Pi.one_apply, smul_eq_mul, mul_one, ge_iff_le]
281279
-- Porting note: Original proof did not define `f`
282280
exact Finset.le_sup (f := fun s ↦ ∑ x in s.support, s x) hd
283281
#align mv_polynomial.is_homogeneous.total_degree MvPolynomial.IsHomogeneous.totalDegree
284282

285283
theorem rename_isHomogeneous {f : σ → τ} (h : φ.IsHomogeneous n):
286284
(rename f φ).IsHomogeneous n := by
287285
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]
290291

291292
theorem rename_isHomogeneous_iff {f : σ → τ} (hf : f.Injective) :
292293
(rename f φ).IsHomogeneous n ↔ φ.IsHomogeneous n := by
293294
refine ⟨fun h d hd ↦ ?_, rename_isHomogeneous⟩
294295
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
296298
· rwa [coeff_rename_mapDomain f hf]
297299

298300
lemma finSuccEquiv_coeff_isHomogeneous {N : ℕ} {φ : MvPolynomial (Fin (N+1)) R} {n : ℕ}
299301
(hφ : φ.IsHomogeneous n) (i j : ℕ) (h : i + j = n) :
300302
((finSuccEquiv _ _ φ).coeff i).IsHomogeneous j := by
301303
intro d hd
302304
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'
306311

307312
-- TODO: develop API for `optionEquivLeft` and get rid of the `[Fintype σ]` assumption
308313
lemma coeff_isHomogeneous_of_optionEquivLeft_symm
@@ -336,7 +341,7 @@ lemma exists_eval_ne_zero_of_coeff_finSuccEquiv_ne_zero_aux
336341
intro i hi
337342
rw [Finset.mem_range] at hi
338343
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]
340345
omega
341346
simp_rw [eval_eq_eval_mv_eval', eval_one_map, Polynomial.eval_eq_sum_range' hdeg,
342347
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
350355
rw [Finsupp.coe_zero, Pi.zero_apply]
351356
by_cases hi : i ∈ d.support
352357
· 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
353359
rw [Finset.sum_eq_zero_iff_of_nonneg (fun _ _ ↦ zero_le')] at this
354360
exact this i hi
355361
· simpa using hi
@@ -468,7 +474,7 @@ open Finset
468474
See `sum_homogeneousComponent` for the statement that `φ` is equal to the sum
469475
of all its homogeneous components. -/
470476
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
472478
#align mv_polynomial.homogeneous_component MvPolynomial.homogeneousComponent
473479

474480
section HomogeneousComponent
@@ -478,54 +484,45 @@ open Finset
478484
variable [CommSemiring R] (n : ℕ) (φ ψ : MvPolynomial σ R)
479485

480486
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
483490
#align mv_polynomial.coeff_homogeneous_component MvPolynomial.coeff_homogeneousComponent
484491

485492
theorem homogeneousComponent_apply :
486493
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 φ
489497
#align mv_polynomial.homogeneous_component_apply MvPolynomial.homogeneousComponent_apply
490498

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 φ
495501
#align mv_polynomial.homogeneous_component_is_homogeneous MvPolynomial.homogeneousComponent_isHomogeneous
496502

497503
@[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)
507506
#align mv_polynomial.homogeneous_component_zero MvPolynomial.homogeneousComponent_zero
508507

509508
@[simp]
510509
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
513512
set_option linter.uppercaseLean3 false in
514513
#align mv_polynomial.homogeneous_component_C_mul MvPolynomial.homogeneousComponent_C_mul
515514

516515
theorem homogeneousComponent_eq_zero'
517-
(h : ∀ d : σ →₀ ℕ, d ∈ φ.support → ∑ i in d.support, d i ≠ n) :
516+
(h : ∀ d : σ →₀ ℕ, d ∈ φ.support → degree d ≠ n) :
518517
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
522520
#align mv_polynomial.homogeneous_component_eq_zero' MvPolynomial.homogeneousComponent_eq_zero'
523521

524522
theorem homogeneousComponent_eq_zero (h : φ.totalDegree < n) : homogeneousComponent n φ = 0 := by
525523
apply homogeneousComponent_eq_zero'
526524
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)
529526
· exact lt_of_le_of_lt (Nat.zero_le _) h
530527
#align mv_polynomial.homogeneous_component_eq_zero MvPolynomial.homogeneousComponent_eq_zero
531528

@@ -539,17 +536,7 @@ theorem sum_homogeneousComponent :
539536

540537
theorem homogeneousComponent_homogeneous_polynomial (m n : ℕ) (p : MvPolynomial σ R)
541538
(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
553540
#align mv_polynomial.homogeneous_component_homogeneous_polynomial MvPolynomial.homogeneousComponent_homogeneous_polynomial
554541

555542
end HomogeneousComponent

0 commit comments

Comments
 (0)