Skip to content

Commit 9ca31d8

Browse files
committed
feat(AlgebraicGeometry): Scheme.Hom.opensFunctor preserves 1-hypercovers (leanprover-community#40990)
We deduce this from the fact that it preserves pullbacks, which we deduce from general facts about thin categories.
1 parent 8b62164 commit 9ca31d8

7 files changed

Lines changed: 161 additions & 0 deletions

File tree

Mathlib/AlgebraicGeometry/OpenImmersion.lean

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module
88
public import Mathlib.Geometry.RingedSpace.OpenImmersion
99
public import Mathlib.AlgebraicGeometry.Scheme
1010
public import Mathlib.CategoryTheory.MorphismProperty.Limits
11+
public import Mathlib.CategoryTheory.Limits.Preorder
1112

1213
/-!
1314
# Open immersions of schemes
@@ -87,6 +88,37 @@ theorem mem_opensRange {f : X ⟶ Y} [IsOpenImmersion f] {y : Y} :
8788
def opensFunctor : X.Opens ⥤ Y.Opens :=
8889
LocallyRingedSpace.IsOpenImmersion.opensFunctor f.toLRSHom
8990

91+
/-- The adjunction image-preimage adjunction for an open immersion of schemes. -/
92+
def opensFunctorAdjunction : f.opensFunctor ⊣ TopologicalSpace.Opens.map f.base :=
93+
IsOpenMap.adjunction ‹IsOpenImmersion f›.base_open.isOpenMap
94+
95+
instance : f.opensFunctor.IsLeftAdjoint :=
96+
f.opensFunctorAdjunction.isLeftAdjoint
97+
98+
instance : f.opensFunctor.IsCocontinuous (Opens.grothendieckTopology _)
99+
(Opens.grothendieckTopology _) := by
100+
rw [f.opensFunctorAdjunction.isCocontinuous_iff_coverPreserving]
101+
exact coverPreserving_opens_map f.base
102+
103+
instance : f.opensFunctor.Full :=
104+
have : Mono f.base := (TopCat.mono_iff_injective f.base).mpr f.isOpenEmbedding.injective
105+
inferInstanceAs f.isOpenEmbedding.functor.Full
106+
107+
lemma coverPreserving_opensFunctor :
108+
CoverPreserving (Opens.grothendieckTopology _) (Opens.grothendieckTopology _) f.opensFunctor :=
109+
f.isOpenEmbedding.isOpenMap.coverPreserving
110+
111+
instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] :
112+
PreservesLimitsOfShape WalkingCospan (Scheme.Hom.opensFunctor f) := by
113+
dsimp [Scheme.Hom.opensFunctor]
114+
infer_instance
115+
116+
instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] :
117+
f.opensFunctor.PreservesOneHypercovers (Opens.grothendieckTopology _)
118+
(Opens.grothendieckTopology _) := by
119+
refine Functor.PreservesOneHypercovers.of_coverPreserving ?_
120+
exact Scheme.Hom.coverPreserving_opensFunctor f
121+
90122
/-- `f ''ᵁ U` is notation for the image (as an open set) of `U` under an open immersion `f`.
91123
The preferred name in lemmas is `image` and it should be treated as an infix. -/
92124
scoped[AlgebraicGeometry] notation3:90 f:91 " ''ᵁ " U:90 => (Scheme.Hom.opensFunctor f).obj U
@@ -206,6 +238,13 @@ theorem appIso_hom' (U) :
206238
(f.appIso U).hom = f.appLE (f ''ᵁ U) U (preimage_image_eq f U).ge :=
207239
f.appIso_hom U
208240

241+
set_option backward.defeqAttrib.useBackward true in
242+
@[reassoc (attr := simp)]
243+
lemma appIso_hom_naturality {U V : X.Opens} (i : op U ⟶ op V) :
244+
dsimp% Y.presheaf.map (f.opensFunctor.op.map i) ≫ (f.appIso V).hom =
245+
(f.appIso U).hom ≫ X.presheaf.map i := by
246+
simp [← cancel_mono (f.appIso V).inv]
247+
209248
@[reassoc (attr := simp)]
210249
theorem app_appIso_inv (U) :
211250
f.app U ≫ (f.appIso (f ⁻¹ᵁ U)).inv =

