|
| 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 |
0 commit comments