Skip to content

Commit 8ade642

Browse files
committed
feat(CategoryTheory/Sites): pushforward and pullback of presieves (leanprover-community#40527)
We define analogues of `Sieve.pushforward` and `Sieve.pullback` for `Presieve`s and show the Galois connection.
1 parent 8480e75 commit 8ade642

4 files changed

Lines changed: 155 additions & 4 deletions

File tree

Mathlib/CategoryTheory/Sites/CoproductSheafCondition.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ lemma Presieve.isSheafFor_sigmaDesc_iff {ι : Type*} {X : ι → C} (f : ∀ i,
8686
[∀ i, HasPullback (f i) (Cofan.IsColimit.desc hc f)]
8787
(F : Cᵒᵖ ⥤ Type*)
8888
[PreservesLimit (Discrete.functor <| fun i ↦ op (X i)) F]
89-
[PreservesLimit (Discrete.functor fun (ij : ι × ι) ↦ op (pullback (f ij.1) (f ij.2))) F] :
89+
[PreservesLimit (Discrete.functor fun (ij : ι × ι) ↦
90+
op (Limits.pullback (f ij.1) (f ij.2))) F] :
9091
Presieve.IsSheafFor F (.singleton <| Cofan.IsColimit.desc hc f) ↔
9192
Presieve.IsSheafFor F (.ofArrows X f) := by
9293
let E := PreZeroHypercover.mk _ _ f

Mathlib/CategoryTheory/Sites/Hypercover/Zero.lean

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,56 @@ lemma Hom.sieve₀_le_sieve₀ {E F : PreZeroHypercover S} (f : E.Hom F) : E.sie
377377
lemma sieve₀_eq_of_iso {E F : PreZeroHypercover S} (e : E ≅ F) : E.sieve₀ = F.sieve₀ :=
378378
le_antisymm e.hom.sieve₀_le_sieve₀ e.inv.sieve₀_le_sieve₀
379379

380+
/-- The equivalence on index types induced by an isomorphism of pre-`0`-hypercovers. -/
381+
@[simps]
382+
def equivOfIso {E F : PreZeroHypercover.{w} S} (e : E ≅ F) : E.I₀ ≃ F.I₀ where
383+
toFun := e.hom.s₀
384+
invFun := e.inv.s₀
385+
left_inv _ := by simp
386+
right_inv _ := by simp
387+
388+
lemma mem_of_iso {K : Precoverage C} [K.IsStableUnderComposition] [K.HasIsos] {X : C}
389+
{E F : PreZeroHypercover.{w} X} (e : E ≅ F) (hE : E.presieve₀ ∈ K X) :
390+
F.presieve₀ ∈ K X := by
391+
have : F.presieve₀ =
392+
Presieve.ofArrows (fun (i : Σ (_ : F.I₀), Unit) ↦ _) (fun i ↦ e.inv.h₀ i.1 ≫ E.f _) := by
393+
simp only [Hom.w₀]
394+
refine le_antisymm ?_ ?_
395+
· rw [Presieve.ofArrows_le_iff]
396+
intro i
397+
exact .mk (⟨i, ⟨⟩⟩ : Σ (_ : F.I₀), Unit)
398+
· simp [Presieve.ofArrows_le_iff]
399+
rw [this]
400+
refine K.comp_mem_coverings (fun i ↦ E.f (e.inv.s₀ i)) ?_ (fun i (k : Unit) ↦ e.inv.h₀ i) ?_
401+
· rwa [← E.presieve₀_reindex (PreZeroHypercover.equivOfIso e.symm)] at hE
402+
· intro i
403+
rw [Presieve.ofArrows_pUnit]
404+
exact K.mem_coverings_of_isIso _
405+
406+
lemma mem_iff_of_iso {K : Precoverage C} [K.IsStableUnderComposition] [K.HasIsos] {X : C}
407+
{E F : PreZeroHypercover.{w} X} (e : E ≅ F) :
408+
E.presieve₀ ∈ K X ↔ F.presieve₀ ∈ K X :=
409+
fun h ↦ PreZeroHypercover.mem_of_iso e h, fun h ↦ PreZeroHypercover.mem_of_iso e.symm h⟩
410+
411+
/-- Compose a pre-`0`-hypercover with a morphism on the right. -/
412+
@[simps]
413+
def pushforward {X Y : C} (f : X ⟶ Y) (E : PreZeroHypercover.{w} X) :
414+
PreZeroHypercover.{w} Y where
415+
I₀ := E.I₀
416+
X := E.X
417+
f i := E.f i ≫ f
418+
419+
lemma presieve₀_pushforward {X Y : C} (f : X ⟶ Y) (E : PreZeroHypercover.{w} X) :
420+
(E.pushforward f).presieve₀ = E.presieve₀.pushforward f := by
421+
simp [presieve₀, Presieve.pushforward_ofArrows, pushforward]
422+
423+
set_option backward.isDefEq.respectTransparency false in
424+
/-- Pushforward along a morphism is the same as refining the singleton pre-`0`-hypercover. -/
425+
@[simps!]
426+
def pushforwardIsoBind {X Y : C} (f : X ⟶ Y) (E : PreZeroHypercover.{w} X) :
427+
E.pushforward f ≅ (singleton f).bind fun _ ↦ E :=
428+
isoMk ((Equiv.uniqueSigma fun i ↦ E.I₀).symm) (fun _ ↦ Iso.refl _)
429+
380430
end Category
381431

382432
section Functoriality
@@ -728,6 +778,16 @@ def weaken {K L : Precoverage C} {X : C} (E : Precoverage.ZeroHypercover K X) (h
728778
__ := E
729779
mem₀ := h _ E.mem₀
730780

781+
/-- Compose a `0`-hypercover with a morphism on the right. -/
782+
@[simps toPreZeroHypercover]
783+
def pushforward [J.IsStableUnderComposition] [J.HasIsos] {X Y : C} (f : X ⟶ Y)
784+
(hf : .singleton f ∈ J _) (E : ZeroHypercover.{w} J X) :
785+
ZeroHypercover.{w} J Y where
786+
__ := E.toPreZeroHypercover.pushforward f
787+
mem₀ := by
788+
rw [PreZeroHypercover.mem_iff_of_iso (E.pushforwardIsoBind _)]
789+
exact ((ZeroHypercover.singleton f hf).bind _).mem₀
790+
731791
instance (K : Precoverage C) [K.HasPullbacks] {X Y : C} (E : K.ZeroHypercover X) (f : Y ⟶ X) :
732792
E.presieve₀.HasPullbacks f :=
733793
K.hasPullbacks_of_mem _ E.mem₀

Mathlib/CategoryTheory/Sites/IsSheafFor.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,10 +1062,10 @@ theorem isSheafFor_trans (P : Cᵒᵖ ⥤ Type*) (R S : Sieve X)
10621062
apply Presieve.isSheafFor_subsieve_aux P this
10631063
· apply isSheafFor_bind _ _ _ hR hS
10641064
intro Y f hf Z g
1065-
rw [← pullback_comp]
1065+
rw [← Sieve.pullback_comp]
10661066
apply (hS (R.downward_closed hf _)).isSeparatedFor
10671067
· intro Y f hf
1068-
have : Sieve.pullback f (Sieve.bind R fun T (k : T ⟶ X) (_ : R k) => pullback k S) =
1068+
have : Sieve.pullback f (Sieve.bind R fun T (k : T ⟶ X) (_ : R k) => Sieve.pullback k S) =
10691069
R.pullback f := by
10701070
ext Z g
10711071
constructor

Mathlib/CategoryTheory/Sites/Sieves.lean

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,82 @@ lemma bindOfArrows_ofArrows {ι : Type*} {S : C} {X : ι → C} (f : (i : ι)
295295
rintro W u ⟨i, v, ⟨j⟩⟩
296296
exact ⟨Sigma.mk i j⟩
297297

298+
/-- Compose a presieve on the right with a morphism. -/
299+
def pushforward {X Y : C} (f : X ⟶ Y) (R : Presieve X) : Presieve Y :=
300+
fun Z fg ↦ ∃ (g : Z ⟶ X), g ≫ f = fg ∧ R g
301+
302+
@[grind .]
303+
lemma pushforward_apply_comp {X Y Z : C} {f : X ⟶ Y} {R : Presieve X} {g : Z ⟶ X} (hg : R g) :
304+
R.pushforward f (g ≫ f) :=
305+
⟨g, rfl, hg⟩
306+
307+
lemma pushforward_ofArrows {ι : Type*} {U : ι → C} {X Y : C} (g : ∀ i, U i ⟶ X)
308+
(f : X ⟶ Y) : (ofArrows _ g).pushforward f = ofArrows _ (g · ≫ f) := by
309+
refine le_antisymm ?_ ?_
310+
· rintro _ _ ⟨u, rfl, ⟨i⟩⟩
311+
exact ⟨i⟩
312+
· rw [ofArrows_le_iff]
313+
intro i
314+
use g i, rfl
315+
exact ⟨i⟩
316+
317+
lemma pushforward_singleton {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) :
318+
(singleton f).pushforward g = .singleton (f ≫ g) := by
319+
rw [← ofArrows_pUnit.{_, _, 0}, pushforward_ofArrows, ofArrows_pUnit.{_, _, 0}]
320+
321+
/-- The pullback of a presieve `R` on `Y` along a morphism `f : X ⟶ Y` is the presieve on `X`
322+
given by all morphisms `g : Z ⟶ X` such that `f ≫ g` is in `R`. -/
323+
def pullback {X Y : C} (f : X ⟶ Y) (R : Presieve Y) : Presieve X :=
324+
fun _ g ↦ R (g ≫ f)
325+
326+
variable {f} in
327+
@[simp, grind =]
328+
lemma pullback_iff {R : Presieve X} {Z : C} {g : Z ⟶ Y} :
329+
R.pullback f g ↔ R (g ≫ f) :=
330+
.rfl
331+
332+
lemma pushforward_le_iff_le_pullback (R : Presieve Y) (T : Presieve X) :
333+
R.pushforward f ≤ T ↔ R ≤ T.pullback f := by
334+
refine ⟨fun hle Z g hg ↦ hle _ _ (pushforward_apply_comp hg), ?_⟩
335+
rintro hle Z - ⟨g, rfl, hg⟩
336+
exact hle _ _ hg
337+
338+
lemma galoisConnection_pushforward_pullback :
339+
GaloisConnection (pushforward f) (pullback f) :=
340+
pushforward_le_iff_le_pullback f
341+
342+
lemma monotone_pushforward : Monotone (pushforward f) :=
343+
(galoisConnection_pushforward_pullback f).monotone_l
344+
345+
lemma monotone_pullback : Monotone (pullback f) :=
346+
(galoisConnection_pushforward_pullback f).monotone_u
347+
348+
lemma pushforward_pullback_le (R : Presieve X) : (R.pullback f).pushforward f ≤ R :=
349+
(galoisConnection_pushforward_pullback f).l_u_le _
350+
351+
lemma le_pullback_pushforward (R : Presieve Y) : R ≤ (R.pushforward f).pullback f :=
352+
(galoisConnection_pushforward_pullback f).le_u_l _
353+
354+
@[simp]
355+
lemma pullback_id (R : Presieve X) : R.pullback (𝟙 X) = R := by
356+
funext
357+
simp
358+
359+
lemma pullback_comp (R : Presieve Z) (g : X ⟶ Z) :
360+
R.pullback (f ≫ g) = (R.pullback g).pullback f := by
361+
funext
362+
simp
363+
364+
@[simp]
365+
lemma pushforward_id (R : Presieve X) : R.pushforward (𝟙 X) = R := by
366+
funext
367+
simp [pushforward]
368+
369+
lemma pushforward_comp (R : Presieve Y) (g : X ⟶ Z) :
370+
R.pushforward (f ≫ g) = (R.pushforward f).pushforward g := by
371+
funext
372+
simp [pushforward]
373+
298374
/-- Given a presieve on `F(X)`, we can define a presieve on `X` by taking the preimage via `F`. -/
299375
def functorPullback (R : Presieve (F.obj X)) : Presieve X := fun _ f => R (F.map f)
300376

@@ -462,7 +538,8 @@ def uncurry : Set (Σ Y, Y ⟶ X) :=
462538
obtain ⟨rfl, h⟩ := h; subst h; constructor
463539

464540
@[simp] theorem uncurry_pullbackArrows [HasPullbacks C] {B : C} (b : B ⟶ X) :
465-
(pullbackArrows b s).uncurry = (fun f ↦ ⟨pullback f.2 b, pullback.snd _ _⟩) '' s.uncurry := by
541+
(pullbackArrows b s).uncurry =
542+
(fun f ↦ ⟨Limits.pullback f.2 b, pullback.snd _ _⟩) '' s.uncurry := by
466543
ext ⟨Z, v⟩; constructor
467544
· rintro ⟨Y, u, hu⟩; exact ⟨⟨Y, u⟩, hu, rfl⟩
468545
· rintro ⟨⟨Y, u⟩, hu, h⟩
@@ -956,6 +1033,19 @@ theorem pullbackArrows_comm {X Y : C} (f : Y ⟶ X) (R : Presieve X) [R.HasPullb
9561033
have := R.hasPullback f hk
9571034
exact ⟨_, _, _, Presieve.pullbackArrows.mk _ _ hk, pullback.lift_snd _ _ comm⟩
9581035

1036+
lemma pullback_arrows {X Y : C} (f : X ⟶ Y) (S : Sieve Y) :
1037+
(S.pullback f).arrows = S.arrows.pullback f :=
1038+
rfl
1039+
1040+
lemma pushforward_arrows {X Y : C} (f : X ⟶ Y) (S : Sieve X) :
1041+
(S.pushforward f).arrows = S.arrows.pushforward f :=
1042+
rfl
1043+
1044+
lemma generate_pushforward {X Y : C} (f : X ⟶ Y) (R : Presieve X) :
1045+
generate (R.pushforward f) = (generate R).pushforward f := by
1046+
ext
1047+
grind [generate_apply, Presieve.pushforward, pushforward_apply]
1048+
9591049
section Functor
9601050

9611051
variable {E : Type u₃} [Category.{v₃} E] (G : D ⥤ E)

0 commit comments

Comments
 (0)