Skip to content

Commit 2754e4a

Browse files
committed
feat(CategoryTheory/Sites): sheaf condition and coproducts (leanprover-community#26231)
We show that under suitable conditions, checking that a presheaf is a sheaf for a covering is equivalent to checking it on the single object covering by the coproduct.
1 parent d38b507 commit 2754e4a

File tree

5 files changed

+156
-1
lines changed

5 files changed

+156
-1
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,7 @@ public import Mathlib.CategoryTheory.Sites.CompatibleSheafification
31483148
public import Mathlib.CategoryTheory.Sites.ConcreteSheafification
31493149
public import Mathlib.CategoryTheory.Sites.ConstantSheaf
31503150
public import Mathlib.CategoryTheory.Sites.Continuous
3151+
public import Mathlib.CategoryTheory.Sites.CoproductSheafCondition
31513152
public import Mathlib.CategoryTheory.Sites.CoverLifting
31523153
public import Mathlib.CategoryTheory.Sites.CoverPreserving
31533154
public import Mathlib.CategoryTheory.Sites.Coverage

Mathlib/CategoryTheory/Limits/Shapes/Products.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,12 @@ theorem Pi.reindex_hom_π (b : β) : (Pi.reindex ε f).hom ≫ Pi.π f (ε b) =
864864
theorem Pi.reindex_inv_π (b : β) : (Pi.reindex ε f).inv ≫ Pi.π (f ∘ ε) b = Pi.π f (ε b) := by
865865
simp [Iso.inv_comp_eq]
866866

867+
variable {f} in
868+
/-- Being a limiting fan is stable under equivalences in the index type. -/
869+
def Fan.isLimitEquivOfEquiv (c : Fan f) :
870+
IsLimit c ≃ IsLimit (Fan.mk _ fun i : β ↦ c.proj (ε i)) :=
871+
IsLimit.whiskerEquivalenceEquiv (Discrete.equivalence ε)
872+
867873
end
868874

869875
section
@@ -892,6 +898,12 @@ set_option backward.isDefEq.respectTransparency false in
892898
theorem Sigma.ι_reindex_inv (b : β) :
893899
Sigma.ι f (ε b) ≫ (Sigma.reindex ε f).inv = Sigma.ι (f ∘ ε) b := by simp [Iso.comp_inv_eq]
894900

901+
variable {f} in
902+
/-- Being a colimiting cofan is stable under equivalences in the index type. -/
903+
def Cofan.isColimitEquivOfEquiv (c : Cofan f) :
904+
IsColimit c ≃ IsColimit (Cofan.mk _ fun i : β ↦ c.inj (ε i)) :=
905+
IsColimit.whiskerEquivalenceEquiv (Discrete.equivalence ε)
906+
895907
end
896908

897909
end Reindex
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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: Christian Merten
5+
-/
6+
module
7+
8+
public import Mathlib.CategoryTheory.Limits.Final
9+
public import Mathlib.CategoryTheory.Limits.VanKampen
10+
public import Mathlib.CategoryTheory.Sites.Hypercover.SheafOfTypes
11+
12+
/-!
13+
# The sheaf condition and universal coproducts
14+
15+
In this file we show that if `{ fᵢ : Yᵢ ⟶ X }` is a family of morphisms and `∐ᵢ Yᵢ` is a universal
16+
coproduct, then any presheaf `F` that preserves products is a sheaf for the single object covering
17+
`{ ∐ᵢ Yᵢ ⟶ X }` if and only if it is a sheaf for `{ fᵢ : Yᵢ ⟶ X }ᵢ`.
18+
19+
We provide both a version for a general coefficient category and one for type values presheafs.
20+
-/
21+
22+
universe w
23+
24+
@[expose] public section
25+
26+
namespace CategoryTheory
27+
28+
open Limits Opposite
29+
30+
variable {C : Type*} [Category* C] {A : Type*} [Category* A] {S : C}
31+
32+
set_option backward.isDefEq.respectTransparency false in
33+
/--
34+
Let `E` be a pre-`0`-hypercover with pairwise pullbacks. If `∐ᵢ Eᵢ` is a universal coproduct
35+
and the presheaf `F` preserves products, then the multifork associated to the single object
36+
`0`-hypercover `{ ∐ᵢ Eᵢ ⟶ S }` is exact if and only if the multifork for `E` is exact.
37+
-/
38+
noncomputable
39+
def PreZeroHypercover.isLimitSigmaOfIsColimitEquiv (E : PreZeroHypercover.{w} S)
40+
[E.HasPullbacks] {c : Cofan E.X} (hc : IsColimit c) (huniv : IsUniversalColimit c)
41+
[(E.sigmaOfIsColimit hc).HasPullbacks]
42+
[∀ i, HasPullback (E.f i) ((E.sigmaOfIsColimit hc).f PUnit.unit)]
43+
(F : Cᵒᵖ ⥤ A)
44+
[PreservesLimit (Discrete.functor fun i ↦ op (E.toPreOneHypercover.X i)) F]
45+
[PreservesLimit (Discrete.functor fun i ↦ op (E.toPreOneHypercover.Y' i)) F] :
46+
IsLimit ((E.sigmaOfIsColimit hc).toPreOneHypercover.multifork F) ≃
47+
IsLimit (E.toPreOneHypercover.multifork F) := by
48+
have : HasPullback (Cofan.IsColimit.desc hc E.f) (Cofan.IsColimit.desc hc E.f) :=
49+
inferInstanceAs <| HasPullback
50+
((E.sigmaOfIsColimit hc).f ⟨⟩) ((E.sigmaOfIsColimit hc).f ⟨⟩)
51+
let c' : Cofan E.toPreOneHypercover.Y' :=
52+
Cofan.mk
53+
((E.sigmaOfIsColimit hc).toPreOneHypercover.Y (i₁ := ⟨⟩) (i₂ := ⟨⟩) ⟨⟩)
54+
fun b ↦ pullback.map _ _ _ _ (c.inj _) (c.inj _) (𝟙 _) (by simp) (by simp)
55+
let equiv : E.toPreOneHypercover.I₁' ≃ E.I₀ × E.I₀ :=
56+
Equiv.sigmaPUnit (E.toPreOneHypercover.I₀ × E.toPreOneHypercover.I₀)
57+
have hc' : IsColimit c' := by
58+
refine (c'.isColimitEquivOfEquiv equiv.symm).symm (Nonempty.some ?_)
59+
exact IsUniversalColimit.nonempty_isColimit_prod_of_isPullback
60+
huniv huniv E.f E.f ((E.sigmaOfIsColimit hc).f ⟨⟩) ((E.sigmaOfIsColimit hc).f ⟨⟩)
61+
(fun i j ↦ .of_hasPullback _ _) (.of_hasPullback _ _) (.refl _) (by simp) (by simp)
62+
(by simp [c', equiv, Equiv.sigmaPUnit]) (by simp [c', equiv, Equiv.sigmaPUnit])
63+
refine .trans ?_ (E.toPreOneHypercover.isLimitSigmaOfIsColimitEquiv hc hc' F)
64+
apply PreOneHypercover.isLimitEquivOfIso
65+
refine PreOneHypercover.isoMk (.refl _) (fun _ ↦ .refl _) (fun _ _ ↦ .refl _)
66+
(fun _ _ _ ↦ Iso.refl _) (by cat_disch) ?_ ?_
67+
· intro ⟨⟩ ⟨⟩ k
68+
refine Cofan.IsColimit.hom_ext hc' _ _ fun k ↦ ?_
69+
congr 1
70+
exact Cofan.IsColimit.hom_ext hc' _ _ fun a ↦ by simp; simp [c']
71+
· intro ⟨⟩ ⟨⟩ k
72+
exact Cofan.IsColimit.hom_ext hc' _ _ fun a ↦ by simp; simp [c']
73+
74+
set_option backward.isDefEq.respectTransparency false in
75+
open PreZeroHypercover in
76+
/--
77+
Let `{ fᵢ : Xᵢ ⟶ S }` be a family of morphisms. If `∐ᵢ Xᵢ` is a universal coproduct
78+
and the presheaf `F` preserves products, then `F` is a sheaf for the single object covering
79+
`{ ∐ᵢ Xᵢ ⟶ S }` if and only if it is a sheaf for `{ fᵢ : Xᵢ ⟶ S }ᵢ`.
80+
-/
81+
lemma Presieve.isSheafFor_sigmaDesc_iff {ι : Type*} {X : ι → C} (f : ∀ i, X i ⟶ S)
82+
[(ofArrows X f).HasPairwisePullbacks] {c : Cofan X} (hc : IsColimit c)
83+
(hc' : IsUniversalColimit c)
84+
[HasPullback (Cofan.IsColimit.desc hc f) (Cofan.IsColimit.desc hc f)]
85+
[∀ i, HasPullback (f i) (Cofan.IsColimit.desc hc f)]
86+
(F : Cᵒᵖ ⥤ Type*)
87+
[PreservesLimit (Discrete.functor <| fun i ↦ op (X i)) F]
88+
[PreservesLimit (Discrete.functor fun (ij : ι × ι) ↦ op (pullback (f ij.1) (f ij.2))) F] :
89+
Presieve.IsSheafFor F (.singleton <| Cofan.IsColimit.desc hc f) ↔
90+
Presieve.IsSheafFor F (.ofArrows X f) := by
91+
let E := PreZeroHypercover.mk _ _ f
92+
have : (E.sigmaOfIsColimit hc).HasPullbacks :=
93+
fun i j ↦ by dsimp [sigmaOfIsColimit]; infer_instance
94+
have (i : E.I₀) : HasPullback (E.f i) ((E.sigmaOfIsColimit hc).f PUnit.unit) := by
95+
dsimp [sigmaOfIsColimit_f]; infer_instance
96+
have : PreservesLimit (Discrete.functor fun i ↦ op (E.toPreOneHypercover.X i)) F := by
97+
dsimp [E]; infer_instance
98+
have : PreservesLimit (Discrete.functor fun i ↦ op (E.toPreOneHypercover.Y' i)) F := by
99+
convert Functor.Initial.preservesLimit_of_comp (Discrete.equivalence <| .sigmaPUnit _).inverse
100+
assumption
101+
let equiv := (E.isLimitSigmaOfIsColimitEquiv hc hc' F).nonempty_congr
102+
rwa [isLimit_toPreOneHypercover_type_iff, isLimit_toPreOneHypercover_type_iff,
103+
presieve₀_sigmaOfIsColimit] at equiv
104+
105+
end CategoryTheory

Mathlib/CategoryTheory/Sites/Hypercover/SheafOfTypes.lean

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,38 @@ open Limits Opposite
3737

3838
variable {C : Type*} [Category* C]
3939

40+
namespace PreZeroHypercover
41+
42+
variable {S : C}
43+
44+
/-- If the pre-`0`-hypercover `E` has pairwise pullbacks, the sections over the multifork
45+
associated to a presheaf of types are equivalent to the compatible families on `E`. -/
46+
@[simps]
47+
def sectionsEquivOfHasPullbacks (E : PreZeroHypercover S)
48+
[E.HasPullbacks] (F : Cᵒᵖ ⥤ Type*) :
49+
(E.toPreOneHypercover.multicospanIndex F).sections ≃
50+
Subtype (Presieve.Arrows.Compatible F E.f) where
51+
toFun s :=
52+
⟨s.val, fun i j W gi gj hgij ↦ by
53+
have heq := s.property ⟨(i, j), ⟨⟩⟩
54+
dsimp at heq
55+
rw [← pullback.lift_fst _ _ hgij]
56+
conv_rhs => rw [← pullback.lift_snd _ _ hgij]
57+
rw [op_comp, Functor.map_comp, op_comp, Functor.map_comp]
58+
simp [heq]⟩
59+
invFun s := ⟨s.val, fun r ↦ s.property _ _ _ _ _ pullback.condition⟩
60+
left_inv _ := rfl
61+
right_inv _ := rfl
62+
63+
lemma isLimit_toPreOneHypercover_type_iff (E : PreZeroHypercover.{w} S) [E.HasPullbacks]
64+
(F : Cᵒᵖ ⥤ Type*) :
65+
Nonempty (IsLimit <| E.toPreOneHypercover.multifork F) ↔ E.presieve₀.IsSheafFor F := by
66+
rw [Multifork.isLimit_types_iff, Presieve.isSheafFor_ofArrows_iff_bijective_toCompabible,
67+
← Function.Bijective.of_comp_iff' (E.sectionsEquivOfHasPullbacks F).symm.bijective]
68+
rfl
69+
70+
end PreZeroHypercover
71+
4072
namespace PreOneHypercover
4173

4274
variable {X : C} {E : PreOneHypercover.{w} X} {F : Cᵒᵖ ⥤ Type*}

Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def add (E : PreZeroHypercover.{w} S) {T : C} (f : T ⟶ S) : PreZeroHypercover.
222222
simp [add, presieve₀_reindex, presieve₀_sum]
223223

224224
/-- The single object pre-`0`-hypercover obtained from taking the coproduct of the components. -/
225-
@[simps I₀ X]
225+
@[simps I₀ X, simps -isSimp f]
226226
def sigmaOfIsColimit (E : PreZeroHypercover.{w} S) {c : Cofan E.X} (hc : IsColimit c) :
227227
PreZeroHypercover.{w} S where
228228
I₀ := PUnit
@@ -235,6 +235,11 @@ lemma inj_sigmaOfIsColimit_f (E : PreZeroHypercover.{w} S) {c : Cofan E.X} (hc :
235235
c.inj i ≫ (E.sigmaOfIsColimit hc).f r = E.f i := by
236236
simp [PreZeroHypercover.sigmaOfIsColimit]
237237

238+
@[simp]
239+
lemma presieve₀_sigmaOfIsColimit (E : PreZeroHypercover.{w} S) {c : Cofan E.X} (hc : IsColimit c) :
240+
(E.sigmaOfIsColimit hc).presieve₀ = Presieve.singleton (Cofan.IsColimit.desc hc E.f) :=
241+
Presieve.ofArrows_pUnit _
242+
238243
section Category
239244

240245
variable {E : PreZeroHypercover.{w} S} {F : PreZeroHypercover.{w'} S}

0 commit comments

Comments
 (0)