Mathlib/CategoryTheory/Discrete/Basic.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Stephen Morgan, Kim Morrison, Floris van Doorn
66
module
77

88
public import Mathlib.CategoryTheory.Pi.Basic
9+
public import Mathlib.Data.Set.Image
910

1011
/-!
1112
# Discrete categories
@@ -63,6 +64,9 @@ def discreteEquiv {α : Type u₁} : Discrete α ≃ α where
6364
left_inv := by cat_disch
6465
right_inv := by cat_disch
6566

67+
lemma Discrete.as_bijective {α : Type*} : (Discrete.as (α := α)).Bijective :=
68+
discreteEquiv.bijective
69+
6670
instance {α : Type u₁} [DecidableEq α] : DecidableEq (Discrete α) :=
6771
discreteEquiv.decidableEq
6872

@@ -179,6 +183,10 @@ theorem functor_obj_eq_as {I : Type u₁} (F : I → C) (X : Discrete I) :
179183
(Discrete.functor F).obj X = F X.as :=
180184
rfl
181185

186+
@[simp]
187+
lemma range_functor {I : Type*} (X : I → C) : Set.range (Discrete.functor X).obj = Set.range X := by
188+
simp [Discrete.functor, Set.range_comp, Discrete.as_bijective.surjective.range_eq]
189+
182190
@[ext]
183191
lemma functor_ext {I : Type u₁} {G F : Discrete I ⥤ C} (h : (i : I) → G.obj ⟨i⟩ = F.obj ⟨i⟩) :
184192
G = F := by

Mathlib/CategoryTheory/Limits/Preorder.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Sina Hazratpour, Joël Riou, Fernando Chu
66
module
77

88
public import Mathlib.CategoryTheory.Limits.Shapes.BinaryProducts
9+
public import Mathlib.CategoryTheory.Limits.Shapes.Products
910
public import Mathlib.Order.Bounds.Defs
1011

1112
/-!
@@ -211,4 +212,18 @@ instance (priority := low) [SemilatticeSup C] : HasBinaryCoproducts C where
211212

212213
end
213214

215+
section
216+
217+
/-- The product of elements in a complete lattice is the infimum. -/
218+
def isLimitIInf [CompleteLattice C] {ι : Type*} (X : ι → C) :
219+
IsLimit (Fan.mk (⨅ i, X i) fun i : ι ↦ homOfLE (iInf_le X i)) :=
220+
isLimitOfIsGLB _ _ (by simp [isGLB_iInf])
221+
222+
/-- The coproduct of elements in a complete lattice is the supremum. -/
223+
def isColimitISup [CompleteLattice C] {ι : Type*} (X : ι → C) :
224+
IsColimit (Cofan.mk (⨆ i, X i) fun i : ι ↦ homOfLE (le_iSup X i)) :=
225+
isColimitOfIsLUB _ _ (by simp [isLUB_iSup])
226+
227+
end
228+
214229
end Preorder

Mathlib/CategoryTheory/Limits/Shapes/Products.lean

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,27 @@ instance [HasColimit F] [HasCoproduct F.obj] : Epi (Sigma.desc (colimit.ι F)) w
967967

968968
end
969969

970+
section Thin
971+
972+
variable [Quiver.IsThin C] {J : Type*} [Category* J] {K : J ⥤ C}
973+
974+
/-- If `K : J ⥤ C` is a diagram with `C` thin, a cone for `K` is limiting
975+
if and only if the cone point is the product of the components. -/
976+
def isLimitEquivFanOfIsThin (c : Cone K) : IsLimit c ≃ IsLimit (Fan.mk c.pt c.π.app) where
977+
toFun hc := Fan.IsLimit.mk _ (fun s ↦ hc.lift { pt := s.pt, π.app j := s.proj j })
978+
(by subsingleton) (by subsingleton)
979+
invFun h := { lift s := Fan.IsLimit.lift h s.π.app }
980+
981+
/-- If `K : J ⥤ C` is a diagram with `C` thin, a cone for `K` is limiting
982+
if and only if the cone point is the product of the components. -/
983+
def isColimitEquivCofanOfIsThin (c : Cocone K) :
984+
IsColimit c ≃ IsColimit (Cofan.mk c.pt c.ι.app) where
985+
toFun hc := Cofan.IsColimit.mk _ (fun s ↦ hc.desc { pt := s.pt, ι.app j := s.inj j })
986+
(by subsingleton) (by subsingleton)
987+
invFun h := { desc s := Cofan.IsColimit.desc h s.ι.app }
988+
989+
end Thin
990+
970991
section Fubini
971992

