Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2361,11 +2361,13 @@ import Mathlib.CategoryTheory.Sites.EffectiveEpimorphic
import Mathlib.CategoryTheory.Sites.EpiMono
import Mathlib.CategoryTheory.Sites.EqualizerSheafCondition
import Mathlib.CategoryTheory.Sites.Equivalence
import Mathlib.CategoryTheory.Sites.GlobalSections
import Mathlib.CategoryTheory.Sites.Grothendieck
import Mathlib.CategoryTheory.Sites.IsSheafFor
import Mathlib.CategoryTheory.Sites.IsSheafOneHypercover
import Mathlib.CategoryTheory.Sites.LeftExact
import Mathlib.CategoryTheory.Sites.Limits
import Mathlib.CategoryTheory.Sites.LocalSite
import Mathlib.CategoryTheory.Sites.Localization
import Mathlib.CategoryTheory.Sites.LocallyBijective
import Mathlib.CategoryTheory.Sites.LocallyFullyFaithful
Expand Down
10 changes: 10 additions & 0 deletions Mathlib/CategoryTheory/Limits/FunctorCategory/Shapes/Products.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Authors: Markus Himmel
-/
import Mathlib.CategoryTheory.Limits.FunctorCategory.Basic
import Mathlib.CategoryTheory.Limits.Shapes.Products
import Mathlib.CategoryTheory.Limits.Shapes.Terminal

/-!
# (Co)products in functor categories
Expand Down Expand Up @@ -45,6 +46,15 @@ alias piObjIso_inv_comp_pi := piObjIso_inv_comp_π

end Product

section Terminal

/-- Evaluating the terminal functor yields the terminal object. -/
noncomputable def terminalObjIso [HasTerminal C] (d : D) : (⊤_ (D ⥤ C)).obj d ≅ ⊤_ C :=
limitObjIsoLimitCompEvaluation _ d ≪≫ HasLimit.isoOfNatIso
((Discrete.compNatIsoDiscrete _ _).trans <| eqToIso <| congrArg _ <| funext fun x ↦ nomatch x)

end Terminal

section Coproduct

variable [HasColimitsOfShape (Discrete α) C]
Expand Down
6 changes: 6 additions & 0 deletions Mathlib/CategoryTheory/Limits/Types.lean
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ theorem limitEquivSections_symm_apply (x : F.sections) (j : J) :
limit.π F j ((limitEquivSections F).symm x) = (x : ∀ j, F.obj j) j :=
isLimitEquivSections_symm_apply _ _ _

/-- The limit of a functor `F : J ⥤ Type _` is naturally isomorphic to `F.sections`. -/
noncomputable def limNatIsoSectionsFunctor :
(lim : (J ⥤ Type max u v) ⥤ _) ≅ Functor.sectionsFunctor _ :=
NatIso.ofComponents (fun _ ↦ (limitEquivSections _).toIso)
fun f ↦ funext fun x ↦ Subtype.ext <| funext fun _ ↦ congrFun (limMap_π f _) x

-- Porting note: `limitEquivSections_symm_apply'` was removed because the linter
-- complains it is unnecessary
--@[simp]
Expand Down
95 changes: 95 additions & 0 deletions Mathlib/CategoryTheory/Sites/GlobalSections.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/-
Copyright (c) 2025 Ben Eltschig. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Ben Eltschig
-/
import Mathlib.CategoryTheory.Limits.FunctorCategory.Shapes.Products
import Mathlib.CategoryTheory.Sites.ConstantSheaf

/-!
# Global sections of sheaves
In this file we define a global sections functor `Sheaf.Γ : Sheaf J A ⥤ A` and show that it
is isomorphic to several other constructions when they exist, most notably evaluation of sheaves
on a terminal object and `Functor.sectionsFunctor`.

## Main definitions / results
* `Sheaf.Γ J A`: the global sections functor `Sheaf J A ⥤ A`, defined as taking each sheaf to
the limit of its underlying presheaf in `A`.
* `constantSheafΓAdj J A`: the adjunction between the constant sheaf functor and `Sheaf.Γ J A`.
* `Sheaf.ΓNatIsoSheafSections J A hT`: on sites with a terminal object `T`, `Sheaf.Γ J A` is
isomorphic to the functor evaluating sheaves at `T`.
* `Sheaf.ΓNatIsoSectionsFunctor J`: for sheaves of types, `Sheaf.Γ J A` is isomorphic to the
functor taking each sheaf to the type of sections of its underlying presheaf in the sense of
`Functor.sections`.
* `Sheaf.ΓNatIsoCoyonedaObj J`: for sheaves of types, `Sheaf.Γ J A` is isomorphic to the
coyoneda embedding of the terminal sheaf, i.e. the functor sending each sheaf `F` to the type
of morphisms from the terminal sheaf to `F`.
-/

