Skip to content

Commit 43178d5

Browse files
committed
feat(Topology/Category): the standard Grothendieck topology on TopCat (leanprover-community#34979)
We define the Grothendieck topology generated by families of jointly surjective open embeddings on `TopCat` and show it is subcanonical. This will be used to show that for a topological space `T`, the presheaf `U ↦ C(U, T)` on `Scheme` is a Zariski-sheaf. Co-authored by: Edward van de Meent <edwardvdmeent@gmail.com> From Proetale.
1 parent 3a29cc2 commit 43178d5

6 files changed

Lines changed: 178 additions & 1 deletion

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7167,6 +7167,7 @@ public import Mathlib.Topology.Category.TopCat.Adjunctions
71677167
public import Mathlib.Topology.Category.TopCat.Basic
71687168
public import Mathlib.Topology.Category.TopCat.EffectiveEpi
71697169
public import Mathlib.Topology.Category.TopCat.EpiMono
7170+
public import Mathlib.Topology.Category.TopCat.GrothendieckTopology
71707171
public import Mathlib.Topology.Category.TopCat.Limits.Basic
71717172
public import Mathlib.Topology.Category.TopCat.Limits.Cofiltered
71727173
public import Mathlib.Topology.Category.TopCat.Limits.Konig

Mathlib/CategoryTheory/MorphismProperty/Limits.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ theorem IsStableUnderBaseChange.mk' [RespectsIso P]
171171
rw [← P.cancel_left_of_respectsIso e.inv, sq.flip.isoPullback_inv_fst]
172172
exact hP₂ _ _ _ f g hg
173173

174+
lemma IsStableUnderBaseChange.of_forall_exists_isPullback {P : MorphismProperty C} [P.RespectsIso]
175+
(H : ∀ {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) [HasPullback f g] (_ : P g),
176+
∃ (T : C) (fst : T ⟶ X) (snd : T ⟶ Y), IsPullback fst snd f g ∧ P fst) :
177+
P.IsStableUnderBaseChange := by
178+
refine .mk' fun X Y S f g _ hg ↦ ?_
179+
obtain ⟨T, fst, snd, h, hfst⟩ := H f g hg
180+
rwa [← h.isoPullback_inv_fst, P.cancel_left_of_respectsIso]
181+
174182
variable (C)
175183

176184
instance IsStableUnderBaseChange.isomorphisms :
@@ -295,6 +303,14 @@ theorem IsStableUnderCobaseChange.mk' [RespectsIso P]
295303
rw [← P.cancel_right_of_respectsIso _ e.hom, sq.flip.inr_isoPushout_hom]
296304
exact hP₂ _ _ _ f g hf
297305

306+
lemma IsStableUnderCobaseChange.of_forall_exists_isPullback {P : MorphismProperty C} [P.RespectsIso]
307+
(H : ∀ {X Y Z : C} (f : Z ⟶ X) (g : Z ⟶ Y) [HasPushout f g] (_ : P f),
308+
∃ (T : C) (inl : X ⟶ T) (inr : Y ⟶ T), IsPushout f g inl inr ∧ P inr) :
309+
P.IsStableUnderCobaseChange := by
310+
refine .mk' fun X Y S f g _ hg ↦ ?_
311+
obtain ⟨T, inl, inr, h, hinl⟩ := H f g hg
312+
rwa [← h.inr_isoPushout_hom, P.cancel_right_of_respectsIso]
313+
298314
instance IsStableUnderCobaseChange.isomorphisms :
299315
(isomorphisms C).IsStableUnderCobaseChange where
300316
of_isPushout {_ _ _ _ f g _ _} h (_ : IsIso f) :=

Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,21 @@ instance (J : Precoverage C) [Small.{w} J] {S : C} (E : ZeroHypercover.{w'} J S)
825825
use E'.I₀, ZeroHypercover.Small.restrictFun _ ∘ ZeroHypercover.Small.restrictFun _
826826
exact E'.mem₀
827827

828+
instance {D : Type*} [Category* D] {F : C ⥤ D} (J : Precoverage D) [Small.{w} J] :
829+
Small.{w} (J.comap F) where
830+
zeroHypercoverSmall {X} E := by
831+
refine ⟨(E.map F le_rfl).restrictIndexOfSmall.I₀, ZeroHypercover.Small.restrictFun _, ?_⟩
832+
simpa using (E.map F le_rfl).restrictIndexOfSmall.mem₀
833+
834+
lemma Small.inf {J K : Precoverage C} [Small.{w} J]
835+
(of_le : ∀ ⦃X : C⦄ ⦃R S : Presieve X⦄, R ≤ S → S ∈ K X → R ∈ K X) :
836+
Small.{w} (J ⊓ K) where
837+
zeroHypercoverSmall {S} E := by
838+
refine ⟨(E.weaken (inf_le_left)).restrictIndexOfSmall.I₀,
839+
ZeroHypercover.Small.restrictFun _, ⟨?_, ?_⟩⟩
840+
· exact (E.weaken (inf_le_left)).restrictIndexOfSmall.mem₀
841+
· exact of_le (by simp) E.mem₀.2
842+
828843
instance [IsStableUnderBaseChange J] : RespectsIso J where
829844
of_iso {S E F} e h := by
830845
refine J.mem_coverings_of_isPullback (fun i ↦ E.f (e.inv.s₀ i)) ?_ (𝟙 S) _ (fun i ↦ ?_) ?_

Mathlib/CategoryTheory/Sites/JointlySurjective.lean

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Authors: Christian Merten
55
-/
66
module
77

8-
public import Mathlib.CategoryTheory.Sites.Precoverage
8+
public import Mathlib.CategoryTheory.Sites.Hypercover.Zero
99
public import Mathlib.CategoryTheory.Limits.Types.Pullbacks
1010

1111
/-!
@@ -77,6 +77,14 @@ instance : jointlySurjectivePrecoverage.IsStableUnderSup where
7777
obtain ⟨Y, f, hf, hx⟩ := hR x
7878
use Y, f, .inl hf
7979

80+
instance : Precoverage.Small.{u} jointlySurjectivePrecoverage.{u} where
81+
zeroHypercoverSmall {X} E := by
82+
choose i y hy using ofArrows_mem_jointlySurjectivePrecoverage_iff.mp E.mem₀
83+
refine ⟨X, i, ?_⟩
84+
rw [ofArrows_mem_jointlySurjectivePrecoverage_iff]
85+
intro x
86+
use x, y x, hy x
87+
8088
end Types
8189

8290
variable {C : Type*} [Category* C] (F : C ⥤ Type u)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/-
2+
Copyright (c) 2026 Christian Merten. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Edward van de Meent, Christian Merten
5+
-/
6+
module
7+
8+
public import Mathlib.CategoryTheory.Sites.Canonical
9+
public import Mathlib.CategoryTheory.Sites.JointlySurjective
10+
public import Mathlib.CategoryTheory.Sites.MorphismProperty
11+
public import Mathlib.Topology.Category.TopCat.Limits.Pullbacks
12+
13+
/-!
14+
15+
# The Grothendieck topology on `TopCat`
16+
17+
In this file we define the standard Grothendieck topology on `TopCat`. This is the topology
18+
generated by families of jointly surjective open embeddings.
19+
20+
## Main definitions and results
21+
22+
- `TopCat.isOpenEmbedding`: The morphism property in `TopCat` given by open embeddings.
23+
- `TopCat.grothendieckTopology`: The Grothendieck topology generated by families of jointly
24+
surjective open embeddings.
25+
- `TopCat.subcanonical_grothendieckTopology`: The Grothendieck topology on `TopCat` is subcanonical.
26+
27+
## TODOs
28+
29+
- Define the étale precoverage on `TopCat` (replace open embedding by local homeomorphism
30+
in the definition of the Grothendieck topology) and show it induces the same Grothendieck
31+
topology.
32+
33+
-/
34+
35+
@[expose] public section
36+
37+
universe u
38+
39+
open CategoryTheory Limits
40+
41+
namespace TopCat
42+
43+
/-- The morphism property on the category of topological spaces given by open embeddings. -/
44+
def isOpenEmbedding : MorphismProperty TopCat :=
45+
fun _ _ f ↦ Topology.IsOpenEmbedding f
46+
47+
@[simp]
48+
lemma isOpenEmbedding_iff {X Y : TopCat} (f : X ⟶ Y) :
49+
isOpenEmbedding f ↔ Topology.IsOpenEmbedding f := .rfl
50+
51+
instance : isOpenEmbedding.IsMultiplicative where
52+
id_mem _ := .id
53+
comp_mem _ _ hf hg := hg.comp hf
54+
55+
instance : isOpenEmbedding.RespectsIso :=
56+
MorphismProperty.respectsIso_of_isStableUnderComposition fun _ _ f (_ : IsIso f) ↦
57+
(TopCat.homeoOfIso (asIso f)).isOpenEmbedding
58+
59+
instance : isOpenEmbedding.IsStableUnderBaseChange :=
60+
.mk' fun _ _ _ _ _ _ hg ↦ fst_isOpenEmbedding_of_right _ hg
61+
62+
/-- The precoverage on `TopCat` given by jointly surjective families of open embeddings. -/
63+
def precoverage : Precoverage TopCat.{u} :=
64+
Types.jointlySurjectivePrecoverage.comap (forget TopCat) ⊓ isOpenEmbedding.precoverage
65+
deriving Precoverage.HasIsos, Precoverage.IsStableUnderBaseChange,
66+
Precoverage.IsStableUnderComposition
67+
68+
/-- The Grothendieck topology on the category of topological spaces is the topology given by
69+
jointly surjective open embeddings. -/
70+
abbrev grothendieckTopology : GrothendieckTopology TopCat.{u} :=
71+
precoverage.toGrothendieck
72+
73+
lemma exists_mem_zeroHypercover_range {X : TopCat} (E : precoverage.ZeroHypercover X) :
74+
∀ x, ∃ (i : E.I₀), x ∈ Set.range (E.f i) := by
75+
simpa using E.mem₀.left
76+
77+
lemma isOpenEmbedding_f_zeroHypercover {X : TopCat} (E : precoverage.ZeroHypercover X) :
78+
∀ i, Topology.IsOpenEmbedding (E.f i) := by
79+
simpa using E.mem₀.right
80+
81+
instance : Precoverage.Small.{u} precoverage.{u} :=
82+
.inf fun _ _ _ hRS hS _ _ hf ↦ hS (hRS _ hf)
83+
84+
/-- The Grothendieck topology on `TopCat` is subcanonical. -/
85+
instance subcanonical_grothendieckTopology : grothendieckTopology.Subcanonical := by
86+
refine .of_isSheaf_yoneda_obj _ fun X ↦ ?_
87+
rw [Precoverage.isSheaf_toGrothendieck_iff_of_isStableUnderBaseChange_of_small]
88+
intro Y 𝒰
89+
rw [Presieve.isSheafFor_arrows_iff]
90+
have heq (i y) : 𝒰.f i y = (Subtype.val : Set.range (𝒰.f i) → Y) ⟨𝒰.f i y, by simp⟩ := rfl
91+
refine fun x hx ↦ ⟨?_, fun i ↦ ?_, fun f hf ↦ ?_⟩
92+
· refine ofHom <| ContinuousMap.liftCover (fun i ↦ Set.range (𝒰.f i)) ?_ ?_ ?_
93+
· intro i
94+
exact ⟨(x i).hom ∘ (isOpenEmbedding_f_zeroHypercover 𝒰 i).toHomeomorph.symm, by fun_prop⟩
95+
· intro i j y
96+
simp only [Set.mem_range, ContinuousMap.coe_mk, Function.comp_apply, forall_exists_index]
97+
intro xi hi xj hj
98+
conv_lhs => simp only [← hi]
99+
conv_rhs => simp only [← hj]
100+
have := hx i j _ (TopCat.pullbackCone (𝒰.f i) (𝒰.f j)).fst
101+
(TopCat.pullbackCone (𝒰.f i) (𝒰.f j)).snd (TopCat.pullbackCone (𝒰.f i) (𝒰.f j)).condition
102+
dsimp at this
103+
simpa using congr($(this) ⟨(xi, xj), hi ▸ hj.symm⟩)
104+
· intro x
105+
obtain ⟨i, hi⟩ := exists_mem_zeroHypercover_range 𝒰 x
106+
exact ⟨i, (isOpenEmbedding_f_zeroHypercover 𝒰 i).isOpen_range.mem_nhds hi⟩
107+
· dsimp
108+
ext
109+
simp only [hom_comp, hom_ofHom, ContinuousMap.comp_apply]
110+
rw [heq, ContinuousMap.liftCover_coe]
111+
simp
112+
· dsimp
113+
ext x
114+
obtain ⟨i, y, rfl⟩ := exists_mem_zeroHypercover_range 𝒰 x
115+
have := congr($(hf i).hom y)
116+
dsimp at this ⊢
117+
rw [this, heq, ContinuousMap.liftCover_coe]
118+
simp
119+
120+
end TopCat

Mathlib/Topology/Homeomorph/Lemmas.lean

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,11 @@ noncomputable def toHomeomorph {f : X → Y} (hf : IsEmbedding f) :
432432
Equiv.ofInjective f hf.injective |>.toHomeomorphOfIsInducing <|
433433
IsInducing.subtypeVal.of_comp_iff.mp hf.toIsInducing
434434

435+
@[simp]
436+
lemma toHomeomorph_symm_apply {f : X → Y} (hf : IsEmbedding f) (x : X) :
437+
hf.toHomeomorph.symm ⟨f x, by simp⟩ = x :=
438+
hf.toHomeomorph.injective (by ext; simp)
439+
435440
/-- A surjective embedding is a homeomorphism. -/
436441
@[simps! apply]
437442
noncomputable def toHomeomorphOfSurjective {f : X → Y}
@@ -454,6 +459,18 @@ theorem homeomorphOfSubsetRange_apply_coe {f : X → Y} (hf : IsEmbedding f)
454459

455460
end Topology.IsEmbedding
456461

462+
lemma Topology.IsEmbedding.uliftMap {f : X → Y} (hf : IsEmbedding f) :
463+
IsEmbedding (ULift.map f) :=
464+
.comp Homeomorph.ulift.symm.isEmbedding (.comp hf <| Homeomorph.ulift.isEmbedding)
465+
466+
lemma Topology.IsOpenEmbedding.uliftMap {f : X → Y} (hf : IsOpenEmbedding f) :
467+
IsOpenEmbedding (ULift.map f) :=
468+
.comp Homeomorph.ulift.symm.isOpenEmbedding (.comp hf <| Homeomorph.ulift.isOpenEmbedding)
469+
470+
lemma Topology.IsClosedEmbedding.uliftMap {f : X → Y} (hf : IsClosedEmbedding f) :
471+
IsClosedEmbedding (ULift.map f) :=
472+
.comp Homeomorph.ulift.symm.isClosedEmbedding (.comp hf <| Homeomorph.ulift.isClosedEmbedding)
473+
457474
end
458475

459476
namespace Continuous

0 commit comments

Comments
 (0)