972993
variable {ι ι' : Type*} {X : ι → ι' → C}

Mathlib/CategoryTheory/Limits/Shapes/Pullback/IsPullback/Basic.lean

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,54 @@ lemma IsPushout.iff_app [HasPushouts D] {F₁ F₂ F₃ F₄ : C ⥤ D}
943943

944944
end Functor
945945

946+
section Thin
947+
948+
variable [Quiver.IsThin C]
949+
950+
lemma isPullback_iff_isLimit_binaryFan_of_isThin {P X Y Z : C}
951+
{fst : P ⟶ X} {snd : P ⟶ Y} {f : X ⟶ Z} {g : Y ⟶ Z} :
952+
IsPullback fst snd f g ↔ Nonempty (IsLimit (BinaryFan.mk fst snd)) := by
953+
refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
954+
· exact ⟨BinaryFan.IsLimit.mk _ (fun u v ↦ h.lift u v (by subsingleton))
955+
(by subsingleton) (by subsingleton) (by subsingleton)⟩
956+
· exact ⟨⟨by subsingleton⟩,
957+
⟨PullbackCone.IsLimit.mk _ (fun s ↦ BinaryFan.IsLimit.lift h.some s.fst s.snd)
958+
(by subsingleton) (by subsingleton) (by subsingleton)⟩⟩
959+
960+
lemma isPushout_iff_isColimit_binaryCofan_of_isThin {P X Y Z : C}
961+
{f : Z ⟶ X} {g : Z ⟶ Y} {inl : X ⟶ P} {inr : Y ⟶ P} :
962+
IsPushout f g inl inr ↔ Nonempty (IsColimit (BinaryCofan.mk inl inr)) := by
963+
refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
964+
· exact ⟨BinaryCofan.IsColimit.mk _ (fun u v ↦ h.desc u v (by subsingleton))
965+
(by subsingleton) (by subsingleton) (by subsingleton)⟩
966+
· exact ⟨⟨by subsingleton⟩,
967+
⟨PushoutCocone.IsColimit.mk _ (fun s ↦ BinaryCofan.IsColimit.desc h.some s.inl s.inr)
968+
(by subsingleton) (by subsingleton) (by subsingleton)⟩⟩
969+
970+
variable {D : Type*} [Category* D] [Quiver.IsThin D] (F : C ⥤ D)
971+
972+
instance (priority := low) [PreservesLimitsOfShape (Discrete WalkingPair) F] :
973+
PreservesLimitsOfShape WalkingCospan F := by
974+
refine preservesLimitsOfShape_walkingCospan_of_forall_isPullback fun X Y Z f g hfg ↦ ?_
975+
use pullback f g, pullback.fst f g, pullback.snd f g, .of_hasPullback f g
976+
rw [isPullback_iff_isLimit_binaryFan_of_isThin]
977+
refine ⟨(BinaryFan.mk (pullback.fst f g) (pullback.snd f g)).isLimitMapConeEquiv ?_⟩
978+
apply isLimitOfPreserves _ (Nonempty.some ?_)
979+
rw [← CategoryTheory.isPullback_iff_isLimit_binaryFan_of_isThin (f := f) (g := g)]
980+
exact .of_hasPullback f g
981+
982+
instance (priority := low) [PreservesColimitsOfShape (Discrete WalkingPair) F] :
983+
PreservesColimitsOfShape WalkingSpan F := by
984+
refine preservesColimitsOfShape_walkingCospan_of_forall_isPushout fun X Y Z f g hfg ↦ ?_
985+
use pushout f g, pushout.inl f g, pushout.inr f g, .of_hasPushout f g
986+
rw [isPushout_iff_isColimit_binaryCofan_of_isThin]
987+
refine ⟨(BinaryCofan.mk (pushout.inl f g) (pushout.inr f g)).isColimitMapConeEquiv ?_⟩
988+
apply isColimitOfPreserves _ (Nonempty.some ?_)
989+
rw [← CategoryTheory.isPushout_iff_isColimit_binaryCofan_of_isThin (f := f) (g := g)]
990+
exact .of_hasPushout f g
991+
992+
end Thin
993+
946994
section IsPullbackOverPullback
947995