universe u v w u₂ v₂

open CategoryTheory Limits Sheaf Opposite GrothendieckTopology

namespace CategoryTheory

variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C)
(A : Type u₂) [Category.{v₂} A]

/-- The global sections functor `Γ`, taking sheaves valued in `A` to its global sections in `A`.
It is given here as a limit instead of evaluation on a terminal object of `C`; this has the
advantage of not requiring `C` to have a terminal object, but the disadvantage of requiring `A`
to have limits of shape `Cᵒᵖ`. -/
noncomputable def Sheaf.Γ [HasLimitsOfShape Cᵒᵖ A] : Sheaf J A ⥤ A :=
sheafToPresheaf J A ⋙ lim

/-- The constant sheaf functor is left-adjoint to the global sections functor when both exist. -/
noncomputable def constantSheafΓAdj [HasWeakSheafify J A] [HasLimitsOfShape Cᵒᵖ A] :
constantSheaf J A ⊣ Γ J A :=
constLimAdj.comp (sheafificationAdjunction J A)

instance [HasWeakSheafify J A] [HasLimitsOfShape Cᵒᵖ A] : (constantSheaf J A).IsLeftAdjoint :=
⟨Γ J A, ⟨constantSheafΓAdj J A⟩⟩

instance [HasWeakSheafify J A] [HasLimitsOfShape Cᵒᵖ A] : (Γ J A).IsRightAdjoint :=
⟨constantSheaf J A, ⟨constantSheafΓAdj J A⟩⟩

/-- For functors `F : C ⥤ Type _`, `F.sections` is naturally isomorphic to the type `⊤_ _ ⟶ F`
of natural transformations from the terminal functor to `F`. -/
noncomputable def sectionsFunctorNatIsoCoyoneda :
Functor.sectionsFunctor.{v,max u w} C ≅ coyoneda.obj (op (⊤_ _)) :=
let _ : ∀ X, Unique ((⊤_ C ⥤ Type max u w).obj X) := fun X ↦ (terminalObjIso X).toEquiv.unique
NatIso.ofComponents fun F ↦ {
hom s := { app X := fun _ ↦ s.1 X }
inv s := ⟨fun X ↦ s.app X default, fun f ↦
(congrFun (s.naturality f).symm _).trans <| congrArg (s.app _) <| Unique.eq_default _⟩
inv_hom_id := funext fun s ↦ by
dsimp; ext X x; simp [Unique.eq_default x]
}

/-- When `C` has a terminal object, the global sections functor is isomorphic to the functor
of sections on that object. -/
noncomputable def Sheaf.ΓNatIsoSheafSections [HasLimitsOfShape Cᵒᵖ A] {T : C}
(hT : IsTerminal T) : Γ J A ≅ (sheafSections J A).obj (op T) := by
refine (isoWhiskerLeft _ ?_).trans <| (sheafSectionsNatIsoEvaluation J A).symm
refine @asIso _ _ _ _ { app := fun F ↦ limit.π _ _ } ?_
have hT' := initialOpOfTerminal hT
exact (NatTrans.isIso_iff_isIso_app _).2 <| fun F ↦ isIso_π_of_isInitial hT' F

/-- For sheaves of types, the global sections functor is isomorphic to the sections functor
on presheaves. -/
noncomputable def Sheaf.ΓNatIsoSectionsFunctor :
Γ J (Type max u w) ≅ sheafToPresheaf J _ ⋙ Functor.sectionsFunctor _ :=
isoWhiskerLeft _ <| Types.limNatIsoSectionsFunctor

/-- For sheaves of types, the global sections functor is isomorphic to the covariant hom
functor of the terminal sheaf. -/
noncomputable def Sheaf.ΓNatIsoCoyonedaObj :
Γ J (Type max u w) ≅ coyoneda.obj (op (⊤_ _)) := by
refine (ΓNatIsoSectionsFunctor J).trans ?_
refine (isoWhiskerLeft _ sectionsFunctorNatIsoCoyoneda).trans ?_
let e : (⊤_ Sheaf J _).val ≅ ⊤_ Cᵒᵖ ⥤ Type max u w :=
(terminalIsoIsTerminal (terminalIsTerminal.isTerminalObj (sheafToPresheaf J _) _)).symm
refine (isoWhiskerLeft _ <| coyoneda.mapIso e.op).trans ?_
exact NatIso.ofComponents fun _ ↦ Sheaf.homEquiv.toIso.symm

end CategoryTheory
145 changes: 145 additions & 0 deletions Mathlib/CategoryTheory/Sites/LocalSite.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/-
Copyright (c) 2025 Ben Eltschig. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Ben Eltschig
-/
import Mathlib.CategoryTheory.Adjunction.Triple
import Mathlib.CategoryTheory.Sites.GlobalSections

