Skip to content

Commit a762a33

Browse files
committed
chore(RingTheory/Localization): mirror tensor product compatibilities and golf (leanprover-community#38177)
We add a mirrored version of `IsLocalization.tensorProduct_tensorProduct` and some related isomorphisms. We use this to golf the proof of `RingHom.locally_isStableUnderBaseChange`.
1 parent 60da1e5 commit a762a33

5 files changed

Lines changed: 120 additions & 43 deletions

File tree

Mathlib/RingTheory/Localization/BaseChange.lean

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ instance IsLocalization.tensor (M : Submonoid R) [IsLocalization M A] :
238238
rw [Algebra.isLocalization_iff_isPushout _ A]
239239
infer_instance
240240

241-
attribute [local instance] Algebra.TensorProduct.rightAlgebra
241+
attribute [local instance] Algebra.TensorProduct.rightAlgebra in
242242
instance IsLocalization.tensorRight (M : Submonoid R) [IsLocalization M A] :
243243
IsLocalization (Algebra.algebraMapSubmonoid S M) (A ⊗[R] S) := by
244244
rw [Algebra.isLocalization_iff_isPushout _ A]
@@ -254,6 +254,7 @@ lemma IsLocalization.tmul_mk' (M : Submonoid R) [IsLocalization M A] (s : S) (x
254254
IsLocalization.mk'_spec', algebraMap_apply, Algebra.algebraMap_self, RingHom.id_apply,
255255
← Algebra.smul_def, smul_tmul, Algebra.smul_def, mul_one]
256256

