File: Mathlib/CategoryTheory/Sites/Sheaf.lean

full_name: CategoryTheory.Presheaf.IsSheaf
code: /-- A sheaf of A is a presheaf P : Cᵒᵖ => A such that for every E : A, the
presheaf of types given by sending U : C to Hom_{A}(E, P U) is a sheaf of types.

https://stacks.math.columbia.edu/tag/00VR
-/
def IsSheaf (P : Cᵒᵖ ⥤ A) : Prop 
goal: Prop

full_name: CategoryTheory.Presheaf.IsSeparated
code: /-- Condition that a presheaf with values in a concrete category is separated for
a Grothendieck topology. -/
def IsSeparated (P : Cᵒᵖ ⥤ A) [ConcreteCategory A] : Prop 
goal: Prop

full_name: CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily_symm_apply_app
code: /-- Given a sieve `S` on `X : C`, a presheaf `P : Cᵒᵖ ⥤ A`, and an object `E` of `A`,
    the cones over the natural diagram `S.arrows.diagram.op ⋙ P` associated to `S` and `P`
    with cone point `E` are in 1-1 correspondence with sieve_compatible family of elements
    for the sieve `S` and the presheaf of types `Hom (E, P -)`. -/
@[simps]
def conesEquivSieveCompatibleFamily :
    (S.arrows.diagram.op ⋙ P).cones.obj E ≃
      { x : FamilyOfElements (P ⋙ coyoneda.obj E) (S : Presieve X) // x.SieveCompatible } 
goal: ((CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily P S E).symm x).app f = ↑x (Opposite.unop f).obj.hom ⋯

full_name: CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily_apply_coe
code: /-- Given a sieve `S` on `X : C`, a presheaf `P : Cᵒᵖ ⥤ A`, and an object `E` of `A`,
    the cones over the natural diagram `S.arrows.diagram.op ⋙ P` associated to `S` and `P`
    with cone point `E` are in 1-1 correspondence with sieve_compatible family of elements
    for the sieve `S` and the presheaf of types `Hom (E, P -)`. -/
@[simps]
def conesEquivSieveCompatibleFamily :
    (S.arrows.diagram.op ⋙ P).cones.obj E ≃
      { x : FamilyOfElements (P ⋙ coyoneda.obj E) (S : Presieve X) // x.SieveCompatible } 
goal: ↑((CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily P S E) π) f h =
  π.app (Opposite.op { obj := CategoryTheory.Over.mk f, property := h })

full_name: CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily
code: /-- Given a sieve `S` on `X : C`, a presheaf `P : Cᵒᵖ ⥤ A`, and an object `E` of `A`,
    the cones over the natural diagram `S.arrows.diagram.op ⋙ P` associated to `S` and `P`
    with cone point `E` are in 1-1 correspondence with sieve_compatible family of elements
    for the sieve `S` and the presheaf of types `Hom (E, P -)`. -/
@[simps]
def conesEquivSieveCompatibleFamily :
    (S.arrows.diagram.op ⋙ P).cones.obj E ≃
      { x : FamilyOfElements (P ⋙ coyoneda.obj E) (S : Presieve X) // x.SieveCompatible } 
goal: (S.arrows.diagram.op.comp P).cones.obj E ≃ { x // x.SieveCompatible }

full_name: CategoryTheory.Presieve.FamilyOfElements.SieveCompatible.cone
code: /-- The cone corresponding to a sieve_compatible family of elements, dot notation enabled. -/
@[simp]
def _root_.CategoryTheory.Presieve.FamilyOfElements.SieveCompatible.cone :
    Cone (S.arrows.diagram.op ⋙ P) 
goal: CategoryTheory.Limits.Cone (S.arrows.diagram.op.comp P)

full_name: CategoryTheory.Presheaf.homEquivAmalgamation
code: /-- Cone morphisms from the cone corresponding to a sieve_compatible family to the natural
    cone associated to a sieve `S` and a presheaf `P` are in 1-1 correspondence with amalgamations
    of the family. -/
def homEquivAmalgamation :
    (hx.cone ⟶ P.mapCone S.arrows.cocone.op) ≃ { t // x.IsAmalgamation t } 
goal: (hx.cone ⟶ P.mapCone S.arrows.cocone.op) ≃ { t // x.IsAmalgamation t }

full_name: CategoryTheory.Presheaf.isLimit_iff_isSheafFor
code: /-- Given sieve `S` and presheaf `P : Cᵒᵖ ⥤ A`, their natural associated cone is a limit cone
    iff `Hom (E, P -)` is a sheaf of types for the sieve `S` and all `E : A`. -/
theorem isLimit_iff_isSheafFor :
    Nonempty (IsLimit (P.mapCone S.arrows.cocone.op)) ↔
      ∀ E : Aᵒᵖ, IsSheafFor (P ⋙ coyoneda.obj E) S.arrows 
goal: Nonempty (CategoryTheory.Limits.IsLimit (P.mapCone S.arrows.cocone.op)) ↔
  ∀ (E : Aᵒᵖ), CategoryTheory.Presieve.IsSheafFor (P.comp (CategoryTheory.coyoneda.obj E)) S.arrows

full_name: CategoryTheory.Presheaf.subsingleton_iff_isSeparatedFor
code: /-- Given sieve `S` and presheaf `P : Cᵒᵖ ⥤ A`, their natural associated cone admits at most one
    morphism from every cone in the same category (i.e. over the same diagram),
    iff `Hom (E, P -)`is separated for the sieve `S` and all `E : A`. -/
theorem subsingleton_iff_isSeparatedFor :
    (∀ c, Subsingleton (c ⟶ P.mapCone S.arrows.cocone.op)) ↔
      ∀ E : Aᵒᵖ, IsSeparatedFor (P ⋙ coyoneda.obj E) S.arrows 
goal: (∀ (c : CategoryTheory.Limits.Cone (S.arrows.diagram.op.comp P)), Subsingleton (c ⟶ P.mapCone S.arrows.cocone.op)) ↔
  ∀ (E : Aᵒᵖ), CategoryTheory.Presieve.IsSeparatedFor (P.comp (CategoryTheory.coyoneda.obj E)) S.arrows

full_name: CategoryTheory.Presheaf.isSheaf_iff_isLimit
code: /-- A presheaf `P` is a sheaf for the Grothendieck topology `J` iff for every covering sieve
    `S` of `J`, the natural cone associated to `P` and `S` is a limit cone. -/
theorem isSheaf_iff_isLimit :
    IsSheaf J P ↔
      ∀ ⦃X : C⦄ (S : Sieve X), S ∈ J X → Nonempty (IsLimit (P.mapCone S.arrows.cocone.op)) 
goal: CategoryTheory.Presheaf.IsSheaf J P ↔
  ∀ ⦃X : C⦄, ∀ S ∈ J.sieves X, Nonempty (CategoryTheory.Limits.IsLimit (P.mapCone S.arrows.cocone.op))

full_name: CategoryTheory.Presheaf.isSeparated_iff_subsingleton
code: /-- A presheaf `P` is separated for the Grothendieck topology `J` iff for every covering sieve
    `S` of `J`, the natural cone associated to `P` and `S` admits at most one morphism from every
    cone in the same category. -/
theorem isSeparated_iff_subsingleton :
    (∀ E : A, Presieve.IsSeparated J (P ⋙ coyoneda.obj (op E))) ↔
      ∀ ⦃X : C⦄ (S : Sieve X), S ∈ J X → ∀ c, Subsingleton (c ⟶ P.mapCone S.arrows.cocone.op) 
goal: (∀ (E : A), CategoryTheory.Presieve.IsSeparated J (P.comp (CategoryTheory.coyoneda.obj (Opposite.op E)))) ↔
  ∀ ⦃X : C⦄,
    ∀ S ∈ J.sieves X,
      ∀ (c : CategoryTheory.Limits.Cone (S.arrows.diagram.op.comp P)), Subsingleton (c ⟶ P.mapCone S.arrows.cocone.op)

full_name: CategoryTheory.Presheaf.isLimit_iff_isSheafFor_presieve
code: /-- Given presieve `R` and presheaf `P : Cᵒᵖ ⥤ A`, the natural cone associated to `P` and
    the sieve `Sieve.generate R` generated by `R` is a limit cone iff `Hom (E, P -)` is a
    sheaf of types for the presieve `R` and all `E : A`. -/
theorem isLimit_iff_isSheafFor_presieve :
    Nonempty (IsLimit (P.mapCone (generate R).arrows.cocone.op)) ↔
      ∀ E : Aᵒᵖ, IsSheafFor (P ⋙ coyoneda.obj E) R 
goal: Nonempty (CategoryTheory.Limits.IsLimit (P.mapCone (CategoryTheory.Sieve.generate R).arrows.cocone.op)) ↔
  ∀ (E : Aᵒᵖ), CategoryTheory.Presieve.IsSheafFor (P.comp (CategoryTheory.coyoneda.obj E)) R

full_name: CategoryTheory.Presheaf.isSheaf_iff_isLimit_pretopology
code: /-- A presheaf `P` is a sheaf for the Grothendieck topology generated by a pretopology `K`
    iff for every covering presieve `R` of `K`, the natural cone associated to `P` and
    `Sieve.generate R` is a limit cone. -/
theorem isSheaf_iff_isLimit_pretopology [HasPullbacks C] (K : Pretopology C) :
    IsSheaf (K.toGrothendieck C) P ↔
      ∀ ⦃X : C⦄ (R : Presieve X),
        R ∈ K X → Nonempty (IsLimit (P.mapCone (generate R).arrows.cocone.op)) 
goal: CategoryTheory.Presheaf.IsSheaf (CategoryTheory.Pretopology.toGrothendieck C K) P ↔
  ∀ ⦃X : C⦄,
    ∀ R ∈ K.coverings X,
      Nonempty (CategoryTheory.Limits.IsLimit (P.mapCone (CategoryTheory.Sieve.generate R).arrows.cocone.op))

full_name: CategoryTheory.Presheaf.IsSheaf.amalgamate
code: /-- This is a wrapper around `Presieve.IsSheafFor.amalgamate` to be used below.
  If `P`s a sheaf, `S` is a cover of `X`, and `x` is a collection of morphisms from `E`
  to `P` evaluated at terms in the cover which are compatible, then we can amalgamate
  the `x`s to obtain a single morphism `E ⟶ P.obj (op X)`. -/
def IsSheaf.amalgamate {A : Type u₂} [Category.{v₂} A] {E : A} {X : C} {P : Cᵒᵖ ⥤ A}
    (hP : Presheaf.IsSheaf J P) (S : J.Cover X) (x : ∀ I : S.Arrow, E ⟶ P.obj (op I.Y))
    (hx : ∀ ⦃I₁ I₂ : S.Arrow⦄ (r : I₁.Relation I₂),
       x I₁ ≫ P.map r.g₁.op = x I₂ ≫ P.map r.g₂.op) : E ⟶ P.obj (op X) 
goal: E ⟶ P.obj (Opposite.op X)

full_name: CategoryTheory.Presheaf.IsSheaf.amalgamate_map
code: @[reassoc (attr := simp)]
theorem IsSheaf.amalgamate_map {A : Type u₂} [Category.{v₂} A] {E : A} {X : C} {P : Cᵒᵖ ⥤ A}
    (hP : Presheaf.IsSheaf J P) (S : J.Cover X) (x : ∀ I : S.Arrow, E ⟶ P.obj (op I.Y))
    (hx : ∀ ⦃I₁ I₂ : S.Arrow⦄ (r : I₁.Relation I₂),
       x I₁ ≫ P.map r.g₁.op = x I₂ ≫ P.map r.g₂.op)
    (I : S.Arrow) :
    hP.amalgamate S x hx ≫ P.map I.f.op = x _ 
goal: CategoryTheory.CategoryStruct.comp (hP.amalgamate S x hx) (P.map I.f.op) = x I

full_name: CategoryTheory.Presheaf.IsSheaf.hom_ext
code: theorem IsSheaf.hom_ext {A : Type u₂} [Category.{v₂} A] {E : A} {X : C} {P : Cᵒᵖ ⥤ A}
    (hP : Presheaf.IsSheaf J P) (S : J.Cover X) (e₁ e₂ : E ⟶ P.obj (op X))
    (h : ∀ I : S.Arrow, e₁ ≫ P.map I.f.op = e₂ ≫ P.map I.f.op) : e₁ = e₂ 
goal: e₁ = e₂

full_name: CategoryTheory.Presheaf.IsSheaf.hom_ext_ofArrows
code: lemma IsSheaf.hom_ext_ofArrows
    {P : Cᵒᵖ ⥤ A} (hP : Presheaf.IsSheaf J P) {I : Type*} {S : C} {X : I → C}
    (f : ∀ i, X i ⟶ S) (hf : Sieve.ofArrows _ f ∈ J S) {E : A}
    {x y : E ⟶ P.obj (op S)} (h : ∀ i, x ≫ P.map (f i).op = y ≫ P.map (f i).op) :
    x = y 
goal: x = y

full_name: CategoryTheory.Presheaf.IsSheaf.exists_unique_amalgamation_ofArrows
code: lemma IsSheaf.exists_unique_amalgamation_ofArrows :
    ∃! (g : E ⟶ P.obj (op S)), ∀ (i : I), g ≫ P.map (f i).op = x i 
goal: ∃! g, ∀ (i : I), CategoryTheory.CategoryStruct.comp g (P.map (f i).op) = x i

full_name: CategoryTheory.Presheaf.IsSheaf.amalgamateOfArrows
code: /-- If `P : Cᵒᵖ ⥤ A` is a sheaf and `f i : X i ⟶ S` is a covering family, then
a morphism `E ⟶ P.obj (op S)` can be constructed from a compatible family of
morphisms `x : E ⟶ P.obj (op (X i))`. -/
def IsSheaf.amalgamateOfArrows : E ⟶ P.obj (op S) 
goal: E ⟶ P.obj (Opposite.op S)

full_name: CategoryTheory.Presheaf.IsSheaf.amalgamateOfArrows_map
code: @[reassoc (attr := simp)]
lemma IsSheaf.amalgamateOfArrows_map (i : I) :
    hP.amalgamateOfArrows f hf x hx ≫ P.map (f i).op = x i 
goal: CategoryTheory.CategoryStruct.comp (hP.amalgamateOfArrows f hf x hx) (P.map (f i).op) = x i

full_name: CategoryTheory.Presheaf.isSheaf_of_iso_iff
code: theorem isSheaf_of_iso_iff {P P' : Cᵒᵖ ⥤ A} (e : P ≅ P') : IsSheaf J P ↔ IsSheaf J P' 
goal: CategoryTheory.Presheaf.IsSheaf J P ↔ CategoryTheory.Presheaf.IsSheaf J P'

full_name: CategoryTheory.Presheaf.isSheaf_of_isTerminal
code: theorem isSheaf_of_isTerminal {X : A} (hX : IsTerminal X) :
    Presheaf.IsSheaf J ((CategoryTheory.Functor.const _).obj X) 
goal: CategoryTheory.Presheaf.IsSheaf J ((CategoryTheory.Functor.const Cᵒᵖ).obj X)

full_name: CategoryTheory.Sheaf
code: /-- The category of sheaves taking values in `A` on a grothendieck topology. -/
structure Sheaf where
  /-- the underlying presheaf -/
  val : Cᵒᵖ ⥤ A
  /-- the condition that the presheaf is a sheaf -/
  cond : Presheaf.IsSheaf J val
goal: Type (max (max (max u₁ u₂) v₁) v₂)

full_name: CategoryTheory.Sheaf.cond
code: /-- The category of sheaves taking values in `A` on a grothendieck topology. -/
structure Sheaf where
  /-- the underlying presheaf -/
  val : Cᵒᵖ ⥤ A
  /-- the condition that the presheaf is a sheaf -/
  cond : Presheaf.IsSheaf J val
goal: CategoryTheory.Presheaf.IsSheaf J self.val

full_name: CategoryTheory.Sheaf.val
code: /-- The category of sheaves taking values in `A` on a grothendieck topology. -/
structure Sheaf where
  /-- the underlying presheaf -/
  val : Cᵒᵖ ⥤ A
  /-- the condition that the presheaf is a sheaf -/
  cond : Presheaf.IsSheaf J val
goal: CategoryTheory.Functor Cᵒᵖ A

full_name: CategoryTheory.Sheaf.Hom
code: /-- Morphisms between sheaves are just morphisms of presheaves. -/
@[ext]
structure Hom (X Y : Sheaf J A) where
  /-- a morphism between the underlying presheaves -/
  val : X.val ⟶ Y.val
goal: Type (max u₁ v₂)

full_name: CategoryTheory.Sheaf.Hom.val
code: /-- Morphisms between sheaves are just morphisms of presheaves. -/
@[ext]
structure Hom (X Y : Sheaf J A) where
  /-- a morphism between the underlying presheaves -/
  val : X.val ⟶ Y.val
goal: X.val ⟶ Y.val

full_name: CategoryTheory.Sheaf.instCategorySheaf
code: @[simps id_val comp_val]
instance instCategorySheaf : Category (Sheaf J A) 
goal: CategoryTheory.Category.{max u₁ v₂, max (max (max u₂ u₁) v₂) v₁} (CategoryTheory.Sheaf J A)

full_name: CategoryTheory.Sheaf.instCategorySheaf_id_val
code: @[simps id_val comp_val]
instance instCategorySheaf : Category (Sheaf J A) 
goal: ∀ (x : CategoryTheory.Sheaf J A), (CategoryTheory.CategoryStruct.id x).val = CategoryTheory.CategoryStruct.id x.val

full_name: CategoryTheory.Sheaf.instCategorySheaf_comp_val
code: @[simps id_val comp_val]
instance instCategorySheaf : Category (Sheaf J A) 
goal: ∀ {X Y Z : CategoryTheory.Sheaf J A} (f : X ⟶ Y) (g : Y ⟶ Z),
  (CategoryTheory.CategoryStruct.comp f g).val = CategoryTheory.CategoryStruct.comp f.val g.val

full_name: CategoryTheory.Sheaf.instInhabitedHom
code: instance (X : Sheaf J A) : Inhabited (Hom X X) 
goal: Inhabited (X.Hom X)

full_name: CategoryTheory.Sheaf.hom_ext
code: @[ext]
lemma hom_ext {X Y : Sheaf J A} (x y : X ⟶ Y) (h : x.val = y.val) : x = y 
goal: x = y

full_name: CategoryTheory.sheafToPresheaf_obj
code: /-- The inclusion functor from sheaves to presheaves. -/
@[simps]
def sheafToPresheaf : Sheaf J A ⥤ Cᵒᵖ ⥤ A 
goal: (CategoryTheory.sheafToPresheaf J A).obj self = self.val

full_name: CategoryTheory.sheafToPresheaf_map
code: /-- The inclusion functor from sheaves to presheaves. -/
@[simps]
def sheafToPresheaf : Sheaf J A ⥤ Cᵒᵖ ⥤ A 
goal: ∀ {X Y : CategoryTheory.Sheaf J A} (f : X ⟶ Y), (CategoryTheory.sheafToPresheaf J A).map f = f.val

full_name: CategoryTheory.sheafToPresheaf
code: /-- The inclusion functor from sheaves to presheaves. -/
@[simps]
def sheafToPresheaf : Sheaf J A ⥤ Cᵒᵖ ⥤ A 
goal: CategoryTheory.Functor (CategoryTheory.Sheaf J A) (CategoryTheory.Functor Cᵒᵖ A)

full_name: CategoryTheory.sheafSections
code: /-- The sections of a sheaf (i.e. evaluation as a presheaf on `C`). -/
abbrev sheafSections : Cᵒᵖ ⥤ Sheaf J A ⥤ A 
goal: CategoryTheory.Functor Cᵒᵖ (CategoryTheory.Functor (CategoryTheory.Sheaf J A) A)

full_name: CategoryTheory.fullyFaithfulSheafToPresheaf_preimage_val
code: /-- The functor `Sheaf J A ⥤ Cᵒᵖ ⥤ A` is fully faithful. -/
@[simps]
def fullyFaithfulSheafToPresheaf : (sheafToPresheaf J A).FullyFaithful 
goal: ∀ {X Y : CategoryTheory.Sheaf J A}
  (f : (CategoryTheory.sheafToPresheaf J A).obj X ⟶ (CategoryTheory.sheafToPresheaf J A).obj Y),
  ((CategoryTheory.fullyFaithfulSheafToPresheaf J A).preimage f).val = f

full_name: CategoryTheory.fullyFaithfulSheafToPresheaf
code: /-- The functor `Sheaf J A ⥤ Cᵒᵖ ⥤ A` is fully faithful. -/
@[simps]
def fullyFaithfulSheafToPresheaf : (sheafToPresheaf J A).FullyFaithful 
goal: (CategoryTheory.sheafToPresheaf J A).FullyFaithful

full_name: CategoryTheory.Sheaf.homEquiv
code: /-- The bijection `(X ⟶ Y) ≃ (X.val ⟶ Y.val)` when `X` and `Y` are sheaves. -/
abbrev Sheaf.homEquiv {X Y : Sheaf J A} : (X ⟶ Y) ≃ (X.val ⟶ Y.val) 
goal: (X ⟶ Y) ≃ (X.val ⟶ Y.val)

full_name: CategoryTheory.instFullSheafFunctorOppositeSheafToPresheaf
code: instance : (sheafToPresheaf J A).Full 
goal: (CategoryTheory.sheafToPresheaf J A).Full

full_name: CategoryTheory.instFaithfulSheafFunctorOppositeSheafToPresheaf
code: instance : (sheafToPresheaf J A).Faithful 
goal: (CategoryTheory.sheafToPresheaf J A).Faithful

full_name: CategoryTheory.instReflectsIsomorphismsSheafFunctorOppositeSheafToPresheaf
code: instance : (sheafToPresheaf J A).ReflectsIsomorphisms 
goal: (CategoryTheory.sheafToPresheaf J A).ReflectsIsomorphisms

full_name: CategoryTheory.Sheaf.Hom.mono_of_presheaf_mono
code: /-- This is stated as a lemma to prevent class search from forming a loop since a sheaf morphism is
monic if and only if it is monic as a presheaf morphism (under suitable assumption). -/
theorem Sheaf.Hom.mono_of_presheaf_mono {F G : Sheaf J A} (f : F ⟶ G) [h : Mono f.1] : Mono f 
goal: CategoryTheory.Mono f

full_name: CategoryTheory.Sheaf.Hom.epi_of_presheaf_epi
code: instance Sheaf.Hom.epi_of_presheaf_epi {F G : Sheaf J A} (f : F ⟶ G) [h : Epi f.1] : Epi f 
goal: CategoryTheory.Epi f

full_name: CategoryTheory.sheafOver
code: /-- The sheaf of sections guaranteed by the sheaf condition. -/
@[simps]
def sheafOver {A : Type u₂} [Category.{v₂} A] {J : GrothendieckTopology C} (ℱ : Sheaf J A) (E : A) :
    SheafOfTypes J 
goal: CategoryTheory.SheafOfTypes J

full_name: CategoryTheory.sheafOver_val
code: /-- The sheaf of sections guaranteed by the sheaf condition. -/
@[simps]
def sheafOver {A : Type u₂} [Category.{v₂} A] {J : GrothendieckTopology C} (ℱ : Sheaf J A) (E : A) :
    SheafOfTypes J 
goal: (CategoryTheory.sheafOver ℱ E).val = ℱ.val.comp (CategoryTheory.coyoneda.obj (Opposite.op E))

full_name: CategoryTheory.isSheaf_iff_isSheaf_of_type
code: theorem isSheaf_iff_isSheaf_of_type (P : Cᵒᵖ ⥤ Type w) :
    Presheaf.IsSheaf J P ↔ Presieve.IsSheaf J P 
goal: CategoryTheory.Presheaf.IsSheaf J P ↔ CategoryTheory.Presieve.IsSheaf J P

full_name: CategoryTheory.Presheaf.IsSheaf.isSheafFor
code: lemma Presheaf.IsSheaf.isSheafFor {P : Cᵒᵖ ⥤ Type w} (hP : Presheaf.IsSheaf J P)
    {X : C} (S : Sieve X) (hS : S ∈ J X) : Presieve.IsSheafFor P S.arrows 
goal: CategoryTheory.Presieve.IsSheafFor P S.arrows

full_name: CategoryTheory.sheafEquivSheafOfTypes_unitIso
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: (CategoryTheory.sheafEquivSheafOfTypes J).unitIso =
  CategoryTheory.NatIso.ofComponents
    (fun X => CategoryTheory.Iso.refl ((CategoryTheory.Functor.id (CategoryTheory.Sheaf J (Type w))).obj X)) ⋯

full_name: CategoryTheory.sheafEquivSheafOfTypes_counitIso
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: (CategoryTheory.sheafEquivSheafOfTypes J).counitIso =
  CategoryTheory.NatIso.ofComponents
    (fun X =>
      CategoryTheory.Iso.refl
        (({ obj := fun S => { val := S.val, cond := ⋯ }, map := fun {X Y} f => { val := f.val }, map_id := ⋯,
                  map_comp := ⋯ }.comp
              { obj := fun S => { val := S.val, cond := ⋯ }, map := fun {X Y} f => { val := f.val }, map_id := ⋯,
                map_comp := ⋯ }).obj
          X))
    ⋯

full_name: CategoryTheory.sheafEquivSheafOfTypes_functor_obj_val
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: ((CategoryTheory.sheafEquivSheafOfTypes J).functor.obj S).val = S.val

full_name: CategoryTheory.sheafEquivSheafOfTypes_inverse_map_val
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: ∀ {X Y : CategoryTheory.SheafOfTypes J} (f : X ⟶ Y),
  ((CategoryTheory.sheafEquivSheafOfTypes J).inverse.map f).val = f.val

full_name: CategoryTheory.sheafEquivSheafOfTypes
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: CategoryTheory.Sheaf J (Type w) ≌ CategoryTheory.SheafOfTypes J

full_name: CategoryTheory.sheafEquivSheafOfTypes_functor_map_val
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: ∀ {X Y : CategoryTheory.Sheaf J (Type w)} (f : X ⟶ Y),
  ((CategoryTheory.sheafEquivSheafOfTypes J).functor.map f).val = f.val

full_name: CategoryTheory.sheafEquivSheafOfTypes_inverse_obj_val
code: /-- The category of sheaves taking values in Type is the same as the category of set-valued sheaves.
-/
@[simps]
def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J 
goal: ((CategoryTheory.sheafEquivSheafOfTypes J).inverse.obj S).val = S.val

full_name: CategoryTheory.instInhabitedSheafBotGrothendieckTopologyType
code: instance : Inhabited (Sheaf (⊥ : GrothendieckTopology C) (Type w)) 
goal: Inhabited (CategoryTheory.Sheaf ⊥ (Type w))

full_name: CategoryTheory.Sheaf.isTerminalOfBotCover
code: /-- If the empty sieve is a cover of `X`, then `F(X)` is terminal. -/
def Sheaf.isTerminalOfBotCover (F : Sheaf J A) (X : C) (H : ⊥ ∈ J X) :
    IsTerminal (F.1.obj (op X)) 
goal: CategoryTheory.Limits.IsTerminal (F.val.obj (Opposite.op X))

full_name: CategoryTheory.sheafHomHasZSMul
code: instance sheafHomHasZSMul : SMul ℤ (P ⟶ Q) 
goal: SMul ℤ (P ⟶ Q)

full_name: CategoryTheory.instSubHomSheaf
code: instance : Sub (P ⟶ Q) 
goal: Sub (P ⟶ Q)

full_name: CategoryTheory.instNegHomSheaf
code: instance : Neg (P ⟶ Q) 
goal: Neg (P ⟶ Q)

full_name: CategoryTheory.sheafHomHasNSMul
code: instance sheafHomHasNSMul : SMul ℕ (P ⟶ Q) 
goal: SMul ℕ (P ⟶ Q)

full_name: CategoryTheory.instZeroHomSheaf
code: instance : Zero (P ⟶ Q) 
goal: Zero (P ⟶ Q)

full_name: CategoryTheory.instAddHomSheaf
code: instance : Add (P ⟶ Q) 
goal: Add (P ⟶ Q)

full_name: CategoryTheory.Sheaf.Hom.add_app
code: @[simp]
theorem Sheaf.Hom.add_app (f g : P ⟶ Q) (U) : (f + g).1.app U = f.1.app U + g.1.app U 
goal: (f + g).val.app U = f.val.app U + g.val.app U

full_name: CategoryTheory.Sheaf.Hom.addCommGroup
code: instance Sheaf.Hom.addCommGroup : AddCommGroup (P ⟶ Q) 
goal: AddCommGroup (P ⟶ Q)

full_name: CategoryTheory.instPreadditiveSheaf
code: instance : Preadditive (Sheaf J A) 
goal: CategoryTheory.Preadditive (CategoryTheory.Sheaf J A)

full_name: CategoryTheory.Presheaf.isLimitOfIsSheaf
code: /-- When `P` is a sheaf and `S` is a cover, the associated multifork is a limit. -/
def isLimitOfIsSheaf {X : C} (S : J.Cover X) (hP : IsSheaf J P) : IsLimit (S.multifork P) 
goal: CategoryTheory.Limits.IsLimit (S.multifork P)

full_name: CategoryTheory.Presheaf.isSheaf_iff_multifork
code: theorem isSheaf_iff_multifork :
    IsSheaf J P ↔ ∀ (X : C) (S : J.Cover X), Nonempty (IsLimit (S.multifork P)) 
goal: CategoryTheory.Presheaf.IsSheaf J P ↔
  ∀ (X : C) (S : J.Cover X), Nonempty (CategoryTheory.Limits.IsLimit (S.multifork P))

full_name: CategoryTheory.Presheaf.IsSheaf.isLimitMultifork
code: /-- If `F : Cᵒᵖ ⥤ A` is a sheaf for a Grothendieck topology `J` on `C`,
and `S` is a cover of `X : C`, then the multifork `S.multifork F` is limit. -/
def IsSheaf.isLimitMultifork
    (hP : Presheaf.IsSheaf J P) {X : C} (S : J.Cover X) : IsLimit (S.multifork P) 
goal: CategoryTheory.Limits.IsLimit (S.multifork P)

full_name: CategoryTheory.Presheaf.isSheaf_iff_multiequalizer
code: theorem isSheaf_iff_multiequalizer [∀ (X : C) (S : J.Cover X), HasMultiequalizer (S.index P)] :
    IsSheaf J P ↔ ∀ (X : C) (S : J.Cover X), IsIso (S.toMultiequalizer P) 
goal: CategoryTheory.Presheaf.IsSheaf J P ↔ ∀ (X : C) (S : J.Cover X), CategoryTheory.IsIso (S.toMultiequalizer P)

full_name: CategoryTheory.Presheaf.firstObj
code: /--
The middle object of the fork diagram given in Equation (3) of [MM92], as well as the fork diagram
of <https://stacks.math.columbia.edu/tag/00VM>.
-/
def firstObj : A 
goal: A

full_name: CategoryTheory.Presheaf.forkMap
code: /--
The left morphism of the fork diagram given in Equation (3) of [MM92], as well as the fork diagram
of <https://stacks.math.columbia.edu/tag/00VM>.
-/
def forkMap : P.obj (op U) ⟶ firstObj R P 
goal: P.obj (Opposite.op U) ⟶ CategoryTheory.Presheaf.firstObj R P

full_name: CategoryTheory.Presheaf.secondObj
code: /-- The rightmost object of the fork diagram of https://stacks.math.columbia.edu/tag/00VM, which
contains the data used to check a family of elements for a presieve is compatible.
-/
def secondObj : A 
goal: A

full_name: CategoryTheory.Presheaf.firstMap
code: /-- The map `pr₀*` of <https://stacks.math.columbia.edu/tag/00VM>. -/
def firstMap : firstObj R P ⟶ secondObj R P 
goal: CategoryTheory.Presheaf.firstObj R P ⟶ CategoryTheory.Presheaf.secondObj R P

full_name: CategoryTheory.Presheaf.secondMap
code: /-- The map `pr₁*` of <https://stacks.math.columbia.edu/tag/00VM>. -/
def secondMap : firstObj R P ⟶ secondObj R P 
goal: CategoryTheory.Presheaf.firstObj R P ⟶ CategoryTheory.Presheaf.secondObj R P

full_name: CategoryTheory.Presheaf.w
code: theorem w : forkMap R P ≫ firstMap R P = forkMap R P ≫ secondMap R P 
goal: CategoryTheory.CategoryStruct.comp (CategoryTheory.Presheaf.forkMap R P) (CategoryTheory.Presheaf.firstMap R P) =
  CategoryTheory.CategoryStruct.comp (CategoryTheory.Presheaf.forkMap R P) (CategoryTheory.Presheaf.secondMap R P)

full_name: CategoryTheory.Presheaf.IsSheaf'
code: /-- An alternative definition of the sheaf condition in terms of equalizers. This is shown to be
equivalent in `CategoryTheory.Presheaf.isSheaf_iff_isSheaf'`.
-/
def IsSheaf' (P : Cᵒᵖ ⥤ A) : Prop 
goal: Prop

full_name: CategoryTheory.Presheaf.isSheafForIsSheafFor'
code: /-- (Implementation). An auxiliary lemma to convert between sheaf conditions. -/
def isSheafForIsSheafFor' (P : Cᵒᵖ ⥤ A) (s : A ⥤ Type max v₁ u₁)
    [∀ J, PreservesLimitsOfShape (Discrete.{max v₁ u₁} J) s] (U : C) (R : Presieve U) :
    IsLimit (s.mapCone (Fork.ofι _ (w R P))) ≃
      IsLimit (Fork.ofι _ (Equalizer.Presieve.w (P ⋙ s) R)) 
goal: CategoryTheory.Limits.IsLimit (s.mapCone (CategoryTheory.Limits.Fork.ofι (CategoryTheory.Presheaf.forkMap R P) ⋯)) ≃
  CategoryTheory.Limits.IsLimit (CategoryTheory.Limits.Fork.ofι (CategoryTheory.Equalizer.forkMap (P.comp s) R) ⋯)

full_name: CategoryTheory.Presheaf.isSheaf_iff_isSheaf'
code: /-- The equalizer definition of a sheaf given by `isSheaf'` is equivalent to `isSheaf`. -/
theorem isSheaf_iff_isSheaf' : IsSheaf J P' ↔ IsSheaf' J P' 
goal: CategoryTheory.Presheaf.IsSheaf J P' ↔ CategoryTheory.Presheaf.IsSheaf' J P'

full_name: CategoryTheory.Presheaf.isSheaf_of_isSheaf_comp
code: theorem isSheaf_of_isSheaf_comp (s : A ⥤ B) [ReflectsLimitsOfSize.{v₁, max v₁ u₁} s]
    (h : IsSheaf J (P ⋙ s)) : IsSheaf J P 
goal: CategoryTheory.Presheaf.IsSheaf J P

full_name: CategoryTheory.Presheaf.isSheaf_comp_of_isSheaf
code: theorem isSheaf_comp_of_isSheaf (s : A ⥤ B) [PreservesLimitsOfSize.{v₁, max v₁ u₁} s]
    (h : IsSheaf J P) : IsSheaf J (P ⋙ s) 
goal: CategoryTheory.Presheaf.IsSheaf J (P.comp s)

full_name: CategoryTheory.Presheaf.isSheaf_iff_isSheaf_comp
code: theorem isSheaf_iff_isSheaf_comp (s : A ⥤ B) [HasLimitsOfSize.{v₁, max v₁ u₁} A]
    [PreservesLimitsOfSize.{v₁, max v₁ u₁} s] [s.ReflectsIsomorphisms] :
    IsSheaf J P ↔ IsSheaf J (P ⋙ s) 
goal: CategoryTheory.Presheaf.IsSheaf J P ↔ CategoryTheory.Presheaf.IsSheaf J (P.comp s)

full_name: CategoryTheory.Presheaf.isSheaf_iff_isSheaf_forget
code: /--
For a concrete category `(A, s)` where the forgetful functor `s : A ⥤ Type v` preserves limits and
reflects isomorphisms, and `A` has limits, an `A`-valued presheaf `P : Cᵒᵖ ⥤ A` is a sheaf iff its
underlying `Type`-valued presheaf `P ⋙ s : Cᵒᵖ ⥤ Type` is a sheaf.

Note this lemma applies for "algebraic" categories, eg groups, abelian groups and rings, but not
for the category of topological spaces, topological rings, etc since reflecting isomorphisms doesn't
hold.
-/
theorem isSheaf_iff_isSheaf_forget (s : A' ⥤ Type max v₁ u₁) [HasLimits A'] [PreservesLimits s]
    [s.ReflectsIsomorphisms] : IsSheaf J P' ↔ IsSheaf J (P' ⋙ s) 
goal: CategoryTheory.Presheaf.IsSheaf J P' ↔ CategoryTheory.Presheaf.IsSheaf J (P'.comp s)