/-!
# Local sites
A site (C,J) is called local if it has a terminal object whose only covering sieve is trivial -
this makes it possible to define codiscrete sheaves on it, giving its sheaf topos the structure
of a local topos. This makes them an important stepping stone to cohesive sites.

See https://ncatlab.org/nlab/show/local+site.

## Main definitions / results
* `LocalSite J`: typeclass stating that (C,J) is a local site.
* `Sheaf.codisc`: the codiscrete functor `Type w ⥤ Sheaf J (Type max v w)` defined on any
local site.
* `Sheaf.ΓCodiscAdj`: the adjunction between the global sections functor `Γ` and `Sheaf.codisc`.
* `Sheaf.fullyFaithfulCodisc`: `Sheaf.codisc` is fully faithful.
* `fullyFaithfulConstantSheaf`: on local sites, the constant sheaf functor is fully faithful.
All together this shows that for local sites `Sheaf J (Type max u v w)` forms a local topos, but
since we don't yet have local topoi this can't be stated yet.
-/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a reference where this notion of local site is used?


universe u v w

open CategoryTheory Limits Sheaf Opposite GrothendieckTopology

namespace CategoryTheory

variable {C : Type u} [Category.{v} C] (J : GrothendieckTopology C)

/-- A local site is a site that has a terminal object with only a single covering sieve. -/
class LocalSite extends HasTerminal C where

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a Prop, we usually like to use the prefix Is. This should probably go into the GrothendieckTopology namespace, so that we may write J.IsLocal, or J.IsLocalSite.

/-- The only covering sieve of the terminal object is the trivial sieve. -/
eq_top_of_mem : ∀ S ∈ J (⊤_ C), S = ⊤

/-- On a local site, every covering sieve contains every morphism from the terminal object. -/
lemma LocalSite.from_terminal_mem_of_mem [LocalSite J] {X : C} (f : ⊤_ C ⟶ X) {S : Sieve X}
(hS : S ∈ J X) : S.arrows f :=
(S.mem_iff_pullback_eq_top f).2 <| LocalSite.eq_top_of_mem _ <| J.pullback_stable f hS

/-- Every category with a terminal object becomes a local site with the trivial topology. -/
instance {C : Type u} [Category.{v} C] [HasTerminal C] : LocalSite (trivial C) where
eq_top_of_mem _ := trivial_covering.1

/-- The functor that sends any set `A` to the functor `Cᵒᵖ → Type _` that sends any `X : C`
to the set of all functions `A → (⊤_ C ⟶ X)`. This can be defined on any site with a terminal
object, but has values in sheaves in the case of local sites. -/
noncomputable def Presheaf.codisc {C : Type u} [Category.{v} C] [HasTerminal C] :
Type w ⥤ (Cᵒᵖ ⥤ Type max v w) :=
uliftFunctor ⋙ yoneda ⋙ (whiskeringLeft _ _ _).obj
(coyoneda.obj (op (⊤_ C)) ⋙ uliftFunctor).op

/-- On local sites, `Presheaf.codisc` actually takes values in sheaves. -/
lemma Presheaf.codisc_isSheaf [LocalSite J] (X : Type w) : IsSheaf J (codisc.obj X) := by
refine (isSheaf_iff_isSheaf_of_type J _).2 fun Y S hS f hf ↦ ?_
refine ⟨fun g ↦ f g.down (LocalSite.from_terminal_mem_of_mem J g.down hS) ⟨𝟙 _⟩, ?_, ?_⟩
· intro Z g hg
exact funext fun (x : ULift (_ ⟶ _)) ↦
(congrFun (f.comp_of_compatible S hf hg x.down) _).trans (congrArg (f g hg) <| by simp)
· intro g hg
exact funext fun h : ULift (⊤_ C ⟶ Y) ↦ Eq.trans (by simp [Presheaf.codisc]) <|
congrFun (hg h.down ((LocalSite.from_terminal_mem_of_mem J h.down hS))) _

/-- The right adjoint to the global sections functor that exists over any local site.
Takes a type `X` to the sheaf that sends each `Y : C` to the type of functions `Y → X`. -/
noncomputable def Sheaf.codisc [LocalSite J] :
Type w ⥤ Sheaf J (Type (max v w)) where
obj X := ⟨Presheaf.codisc.obj X, Presheaf.codisc_isSheaf J X⟩
map f := ⟨Presheaf.codisc.map f⟩
map_id _ := rfl
map_comp _ _ := rfl

