Skip to content

Commit af9ecce

Browse files
committed
feat(Algebra/MvPolynomial): nilpotents and units (#25062)
Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>
1 parent c489fb1 commit af9ecce

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ import Mathlib.Algebra.MvPolynomial.Expand
725725
import Mathlib.Algebra.MvPolynomial.Funext
726726
import Mathlib.Algebra.MvPolynomial.Invertible
727727
import Mathlib.Algebra.MvPolynomial.Monad
728+
import Mathlib.Algebra.MvPolynomial.Nilpotent
728729
import Mathlib.Algebra.MvPolynomial.PDeriv
729730
import Mathlib.Algebra.MvPolynomial.Polynomial
730731
import Mathlib.Algebra.MvPolynomial.Rename
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/-
2+
Copyright (c) 2025 Andrew Yang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Andrew Yang
5+
-/
6+
import Mathlib.RingTheory.MvPolynomial.Homogeneous
7+
import Mathlib.RingTheory.Polynomial.Nilpotent
8+
9+
/-!
10+
# Nilpotents and units in multivariate polynomial rings
11+
12+
We prove that
13+
- `MvPolynomial.isNilpotent_iff`:
14+
A multivariate polynomial is nilpotent iff all its coefficents are.
15+
- `MvPolynomial.isUnit_iff`:
16+
A multivariate polynomial is invertible iff its constant term is invertible
17+
and its other coefficients are nilpotent.
18+
-/
19+
20+
namespace MvPolynomial
21+
22+
variable {σ R : Type*} [CommRing R] {P : MvPolynomial σ R}
23+
24+
-- Subsumed by `isNilpotent_iff` below.
25+
private theorem isNilpotent_iff_of_fintype [Fintype σ] :
26+
IsNilpotent P ↔ ∀ i, IsNilpotent (P.coeff i) := by
27+
classical
28+
refine Fintype.induction_empty_option ?_ ?_ ?_ σ P
29+
· intros α β _ e h₁ P
30+
rw [← IsNilpotent.map_iff (rename_injective _ e.symm.injective), h₁,
31+
(Finsupp.equivCongrLeft e).forall_congr_left]
32+
simp [Finsupp.equivMapDomain_eq_mapDomain, coeff_rename_mapDomain _ e.symm.injective]
33+
· intro P
34+
simp [Unique.forall_iff, ← IsNilpotent.map_iff (isEmptyRingEquiv R PEmpty).injective,
35+
-isEmptyRingEquiv_apply, isEmptyRingEquiv_eq_coeff_zero]
36+
rfl
37+
· intro α _ H P
38+
obtain ⟨P, rfl⟩ := (optionEquivLeft _ _).symm.surjective P
39+
simp [IsNilpotent.map_iff (optionEquivLeft _ _).symm.injective,
40+
Polynomial.isNilpotent_iff, H, Finsupp.optionEquiv.forall_congr_left,
41+
← optionEquivLeft_coeff_coeff, Finsupp.coe_update]
42+
43+
theorem isNilpotent_iff : IsNilpotent P ↔ ∀ i, IsNilpotent (P.coeff i) := by
44+
obtain ⟨n, f, hf, P, rfl⟩ := P.exists_fin_rename
45+
rw [IsNilpotent.map_iff (rename_injective _ hf), MvPolynomial.isNilpotent_iff_of_fintype]
46+
lift f to Fin n ↪ σ using hf
47+
refine ⟨fun H i ↦ ?_, fun H i ↦ by simpa using H (i.embDomain f)⟩
48+
by_cases H : i ∈ Set.range (Finsupp.embDomain f)
49+
· aesop
50+
· rw [coeff_rename_eq_zero] <;> aesop (add simp Finsupp.embDomain_eq_mapDomain)
51+
52+
instance [IsReduced R] : IsReduced (MvPolynomial σ R) := by
53+
simp [isReduced_iff, isNilpotent_iff, MvPolynomial.ext_iff]
54+
55+
theorem isUnit_iff : IsUnit P ↔ IsUnit (P.coeff 0) ∧ ∀ i ≠ 0, IsNilpotent (P.coeff i) := by
56+
classical
57+
refine ⟨fun H ↦ ⟨H.map constantCoeff, ?_⟩, fun ⟨h₁, h₂⟩ ↦ ?_⟩
58+
· intros n hn
59+
obtain ⟨i, hi⟩ : ∃ i, n i ≠ 0 := by simpa [Finsupp.ext_iff] using hn
60+
let e := (optionEquivLeft _ _).symm.trans (renameEquiv R (Equiv.optionSubtypeNe i))
61+
have H := (Polynomial.coeff_isUnit_isNilpotent_of_isUnit (H.map e.symm)).2 (n i) hi
62+
simp only [ne_eq, isNilpotent_iff_eq_zero, isNilpotent_iff] at H
63+
convert ← H (n.equivMapDomain (Equiv.optionSubtypeNe i).symm).some
64+
refine (optionEquivLeft_coeff_coeff _ _ _ _).trans ?_
65+
simp [e, optionEquivLeft_coeff_coeff, Finsupp.equivMapDomain_eq_mapDomain,
66+
coeff_rename_mapDomain _ (Equiv.optionSubtypeNe i).symm.injective]
67+
· have : IsNilpotent (P - C (P.coeff 0)) := by
68+
simp +contextual [isNilpotent_iff, apply_ite, eq_comm, h₂]
69+
simpa using this.isUnit_add_right_of_commute (h₁.map C) (.all _ _)
70+
71+
instance : IsLocalHom (C : _ →+* MvPolynomial σ R) where
72+
map_nonunit := by classical simp +contextual [isUnit_iff, coeff_C, apply_ite]
73+
74+
instance : IsLocalHom (algebraMap R (MvPolynomial σ R)) :=
75+
inferInstanceAs (IsLocalHom C)
76+
77+
theorem isUnit_iff_totalDegree_of_isReduced [IsReduced R] :
78+
IsUnit P ↔ IsUnit (P.coeff 0) ∧ P.totalDegree = 0 := by
79+
convert isUnit_iff (P := P)
80+
rw [totalDegree_eq_zero_iff]
81+
simp [not_imp_comm (a := _ = (0 : R)), Finsupp.ext_iff]
82+
83+
theorem isUnit_iff_eq_C_of_isReduced [IsReduced R] :
84+
IsUnit P ↔ ∃ r, IsUnit r ∧ P = C r := by
85+
rw [isUnit_iff_totalDegree_of_isReduced, totalDegree_eq_zero_iff_eq_C]
86+
refine ⟨fun H ↦ ⟨_, H⟩, ?_⟩
87+
rintro ⟨r, hr, rfl⟩
88+
simpa
89+
90+
end MvPolynomial

Mathlib/Data/Finsupp/Basic.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,26 @@ theorem some_single_some [Zero M] (a : α) (m : M) :
754754
ext b
755755
simp [single_apply]
756756

757+
@[simp]
758+
theorem embDomain_some_some [Zero M] (f : α →₀ M) (x) : f.embDomain .some (.some x) = f x := by
759+
simp [← Function.Embedding.some_apply]
760+
761+
@[simp]
762+
theorem some_update_none [Zero M] (f : Option α →₀ M) (a : M) :
763+
(f.update .none a).some = f.some := by
764+
ext
765+
simp [Finsupp.update]
766+
767+
/-- `Finsupp`s from `Option` are equivalent to
768+
pairs of an element and a `Finsupp` on the original type. -/
769+
@[simps]
770+
noncomputable
771+
def optionEquiv [Zero M] : (Option α →₀ M) ≃ M × (α →₀ M) where
772+
toFun P := (P .none, P.some)
773+
invFun P := (P.2.embDomain .some).update .none P.1
774+
left_inv P := by ext (_|a) <;> simp [Finsupp.update]
775+
right_inv P := by ext <;> simp [Finsupp.update]
776+
757777
@[to_additive]
758778
theorem prod_option_index [AddZeroClass M] [CommMonoid N] (f : Option α →₀ M)
759779
(b : Option α → M → N) (h_zero : ∀ o, b o 0 = 1)
@@ -1491,3 +1511,5 @@ theorem sigmaFinsuppAddEquivPiFinsupp_apply {α : Type*} {ιs : η → Type*} [A
14911511
end Sigma
14921512

14931513
end Finsupp
1514+
1515+
set_option linter.style.longFile 1700

0 commit comments

Comments
 (0)