257+
attribute [local instance] Algebra.TensorProduct.rightAlgebra in
257258
open Algebra.TensorProduct in
258259
lemma IsLocalization.mk'_tmul (M : Submonoid R) [IsLocalization M A] (s : S) (x : R) (y : M) :
259260
IsLocalization.mk' A x y ⊗ₜ s =
@@ -318,7 +319,7 @@ end Localization
318319
variable (R S) {A} in
319320
/-- `A[M⁻¹] ⊗[R] S` is the localization of `A ⊗[R] S` at `M`. -/
320321
lemma IsLocalization.tensorProduct_tensorProduct (M : Submonoid A)
321-
(B : Type*) [CommRing B] [Algebra R B] [Algebra A B] [IsScalarTower R A B]
322+
(B : Type*) [CommSemiring B] [Algebra R B] [Algebra A B] [IsScalarTower R A B]
322323
[IsLocalization M B]
323324
[Algebra (A ⊗[R] S) (B ⊗[R] S)] [IsScalarTower A (A ⊗[R] S) (B ⊗[R] S)]
324325
(H : (algebraMap (A ⊗[R] S) (B ⊗[R] S)).comp Algebra.TensorProduct.includeRight.toRingHom =
@@ -327,6 +328,88 @@ lemma IsLocalization.tensorProduct_tensorProduct (M : Submonoid A)
327328
(Algebra.isLocalization_iff_isPushout M _).mpr
328329
(Algebra.IsPushout.tensorProduct_tensorProduct R S A B H).symm
329330

331+
attribute [local instance] Algebra.TensorProduct.rightAlgebra in
332+
variable (R S) {A} in
333+
/-- `S ⊗[R] A[M⁻¹]` is the localization of `S ⊗[R] A` at `M`. -/
334+
lemma IsLocalization.tensorProduct_tensorProduct_right (M : Submonoid A)
335+
(B : Type*) [CommSemiring B] [Algebra R B] [Algebra A B] [IsScalarTower R A B]
336+
[IsLocalization M B]
337+
[Algebra (S ⊗[R] A) (S ⊗[R] B)] [IsScalarTower S (S ⊗[R] A) (S ⊗[R] B)]
338+
(H : (algebraMap (S ⊗[R] A) (S ⊗[R] B)).comp Algebra.TensorProduct.includeRight.toRingHom =
339+
Algebra.TensorProduct.includeRight.toRingHom.comp (algebraMap A B)) :
340+
IsLocalization (M.map (Algebra.TensorProduct.includeRight (R := R) (A := S))) (S ⊗[R] B) := by
341+
change IsLocalization (Algebra.algebraMapSubmonoid _ M) (S ⊗[R] B)
342+
let : Algebra A (S ⊗[R] B) := .compHom _ (algebraMap A B)
343+
have : IsScalarTower A (S ⊗[R] A) (S ⊗[R] B) := .of_algebraMap_eq' H.symm
344+
have : IsScalarTower R A (S ⊗[R] B) :=
345+
.of_algebraMap_eq' <| by
346+
rw [Algebra.compHom_algebraMap_eq, RingHom.comp_assoc, ← IsScalarTower.algebraMap_eq,
347+
IsScalarTower.algebraMap_eq R B]
348+
have : IsScalarTower R (S ⊗[R] A) (S ⊗[R] B) := .to₁₃₄ _ A _ _
349+
have : IsScalarTower A B (S ⊗[R] B) := .of_algebraMap_eq' rfl
350+
rw [Algebra.isLocalization_iff_isPushout _ B, Algebra.IsPushout.comm,
351+
← Algebra.IsPushout.comp_iff R _ S]
352+
infer_instance
353+
354+
variable (R S) {A} in
355+
/-- The natural isomorphism `S ⊗[R] A[M⁻¹] ≃ (S ⊗[R] A)[M⁻¹]`. -/
356+
noncomputable
357+
def IsLocalization.tensorProductEquivOfMapIncludeRight (M : Submonoid A)
358+
(B : Type*) [CommSemiring B] [Algebra R B] [Algebra A B] [IsScalarTower R A B]
359+
[IsLocalization M B]
360+
(C : Type*) [CommSemiring C] [Algebra S C] [Algebra (S ⊗[R] A) C] [IsScalarTower S (S ⊗[R] A) C]
361+
[IsLocalization (M.map (Algebra.TensorProduct.includeRight (R := R) (A := S))) C] :
362+
S ⊗[R] B ≃ₐ[S] C :=
363+
letI M' : Submonoid (S ⊗[R] A) := M.map (Algebra.TensorProduct.includeRight (R := R) (A := S))
364+
letI : Algebra (S ⊗[R] A) (S ⊗[R] B) :=
365+
(Algebra.TensorProduct.map (AlgHom.id R S) (IsScalarTower.toAlgHom R _ _)).toAlgebra
366+
haveI : IsScalarTower S (S ⊗[R] A) (S ⊗[R] B) :=
367+
.of_algebraMap_eq <| by intro; simp [RingHom.algebraMap_toAlgebra]
368+
haveI := IsLocalization.tensorProduct_tensorProduct_right R S M B
369+
(by ext; simp [RingHom.algebraMap_toAlgebra])
370+
(IsLocalization.algEquiv M' _ _).restrictScalars S
371+
372+
set_option backward.isDefEq.respectTransparency false in
373+
@[simp]
374+
lemma IsLocalization.tensorProductEquivOfMapIncludeRight_tmul (M : Submonoid A)
375+
(B : Type*) [CommSemiring B] [Algebra R B] [Algebra A B]
376+
[IsScalarTower R A B] [IsLocalization M B]
377+
(C : Type*) [CommSemiring C] [Algebra S C] [Algebra (S ⊗[R] A) C] [IsScalarTower S (S ⊗[R] A) C]
378+
[IsLocalization (M.map (Algebra.TensorProduct.includeRight (R := R) (A := S))) C]
379+
(x : S) (a : A) :
380+
IsLocalization.tensorProductEquivOfMapIncludeRight R S M B C (x ⊗ₜ algebraMap A B a) =
381+
algebraMap _ _ (x ⊗ₜ[R] a) := by
382+
letI : Algebra (S ⊗[R] A) (S ⊗[R] B) :=
383+
(Algebra.TensorProduct.map (AlgHom.id R S) (IsScalarTower.toAlgHom R _ _)).toAlgebra
384+
have heq : x ⊗ₜ[R] (algebraMap A B) a = algebraMap _ _ (x ⊗ₜ[R] a) := rfl
385+
simp [heq, IsLocalization.tensorProductEquivOfMapIncludeRight]
386+
387+
variable (R S) {A} in
388+
/-- The natural isomorphism `S ⊗[R] A[1/g] ≃ (S ⊗[R] A)[1/g]`. -/
389+
noncomputable
390+
def IsLocalization.Away.tensorProductEquivTMulRight (g : A) (B : Type*) [CommSemiring B]
391+
[Algebra R B] [Algebra A B] [IsScalarTower R A B] [IsLocalization.Away g B] :
392+
S ⊗[R] B ≃ₐ[S] Localization.Away ((1 : S) ⊗ₜ[R] g) :=
393+
haveI : IsLocalization
394+
((Submonoid.powers g).map (Algebra.TensorProduct.includeRight (R := R) (A := S)))
395+
(Localization.Away ((1 : S) ⊗ₜ[R] g)) := by
396+
simp only [Submonoid.map_powers, Algebra.TensorProduct.includeRight_apply]
397+
infer_instance
398+
IsLocalization.tensorProductEquivOfMapIncludeRight _ _ (.powers g) _ _
399+
400+
@[simp]
401+
lemma IsLocalization.Away.tensorProductEquivTMulRight_tmul (g : A) (B : Type*) [CommSemiring B]
402+
[Algebra R B] [Algebra A B] [IsScalarTower R A B] [IsLocalization.Away g B]
403+
(x : S) (a : A) :
404+
IsLocalization.Away.tensorProductEquivTMulRight R S g B (x ⊗ₜ algebraMap _ _ a) =
405+
algebraMap _ _ (x ⊗ₜ[R] a) :=
406+
haveI : IsLocalization
407+
((Submonoid.powers g).map (Algebra.TensorProduct.includeRight (R := R) (A := S)))
408+
(Localization.Away ((1 : S) ⊗ₜ[R] g)) := by
409+
simp only [Submonoid.map_powers, Algebra.TensorProduct.includeRight_apply]
410+
infer_instance
411+
IsLocalization.tensorProductEquivOfMapIncludeRight_tmul _ _ _ _ _ _
412+
330413
namespace IsLocalization.Away
331414

332415
instance tensor [IsLocalization.Away r A] :

Mathlib/RingTheory/Localization/Basic.lean

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,9 +533,17 @@ noncomputable def localizationAlgebra : Algebra Rₘ Sₘ :=
533533
noncomputable instance : Algebra (Localization M)
534534
(Localization (Algebra.algebraMapSubmonoid S M)) := localizationAlgebra M S
535535

536+
-- This is not an instance, because the discrimination tree key is `IsScalarTower _ _ _ _ _ _`, so
537+
-- it would cause significant slowdowns.
538+
lemma isScalarTower_localizationAlgebra [Algebra R Sₘ] [IsScalarTower R S Sₘ] :
539+
letI : Algebra Rₘ Sₘ := localizationAlgebra M S
540+
IsScalarTower R Rₘ Sₘ :=
541+
letI : Algebra Rₘ Sₘ := localizationAlgebra M S
542+
.of_algebraMap_eq' <| by
543+
simp [RingHom.algebraMap_toAlgebra, IsScalarTower.algebraMap_eq R S Sₘ]
544+
536545
instance : IsScalarTower R (Localization M) (Localization (Algebra.algebraMapSubmonoid S M)) :=
537-
IsScalarTower.of_algebraMap_eq (fun x ↦
538-
(IsLocalization.map_eq (T := (Algebra.algebraMapSubmonoid S M)) M.le_comap_map x).symm)
546+
isScalarTower_localizationAlgebra _ _
539547

540548
end
541549

Mathlib/RingTheory/Localization/Finiteness.lean

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ instance {R S : Type*} [CommRing R] {P : Ideal R} [CommRing S] [Algebra R S]
155155
open Algebra nonZeroDivisors in
156156
instance {A C : Type*} [CommRing A] [CommRing C] [Algebra A C] [Module.Finite A C] :
157157
Module.Finite (FractionRing A) (Localization (algebraMapSubmonoid C A⁰)) :=
158-
have : IsScalarTower A (FractionRing A) (Localization (algebraMapSubmonoid C A⁰)) :=
159-
instIsScalarTowerLocalizationAlgebraMapSubmonoid A⁰ C
160158
.of_isLocalization A C A⁰
161159

162160
include S f in

Mathlib/RingTheory/RingHom/Locally.lean

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ def Locally {R S : Type u} [CommRing R] [CommRing S] (f : R →+* S) : Prop :=
6565

6666
variable {R S : Type u} [CommRing R] [CommRing S]
6767

68+
lemma locally_iff_span_eq_top {f : R →+* S} :
69+
Locally P f ↔ Ideal.span {g : S | P ((algebraMap S (Localization.Away g)).comp f)} = ⊤ := by
70+
refine ⟨fun ⟨s, hs, h⟩ ↦ ?_, fun h ↦ ⟨_, h, fun g hg ↦ hg⟩⟩
71+
rw [eq_top_iff, ← hs, Ideal.span_le]
72+
intro g hg
73+
exact Ideal.subset_span (h _ hg)
74+
75+
alias ⟨Locally.span_eq_top, _⟩ := locally_iff_span_eq_top
76+
6877
lemma locally_iff_finite (f : R →+* S) :
6978
Locally P f ↔ ∃ (s : Finset S) (_ : Ideal.span (s : Set S) = ⊤),
7079
∀ t ∈ s, P ((algebraMap S (Localization.Away t)).comp f) := by
@@ -280,48 +289,20 @@ lemma locally_stableUnderCompositionWithLocalizationAwaySource
280289
alias locally_StableUnderCompositionWithLocalizationAwaySource :=
281290
locally_stableUnderCompositionWithLocalizationAwaySource
282291

283-
284-
attribute [local instance] Algebra.TensorProduct.rightAlgebra in
285292
/-- If `P` is stable under base change, then so is `Locally P`. -/
286293
lemma locally_isStableUnderBaseChange (hPi : RespectsIso P) (hPb : IsStableUnderBaseChange P) :
287294
IsStableUnderBaseChange (Locally P) := by
288295
apply IsStableUnderBaseChange.mk (locally_respectsIso hPi)
289296
introv hf
290-
obtain ⟨s, hsone, hs⟩ := hf
291-
rw [locally_iff_exists hPi]
292-
letI (a : s) : Algebra (S ⊗[R] T) (S ⊗[R] Localization.Away a.val) :=
293-
(Algebra.TensorProduct.map (AlgHom.id R S) (IsScalarTower.toAlgHom R _ _)).toRingHom.toAlgebra
294-
letI (a : s) : Algebra T (S ⊗[R] Localization.Away a.val) :=
295-
((algebraMap _ (S ⊗[R] Localization.Away a.val)).comp (algebraMap T (S ⊗[R] T))).toAlgebra
296-
haveI (a : s) : IsScalarTower T (S ⊗[R] T) (S ⊗[R] Localization.Away a.val) :=
297-
IsScalarTower.of_algebraMap_eq' rfl
298-
haveI (a : s) : IsScalarTower T (Localization.Away a.val) (S ⊗[R] Localization.Away a.val) :=
299-
IsScalarTower.of_algebraMap_eq' rfl
300-
haveI (a : s) : IsScalarTower S (S ⊗[R] T) (S ⊗[R] Localization.Away a.val) :=
301-
IsScalarTower.of_algebraMap_eq <| by
302-
intro x
303-
simp [RingHom.algebraMap_toAlgebra]
304-
haveI (a : s) : Algebra.IsPushout T (Localization.Away a.val) (S ⊗[R] T)
305-
(S ⊗[R] Localization.Away a.val) := by
306-
rw [← Algebra.IsPushout.comp_iff R _ S]
307-
infer_instance
308-
refine ⟨s, fun a ↦ Algebra.TensorProduct.includeRight a.val, ?_,
309-
fun a ↦ (S ⊗[R] Localization.Away a.val), inferInstance, inferInstance, ?_, ?_⟩
310-
· rw [← Set.image_eq_range, ← Ideal.map_span, hsone, Ideal.map_top]
311-
· intro a
312-
convert_to IsLocalization (Algebra.algebraMapSubmonoid (S ⊗[R] T) (Submonoid.powers a.val))
313-
(S ⊗[R] Localization.Away a.val)
314-
· simp only [Algebra.TensorProduct.includeRight_apply, Algebra.algebraMapSubmonoid,
315-
Submonoid.map_powers]
316-
rfl
317-
· rw [← isLocalizedModule_iff_isLocalization, isLocalizedModule_iff_isBaseChange
318-
(S := Submonoid.powers a.val) (A := Localization.Away a.val)]
319-
exact Algebra.IsPushout.out
320-
· intro a
321-
rw [← IsScalarTower.algebraMap_eq]
322-
apply hPb R (Localization.Away a.val)
323-
rw [IsScalarTower.algebraMap_eq R T]
324-
exact hs a a.property
297+
rw [locally_iff_span_eq_top, eq_top_iff, ← Ideal.map_top Algebra.TensorProduct.includeRight,
298+
← hf.span_eq_top, Ideal.map_le_iff_le_comap, Ideal.span_le]
299+
intro g hg
300+
apply Ideal.subset_span
301+
simp only [Set.mem_setOf_eq, Algebra.TensorProduct.includeRight_apply,
302+
← IsScalarTower.algebraMap_eq] at hg ⊢
303+
let e := IsLocalization.Away.tensorProductEquivTMulRight R S g (Localization.Away g)
304+
rw [← e.toAlgHom.comp_algebraMap]
305+
exact hPi.left _ _ (hPb.tensorProduct _ hg)
325306

326307
/-- If `P` is preserved by localization away, then so is `Locally P`. -/
327308
lemma locally_localizationAwayPreserves (hPl : LocalizationAwayPreserves P) :

Mathlib/RingTheory/RingHomProperties.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ theorem IsStableUnderBaseChange.mk (h₁ : RespectsIso @P)
154154

155155
attribute [local instance] Algebra.TensorProduct.rightAlgebra
156156

157+
lemma IsStableUnderBaseChange.tensorProduct (hP : RingHom.IsStableUnderBaseChange P)
158+
{R S : Type u} (T : Type u) [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T]
159+
(h : P (algebraMap R S)) :
160+
P (algebraMap T (T ⊗[R] S)) :=
161+
-- This only works because the `Algebra.TensorProduct.rightAlgebra` instance is present here.
162+
hP _ _ _ _ h
163+
157164
set_option backward.isDefEq.respectTransparency false in
158165
theorem IsStableUnderBaseChange.pushout_inl (hP : RingHom.IsStableUnderBaseChange @P)
159166
(hP' : RingHom.RespectsIso @P) {R S T : CommRingCat} (f : R ⟶ S) (g : R ⟶ T) (H : P g.hom) :

0 commit comments

Comments
 (0)