Skip to content

Commit 307e9f2

Browse files
joelrioukim-em
authored andcommitted
feat(CategoryTheory/Sites): relation between IsPrestack and the full faithfulness of toDescentData (leanprover-community#33179)
We show that a pseudofunctor `F` is a prestack iff the functors `F.toDescentData f` are fully faithful whenever `f` is a covering family. We also introduce predicates `F.IsPrestackFor R` and `F.IsStackFor R` (for a presieve `R`) saying the corresponding functor `F.DescentData (fun (f : R.category) ↦ f.obj.hom)` is fully faithful or an equivalence.
1 parent a8bc6bd commit 307e9f2

File tree

4 files changed

+275
-3
lines changed

4 files changed

+275
-3
lines changed

Mathlib/CategoryTheory/Comma/Over/Basic.lean

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ lemma forall_iff (P : Over X → Prop) :
131131
(∀ Y, P Y) ↔ (∀ (Y) (f : Y ⟶ X), P (.mk f)) := by
132132
aesop
133133

134+
lemma mk_surjective {S : T} (X : Over S) :
135+
∃ (Y : T) (f : Y ⟶ S), Over.mk f = X :=
136+
⟨_, X.hom, rfl⟩
137+
138+
lemma homMk_surjective
139+
{S : T} {X Y : Over S} (f : X ⟶ Y) :
140+
∃ (g : X.left ⟶ Y.left) (hg : g ≫ Y.hom = X.hom), f = Over.homMk g :=
141+
⟨f.left, by simp⟩
142+
134143
section
135144

136145
variable (X)
@@ -592,6 +601,15 @@ lemma forall_iff (P : Under X → Prop) :
592601
(∀ Y, P Y) ↔ (∀ (Y) (f : X ⟶ Y), P (.mk f)) := by
593602
aesop
594603

604+
lemma mk_surjective {S : T} (X : Under S) :
605+
∃ (Y : T) (f : S ⟶ Y), Under.mk f = X :=
606+
⟨_, X.hom, rfl⟩
607+
608+
lemma homMk_surjective
609+
{S : T} {X Y : Under S} (f : X ⟶ Y) :
610+
∃ (g : X.right ⟶ Y.right) (hg : X.hom ≫ g = Y.hom), Under.homMk g = f :=
611+
⟨f.right, by simp⟩
612+
595613
section
596614

597615
variable (X)

Mathlib/CategoryTheory/Functor/FullyFaithful.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,21 @@ def isoEquiv {X Y : C} : (X ≅ Y) ≃ (F.obj X ≅ F.obj Y) where
217217
def comp {G : D ⥤ E} (hG : G.FullyFaithful) : (F ⋙ G).FullyFaithful where
218218
preimage f := hF.preimage (hG.preimage f)
219219

220+
/-- If `F` is fully faithful and `F ≅ G`, then `G` is fully faithful. -/
221+
def ofIso {G : C ⥤ D} (e : F ≅ G) : G.FullyFaithful where
222+
preimage f := hF.preimage (e.hom.app _ ≫ f ≫ e.inv.app _)
223+
map_preimage f := by simp [← NatIso.naturality_1 e]
224+
220225
end
221226

227+
variable (F) in
228+
lemma nonempty_iff_map_bijective :
229+
Nonempty F.FullyFaithful ↔ ∀ (X Y : C), Function.Bijective (F.map : (X ⟶ Y) → _) :=
230+
fun ⟨hF⟩ ↦ hF.map_bijective, fun hF ↦ by
231+
have : F.Faithful := ⟨fun h ↦ (hF _ _).injective h⟩
232+
have : F.Full := ⟨(hF _ _).surjective⟩
233+
exact ⟨.ofFullyFaithful _⟩⟩
234+
222235
/-- If `F ⋙ G` is fully faithful and `G` is faithful, then `F` is fully faithful. -/
223236
def ofCompFaithful {G : D ⥤ E} [G.Faithful] (hFG : (F ⋙ G).FullyFaithful) :
224237
F.FullyFaithful where

Mathlib/CategoryTheory/Sites/Descent/DescentData.lean

Lines changed: 235 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@ when we replace `S` by an isomorphic object, or the family `f i : X i ⟶ S`
2020
by another family which generates the same sieve
2121
(see `Pseudofunctor.DescentData.pullFunctorEquivalence`).
2222
23+
Given a presieve `R`, we introduce predicates `F.IsPrestackFor R` and `F.IsStackFor R`
24+
saying the functor `F.DescentData (fun (f : R.category) ↦ f.obj.hom)` attached
25+
to `R` is respectively fully faithful or an equivalence. We show that
26+
`F` satisfies `F.IsPrestack J` for a Grothendieck topology `J` iff it
27+
satisfies `F.IsPrestackFor R.arrows` for all covering sieves `R`.
28+
2329
## TODO (@joelriou, @chrisflav)
24-
* Relate the prestack condition to the fully faithfullness of `Pseudofunctor.toDescentData`.
2530
* Define stacks.
2631
* Introduce multiple variants of `DescentData` (when `C` has pullbacks,
2732
when `F` also has a covariant functoriality, etc.).
@@ -379,8 +384,237 @@ def pullFunctorEquivalence {S' : C} {ι' : Type t'} {X' : ι' → C} {f' : ∀ j
379384
Cat.Hom.inv_hom_id_toNatTrans_app]
380385
simp [D.hom_self _ _ rfl]
381386

387+
lemma exists_equivalence_of_sieve_eq
388+
{ι' : Type t'} {X' : ι' → C} (f' : ∀ i', X' i' ⟶ S)
389+
(h : Sieve.ofArrows _ f = Sieve.ofArrows _ f') :
390+
∃ (e : F.DescentData f ≌ F.DescentData f'),
391+
Nonempty (F.toDescentData f ⋙ e.functor ≅ F.toDescentData f') := by
392+
have h₁ (i' : ι') : ∃ (i : ι) (g' : X' i' ⟶ X i), g' ≫ f i = f' i' := by
393+
obtain ⟨_, _, _, ⟨i⟩, fac⟩ : Sieve.ofArrows X f (f' i') := by
394+
rw [h]; apply Sieve.ofArrows_mk
395+
exact ⟨i, _, fac⟩
396+
have h₂ (i : ι) : ∃ (i' : ι') (g : X i ⟶ X' i'), g ≫ f' i' = f i := by
397+
obtain ⟨_, _, _, ⟨i'⟩, fac⟩ : Sieve.ofArrows X' f' (f i) := by
398+
rw [← h]; apply Sieve.ofArrows_mk
399+
exact ⟨i', _, fac⟩
400+
choose α p' w using h₁
401+
choose β q' w' using h₂
402+
exact ⟨pullFunctorEquivalence (p' := p') (q' := q') F (Iso.refl _)
403+
(by cat_disch) (by cat_disch), ⟨toDescentDataCompPullFunctorIso _ _ ≪≫
404+
Functor.isoWhiskerRight (Cat.Hom.toNatIso (F.mapId _)) _ ≪≫ Functor.leftUnitor _⟩⟩
405+
406+
lemma nonempty_fullyFaithful_toDescentData_iff_of_sieve_eq
407+
{ι : Type t} {S : C} {X : ι → C} (f : ∀ i, X i ⟶ S)
408+
{ι' : Type t'} {X' : ι' → C} (f' : ∀ i', X' i' ⟶ S)
409+
(h : Sieve.ofArrows _ f = Sieve.ofArrows _ f') :
410+
Nonempty (F.toDescentData f).FullyFaithful ↔
411+
Nonempty (F.toDescentData f').FullyFaithful := by
412+
obtain ⟨e, ⟨iso⟩⟩ := DescentData.exists_equivalence_of_sieve_eq F f f' h
413+
exact ⟨fun ⟨h⟩ ↦ ⟨(h.comp e.fullyFaithfulFunctor).ofIso iso⟩,
414+
fun ⟨h⟩ ↦ ⟨(h.comp e.fullyFaithfulInverse).ofIso iso.symm.compInverseIso⟩⟩
415+
416+
lemma isEquivalence_toDescentData_iff_of_sieve_eq
417+
{ι : Type t} {S : C} {X : ι → C} (f : ∀ i, X i ⟶ S)
418+
{ι' : Type t'} {X' : ι' → C} (f' : ∀ i', X' i' ⟶ S)
419+
(h : Sieve.ofArrows _ f = Sieve.ofArrows _ f') :
420+
(F.toDescentData f).IsEquivalence ↔ (F.toDescentData f').IsEquivalence := by
421+
obtain ⟨e, ⟨iso⟩⟩ := DescentData.exists_equivalence_of_sieve_eq F f f' h
422+
rw [← Functor.isEquivalence_iff_of_iso iso]
423+
exact ⟨fun _ ↦ inferInstance,
424+
fun _ ↦ Functor.isEquivalence_of_comp_right _ e.functor⟩
425+
426+
/-- Morphisms between objects in the image of the functor `F.toDescentData f`
427+
identify to compatible families of sections of the presheaf `F.presheafHom M N` on
428+
the object `Over.mk (𝟙 S)`, relatively to the family of morphisms in `Over S`
429+
corresponding to the family `f`. -/
430+
def subtypeCompatibleHomEquiv {M N : F.obj (.mk (op S))} :
431+
Subtype (Presieve.Arrows.Compatible (F.presheafHom M N)
432+
(X := fun i ↦ Over.mk (f i)) (B := Over.mk (𝟙 S)) (fun i ↦ Over.homMk (f i))) ≃
433+
((F.toDescentData f).obj M ⟶ (F.toDescentData f).obj N) where
434+
toFun φ :=
435+
{ hom := φ.val
436+
comm Y q i₁ i₂ f₁ f₂ hf₁ hf₂ := by
437+
have := φ.property i₁ i₂ (Over.mk q) (Over.homMk f₁) (Over.homMk f₂) (by cat_disch)
438+
simp_all [map_eq_pullHom] }
439+
invFun g :=
440+
{ val := g.hom
441+
property i₁ i₂ Z f₁ f₂ h := by
442+
simpa [map_eq_pullHom (g.hom i₁) f₁.left Z.hom Z.hom (Over.w f₁) (Over.w f₁),
443+
map_eq_pullHom (g.hom i₂) f₂.left Z.hom Z.hom (Over.w f₂) (Over.w f₂),
444+
cancel_epi, cancel_mono] using g.comm Z.hom f₁.left f₂.left (Over.w f₁) (Over.w f₂) }
445+
446+
lemma subtypeCompatibleHomEquiv_toCompatible_presheafHomObjHomEquiv
447+
{M N : F.obj (.mk (op S))} (φ : M ⟶ N) :
448+
subtypeCompatibleHomEquiv F f (Presieve.Arrows.toCompatible _ _
449+
(F.presheafHomObjHomEquiv φ)) = (F.toDescentData f).map φ := by
450+
ext i
451+
simp [subtypeCompatibleHomEquiv, presheafHomObjHomEquiv, pullHom,
452+
← Functor.map_comp, Pseudofunctor.mapComp'_id_comp_hom_app_assoc,
453+
Pseudofunctor.mapComp'_id_comp_inv_app]
454+
382455
end DescentData
383456

457+
/-- The condition that a pseudofunctor satisfies the descent of morphisms
458+
relative to a presieve. -/
459+
@[mk_iff]
460+
structure IsPrestackFor (R : Presieve S) : Prop where
461+
nonempty_fullyFaithful :
462+
Nonempty (F.toDescentData (fun (f : R.category) ↦ f.obj.hom)).FullyFaithful
463+
464+
variable {F} in
465+
/-- If `R` is a presieve such that `F.IsPrestackFor R`, then the functor
466+
`F.toDescentData (fun (f : R.category) ↦ f.obj.hom)` is fully faithful. -/
467+
noncomputable def IsPrestackFor.fullyFaithful {R : Presieve S} (hF : F.IsPrestackFor R) :
468+
(F.toDescentData (fun (f : R.category) ↦ f.obj.hom)).FullyFaithful :=
469+
hF.nonempty_fullyFaithful.some
470+
471+
lemma isPrestackFor_iff_of_sieve_eq
472+
{R R' : Presieve S} (h : Sieve.generate R = Sieve.generate R') :
473+
F.IsPrestackFor R ↔ F.IsPrestackFor R' := by
474+
simp only [isPrestackFor_iff]
475+
obtain ⟨_, _, f, rfl⟩ := Presieve.exists_eq_ofArrows R
476+
obtain ⟨_, _, f', rfl⟩ := Presieve.exists_eq_ofArrows R'
477+
apply DescentData.nonempty_fullyFaithful_toDescentData_iff_of_sieve_eq
478+
simpa only [Sieve.ofArrows_category']
479+
480+
@[simp]
481+
lemma IsPrestackFor_generate_iff (R : Presieve S) :
482+
F.IsPrestackFor (Sieve.generate R).arrows ↔ F.IsPrestackFor R :=
483+
F.isPrestackFor_iff_of_sieve_eq (by simp)
484+
485+
lemma isPrestackFor_ofArrows_iff :
486+
F.IsPrestackFor (Presieve.ofArrows _ f) ↔
487+
Nonempty (F.toDescentData f).FullyFaithful := by
488+
simp only [isPrestackFor_iff]
489+
apply DescentData.nonempty_fullyFaithful_toDescentData_iff_of_sieve_eq
490+
rw [Sieve.ofArrows_category']
491+
492+
/-- The condition that a pseudofunctor has effective descent
493+
relative to a presieve. -/
494+
@[mk_iff]
495+
structure IsStackFor (R : Presieve S) : Prop where
496+
isEquivalence :
497+
(F.toDescentData (fun (f : R.category) ↦ f.obj.hom)).IsEquivalence
498+
499+
variable {F} in
500+
lemma IsStackFor.isPrestackFor {R : Presieve S} (h : F.IsStackFor R) :
501+
F.IsPrestackFor R where
502+
nonempty_fullyFaithful := ⟨by
503+
rw [isStackFor_iff] at h
504+
exact .ofFullyFaithful _⟩
505+
506+
lemma isStackFor_iff_of_sieve_eq
507+
{R R' : Presieve S} (h : Sieve.generate R = Sieve.generate R') :
508+
F.IsStackFor R ↔ F.IsStackFor R' := by
509+
simp only [isStackFor_iff]
510+
obtain ⟨_, _, f, rfl⟩ := Presieve.exists_eq_ofArrows R
511+
obtain ⟨_, _, f', rfl⟩ := Presieve.exists_eq_ofArrows R'
512+
apply DescentData.isEquivalence_toDescentData_iff_of_sieve_eq
513+
simpa only [Sieve.ofArrows_category']
514+
515+
@[simp]
516+
lemma IsStackFor_generate_iff (R : Presieve S) :
517+
F.IsStackFor (Sieve.generate R).arrows ↔ F.IsStackFor R :=
518+
F.isStackFor_iff_of_sieve_eq (by simp)
519+
520+
lemma isStackFor_ofArrows_iff :
521+
F.IsStackFor (Presieve.ofArrows _ f) ↔
522+
(F.toDescentData f).IsEquivalence := by
523+
simp only [isStackFor_iff]
524+
apply DescentData.isEquivalence_toDescentData_iff_of_sieve_eq
525+
rw [Sieve.ofArrows_category']
526+
527+
variable {F} in
528+
lemma bijective_toDescentData_map_iff (M N : F.obj (.mk (op S))) :
529+
Function.Bijective ((F.toDescentData f).map : (M ⟶ N) → _) ↔
530+
Presieve.IsSheafFor (F.presheafHom M N) (X := Over.mk (𝟙 S))
531+
(Presieve.ofArrows (Y := fun i ↦ Over.mk (f i)) (fun i ↦ Over.homMk (f i))) := by
532+
rw [Presieve.isSheafFor_ofArrows_iff_bijective_toCompabible,
533+
← (DescentData.subtypeCompatibleHomEquiv F f).bijective.of_comp_iff',
534+
← Function.Bijective.of_comp_iff _ (presheafHomObjHomEquiv F).bijective]
535+
convert Iff.rfl
536+
ext φ : 1
537+
apply DescentData.subtypeCompatibleHomEquiv_toCompatible_presheafHomObjHomEquiv
538+
539+
lemma isPrestackFor_iff_isSheafFor {S : C} (R : Sieve S) :
540+
F.IsPrestackFor R.arrows ↔ ∀ (M N : F.obj (.mk (op S))),
541+
Presieve.IsSheafFor (P := F.presheafHom M N)
542+
((Sieve.overEquiv (Over.mk (𝟙 S))).symm R).arrows := by
543+
rw [isPrestackFor_iff, Functor.FullyFaithful.nonempty_iff_map_bijective]
544+
refine forall_congr' (fun M ↦ forall_congr' (fun N ↦ ?_))
545+
rw [bijective_toDescentData_map_iff]
546+
convert Iff.rfl
547+
refine le_antisymm ?_ ?_
548+
· rintro X f (hf : R.arrows f.left)
549+
obtain ⟨X, g, rfl⟩ := Over.mk_surjective X
550+
obtain rfl : f = Over.homMk g := by ext; simpa using Over.w f
551+
exact Presieve.ofArrows.mk (ι := R.arrows.category) ⟨Over.mk g, hf⟩
552+
· rintro _ _ ⟨_, h⟩
553+
exact h
554+
555+
lemma isPrestackFor_iff_isSheafFor' {S : C} (R : Sieve S) :
556+
F.IsPrestackFor R.arrows ↔ ∀ ⦃S₀ : C⦄ (M N : F.obj (.mk (op S₀))) (a : S ⟶ S₀),
557+
Presieve.IsSheafFor (F.presheafHom M N) ((Sieve.overEquiv (Over.mk a)).symm R).arrows := by
558+
rw [isPrestackFor_iff_isSheafFor]
559+
refine ⟨fun h S₀ M N a ↦ ?_, by tauto⟩
560+
replace h := h ((F.map a.op.toLoc).toFunctor.obj M) ((F.map a.op.toLoc).toFunctor.obj N)
561+
rw [← Presieve.isSheafFor_iff_of_iso (F.overMapCompPresheafHomIso M N a),
562+
Presieve.isSheafFor_over_map_op_comp_iff (X' := Over.mk a)
563+
(e := Over.isoMk (Iso.refl _))] at h
564+
convert h
565+
refine le_antisymm ?_ ?_
566+
· intro Y f hf
567+
exact ⟨Over.mk f.left, Over.homMk f.left, Over.homMk (𝟙 _) (by simpa using Over.w f),
568+
hf, by cat_disch⟩
569+
· rintro X b ⟨Y, c, d, h, fac⟩
570+
replace fac := (Over.forget _).congr_map fac
571+
dsimp at fac
572+
rw [Category.comp_id] at fac
573+
change R.arrows b.left
574+
simpa [fac] using R.downward_closed h d.left
575+
576+
variable {F} in
577+
lemma IsPrestackFor.isSheafFor'
578+
{S₀ : C} (S : Over S₀) {R : Sieve S} (hF : F.IsPrestackFor (Sieve.overEquiv _ R).arrows)
579+
(M N : F.obj (.mk (op S₀))) :
580+
Presieve.IsSheafFor (F.presheafHom M N) R.arrows := by
581+
rw [isPrestackFor_iff_isSheafFor'] at hF
582+
obtain ⟨S, a, rfl⟩ := S.mk_surjective
583+
simpa using hF M N a
584+
585+
variable {J : GrothendieckTopology C}
586+
587+
/-- If `F` is a prestack for a Grothendieck topology `J`, and `f` is a covering
588+
family of morphims, then the functor `F.toDescentData f` is fully faithful. -/
589+
noncomputable def fullyFaithfulToDescentData [F.IsPrestack J] (hf : Sieve.ofArrows _ f ∈ J S) :
590+
(F.toDescentData f).FullyFaithful :=
591+
Nonempty.some (by
592+
rw [← isPrestackFor_ofArrows_iff, ← IsPrestackFor_generate_iff,
593+
isPrestackFor_iff_isSheafFor]
594+
intro M N
595+
refine ((isSheaf_iff_isSheaf_of_type _ _).1
596+
(IsPrestack.isSheaf J M N)).isSheafFor _ _ ?_
597+
rwa [GrothendieckTopology.mem_over_iff, Sieve.generate_sieve, Equiv.apply_symm_apply])
598+
599+
lemma isPrestackFor [F.IsPrestack J] {S : C} (R : Presieve S) (hR : Sieve.generate R ∈ J S) :
600+
F.IsPrestackFor R := by
601+
rw [isPrestackFor_iff]
602+
exact ⟨F.fullyFaithfulToDescentData _ (by rwa [Sieve.ofArrows_category'])⟩
603+
604+
lemma isPrestackFor' [F.IsPrestack J] {S : C} (R : Sieve S) (hR : R ∈ J S) :
605+
F.IsPrestackFor R.arrows :=
606+
F.isPrestackFor _ (by simpa)
607+
608+
variable {F} in
609+
lemma IsPrestack.of_isPrestackFor
610+
(hF : ∀ (S : C) (R : Sieve S) (_ : R ∈ J S), F.IsPrestackFor R.arrows) :
611+
F.IsPrestack J where
612+
isSheaf M N := by
613+
rw [isSheaf_iff_isSheaf_of_type]
614+
intro U S hS
615+
obtain ⟨U, u, rfl⟩ := Over.mk_surjective U
616+
apply (hF _ _ hS).isSheafFor'
617+
384618
end Pseudofunctor
385619

386620
end CategoryTheory

Mathlib/CategoryTheory/Sites/Descent/IsPrestack.lean

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ def presheafHom : (Over S)ᵒᵖ ⥤ Type v' where
131131
(F.map (.toLoc T.unop.hom.op)).toFunctor.obj N
132132
map {T₁ T₂} p f := pullHom f p.unop.left T₂.unop.hom T₂.unop.hom
133133

134+
/-- The bijection `(M ⟶ N) ≃ (F.presheafHom M N).obj (op (Over.mk (𝟙 S)))`. -/
135+
@[simps! -isSimp]
136+
def presheafHomObjHomEquiv {M N : (F.obj (.mk (op S)))} :
137+
(M ⟶ N) ≃ (F.presheafHom M N).obj (op (Over.mk (𝟙 S))) :=
138+
Iso.homCongr ((Cat.Hom.toNatIso (F.mapId (.mk (op S)))).symm.app M)
139+
((Cat.Hom.toNatIso (F.mapId (.mk (op S)))).symm.app N)
140+
134141
/-- Compatibility isomorphism of `Pseudofunctor.presheafHom` with "restrictions". -/
135142
def overMapCompPresheafHomIso {S' : C} (q : S' ⟶ S) :
136143
(Over.map q).op ⋙ F.presheafHom M N ≅
@@ -157,7 +164,7 @@ satisfies the descent property for morphisms, i.e. is a prestack.
157164
(See the terminological note in the introduction of the file `Sites.Descent.IsPrestack`.) -/
158165
@[stacks 026F "(2)"]
159166
class IsPrestack (J : GrothendieckTopology C) : Prop where
160-
isSheaf {S : C} (M N : F.obj (.mk (op S))) :
167+
isSheaf (J) {S : C} (M N : F.obj (.mk (op S))) :
161168
Presheaf.IsSheaf (J.over S) (F.presheafHom M N)
162169

163170
/-- If `F` is a prestack from `Cᵒᵖ` to `Cat` relatively to a Grothendieck topology `J`,
@@ -169,7 +176,7 @@ def sheafHom (J : GrothendieckTopology C) [F.IsPrestack J]
169176
{S : C} (M N : F.obj (.mk (op S))) :
170177
Sheaf (J.over S) (Type v') where
171178
val := F.presheafHom M N
172-
cond := IsPrestack.isSheaf _ _
179+
cond := IsPrestack.isSheaf _ _ _
173180

174181
end Pseudofunctor
175182

0 commit comments

Comments
 (0)