Skip to content

Commit 243eee5

Browse files
committed
feat(RingTheory): compute the height of the ideal spanning a (sub)set of variables in a polynomial ring
1 parent a1566c2 commit 243eee5

4 files changed

Lines changed: 83 additions & 0 deletions

File tree

‎Mathlib.lean‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6787,6 +6787,7 @@ public import Mathlib.RingTheory.MvPolynomial.EulerIdentity
67876787
public import Mathlib.RingTheory.MvPolynomial.Expand
67886788
public import Mathlib.RingTheory.MvPolynomial.FreeCommRing
67896789
public import Mathlib.RingTheory.MvPolynomial.Groebner
6790+
public import Mathlib.RingTheory.MvPolynomial.Height
67906791
public import Mathlib.RingTheory.MvPolynomial.Homogeneous
67916792
public import Mathlib.RingTheory.MvPolynomial.Ideal
67926793
public import Mathlib.RingTheory.MvPolynomial.IrreducibleQuadratic

‎Mathlib/RingTheory/Ideal/Height.lean‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,18 @@ lemma RingEquiv.height_comap {S : Type*} [CommRing S] (e : R ≃+* S) (I : Ideal
353353
simp only [EquivLike.coe_coe, RingEquiv.idealComapOrderIso_apply,
354354
← Ideal.height_eq_primeHeight, RingEquiv.height_comap_of_isPrime]
355355

356+
theorem RingHom.height_le_height_comap_of_surjective {S : Type*} [CommRing S] {f : R →+* S}
357+
(hf : Function.Surjective f) (J : Ideal S) :
358+
J.height ≤ (Ideal.comap f J).height := by
359+
iterate 2 rw [height_eq_inf_minimalPrimes]
360+
refine le_iInf₂_iff.mpr fun I hI ↦ ?_
361+
obtain ⟨K, hK₁, hK₂⟩ := exists_minimalPrimes_comap_eq f I hI
362+
have := f.strictMono_comap_of_surjective hf
363+
have := Order.height_le_height_apply_of_strictMono _ this ⟨K, hK₁.1.1⟩
364+
simp only [← PrimeSpectrum.height_eq_orderHeight, PrimeSpectrum.comap_asIdeal] at this
365+
grw [← hK₂, ← this]
366+
exact iInf₂_le K hK₁
367+
356368
@[simp]
357369
lemma RingEquiv.height_map {S : Type*} [CommRing S] (e : R ≃+* S) (I : Ideal R) :
358370
(I.map e).height = I.height := by
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/-
2+
Copyright (c) 2026 Vlad Tsyrklevich. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Vlad Tsyrklevich
5+
-/
6+
module
7+
8+
public import Mathlib.RingTheory.Ideal.KrullsHeightTheorem
9+
public import Mathlib.RingTheory.MvPolynomial.Ideal
10+
11+
/-!
12+
# Height of polynomial ideals
13+
14+
This file computes the height of the ideal generated by an arbitrary set of variables `(Xₛ, ...)`
15+
in the polynomial ring `R[X₁, ..., Xₙ]`.
16+
-/
17+
18+
public section
19+
20+
namespace MvPolynomial
21+
22+
variable {σ R : Type*} [CommRing R]
23+
24+
private theorem le_height_span_X_image_of_isDomain [IsDomain R] (s : Set σ) :
25+
s.encard ≤ (Ideal.span (X (R := R) '' s)).height := by
26+
refine ENat.forall_natCast_le_iff_le.mp fun n hn ↦ ?_
27+
induction n generalizing s with
28+
| zero => simp
29+
| succ n ih =>
30+
by_cases! he : IsEmpty s
31+
· simp_all
32+
obtain ⟨x, hx⟩ := he
33+
have := ih (s \ {x}) (by grw [← Set.encard_tsub_one_le_encard_sdiff_singleton, ← hn]; norm_cast)
34+
push_cast
35+
grw [this]
36+
have := span_X_image_isPrime (R := R) (σ := σ)
37+
refine Ideal.height_add_one_le_of_lt_of_isPrime <| lt_iff_le_and_ne'.mpr ⟨?_, ?_⟩
38+
· exact Ideal.span_mono (by grind)
39+
· exact ne_of_mem_of_not_mem' (a := X x) (by simp [hx]) (by simp)
40+
41+
theorem le_height_span_X_image (s : Set σ) :
42+
s.encard ≤ (Ideal.span (X (R := R) '' s)).height := by
43+
rw [Ideal.height_eq_inf_minimalPrimes]
44+
refine le_iInf₂ fun I hI ↦ ?_
45+
let π := MvPolynomial.map (σ := σ) (Ideal.Quotient.mk (Ideal.comap C I))
46+
have h₁ : (Ideal.map π I).height ≤ I.height := by
47+
have : Function.Surjective π := MvPolynomial.map_surjective _ Ideal.Quotient.mk_surjective
48+
grw [RingHom.height_le_height_comap_of_surjective this, Ideal.comap_map_of_surjective _ this]
49+
simp [π, ← RingHom.ker_eq_comap_bot, ker_map, Ideal.map_comap_le]
50+
have h₂ : Ideal.span (X '' s) ≤ Ideal.map π I := by
51+
grw [← Ideal.map_mono hI.1.2, Ideal.map_span, Ideal.span_mono]
52+
rintro x ⟨y, hy₁, hy₂⟩
53+
simpa using ⟨y, hy₁, hy₂ ▸ map_X _ y⟩
54+
have := hI.1.1
55+
grw [← h₁, ← Ideal.height_mono h₂, ← le_height_span_X_image_of_isDomain]
56+
57+
theorem height_span_X_image_eq [Nontrivial R] [IsNoetherianRing R] [Finite σ] (s : Set σ) :
58+
(Ideal.span (X (R := R) '' s)).height = s.encard := by
59+
refine le_antisymm ?_ (le_height_span_X_image ..)
60+
grw [Ideal.height_span_le_encard_of_span_ne_top, Set.encard_image_le]
61+
exact (Ideal.ne_top_iff_one _).mpr (by simp [mem_ideal_span_X_image])
62+
63+
end MvPolynomial

‎Mathlib/RingTheory/MvPolynomial/Ideal.lean‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ theorem mem_ideal_span_X_image {x : MvPolynomial σ R} {s : Set σ} :
5959
refine this.trans ?_
6060
simp [Nat.one_le_iff_ne_zero]
6161

62+
@[simp]
63+
theorem X_mem_ideal_span_X_image_iff [Nontrivial R] {x : σ} {s : Set σ} :
64+
X x ∈ Ideal.span (X '' s : Set (MvPolynomial σ R)) ↔ x ∈ s := by
65+
refine ⟨fun h ↦ ?_, fun _ ↦ Submodule.mem_span_of_mem (by grind)⟩
66+
have := mem_ideal_span_X_image.mp h (Finsupp.single x 1)
67+
grind [coeff_X_same, one_ne_zero, Finsupp.single_apply_eq_zero]
68+
6269
section idealOfVars
6370

6471
open Finset Finsupp

0 commit comments

Comments
 (0)