Skip to content

Commit 33614d2

Browse files
committed
feat(AlgebraicGeometry): API for affine opens (#15259)
1 parent c35f067 commit 33614d2

File tree

2 files changed

+102
-25
lines changed

2 files changed

+102
-25
lines changed

Mathlib/AlgebraicGeometry/AffineScheme.lean

Lines changed: 98 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,18 @@ def arrowIsoΓSpecOfIsAffine {A B : CommRingCat} (f : A ⟶ B) :
121121
Arrow.isoMk (Scheme.ΓSpecIso _).symm (Scheme.ΓSpecIso _).symm
122122
(Scheme.ΓSpecIso_inv_naturality f).symm
123123

124+
theorem Scheme.isoSpec_Spec (R : CommRingCat.{u}) :
125+
(Spec R).isoSpec = Scheme.Spec.mapIso (Scheme.ΓSpecIso R).op :=
126+
Iso.ext (SpecMap_ΓSpecIso_hom R).symm
127+
128+
@[simp] theorem Scheme.isoSpec_Spec_hom (R : CommRingCat.{u}) :
129+
(Spec R).isoSpec.hom = Spec.map (Scheme.ΓSpecIso R).hom :=
130+
(SpecMap_ΓSpecIso_hom R).symm
131+
132+
@[simp] theorem Scheme.isoSpec_Spec_inv (R : CommRingCat.{u}) :
133+
(Spec R).isoSpec.inv = Spec.map (Scheme.ΓSpecIso R).inv :=
134+
congr($(isoSpec_Spec R).inv)
135+
124136
namespace AffineScheme
125137

126138
/-- The `Spec` functor into the category of affine schemes. -/
@@ -259,23 +271,60 @@ namespace IsAffineOpen
259271

260272
variable {X Y : Scheme.{u}} {U : X.Opens} (hU : IsAffineOpen U) (f : Γ(X, U))
261273

274+
attribute [-simp] eqToHom_op in
275+
/-- The isomorphism `U ≅ Spec Γ(X, U)` for an affine `U`. -/
276+
@[simps! (config := .lemmasOnly) hom inv]
277+
def isoSpec :
278+
↑U ≅ Spec Γ(X, U) :=
279+
haveI : IsAffine U := hU
280+
U.toScheme.isoSpec ≪≫ Scheme.Spec.mapIso
281+
(X.presheaf.mapIso (eqToIso U.openEmbedding_obj_top).op).op
282+
283+
open LocalRing in
284+
lemma isoSpec_hom_val_base_apply (x : U) :
285+
hU.isoSpec.hom.1.base x = (Spec.map (X.presheaf.germ _ x x.2)).val.base (closedPoint _) := by
286+
dsimp [IsAffineOpen.isoSpec_hom, Scheme.isoSpec_hom, Scheme.toSpecΓ_val_base]
287+
rw [← Scheme.comp_val_base_apply, ← Spec.map_comp,
288+
(Iso.eq_comp_inv _).mpr (Scheme.Opens.germ_stalkIso_hom U (V := ⊤) x trivial),
289+
X.presheaf.germ_res_assoc, Spec.map_comp, Scheme.comp_val_base_apply]
290+
congr 1
291+
have := isLocalRingHom_of_isIso (U.stalkIso x).inv
292+
exact LocalRing.comap_closedPoint (U.stalkIso x).inv
293+
294+
lemma isoSpec_inv_app_top :
295+
hU.isoSpec.inv.app ⊤ = U.topIso.hom ≫ (Scheme.ΓSpecIso Γ(X, U)).inv := by
296+
simp only [Scheme.Opens.toScheme_presheaf_obj, isoSpec_inv, Scheme.isoSpec, asIso_inv,
297+
Scheme.comp_coeBase, Opens.map_comp_obj, Opens.map_top, Scheme.comp_app, Scheme.inv_app_top,
298+
Scheme.Opens.topIso_hom, Scheme.ΓSpecIso_inv_naturality, IsIso.inv_comp_eq]
299+
rw [Scheme.toSpecΓ_app_top]
300+
erw [Iso.hom_inv_id_assoc]
301+
302+
lemma isoSpec_hom_app_top :
303+
hU.isoSpec.hom.app ⊤ = (Scheme.ΓSpecIso Γ(X, U)).hom ≫ U.topIso.inv := by
304+
have := congr(inv $hU.isoSpec_inv_app_top)
305+
rw [IsIso.inv_comp, IsIso.Iso.inv_inv, IsIso.Iso.inv_hom] at this
306+
have := (Scheme.Γ.map_inv hU.isoSpec.inv.op).trans this
307+
rwa [← op_inv, IsIso.Iso.inv_inv] at this
308+
262309
/-- The open immersion `Spec Γ(X, U) ⟶ X` for an affine `U`. -/
263310
def fromSpec :
264311
Spec Γ(X, U) ⟶ X :=
265312
haveI : IsAffine U := hU
266-
Spec.map (X.presheaf.map (eqToHom U.openEmbedding_obj_top.symm).op) ≫
267-
U.toScheme.isoSpec.inv ≫ U.ι
313+
hU.isoSpec.inv ≫ U.ι
268314

269315
instance isOpenImmersion_fromSpec :
270316
IsOpenImmersion hU.fromSpec := by
271317
delta fromSpec
272318
infer_instance
273319

320+
@[reassoc (attr := simp)]
321+
lemma isoSpec_inv_ι : hU.isoSpec.inv ≫ U.ι = hU.fromSpec := rfl
322+
274323
@[simp]
275324
theorem range_fromSpec :
276325
Set.range hU.fromSpec.1.base = (U : Set X) := by
277-
delta IsAffineOpen.fromSpec; dsimp
278-
rw [Function.comp_assoc, Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ]
326+
delta IsAffineOpen.fromSpec; dsimp [IsAffineOpen.isoSpec_inv]
327+
rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ]
279328
· exact Subtype.range_coe
280329
erw [← coe_comp, ← TopCat.epi_iff_surjective] -- now `erw` after #13170
281330
infer_instance
@@ -289,9 +338,37 @@ theorem map_fromSpec {V : X.Opens} (hV : IsAffineOpen V) (f : op U ⟶ op V) :
289338
have : IsAffine (X.restrictFunctor.obj U).left := hU
290339
haveI : IsAffine _ := hV
291340
conv_rhs =>
292-
rw [fromSpec, ← X.restrictFunctor_map_ofRestrict f.unop, ← Scheme.isoSpec_inv_naturality_assoc,
341+
rw [fromSpec, ← X.restrictFunctor_map_ofRestrict f.unop, isoSpec_inv, Category.assoc,
342+
← Scheme.isoSpec_inv_naturality_assoc,
293343
← Spec.map_comp_assoc, Scheme.restrictFunctor_map_app, ← Functor.map_comp]
294-
rw [fromSpec, ← Spec.map_comp_assoc, ← Functor.map_comp]
344+
rw [fromSpec, isoSpec_inv, Category.assoc, ← Spec.map_comp_assoc, ← Functor.map_comp]
345+
rfl
346+
347+
@[reassoc]
348+
lemma Spec_map_appLE_fromSpec (f : X ⟶ Y) {V : X.Opens} {U : Y.Opens}
349+
(hU : IsAffineOpen U) (hV : IsAffineOpen V) (i : V ≤ f ⁻¹ᵁ U) :
350+
Spec.map (f.appLE U V i) ≫ hU.fromSpec = hV.fromSpec ≫ f := by
351+
have : IsAffine U := hU
352+
simp only [IsAffineOpen.fromSpec, Category.assoc, isoSpec_inv]
353+
rw [← Scheme.restrictFunctor_map_ofRestrict (homOfLE i), Category.assoc, ← morphismRestrict_ι,
354+
← Category.assoc _ (f ∣_ U) U.ι, ← @Scheme.isoSpec_inv_naturality_assoc,
355+
← Spec.map_comp_assoc, ← Spec.map_comp_assoc, Scheme.comp_app, morphismRestrict_app,
356+
Scheme.restrictFunctor_map_app, Scheme.Hom.app_eq_appLE, Scheme.Hom.appLE_map,
357+
Scheme.Hom.appLE_map, Scheme.Hom.appLE_map, Scheme.Hom.map_appLE]
358+
359+
lemma fromSpec_top [IsAffine X] : (isAffineOpen_top X).fromSpec = X.isoSpec.inv := by
360+
rw [fromSpec, isoSpec_inv, Category.assoc, ← @Scheme.isoSpec_inv_naturality, Scheme.Opens.ι_app,
361+
← Spec.map_comp_assoc, ← X.presheaf.map_comp, ← op_comp, eqToHom_comp_homOfLE,
362+
← eqToHom_eq_homOfLE rfl, eqToHom_refl, op_id, X.presheaf.map_id, Spec.map_id, Category.id_comp]
363+
364+
lemma fromSpec_app_of_le (V : X.Opens) (h : U ≤ V) :
365+
hU.fromSpec.app V = X.presheaf.map (homOfLE h).op ≫
366+
(Scheme.ΓSpecIso Γ(X, U)).inv ≫ (Spec _).presheaf.map (homOfLE le_top).op := by
367+
have : U.ι ⁻¹ᵁ V = ⊤ := eq_top_iff.mpr fun x _ ↦ h x.2
368+
rw [IsAffineOpen.fromSpec, Scheme.comp_app, Scheme.Opens.ι_app, Scheme.app_eq _ this,
369+
IsAffineOpen.isoSpec_inv_app_top]
370+
simp only [Scheme.Opens.toScheme_presheaf_map, Scheme.Opens.topIso_hom,
371+
Category.assoc, ← X.presheaf.map_comp_assoc]
295372
rfl
296373

297374
include hU in
@@ -362,22 +439,20 @@ theorem fromSpec_preimage_self :
362439
rw [Opens.map_coe, Opens.coe_top, ← hU.range_fromSpec, ← Set.image_univ]
363440
exact Set.preimage_image_eq _ PresheafedSpace.IsOpenImmersion.base_open.inj
364441

365-
theorem SpecΓIdentity_hom_app_fromSpec :
442+
theorem ΓSpecIso_hom_fromSpec_app :
366443
(Scheme.ΓSpecIso Γ(X, U)).hom ≫ hU.fromSpec.app U =
367444
(Spec Γ(X, U)).presheaf.map (eqToHom hU.fromSpec_preimage_self).op := by
368-
simp only [fromSpec, Scheme.isoSpec, asIso_inv, Scheme.comp_coeBase, Opens.map_comp_obj,
369-
ΓSpecIso_obj_hom, Scheme.Opens.topIso_inv, Opens.map_top, Scheme.Opens.topIso_hom,
370-
Scheme.comp_app, Scheme.Opens.ι_app_self, unop_op, Category.assoc, ← Functor.map_comp_assoc, ←
371-
op_comp, eqToHom_trans, Scheme.Opens.eq_presheaf_map_eqToHom, Scheme.Hom.naturality_assoc,
372-
Scheme.inv_app_top, IsIso.hom_inv_id_assoc]
373-
simp only [eqToHom_op, eqToHom_map, Spec.map_eqToHom, eqToHom_unop,
374-
Scheme.Spec_map_presheaf_map_eqToHom, eqToHom_trans]
445+
simp only [fromSpec, Scheme.comp_coeBase, Opens.map_comp_obj, Scheme.comp_app,
446+
Scheme.Opens.ι_app_self, eqToHom_op, Scheme.app_eq _ U.ι_preimage_self,
447+
Scheme.Opens.toScheme_presheaf_map, eqToHom_unop, eqToHom_map U.ι.opensFunctor, Opens.map_top,
448+
isoSpec_inv_app_top, Scheme.Opens.topIso_hom, Category.assoc, ← Functor.map_comp_assoc,
449+
eqToHom_trans, eqToHom_refl, X.presheaf.map_id, Category.id_comp, Iso.hom_inv_id_assoc]
375450

376451
@[elementwise]
377452
theorem fromSpec_app_self :
378453
hU.fromSpec.app U = (Scheme.ΓSpecIso Γ(X, U)).inv ≫
379454
(Spec Γ(X, U)).presheaf.map (eqToHom hU.fromSpec_preimage_self).op := by
380-
rw [← hU.SpecΓIdentity_hom_app_fromSpec, Iso.inv_hom_id_assoc]
455+
rw [← hU.ΓSpecIso_hom_fromSpec_app, Iso.inv_hom_id_assoc]
381456

382457
theorem fromSpec_preimage_basicOpen' :
383458
hU.fromSpec ⁻¹ᵁ X.basicOpen f = (Spec Γ(X, U)).basicOpen ((Scheme.ΓSpecIso Γ(X, U)).inv f) := by
@@ -532,20 +607,18 @@ theorem _root_.AlgebraicGeometry.exists_basicOpen_le_affine_inter
532607
/-- The prime ideal of `𝒪ₓ(U)` corresponding to a point `x : U`. -/
533608
noncomputable def primeIdealOf (x : U) :
534609
PrimeSpectrum Γ(X, U) :=
535-
((@Scheme.isoSpec U hU).hom ≫
536-
Spec.map (X.presheaf.map (eqToHom U.openEmbedding_obj_top).op)).1.base x
610+
hU.isoSpec.hom.1.base x
537611

538612
theorem fromSpec_primeIdealOf (x : U) :
539613
hU.fromSpec.val.base (hU.primeIdealOf x) = x.1 := by
540614
dsimp only [IsAffineOpen.fromSpec, Subtype.coe_mk, IsAffineOpen.primeIdealOf]
541-
-- Porting note: in the porting note of `Scheme.comp_val_base`, it says that `elementwise` is
542-
-- unnecessary, indeed, the linter did not like it, so I just use `elementwise_of%` instead of
543-
-- adding the corresponding lemma in `Scheme.lean` file
544-
erw [← elementwise_of% Scheme.comp_val_base] -- now `erw` after #13170
545-
simp only [Scheme.Opens.toScheme_presheaf_obj, Category.assoc, ← Spec.map_comp_assoc,
546-
← Functor.map_comp, ← op_comp, eqToHom_trans, eqToHom_refl, op_id,
547-
CategoryTheory.Functor.map_id, Spec.map_id, Category.id_comp, Iso.hom_inv_id_assoc]
548-
rfl -- `rfl` was not needed before #13170
615+
rw [← Scheme.comp_val_base_apply, Iso.hom_inv_id_assoc]
616+
rfl
617+
618+
open LocalRing in
619+
theorem primeIdealOf_eq_map_closedPoint (x : U) :
620+
hU.primeIdealOf x = (Spec.map (X.presheaf.germ _ x x.2)).val.base (closedPoint _) :=
621+
hU.isoSpec_hom_val_base_apply _
549622

550623
theorem isLocalization_stalk' (y : PrimeSpectrum Γ(X, U)) (hy : hU.fromSpec.1.base y ∈ U) :
551624
@IsLocalization.AtPrime

Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,10 @@ instance isIso_adjunction_counit : IsIso ΓSpec.adjunction.counit := by
413413

414414
end ΓSpec
415415

416+
theorem Scheme.toSpecΓ_val_base (X : Scheme.{u}) (x) :
417+
(Scheme.toSpecΓ X).1.base x =
418+
(Spec.map (X.presheaf.germ ⊤ x trivial)).1.base (LocalRing.closedPoint _) := rfl
419+
416420
@[reassoc (attr := simp)]
417421
theorem Scheme.toSpecΓ_naturality {X Y : Scheme.{u}} (f : X ⟶ Y) :
418422
f ≫ Y.toSpecΓ = X.toSpecΓ ≫ Spec.map (f.app ⊤) :=

0 commit comments

Comments
 (0)