/-- On local sites, the global sections functor `Γ` is left-adjoint to the codiscrete functor. -/
noncomputable def Sheaf.ΓCodiscAdj [LocalSite J] : Γ J (Type max u v w) ⊣ codisc J := by
refine Adjunction.ofNatIsoLeft ?_ (ΓNatIsoSheafSections J _ terminalIsTerminal).symm
exact Adjunction.mkOfUnitCounit {
unit := {
app X := ⟨{
app Y (x : X.val.obj Y) y := ⟨X.val.map (op y.down) x⟩
naturality Y Z f := by
ext (x : X.val.obj Y); dsimp [codisc, Presheaf.codisc]; ext z
exact (FunctorToTypes.map_comp_apply X.val _ _ x).symm
}⟩
naturality X Y f := by
ext Z (x : X.val.obj Z); dsimp [codisc, Presheaf.codisc]; ext z
exact congrFun (f.val.naturality _).symm x
}
counit := { app X := fun f : ULift (_ ⟶ _) → _ ↦ (f default).down }
left_triangle := by
ext X (x : X.val.obj _)
dsimp; convert congrFun (X.val.map_id _) x; exact Subsingleton.elim _ _
right_triangle := by
ext X Y (f : _ → _); dsimp [codisc, Presheaf.codisc]; ext y
dsimp; congr; convert Category.id_comp _; exact Subsingleton.elim _ _
}

instance [LocalSite J] : (Γ J (Type max u v w)).IsLeftAdjoint :=
⟨codisc J, ⟨ΓCodiscAdj J⟩⟩

instance [LocalSite J] : (codisc.{u,v,max u v w} J).IsRightAdjoint :=
⟨Γ J _, ⟨ΓCodiscAdj J⟩⟩

/-- The global sections of the codiscrete sheaf on a type are naturally isomorphic to that type. -/
noncomputable def Sheaf.codiscΓNatIsoId [LocalSite J] :
codisc J ⋙ Γ J _ ≅ 𝟭 (Type max u v w) := by
refine (isoWhiskerLeft _ (ΓNatIsoSheafSections J _ terminalIsTerminal)).trans ?_
exact (NatIso.ofComponents (fun X ↦ {
hom x := fun _ ↦ ⟨x⟩
inv f := (f (default : ULift (⊤_ C ⟶ ⊤_ C))).down
inv_hom_id := by
dsimp [codisc, Presheaf.codisc]; ext; dsimp
congr; exact Subsingleton.elim _ _
})).symm

/-- `Sheaf.codisc` is fully faithful. -/
noncomputable def Sheaf.fullyFaithfulCodisc [LocalSite J] :
(codisc.{u,v,max u v w} J).FullyFaithful :=
(ΓCodiscAdj J).fullyFaithfulROfCompIsoId (codiscΓNatIsoId J)

instance [LocalSite J] : (codisc.{u,v,max u v w} J).Full :=
(fullyFaithfulCodisc J).full

instance [LocalSite J] : (codisc.{u,v,max u v w} J).Faithful :=
(fullyFaithfulCodisc J).faithful

/-- On local sites, the constant sheaf functor is fully faithful. -/
noncomputable def fullyFaithfulConstantSheaf [HasWeakSheafify J (Type max u v w)] [LocalSite J] :
(constantSheaf J (Type max u v w)).FullyFaithful :=
((constantSheafΓAdj J _).fullyFaithfulEquiv (Sheaf.ΓCodiscAdj J)).symm <|
Sheaf.fullyFaithfulCodisc J

instance [HasWeakSheafify J (Type max u v w)] [LocalSite J] :
(constantSheaf J (Type max u v w)).Full :=
(fullyFaithfulConstantSheaf J).full

instance [HasWeakSheafify J (Type max u v w)] [LocalSite J] :
(constantSheaf J (Type max u v w)).Faithful :=
(fullyFaithfulConstantSheaf J).faithful

end CategoryTheory
5 changes: 5 additions & 0 deletions Mathlib/CategoryTheory/Sites/Sheaf.lean
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ def sheafToPresheaf : Sheaf J A ⥤ Cᵒᵖ ⥤ A where
/-- The sections of a sheaf (i.e. evaluation as a presheaf on `C`). -/
abbrev sheafSections : Cᵒᵖ ⥤ Sheaf J A ⥤ A := (sheafToPresheaf J A).flip

/-- The sheaf sections functor on `X` is given by evaluation of presheaves on `X`. -/
def sheafSectionsNatIsoEvaluation {X : C} :
(sheafSections J A).obj (op X) ≅ sheafToPresheaf J A ⋙ (evaluation _ _).obj (op X) :=
NatIso.ofComponents fun _ ↦ eqToIso rfl

/-- The functor `Sheaf J A ⥤ Cᵒᵖ ⥤ A` is fully faithful. -/
@[simps]
def fullyFaithfulSheafToPresheaf : (sheafToPresheaf J A).FullyFaithful where
Expand Down