Skip to content

Commit 7cecd1f

Browse files
committed
feat(RingTheory/MvPolynomial): powers of ideal of variables (leanprover-community#33539)
1. Added a new file `Algebra/Group/TypeTags/Pointwise.lean` to provide more helper results about pointwise operations on sets 2. Provided more APIs for `MvPolynomial.restrictSupport` and defined `restrictSupportIdeal` to be the ideal determined by `restrictSupport R s` when `s` is an upper set 3. Defined `MvPolynomial.idealOfVars` to be the ideal spanned by all variables in `MvPolynomial` and provided results about its powers 4. Provided some relavent helper results while golfing
1 parent 20310f5 commit 7cecd1f

7 files changed

Lines changed: 260 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ public import Mathlib.Algebra.Group.Translate
467467
public import Mathlib.Algebra.Group.TypeTags.Basic
468468
public import Mathlib.Algebra.Group.TypeTags.Finite
469469
public import Mathlib.Algebra.Group.TypeTags.Hom
470+
public import Mathlib.Algebra.Group.TypeTags.Pointwise
470471
public import Mathlib.Algebra.Group.ULift
471472
public import Mathlib.Algebra.Group.UniqueProds.Basic
472473
public import Mathlib.Algebra.Group.UniqueProds.VectorSpace

Mathlib/Algebra/Group/Pointwise/Set/Basic.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,13 @@ lemma image_pow [MonoidHomClass F α β] (f : F) (s : Set α) : ∀ n, f '' (s ^
985985
| 0 => by simp [singleton_one]
986986
| n + 1 => image_pow_of_ne_zero n.succ_ne_zero ..
987987

988+
@[to_additive]
989+
lemma preimage_pow_subset [MonoidHomClass F α β] (f : F) (s : Set β) :
990+
∀ n, (f ⁻¹' s) ^ n ⊆ f ⁻¹' (s ^ n)
991+
| 0 => by simp [Set.subset_def]
992+
| n + 1 => by simpa [pow_succ] using Subset.trans (mul_subset_mul_right
993+
(preimage_pow_subset f s n)) (preimage_mul_preimage_subset f)
994+
988995
end Monoid
989996

990997
section Group
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/-
2+
Copyright (c) 2026 Andrew Yang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Andrew Yang
5+
-/
6+
module
7+
8+
public import Mathlib.Algebra.Group.Pointwise.Set.Basic
9+
public import Mathlib.Algebra.Group.TypeTags.Basic
10+
11+
/-!
12+
# Lemmas about pointwise operations in the presence of `Multiplicative` and `Additive`.
13+
-/
14+
15+
public section
16+
17+
open Pointwise
18+
19+
variable {M : Type*}
20+
21+
namespace Multiplicative
22+
23+
variable [AddMonoid M]
24+
25+
@[simp]
26+
lemma ofAdd_image_setAdd (s t : Set M) :
27+
ofAdd '' (s + t) = ofAdd '' s * ofAdd '' t := by
28+
rw [← Set.image2_add, Set.image_image2_distrib ofAdd_add, Set.image2_mul]
29+
30+
@[simp]
31+
lemma ofAdd_image_nsmul (n : ℕ) (s : Set M) :
32+
ofAdd '' (n • s) = (ofAdd '' s) ^ n := by
33+
induction n with
34+
| zero => simp; rfl
35+
| succ n IH => simp [succ_nsmul, pow_succ, IH]
36+
37+
@[simp]
38+
lemma toAdd_image_setMul (s t : Set (Multiplicative M)) :
39+
toAdd '' (s * t) = (toAdd '' s) + (toAdd '' t) := by
40+
rw [← Set.image2_mul, Set.image_image2_distrib toAdd_mul, Set.image2_add]
41+
42+
@[simp]
43+
lemma toAdd_image_nsmul (n : ℕ) (s : Set (Multiplicative M)) :
44+
toAdd '' (s ^ n) = n • (toAdd '' s) := by
45+
induction n with
46+
| zero => simp; rfl
47+
| succ n IH => simp [succ_nsmul, pow_succ, IH]
48+
49+
end Multiplicative

Mathlib/Algebra/Order/Group/Pointwise/Interval.lean

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,4 +879,29 @@ theorem inv_Iio₀ {a : α} (ha : a < 0) : (Iio a)⁻¹ = Ioo a⁻¹ 0 := by
879879

880880
end LinearOrderedField
881881

882+
section CanonicallyOrdered
883+
884+
variable {α : Type*} [Monoid α]
885+
variable [Preorder α] [CanonicallyOrderedMul α] [MulRightMono α]
886+
887+
@[to_additive]
888+
theorem Ici_mul_Ici_eq {a b : α} :
889+
Ici a * Ici b = Ici (a * b) := by
890+
refine Subset.antisymm (Ici_mul_Ici_subset' ..) (subset_def ▸ fun c c_in ↦
891+
mem_mul.mpr ⟨a, ⟨by simp, ?_⟩⟩)
892+
obtain ⟨d, hd⟩ := exists_mul_of_le <| mem_Ici.mp c_in
893+
exact ⟨b * d, by simp [← mul_assoc, hd]⟩
894+
895+
@[to_additive]
896+
theorem Ici_pow_eq {a : α} :
897+
∀ n ≠ 0, Ici a ^ n = Ici (a ^ n)
898+
| 1, _ => by simp
899+
| n + 2, _ => by simp [pow_succ _ n.succ, Ici_pow_eq, Ici_mul_Ici_eq]
900+
901+
omit [MulRightMono α] in
902+
@[to_additive]
903+
lemma Ici_one_eq_univ : Set.Ici (1 : α) = Set.univ := by aesop
904+
905+
end CanonicallyOrdered
906+
882907
end Set

Mathlib/Data/Finsupp/Weight.lean

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public import Mathlib.Data.Finsupp.Antidiagonal
99
public import Mathlib.Data.Finsupp.Order
1010
public import Mathlib.LinearAlgebra.Finsupp.LinearCombination
1111

12+
import Mathlib.Algebra.Group.TypeTags.Pointwise
13+
1214
/-! # weights of Finsupp functions
1315
1416
The theory of multivariate polynomials and power series is built
@@ -261,4 +263,61 @@ lemma range_single_one :
261263
obtain ⟨a, rfl⟩ := (Finsupp.sum_eq_one_iff _).mp hp
262264
use a
263265

266+
lemma degree_mono {R : Type*} [AddCommMonoid R] [PartialOrder R] [CanonicallyOrderedAdd R] :
267+
Monotone (Finsupp.degree (σ := σ) (R := R)) :=
268+
fun _ _ e ↦
269+
(Finset.sum_le_sum_of_subset (support_mono e)).trans (Finset.sum_le_sum fun _ _ ↦ e _)
270+
271+
lemma exists_le_degree_eq {σ : Type*} (f : σ →₀ ℕ) (n : ℕ) (hn : n ≤ f.degree) :
272+
∃ g ≤ f, g.degree = n := by
273+
induction n with
274+
| zero => simp [degree_eq_zero_iff]
275+
| succ n IH =>
276+
obtain ⟨g, hgf, rfl⟩ := IH (by lia)
277+
obtain ⟨f, rfl⟩ := le_iff_exists_add.mp hgf
278+
obtain ⟨i, hi⟩ : f.support.Nonempty := by aesop
279+
exact ⟨g + .single i 1, add_le_add_right (by simp; grind) _, by simp⟩
280+
281+
open scoped Pointwise in
282+
lemma degree_preimage_add {σ : Type*} (s t : Set ℕ) :
283+
degree (σ := σ) ⁻¹' (s + t) = degree (σ := σ) ⁻¹' s + degree (σ := σ) ⁻¹' t := by
284+
refine (Set.preimage_add_preimage_subset ..).antisymm' ?_
285+
rintro f ⟨m, hm, n, hn, e : m + n = _⟩
286+
obtain ⟨g, hgf, rfl⟩ := exists_le_degree_eq f m (by grind)
287+
obtain ⟨f, rfl⟩ := le_iff_exists_add.mp hgf
288+
exact Set.add_mem_add hm (by simp_all)
289+
290+
open scoped Pointwise in
291+
lemma degree_preimage_nsmul {σ : Type*} (s : Set ℕ) (n : ℕ) (hn : n ≠ 0) :
292+
degree (σ := σ) ⁻¹' (n • s) = n • degree (σ := σ) ⁻¹' s := by
293+
obtain (_ | n) := n; · contradiction
294+
induction n <;> simp_all [succ_nsmul, degree_preimage_add]
295+
296+
open scoped Pointwise in
297+
lemma nsmul_single_one_image {α : Type*} {n : ℕ} {s : Set α} :
298+
n • (single · 1) '' s = {x : α →₀ ℕ | x.degree = n ∧ ↑x.support ⊆ s} := by
299+
classical
300+
induction n with
301+
| zero => aesop (add simp degree_eq_zero_iff)
302+
| succ n ih =>
303+
rw [succ_nsmul, ih]
304+
refine subset_antisymm ?_ fun f ⟨f_deg, f_supp⟩ ↦ ?_
305+
· simp [Set.subset_def, Set.mem_add, @forall_comm (α →₀ ℕ)]; grind
306+
obtain ⟨i, hi⟩ : f.support.Nonempty := by aesop
307+
obtain ⟨x, hx⟩ := le_iff_exists_add'.mp
308+
(show single i 1 ≤ f by simpa [Nat.one_le_iff_ne_zero] using hi)
309+
exact ⟨x, by aesop (add simp Set.subset_def), _, ⟨_, f_supp (by simp_all), rfl⟩, hx.symm⟩
310+
311+
open scoped Pointwise in
312+
theorem image_pow_eq_finsuppProd_image {α β : Type*} [CommMonoid β] {f : α → β} {n} {s : Set α} :
313+
(f '' s) ^ n = (·.prod (f · ^ ·)) '' {x : α →₀ ℕ | x.degree = n ∧ ↑x.support ⊆ s} := by
314+
classical
315+
suffices ∀ (s : Set (α →₀ ℕ)), ((·.prod (f · ^ ·)) '' s) ^ n = (·.prod (f · ^ ·)) '' (n • s) by
316+
simp [← nsmul_single_one_image, ← this, Set.image_image]
317+
intro s
318+
refine (Set.image_pow (⟨⟨(·.prod (f · ^ ·)) ∘ Multiplicative.toAdd, by simp⟩,
319+
by simp [Finsupp.prod_add_index, pow_add]⟩ : Multiplicative (α →₀ ℕ) →* β) _ _).symm.trans ?_
320+
simp [-Function.comp_apply, Set.image_comp, show Multiplicative.toAdd '' s = s from
321+
Set.image_id _]
322+
264323
end Finsupp

Mathlib/RingTheory/MvPolynomial/Basic.lean

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,62 @@ def basisRestrictSupport (s : Set (σ →₀ ℕ)) : Basis s R (restrictSupport
103103
theorem restrictSupport_mono {s t : Set (σ →₀ ℕ)} (h : s ⊆ t) :
104104
restrictSupport R s ≤ restrictSupport R t := Finsupp.supported_mono h
105105

106+
lemma restrictSupport_eq_span (s : Set (σ →₀ ℕ)) :
107+
restrictSupport R s = .span _ ((monomial · 1) '' s) := Finsupp.supported_eq_span_single ..
108+
109+
lemma mem_restrictSupport_iff {s : Set (σ →₀ ℕ)} {r : MvPolynomial σ R} :
110+
r ∈ restrictSupport R s ↔ ↑r.support ⊆ s := .rfl
111+
112+
@[simp]
113+
lemma monomial_mem_restrictSupport {s : Set (σ →₀ ℕ)} {m} {r : R} :
114+
monomial m r ∈ restrictSupport R s ↔ m ∈ s ∨ r = 0 := by
115+
classical
116+
by_cases r = 0 <;> simp [mem_restrictSupport_iff, support_monomial, *]
117+
118+
open Pointwise in
119+
lemma restrictSupport_add (s t : Set (σ →₀ ℕ)) :
120+
restrictSupport R (s + t) = restrictSupport R s * restrictSupport R t := by
121+
apply le_antisymm
122+
· rw [restrictSupport_eq_span, Submodule.span_le, Set.image_subset_iff, Set.add_subset_iff]
123+
intro x hx y hy
124+
simp [show monomial (x + y) (1 : R) = monomial x 1 * monomial y 1 by simp, -monomial_mul,
125+
*, Submodule.mul_mem_mul]
126+
· rw [restrictSupport_eq_span, restrictSupport_eq_span, Submodule.span_mul_span,
127+
Submodule.span_le, Set.mul_subset_iff]
128+
simp +contextual [Set.add_mem_add]
129+
130+
open Pointwise in
131+
@[simp] lemma restrictSupport_zero : restrictSupport R (0 : Set (σ →₀ ℕ)) = 1 := by
132+
classical
133+
apply le_antisymm
134+
· rw [restrictSupport_eq_span, Submodule.span_le, Set.image_subset_iff]
135+
simpa using1, by simp⟩
136+
· rintro _ ⟨x, rfl⟩
137+
simp [mem_restrictSupport_iff, Set.subset_def, coeff_one]
138+
139+
@[simp]
140+
lemma restrictSupport_univ : restrictSupport R (.univ : Set (σ →₀ ℕ)) = ⊤ := by
141+
ext; simp [mem_restrictSupport_iff]
142+
143+
open Pointwise in
144+
lemma restrictSupport_nsmul (n : ℕ) (s : Set (σ →₀ ℕ)) :
145+
restrictSupport R (n • s) = restrictSupport R s ^ n := by
146+
induction n <;> simp [add_smul, restrictSupport_add, *, pow_succ]
147+
148+
/-- The ideal defined by `restrictSupport R s` when `s` is an upper set. -/
149+
def restrictSupportIdeal (s : Set (σ →₀ ℕ)) (hs : IsUpperSet s) :
150+
Ideal (MvPolynomial σ R) where
151+
__ := restrictSupport R s
152+
smul_mem' x y hy m (hm : m ∈ (x * y).support) := by
153+
classical
154+
simp only [mem_support_iff, coeff_mul, ne_eq] at hm
155+
obtain ⟨⟨i, j⟩, hij, e⟩ := Finset.exists_ne_zero_of_sum_ne_zero hm
156+
refine hs (by simp_all [eq_comm]) (hy (show j ∈ y.support by aesop))
157+
158+
@[simp]
159+
lemma restrictScalars_restrictSupportIdeal (s : Set (σ →₀ ℕ)) (hs) :
160+
(restrictSupportIdeal (R := R) s hs).restrictScalars R = restrictSupport R s := by rfl
161+
106162
variable (σ)
107163

108164
/-- The submodule of polynomials of total degree less than or equal to `m`. -/

Mathlib/RingTheory/MvPolynomial/Ideal.lean

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ module
88
public import Mathlib.Algebra.MonoidAlgebra.Ideal
99
public import Mathlib.Algebra.MvPolynomial.Division
1010
public import Mathlib.RingTheory.MvPolynomial.MonomialOrder
11+
public import Mathlib.RingTheory.MvPolynomial.Basic
12+
import Mathlib.Algebra.Order.Group.Pointwise.Interval
13+
import Mathlib.RingTheory.Ideal.Operations
1114

1215
/-!
1316
# Lemmas about ideals of `MvPolynomial`
@@ -18,6 +21,7 @@ Notably this contains results about monomial ideals.
1821
1922
* `MvPolynomial.mem_ideal_span_monomial_image`
2023
* `MvPolynomial.mem_ideal_span_X_image`
24+
* `MvPolynomial.mem_pow_idealOfVars_iff`
2125
-/
2226

2327
public section
@@ -54,6 +58,65 @@ theorem mem_ideal_span_X_image {x : MvPolynomial σ R} {s : Set σ} :
5458
refine this.trans ?_
5559
simp [Nat.one_le_iff_ne_zero]
5660

61+
section idealOfVars
62+
63+
open Finset Finsupp
64+
65+
variable (σ R) in
66+
/-- The ideal spanned by all variables. -/
67+
def idealOfVars : Ideal (MvPolynomial σ R) := .span (.range X)
68+
69+
lemma idealOfVars_eq_restrictSupportIdeal :
70+
idealOfVars σ R = restrictSupportIdeal _ _ ((isUpperSet_Ici 1).preimage degree_mono) := by
71+
apply le_antisymm
72+
· simp [idealOfVars, Ideal.span_le, Set.range_subset_iff, restrictSupportIdeal, X]
73+
· simp only [SetLike.le_def, restrictSupportIdeal, Submodule.mem_mk, Submodule.mem_toAddSubmonoid,
74+
← Submodule.restrictScalars_mem R (idealOfVars σ R)]
75+
rw [← SetLike.le_def, restrictSupport_eq_span, Submodule.span_le, Set.image_subset_iff]
76+
intro x hx
77+
obtain ⟨i, hi⟩ : x.support.Nonempty := by aesop
78+
obtain ⟨c, rfl⟩ := le_iff_exists_add'.mp (show single i 1 ≤ x by simp_all; lia)
79+
simpa [monomial_add_single] using Ideal.mul_mem_left _ _ (Ideal.subset_span (by simp))
80+
81+
open Pointwise in
82+
theorem pow_idealOfVars (n : ℕ) :
83+
idealOfVars σ R ^ n = restrictSupportIdeal _ _ ((isUpperSet_Ici n).preimage degree_mono) := by
84+
rw [idealOfVars_eq_restrictSupportIdeal]
85+
apply Submodule.restrictScalars_injective R
86+
by_cases hn : n = 0
87+
· simp [hn, Set.Ici_zero_eq_univ]
88+
rw [Submodule.restrictScalars_pow hn]
89+
refine (restrictSupport_nsmul ..).symm.trans (congr_arg (restrictSupport R) ?_)
90+
simp [← degree_preimage_nsmul, hn, Set.Ici_nsmul_eq]
91+
92+
/-- The `n`th power of `idealOfVars` is spanned by all monic monomials of total degree `n`. -/
93+
theorem pow_idealOfVars_eq_span (n) : idealOfVars σ R ^ n =
94+
.span ((monomial · 1) '' (degree ⁻¹' {n})) := by
95+
rw [idealOfVars, Ideal.span, Submodule.span_pow, ← Set.image_univ,
96+
image_pow_eq_finsuppProd_image]
97+
simp [monomial_eq, Set.preimage, degree]
98+
99+
theorem mem_pow_idealOfVars_iff (n : ℕ) (p : MvPolynomial σ R) :
100+
p ∈ idealOfVars σ R ^ n ↔ ∀ x ∈ p.support, n ≤ degree x := by
101+
rw [pow_idealOfVars]
102+
simp [restrictSupportIdeal, mem_restrictSupport_iff, Set.subset_def]
103+
104+
theorem mem_pow_idealOfVars_iff' (n : ℕ) (p : MvPolynomial σ R) :
105+
p ∈ idealOfVars σ R ^ n ↔ ∀ x, degree x < n → p.coeff x = 0 := by
106+
grind only [mem_pow_idealOfVars_iff, mem_support_iff]
107+
108+
theorem monomial_mem_pow_idealOfVars_iff (n : ℕ) (x : σ →₀ ℕ) {r : R} (h : r ≠ 0) :
109+
monomial x r ∈ idealOfVars σ R ^ n ↔ n ≤ degree x := by
110+
classical
111+
grind only [mem_pow_idealOfVars_iff, mem_support_iff, coeff_monomial]
112+
113+
theorem C_mem_pow_idealOfVars_iff (n r) : C r ∈ idealOfVars σ R ^ n ↔ r = 0 ∨ n = 0 := by
114+
by_cases h : r = 0
115+
· simp [h]
116+
simpa [h] using monomial_mem_pow_idealOfVars_iff (σ := σ) n 0 h
117+
118+
end idealOfVars
119+
57120
end MvPolynomial
58121

59122
namespace MonomialOrder

0 commit comments

Comments
 (0)