Skip to content

Commit 600d7a7

Browse files
committed
feat(RingTheory): localization commutes with integral closure (leanprover-community#32596)
1 parent c38ebf0 commit 600d7a7

2 files changed

Lines changed: 126 additions & 1 deletion

File tree

Mathlib/Algebra/Polynomial/Reverse.lean

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ theorem coeff_reflect (N : ℕ) (f : R[X]) (i : ℕ) : coeff (reflect N f) i = f
102102
rw [revAt_invol]
103103
_ = f (revAt N i) := Finsupp.embDomain_apply_self _ _ _
104104

105+
@[simp] lemma reflect_reflect {N : ℕ} {p : R[X]} : (p.reflect N).reflect N = p := by ext; simp
106+
105107
@[simp]
106108
theorem reflect_zero {N : ℕ} : reflect N (0 : R[X]) = 0 :=
107109
rfl
@@ -124,7 +126,6 @@ theorem reflect_C_mul_X_pow (N n : ℕ) {c : R} : reflect N (C c * X ^ n) = C c
124126
ext
125127
grind
126128

127-
128129
@[simp]
129130
theorem reflect_C (r : R) (N : ℕ) : reflect N (C r) = C r * X ^ N := by
130131
conv_lhs => rw [← mul_one (C r), ← pow_zero X, reflect_C_mul_X_pow, revAt_zero]
@@ -179,6 +180,11 @@ theorem reflect_mul (f g : R[X]) {F G : ℕ} (Ff : f.natDegree ≤ F) (Gg : g.na
179180
reflect (F + G) (f * g) = reflect F f * reflect G g :=
180181
reflect_mul_induction _ _ F G f g f.support.card.le_succ g.support.card.le_succ Ff Gg
181182

183+
lemma natDegree_reflect_le {N : ℕ} {p : R[X]} :
184+
(p.reflect N).natDegree ≤ max N p.natDegree := by
185+
simp +contextual [-le_sup_iff, natDegree_le_iff_coeff_eq_zero,
186+
revAt, not_le_of_gt, coeff_eq_zero_of_natDegree_lt]
187+
182188
section Eval₂
183189

184190
variable {S : Type*} [CommSemiring S]

Mathlib/RingTheory/Localization/Integral.lean

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,72 @@ theorem IsIntegral.exists_multiple_integral_of_isLocalization [Algebra Rₘ S] [
273273
exact one_mem _
274274
· rwa [Polynomial.monic_scaleRoots_iff]
275275

276+
/-- If `t` is `R`-integral in `S[M⁻¹]` where `M` is a submonoid of `R`,
277+
then `m • t` is integral in `S` for some `m ∈ M`. -/
278+
lemma IsLocalization.exists_isIntegral_smul_of_isIntegral_map
279+
{R S Sₘ : Type*} [CommRing R] [CommRing S] [CommRing Sₘ] [Algebra R S] [Algebra S Sₘ]
280+
[Algebra R Sₘ] [IsScalarTower R S Sₘ] (M : Submonoid R)
281+
[IsLocalization (Algebra.algebraMapSubmonoid S M) Sₘ] {x : S}
282+
(hx : IsIntegral R (algebraMap S Sₘ x)) : ∃ m ∈ M, IsIntegral R (m • x) := by
283+
obtain ⟨p, hpm, hp⟩ := hx
284+
simp only [IsScalarTower.algebraMap_eq R S Sₘ, ← hom_eval₂,
285+
IsLocalization.map_eq_zero_iff (Algebra.algebraMapSubmonoid S M), Algebra.algebraMapSubmonoid,
286+
Subtype.exists, Submonoid.mem_map, exists_prop, exists_exists_and_eq_and] at hp
287+
obtain ⟨m, hm, e⟩ := hp
288+
exact ⟨m, hm, by simpa [Algebra.smul_def, leadingCoeff_mul_monic hpm] using
289+
RingHom.isIntegralElem_leadingCoeff_mul (algebraMap R S) (C m * p) x (by simpa)⟩
290+
291+
/-- If `t` is integral over `R[1/t]`, then it is integral over `R`. -/
292+
lemma isIntegral_of_isIntegral_adjoin_of_mul_eq_one
293+
(t s : S) (hst : s * t = 1) (ht : IsIntegral (Algebra.adjoin R {s}) t) :
294+
IsIntegral R t := by
295+
nontriviality S
296+
let φ := aeval (R := R) s
297+
obtain ⟨q, hqm, hqt⟩ : φ.IsIntegralElem t := by
298+
obtain ⟨p, hpm, hpt⟩ := ht
299+
have : p.map (algebraMap _ S) ∈ lifts φ.toRingHom := (lifts_iff_coeff_lifts _).mpr
300+
(by simp [← AlgHom.mem_range, φ, ← Algebra.adjoin_singleton_eq_range_aeval])
301+
obtain ⟨q, hqp, hqd, hqm⟩ := lifts_and_degree_eq_and_monic this (hpm.map _)
302+
exact ⟨q, hqm, by rw [← eval_map, hqp, eval_map, hpt]⟩
303+
let N := q.support.sup (q.coeff · |>.natDegree)
304+
have hN (i : _) : (q.coeff i).natDegree ≤ N := by
305+
by_cases hi : i ∈ q.support
306+
· exact Finset.le_sup (f := (q.coeff · |>.natDegree)) hi
307+
· simp_all
308+
let q' := q.sum fun i r ↦ X ^ i * r.reflect N
309+
have (i : _) : aeval t (reflect N (q.coeff i)) = t ^ N * (aeval s (q.coeff i)) := by
310+
letI : Invertible t := ⟨s, hst, (mul_comm _ _).trans hst⟩
311+
rw [aeval_def, ← eval₂_reflect_mul_pow _ _ N _ ((natDegree_reflect_le ..).trans (by simp [hN]))]
312+
simp [mul_comm, this, aeval_def]
313+
refine ⟨q', ?_, ?_⟩
314+
· refine monic_of_natDegree_le_of_coeff_eq_one (q.natDegree + N) ?_ ?_
315+
· refine natDegree_sum_le_of_forall_le _ _ fun i hi ↦ ?_
316+
grw [natDegree_mul_le, natDegree_pow_le, natDegree_X_le, natDegree_reflect_le]
317+
simp [max_eq_left (hN _), le_natDegree_of_mem_supp _ hi]
318+
· simp only [sum, finset_sum_coeff, coeff_X_pow_mul', coeff_reflect, q']
319+
rw [Finset.sum_eq_single q.natDegree]
320+
· simp [hqm.leadingCoeff]
321+
· intro i hi₁ hi₂
322+
have : N + i < q.natDegree + N :=
323+
add_comm N i ▸ add_lt_add_left ((le_natDegree_of_mem_supp _ hi₁).lt_of_ne hi₂) _
324+
simpa [(le_natDegree_of_mem_supp _ hi₁).trans, revAt, this.not_ge] using
325+
coeff_eq_zero_of_natDegree_lt (by grind)
326+
· simp +contextual
327+
· trans t ^ N * q.sum (t ^ · * φ.toRingHom ·)
328+
· simp [φ, q', Polynomial.sum, ← aeval_def, this, mul_left_comm _ (t ^ N), ← Finset.mul_sum]
329+
· simp_rw [mul_comm (t ^ _), ← eval₂_eq_sum, hqt, zero_mul]
330+
331+
/-- If `t` is integral in `S[1/t]`, then it is integral in `S`. -/
332+
lemma IsLocalization.Away.isIntegral_of_isIntegral_map
333+
{R S Sₘ : Type*} [CommRing R] [CommRing S] [CommRing Sₘ] [Algebra R S] [Algebra S Sₘ]
334+
[Algebra R Sₘ] [IsScalarTower R S Sₘ] (x : S) [IsLocalization.Away x Sₘ]
335+
(hx : IsIntegral R (algebraMap S Sₘ x)) : IsIntegral R x := by
336+
obtain ⟨p, hpm, hp⟩ := hx
337+
simp only [IsScalarTower.algebraMap_eq R S Sₘ, IsLocalization.map_eq_zero_iff (.powers x),
338+
Subtype.exists, Submonoid.mem_powers_iff, ← hom_eval₂, exists_prop, exists_exists_eq_and] at hp
339+
obtain ⟨n, hn⟩ := hp
340+
exact ⟨X ^ n * p, (monic_X_pow n).mul hpm, by simpa⟩
341+
276342
end IsIntegral
277343

278344
variable {A K : Type*} [CommRing A]
@@ -339,6 +405,59 @@ theorem isFractionRing_of_finite_extension [IsDomain A] [Algebra A L] [Algebra K
339405

340406
end integralClosure
341407

408+
section
409+
410+
variable {Rf Sf : Type*} [CommRing Rf] [CommRing Sf] [Algebra R Rf] [Algebra S Sf]
411+
[Algebra Rf Sf] [Algebra R Sf] [IsScalarTower R S Sf] [IsScalarTower R Rf Sf]
412+
413+
/-- Taking integral closure commutes with localizations. -/
414+
-- We take in an arbitrary `Algebra (integralClosure R S) (integralClosure Rf Sf)` instance
415+
-- so that it applies more easily.
416+
protected lemma IsLocalization.integralClosure
417+
(M : Submonoid R) [IsLocalization M Rf] [IsLocalization (Algebra.algebraMapSubmonoid S M) Sf]
418+
[Algebra (integralClosure R S) (integralClosure Rf Sf)]
419+
[IsScalarTower (integralClosure R S) (integralClosure Rf Sf) Sf]
420+
[IsScalarTower R (integralClosure R S) (integralClosure Rf Sf)] :
421+
IsLocalization (Algebra.algebraMapSubmonoid (integralClosure R S) M)
422+
(integralClosure Rf Sf) := by
423+
refine ⟨⟨?_, ?_, ?_⟩⟩
424+
· rintro ⟨_, f, hf, rfl⟩
425+
convert (IsLocalization.map_units (S := Rf) ⟨f, hf⟩).map (algebraMap Rf (integralClosure Rf Sf))
426+
simp [← IsScalarTower.algebraMap_apply]
427+
· rintro ⟨s, hs⟩
428+
obtain ⟨⟨x, _, m₁, hm₁, rfl⟩, e⟩ := IsLocalization.surj (Algebra.algebraMapSubmonoid S M) s
429+
simp only [← IsScalarTower.algebraMap_apply] at e
430+
obtain ⟨⟨m₂, hm₂⟩, hm₂s⟩ := IsIntegral.exists_multiple_integral_of_isLocalization M _ hs
431+
simp only [Submonoid.smul_def, Algebra.smul_def] at hm₂s
432+
obtain ⟨m₃, hm₃, hm₃s⟩ := IsLocalization.exists_isIntegral_smul_of_isIntegral_map (Sₘ := Sf)
433+
M (x := m₂ • x) <| by
434+
simp only [Algebra.smul_def, map_mul, ← IsScalarTower.algebraMap_apply, ← e, ← mul_assoc]
435+
exact hm₂s.mul (.algebraMap (Algebra.IsIntegral.isIntegral _))
436+
refine ⟨⟨⟨_, hm₃s⟩, _, _, mul_mem hm₁ (mul_mem hm₂ hm₃), rfl⟩, ?_⟩
437+
· apply (FaithfulSMul.algebraMap_injective (integralClosure Rf Sf) Sf)
438+
simp [← IsScalarTower.algebraMap_apply, e, ← mul_assoc, Algebra.smul_def]
439+
ring
440+
· rintro ⟨a, ha⟩ ⟨b, hb⟩ e
441+
have := congr(algebraMap _ Sf $e)
442+
have : algebraMap S Sf a = algebraMap S Sf b := by
443+
simpa only [← IsScalarTower.algebraMap_apply] using this
444+
obtain ⟨⟨_, m, hm, rfl⟩, h⟩ :=
445+
(IsLocalization.eq_iff_exists (Algebra.algebraMapSubmonoid S M) _).mp this
446+
refine ⟨⟨_, m, hm, rfl⟩, FaithfulSMul.algebraMap_injective (integralClosure R S) S ?_⟩
447+
simpa only [← IsScalarTower.algebraMap_apply]
448+
449+
-- We take in an arbitrary `Algebra (integralClosure R S) (integralClosure Rf Sf)` instance
450+
-- so that it applies more easily.
451+
protected lemma IsLocalization.Away.integralClosure
452+
(f : R) [IsLocalization.Away f Rf] [IsLocalization.Away (algebraMap R S f) Sf]
453+
[Algebra (integralClosure R S) (integralClosure Rf Sf)]
454+
[IsScalarTower (integralClosure R S) (integralClosure Rf Sf) Sf]
455+
[IsScalarTower R (integralClosure R S) (integralClosure Rf Sf)] :
456+
IsLocalization.Away (algebraMap R (integralClosure R S) f) (integralClosure Rf Sf) := by
457+
convert IsLocalization.integralClosure (S := S) (Rf := Rf) (Sf := Sf) (.powers f)
458+
simp
459+
460+
end
342461
namespace IsFractionRing
343462

344463
variable (R S K)

0 commit comments

Comments
 (0)