948996
open Limits

Mathlib/Topology/Category/TopCat/Opens.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module
77

88
public import Mathlib.CategoryTheory.Category.GaloisConnection
99
public import Mathlib.CategoryTheory.EqToHom
10+
public import Mathlib.CategoryTheory.Limits.Preorder
11+
public import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Products
1012
public import Mathlib.Topology.Category.TopCat.EpiMono
1113
public import Mathlib.Topology.Sets.Opens
1214

@@ -341,6 +343,15 @@ lemma Topology.IsOpenEmbedding.functor_obj_injective {X Y : TopCat.{u}} {f : X
341343
(hf : IsOpenEmbedding f) : Function.Injective hf.functor.obj :=
342344
fun _ _ e ↦ Opens.ext (Set.image_injective.mpr hf.injective (congr_arg (↑· : Opens Y → Set Y) e))
343345

346+
lemma Topology.IsOpenEmbedding.functor_obj_iInf {X Y : TopCat.{u}} (f : X ⟶ Y)
347+
(hf : Topology.IsOpenEmbedding f) {ι : Type*} [Nonempty ι] [Finite ι]
348+
(g : ι → TopologicalSpace.Opens X) :
349+
hf.functor.obj (⨅ i, g i) = ⨅ i, hf.functor.obj (g i) := by
350+
ext : 1
351+
simp only [IsOpenMap.coe_functor_obj, TopologicalSpace.Opens.coe_iInf]
352+
rw [Set.InjOn.image_iInter_eq]
353+
exact hf.injective.injOn
354+
344355
namespace Topology.IsInducing
345356

346357
/-- Given an inducing map `X ⟶ Y` and some `U : Opens X`, this is the union of all open sets
@@ -463,4 +474,15 @@ theorem adjunction_counit_map_functor {X : TopCat.{u}} {U : Opens X} (V : Opens
463474
eqToHom (by dsimp; rw [map_functor_eq V]) := by
464475
subsingleton
465476

477+
open Limits in
478+
instance {X Y : TopCat.{u}} (f : X ⟶ Y) (hf : Topology.IsOpenEmbedding f) {ι : Type*}
479+
[Nonempty ι] [Finite ι] :
480+
PreservesLimitsOfShape (Discrete ι) hf.functor := by
481+
apply +allowSynthFailures preservesLimitsOfShape_of_discrete
482+
intro g
483+
refine preservesLimit_of_preserves_limit_cone (Preorder.isLimitIInf g) ?_
484+
refine (Limits.Fan.isLimitMapConeEquiv _ _ _).symm (Preorder.isLimitOfIsGLB _ _ ?_)
485+
simp only [Discrete.range_functor, homOfLE_leOfHom, Fan.mk_pt, hf.functor_obj_iInf]
486+
apply isGLB_iInf
487+
466488
end TopologicalSpace.Opens

Mathlib/Topology/Sets/Opens.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Floris van Doorn
55
-/
66
module
77

8+
public import Mathlib.Data.Fintype.Option
89
public import Mathlib.Order.Hom.CompleteLattice
910
public import Mathlib.Topology.Compactness.Bases
1011
public import Mathlib.Topology.ContinuousMap.Basic
@@ -232,6 +233,13 @@ instance [Nonempty α] : Nontrivial (Opens α) where
232233
theorem coe_iSup {ι} (s : ι → Opens α) : ((⨆ i, s i : Opens α) : Set α) = ⋃ i, s i := by
233234
simp [iSup]
234235

236+
lemma coe_iInf {ι : Type*} [Finite ι] (U : ι → TopologicalSpace.Opens α) :
237+
(((⨅ i, U i) : Opens α) : Set α) = ⋂ i, U i := by
238+
induction ι using Finite.induction_empty_option with
239+
| of_equiv e ih => rw [← e.iInf_comp, ← e.surjective.iInter_comp, ih]
240+
| h_empty => simp
241+
| h_option ih => rw [iInf_option, Set.iInter_option, Opens.coe_inf, ih]
242+
235243
theorem iSup_def {ι} (s : ι → Opens α) : ⨆ i, s i = ⟨⋃ i, s i, isOpen_iUnion fun i => (s i).2⟩ :=
236244
ext <| coe_iSup s
237245

0 commit comments

Comments
 (0)