|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Markus Himmel. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Markus Himmel |
| 5 | +-/ |
| 6 | +import Mathlib.CategoryTheory.Comma.Final |
| 7 | +import Mathlib.CategoryTheory.Limits.Indization.IndObject |
| 8 | + |
| 9 | +/-! |
| 10 | +# Parallel pairs of natural transformations between ind-objects |
| 11 | +
|
| 12 | +We show that if `A` and `B` are ind-objects and `f` and `g` are natural transformations between |
| 13 | +`A` and `B`, then there is a small filtered category `I` such that `A`, `B`, `f` and `g` are |
| 14 | +commonly presented by diagrams and natural transformations in `I ⥤ C`. |
| 15 | +
|
| 16 | +
|
| 17 | +## References |
| 18 | +* [M. Kashiwara, P. Schapira, *Categories and Sheaves*][Kashiwara2006], Proposition 6.1.15 (though |
| 19 | + our proof is more direct). |
| 20 | +-/ |
| 21 | + |
| 22 | +universe v₁ v₂ v₃ u₁ u₂ u₃ |
| 23 | + |
| 24 | +namespace CategoryTheory |
| 25 | + |
| 26 | +open Limits |
| 27 | + |
| 28 | +variable {C : Type u₁} [Category.{v₁} C] |
| 29 | + |
| 30 | +/-- Structure containing data exhibiting two parallel natural transformations `f` and `g` between |
| 31 | +presheaves `A` and `B` as induced by a natural transformation in a functor category exhibiting |
| 32 | +`A` and `B` as ind-objects. -/ |
| 33 | +structure IndParallelPairPresentation {A B : Cᵒᵖ ⥤ Type v₁} (f g : A ⟶ B) where |
| 34 | + /-- The indexing category. -/ |
| 35 | + I : Type v₁ |
| 36 | + /-- Category instance on the indexing category. -/ |
| 37 | + [ℐ : SmallCategory I] |
| 38 | + [hI : IsFiltered I] |
| 39 | + /-- The diagram presenting `A`. -/ |
| 40 | + F₁ : I ⥤ C |
| 41 | + /-- The diagram presenting `B`. -/ |
| 42 | + F₂ : I ⥤ C |
| 43 | + /-- The cocone on `F₁` with apex `A`. -/ |
| 44 | + ι₁ : F₁ ⋙ yoneda ⟶ (Functor.const I).obj A |
| 45 | + /-- The cocone on `F₁` with apex `A` is a colimit cocone. -/ |
| 46 | + isColimit₁ : IsColimit (Cocone.mk A ι₁) |
| 47 | + /-- The cocone on `F₂` with apex `B`. -/ |
| 48 | + ι₂ : F₂ ⋙ yoneda ⟶ (Functor.const I).obj B |
| 49 | + /-- The cocone on `F₂` with apex `B` is a colimit cocone. -/ |
| 50 | + isColimit₂ : IsColimit (Cocone.mk B ι₂) |
| 51 | + /-- The natural transformation presenting `f`. -/ |
| 52 | + φ : F₁ ⟶ F₂ |
| 53 | + /-- The natural transformation presenting `g`. -/ |
| 54 | + ψ : F₁ ⟶ F₂ |
| 55 | + /-- `f` is in fact presented by `φ`. -/ |
| 56 | + hf : f = IsColimit.map isColimit₁ (Cocone.mk B ι₂) (whiskerRight φ yoneda) |
| 57 | + /-- `g` is in fact presented by `ψ`. -/ |
| 58 | + hg : g = IsColimit.map isColimit₁ (Cocone.mk B ι₂) (whiskerRight ψ yoneda) |
| 59 | + |
| 60 | +instance {A B : Cᵒᵖ ⥤ Type v₁} {f g : A ⟶ B} (P : IndParallelPairPresentation f g) : |
| 61 | + SmallCategory P.I := P.ℐ |
| 62 | +instance {A B : Cᵒᵖ ⥤ Type v₁} {f g : A ⟶ B} (P : IndParallelPairPresentation f g) : |
| 63 | + IsFiltered P.I := P.hI |
| 64 | + |
| 65 | +namespace NonemptyParallelPairPresentationAux |
| 66 | + |
| 67 | +variable {A B : Cᵒᵖ ⥤ Type v₁} (f g : A ⟶ B) (P₁ : IndObjectPresentation A) |
| 68 | + (P₂ : IndObjectPresentation B) |
| 69 | + |
| 70 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 71 | +abbrev K : Type v₁ := |
| 72 | + Comma ((P₁.toCostructuredArrow ⋙ CostructuredArrow.map f).prod' |
| 73 | + (P₁.toCostructuredArrow ⋙ CostructuredArrow.map g)) |
| 74 | + (P₂.toCostructuredArrow.prod' P₂.toCostructuredArrow) |
| 75 | + |
| 76 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 77 | +abbrev F₁ : K f g P₁ P₂ ⥤ C := Comma.fst _ _ ⋙ P₁.F |
| 78 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 79 | +abbrev F₂ : K f g P₁ P₂ ⥤ C := Comma.snd _ _ ⋙ P₂.F |
| 80 | + |
| 81 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 82 | +abbrev ι₁ : F₁ f g P₁ P₂ ⋙ yoneda ⟶ (Functor.const (K f g P₁ P₂)).obj A := |
| 83 | + whiskerLeft (Comma.fst _ _) P₁.ι |
| 84 | + |
| 85 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 86 | +noncomputable abbrev isColimit₁ : IsColimit (Cocone.mk A (ι₁ f g P₁ P₂)) := |
| 87 | + (Functor.Final.isColimitWhiskerEquiv _ _).symm P₁.isColimit |
| 88 | + |
| 89 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 90 | +abbrev ι₂ : F₂ f g P₁ P₂ ⋙ yoneda ⟶ (Functor.const (K f g P₁ P₂)).obj B := |
| 91 | + whiskerLeft (Comma.snd _ _) P₂.ι |
| 92 | + |
| 93 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 94 | +noncomputable abbrev isColimit₂ : IsColimit (Cocone.mk B (ι₂ f g P₁ P₂)) := |
| 95 | + (Functor.Final.isColimitWhiskerEquiv _ _).symm P₂.isColimit |
| 96 | + |
| 97 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 98 | +def ϕ : F₁ f g P₁ P₂ ⟶ F₂ f g P₁ P₂ where |
| 99 | + app h := h.hom.1.left |
| 100 | + naturality _ _ h := by |
| 101 | + have := h.w |
| 102 | + simp only [Functor.prod'_obj, Functor.comp_obj, prod_Hom, Functor.prod'_map, Functor.comp_map, |
| 103 | + prod_comp, Prod.mk.injEq, CostructuredArrow.hom_eq_iff, CostructuredArrow.map_obj_left, |
| 104 | + IndObjectPresentation.toCostructuredArrow_obj_left, CostructuredArrow.comp_left, |
| 105 | + CostructuredArrow.map_map_left, IndObjectPresentation.toCostructuredArrow_map_left] at this |
| 106 | + exact this.1 |
| 107 | + |
| 108 | +theorem hf : f = IsColimit.map (isColimit₁ f g P₁ P₂) |
| 109 | + (Cocone.mk B (ι₂ f g P₁ P₂)) (whiskerRight (ϕ f g P₁ P₂) yoneda) := by |
| 110 | + refine (isColimit₁ f g P₁ P₂).hom_ext (fun i => ?_) |
| 111 | + rw [IsColimit.ι_map] |
| 112 | + simpa using i.hom.1.w.symm |
| 113 | + |
| 114 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 115 | +def ψ : F₁ f g P₁ P₂ ⟶ F₂ f g P₁ P₂ where |
| 116 | + app h := h.hom.2.left |
| 117 | + naturality _ _ h := by |
| 118 | + have := h.w |
| 119 | + simp only [Functor.prod'_obj, Functor.comp_obj, prod_Hom, Functor.prod'_map, Functor.comp_map, |
| 120 | + prod_comp, Prod.mk.injEq, CostructuredArrow.hom_eq_iff, CostructuredArrow.map_obj_left, |
| 121 | + IndObjectPresentation.toCostructuredArrow_obj_left, CostructuredArrow.comp_left, |
| 122 | + CostructuredArrow.map_map_left, IndObjectPresentation.toCostructuredArrow_map_left] at this |
| 123 | + exact this.2 |
| 124 | + |
| 125 | +theorem hg : g = IsColimit.map (isColimit₁ f g P₁ P₂) |
| 126 | + (Cocone.mk B (ι₂ f g P₁ P₂)) (whiskerRight (ψ f g P₁ P₂) yoneda) := by |
| 127 | + refine (isColimit₁ f g P₁ P₂).hom_ext (fun i => ?_) |
| 128 | + rw [IsColimit.ι_map] |
| 129 | + simpa using i.hom.2.w.symm |
| 130 | + |
| 131 | +attribute [local instance] Comma.isFiltered_of_final in |
| 132 | +/-- Implementation; see `nonempty_indParallelPairPresentation`. -/ |
| 133 | +noncomputable def presentation : IndParallelPairPresentation f g where |
| 134 | + I := K f g P₁ P₂ |
| 135 | + F₁ := F₁ f g P₁ P₂ |
| 136 | + F₂ := F₂ f g P₁ P₂ |
| 137 | + ι₁ := ι₁ f g P₁ P₂ |
| 138 | + isColimit₁ := isColimit₁ f g P₁ P₂ |
| 139 | + ι₂ := ι₂ f g P₁ P₂ |
| 140 | + isColimit₂ := isColimit₂ f g P₁ P₂ |
| 141 | + φ := ϕ f g P₁ P₂ |
| 142 | + ψ := ψ f g P₁ P₂ |
| 143 | + hf := hf f g P₁ P₂ |
| 144 | + hg := hg f g P₁ P₂ |
| 145 | + |
| 146 | +end NonemptyParallelPairPresentationAux |
| 147 | + |
| 148 | +theorem nonempty_indParallelPairPresentation {A B : Cᵒᵖ ⥤ Type v₁} (hA : IsIndObject A) |
| 149 | + (hB : IsIndObject B) (f g : A ⟶ B) : Nonempty (IndParallelPairPresentation f g) := |
| 150 | + ⟨NonemptyParallelPairPresentationAux.presentation f g hA.presentation hB.presentation⟩ |
| 151 | + |
| 152 | +namespace IndParallelPairPresentation |
| 153 | + |
| 154 | +/-- Given an `IndParallelPairPresentation f g`, we can understand the parallel pair `(f, g)` |
| 155 | +as the colimit of `(P.φ, P.ψ)` in `Cᵒᵖ ⥤ Type v`. -/ |
| 156 | +noncomputable def parallelPairIsoParallelPairCompYoneda {A B : Cᵒᵖ ⥤ Type v₁} {f g : A ⟶ B} |
| 157 | + (P : IndParallelPairPresentation f g) : |
| 158 | + parallelPair f g ≅ parallelPair P.φ P.ψ ⋙ (whiskeringRight _ _ _).obj yoneda ⋙ colim := |
| 159 | + parallelPair.ext |
| 160 | + (P.isColimit₁.coconePointUniqueUpToIso (colimit.isColimit _)) |
| 161 | + (P.isColimit₂.coconePointUniqueUpToIso (colimit.isColimit _)) |
| 162 | + (P.isColimit₁.hom_ext (fun j => by |
| 163 | + simp [P.hf, P.isColimit₁.ι_map_assoc, P.isColimit₁.comp_coconePointUniqueUpToIso_hom_assoc, |
| 164 | + P.isColimit₂.comp_coconePointUniqueUpToIso_hom])) |
| 165 | + (P.isColimit₁.hom_ext (fun j => by |
| 166 | + simp [P.hg, P.isColimit₁.ι_map_assoc, P.isColimit₁.comp_coconePointUniqueUpToIso_hom_assoc, |
| 167 | + P.isColimit₂.comp_coconePointUniqueUpToIso_hom])) |
| 168 | + |
| 169 | +end IndParallelPairPresentation |
| 170 | + |
| 171 | +end CategoryTheory |
0 commit comments