|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Reid Barton. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Reid Barton, Johan Commelin |
| 5 | +-/ |
| 6 | + |
| 7 | +import category_theory.limits.preserves |
| 8 | +import category_theory.whiskering |
| 9 | +import category_theory.equivalence |
| 10 | + |
| 11 | +namespace category_theory |
| 12 | +open category |
| 13 | +open category_theory.limits |
| 14 | + |
| 15 | +universes v₁ v₂ v₃ u₁ u₂ u₃ -- declare the `v`'s first; see `category_theory.category` for an explanation |
| 16 | + |
| 17 | +local attribute [elab_simple] whisker_left whisker_right |
| 18 | + |
| 19 | +variables {C : Type u₁} [𝒞 : category.{v₁} C] {D : Type u₂} [𝒟 : category.{v₂} D] |
| 20 | +include 𝒞 𝒟 |
| 21 | + |
| 22 | +/-- |
| 23 | +`adjunction F G` represents the data of an adjunction between two functors |
| 24 | +`F : C ⥤ D` and `G : D ⥤ C`. `F` is the left adjoint and `G` is the right adjoint. |
| 25 | +-/ |
| 26 | +structure adjunction (F : C ⥤ D) (G : D ⥤ C) := |
| 27 | +(hom_equiv : Π (X Y), (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)) |
| 28 | +(unit : functor.id C ⟶ F.comp G) |
| 29 | +(counit : G.comp F ⟶ functor.id D) |
| 30 | +(hom_equiv_unit' : Π {X Y f}, (hom_equiv X Y) f = (unit : _ ⟹ _).app X ≫ G.map f . obviously) |
| 31 | +(hom_equiv_counit' : Π {X Y g}, (hom_equiv X Y).symm g = F.map g ≫ counit.app Y . obviously) |
| 32 | + |
| 33 | +namespace adjunction |
| 34 | + |
| 35 | +restate_axiom hom_equiv_unit' |
| 36 | +restate_axiom hom_equiv_counit' |
| 37 | +attribute [simp, priority 1] hom_equiv_unit hom_equiv_counit |
| 38 | + |
| 39 | +section |
| 40 | + |
| 41 | +variables {F : C ⥤ D} {G : D ⥤ C} (adj : adjunction F G) {X' X : C} {Y Y' : D} |
| 42 | + |
| 43 | +@[simp, priority 1] lemma hom_equiv_naturality_left_symm (f : X' ⟶ X) (g : X ⟶ G.obj Y) : |
| 44 | + (adj.hom_equiv X' Y).symm (f ≫ g) = F.map f ≫ (adj.hom_equiv X Y).symm g := |
| 45 | +by rw [hom_equiv_counit, F.map_comp, assoc, adj.hom_equiv_counit.symm] |
| 46 | + |
| 47 | +@[simp] lemma hom_equiv_naturality_left (f : X' ⟶ X) (g : F.obj X ⟶ Y) : |
| 48 | + (adj.hom_equiv X' Y) (F.map f ≫ g) = f ≫ (adj.hom_equiv X Y) g := |
| 49 | +by rw [← equiv.eq_symm_apply]; simp [-hom_equiv_unit] |
| 50 | + |
| 51 | +@[simp, priority 1] lemma hom_equiv_naturality_right (f : F.obj X ⟶ Y) (g : Y ⟶ Y') : |
| 52 | + (adj.hom_equiv X Y') (f ≫ g) = (adj.hom_equiv X Y) f ≫ G.map g := |
| 53 | +by rw [hom_equiv_unit, G.map_comp, ← assoc, ←hom_equiv_unit] |
| 54 | + |
| 55 | +@[simp] lemma hom_equiv_naturality_right_symm (f : X ⟶ G.obj Y) (g : Y ⟶ Y') : |
| 56 | + (adj.hom_equiv X Y').symm (f ≫ G.map g) = (adj.hom_equiv X Y).symm f ≫ g := |
| 57 | +by rw [equiv.symm_apply_eq]; simp [-hom_equiv_counit] |
| 58 | + |
| 59 | +@[simp] lemma left_triangle : |
| 60 | + (whisker_right adj.unit F).vcomp (whisker_left F adj.counit) = nat_trans.id _ := |
| 61 | +begin |
| 62 | + ext1 X, dsimp, |
| 63 | + erw [← adj.hom_equiv_counit, equiv.symm_apply_eq, adj.hom_equiv_unit], |
| 64 | + simp |
| 65 | +end |
| 66 | + |
| 67 | +@[simp] lemma right_triangle : |
| 68 | + (whisker_left G adj.unit).vcomp (whisker_right adj.counit G) = nat_trans.id _ := |
| 69 | +begin |
| 70 | + ext1 Y, dsimp, |
| 71 | + erw [← adj.hom_equiv_unit, ← equiv.eq_symm_apply, adj.hom_equiv_counit], |
| 72 | + simp |
| 73 | +end |
| 74 | + |
| 75 | +@[simp] lemma left_triangle_components : |
| 76 | + F.map (adj.unit.app X) ≫ adj.counit.app (F.obj X) = 𝟙 _ := |
| 77 | +congr_arg (λ (t : _ ⟹ functor.id C ⋙ F), t.app X) adj.left_triangle |
| 78 | + |
| 79 | +@[simp] lemma right_triangle_components {Y : D} : |
| 80 | + adj.unit.app (G.obj Y) ≫ G.map (adj.counit.app Y) = 𝟙 _ := |
| 81 | +congr_arg (λ (t : _ ⟹ G ⋙ functor.id C), t.app Y) adj.right_triangle |
| 82 | + |
| 83 | +end |
| 84 | + |
| 85 | +structure core_hom_equiv (F : C ⥤ D) (G : D ⥤ C) := |
| 86 | +(hom_equiv : Π (X Y), (F.obj X ⟶ Y) ≃ (X ⟶ G.obj Y)) |
| 87 | +(hom_equiv_naturality_left_symm' : Π {X' X Y} (f : X' ⟶ X) (g : X ⟶ G.obj Y), |
| 88 | + (hom_equiv X' Y).symm (f ≫ g) = F.map f ≫ (hom_equiv X Y).symm g . obviously) |
| 89 | +(hom_equiv_naturality_right' : Π {X Y Y'} (f : F.obj X ⟶ Y) (g : Y ⟶ Y'), |
| 90 | + (hom_equiv X Y') (f ≫ g) = (hom_equiv X Y) f ≫ G.map g . obviously) |
| 91 | + |
| 92 | +namespace core_hom_equiv |
| 93 | + |
| 94 | +restate_axiom hom_equiv_naturality_left_symm' |
| 95 | +restate_axiom hom_equiv_naturality_right' |
| 96 | +attribute [simp, priority 1] hom_equiv_naturality_left_symm hom_equiv_naturality_right |
| 97 | + |
| 98 | +variables {F : C ⥤ D} {G : D ⥤ C} (adj : core_hom_equiv F G) {X' X : C} {Y Y' : D} |
| 99 | + |
| 100 | +@[simp] lemma hom_equiv_naturality_left (f : X' ⟶ X) (g : F.obj X ⟶ Y) : |
| 101 | + (adj.hom_equiv X' Y) (F.map f ≫ g) = f ≫ (adj.hom_equiv X Y) g := |
| 102 | +by rw [← equiv.eq_symm_apply]; simp |
| 103 | + |
| 104 | +@[simp] lemma hom_equiv_naturality_right_symm (f : X ⟶ G.obj Y) (g : Y ⟶ Y') : |
| 105 | + (adj.hom_equiv X Y').symm (f ≫ G.map g) = (adj.hom_equiv X Y).symm f ≫ g := |
| 106 | +by rw [equiv.symm_apply_eq]; simp |
| 107 | + |
| 108 | +end core_hom_equiv |
| 109 | + |
| 110 | +structure core_unit_counit (F : C ⥤ D) (G : D ⥤ C) := |
| 111 | +(unit : functor.id C ⟶ F.comp G) |
| 112 | +(counit : G.comp F ⟶ functor.id D) |
| 113 | +(left_triangle' : (whisker_right unit F).vcomp (whisker_left F counit) = nat_trans.id _ . obviously) |
| 114 | +(right_triangle' : (whisker_left G unit).vcomp (whisker_right counit G) = nat_trans.id _ . obviously) |
| 115 | + |
| 116 | +namespace core_unit_counit |
| 117 | + |
| 118 | +restate_axiom left_triangle' |
| 119 | +restate_axiom right_triangle' |
| 120 | +attribute [simp] left_triangle right_triangle |
| 121 | + |
| 122 | +end core_unit_counit |
| 123 | + |
| 124 | +variables (F : C ⥤ D) (G : D ⥤ C) |
| 125 | + |
| 126 | +def mk_of_hom_equiv (adj : core_hom_equiv F G) : adjunction F G := |
| 127 | +{ unit := |
| 128 | + { app := λ X, (adj.hom_equiv X (F.obj X)) (𝟙 (F.obj X)), |
| 129 | + naturality' := |
| 130 | + begin |
| 131 | + intros, |
| 132 | + erw [← adj.hom_equiv_naturality_left, ← adj.hom_equiv_naturality_right], |
| 133 | + dsimp, simp |
| 134 | + end }, |
| 135 | + counit := |
| 136 | + { app := λ Y, (adj.hom_equiv _ _).inv_fun (𝟙 (G.obj Y)), |
| 137 | + naturality' := |
| 138 | + begin |
| 139 | + intros, |
| 140 | + erw [← adj.hom_equiv_naturality_left_symm, ← adj.hom_equiv_naturality_right_symm], |
| 141 | + dsimp, simp |
| 142 | + end }, |
| 143 | + hom_equiv_unit' := λ X Y f, by erw [← adj.hom_equiv_naturality_right]; simp, |
| 144 | + hom_equiv_counit' := λ X Y f, by erw [← adj.hom_equiv_naturality_left_symm]; simp, |
| 145 | + .. adj } |
| 146 | + |
| 147 | +def mk_of_unit_counit (adj : core_unit_counit F G) : adjunction F G := |
| 148 | +{ hom_equiv := λ X Y, |
| 149 | + { to_fun := λ f, adj.unit.app X ≫ G.map f, |
| 150 | + inv_fun := λ g, F.map g ≫ adj.counit.app Y, |
| 151 | + left_inv := λ f, begin |
| 152 | + change F.map (_ ≫ _) ≫ _ = _, |
| 153 | + rw [F.map_comp, assoc, ←functor.comp_map, adj.counit.naturality, ←assoc], |
| 154 | + convert id_comp _ f, |
| 155 | + exact congr_arg (λ t : _ ⟹ _, t.app _) adj.left_triangle |
| 156 | + end, |
| 157 | + right_inv := λ g, begin |
| 158 | + change _ ≫ G.map (_ ≫ _) = _, |
| 159 | + rw [G.map_comp, ←assoc, ←functor.comp_map, ←adj.unit.naturality, assoc], |
| 160 | + convert comp_id _ g, |
| 161 | + exact congr_arg (λ t : _ ⟹ _, t.app _) adj.right_triangle |
| 162 | + end }, |
| 163 | + .. adj } |
| 164 | + |
| 165 | +section |
| 166 | +omit 𝒟 |
| 167 | + |
| 168 | +def id : adjunction (functor.id C) (functor.id C) := |
| 169 | +{ hom_equiv := λ X Y, equiv.refl _, |
| 170 | + unit := 𝟙 _, |
| 171 | + counit := 𝟙 _ } |
| 172 | + |
| 173 | +end |
| 174 | + |
| 175 | +/- |
| 176 | +TODO |
| 177 | +* define adjoint equivalences |
| 178 | +* show that every equivalence can be improved into an adjoint equivalence |
| 179 | +-/ |
| 180 | + |
| 181 | +section |
| 182 | +variables {E : Type u₃} [ℰ : category.{v₃} E] (H : D ⥤ E) (I : E ⥤ D) |
| 183 | + |
| 184 | +def comp (adj₁ : adjunction F G) (adj₂ : adjunction H I) : adjunction (F ⋙ H) (I ⋙ G) := |
| 185 | +{ hom_equiv := λ X Z, equiv.trans (adj₂.hom_equiv _ _) (adj₁.hom_equiv _ _), |
| 186 | + unit := adj₁.unit ≫ |
| 187 | + (whisker_left F $ whisker_right adj₂.unit G) ≫ (functor.associator _ _ _).inv, |
| 188 | + counit := (functor.associator _ _ _).hom ≫ |
| 189 | + (whisker_left I $ whisker_right adj₁.counit H) ≫ adj₂.counit } |
| 190 | + |
| 191 | +end |
| 192 | + |
| 193 | +structure is_left_adjoint (left : C ⥤ D) := |
| 194 | +(right : D ⥤ C) |
| 195 | +(adj : adjunction left right) |
| 196 | + |
| 197 | +structure is_right_adjoint (right : D ⥤ C) := |
| 198 | +(left : C ⥤ D) |
| 199 | +(adj : adjunction left right) |
| 200 | + |
| 201 | +section construct_left |
| 202 | +-- Construction of a left adjoint. In order to construct a left |
| 203 | +-- adjoint to a functor G : D → C, it suffices to give the object part |
| 204 | +-- of a functor F : C → D together with isomorphisms Hom(FX, Y) ≃ |
| 205 | +-- Hom(X, GY) natural in Y. The action of F on morphisms can be |
| 206 | +-- constructed from this data. |
| 207 | +variables {F_obj : C → D} {G} |
| 208 | +variables (e : Π X Y, (F_obj X ⟶ Y) ≃ (X ⟶ G.obj Y)) |
| 209 | +variables (he : Π X Y Y' g h, e X Y' (h ≫ g) = e X Y h ≫ G.map g) |
| 210 | +include he |
| 211 | + |
| 212 | +private lemma he' {X Y Y'} (f g) : (e X Y').symm (f ≫ G.map g) = (e X Y).symm f ≫ g := |
| 213 | +by intros; rw [equiv.symm_apply_eq, he]; simp |
| 214 | + |
| 215 | +def left_adjoint_of_equiv : C ⥤ D := |
| 216 | +{ obj := F_obj, |
| 217 | + map := λ X X' f, (e X (F_obj X')).symm (f ≫ e X' (F_obj X') (𝟙 _)), |
| 218 | + map_comp' := λ X X' X'' f f', begin |
| 219 | + rw [equiv.symm_apply_eq, he, equiv.apply_inverse_apply], |
| 220 | + conv { to_rhs, rw [assoc, ←he, id_comp, equiv.apply_inverse_apply] }, |
| 221 | + simp |
| 222 | + end } |
| 223 | + |
| 224 | +def adjunction_of_equiv_left : adjunction (left_adjoint_of_equiv e he) G := |
| 225 | +mk_of_hom_equiv (left_adjoint_of_equiv e he) G |
| 226 | +{ hom_equiv := e, |
| 227 | + hom_equiv_naturality_left_symm' := |
| 228 | + begin |
| 229 | + intros, |
| 230 | + erw [← he' e he, ← equiv.apply_eq_iff_eq], |
| 231 | + simp [(he _ _ _ _ _).symm] |
| 232 | + end } |
| 233 | + |
| 234 | +end construct_left |
| 235 | + |
| 236 | +section construct_right |
| 237 | +-- Construction of a right adjoint, analogous to the above. |
| 238 | +variables {F} {G_obj : D → C} |
| 239 | +variables (e : Π X Y, (F.obj X ⟶ Y) ≃ (X ⟶ G_obj Y)) |
| 240 | +variables (he : Π X' X Y f g, e X' Y (F.map f ≫ g) = f ≫ e X Y g) |
| 241 | +include he |
| 242 | + |
| 243 | +private lemma he' {X' X Y} (f g) : F.map f ≫ (e X Y).symm g = (e X' Y).symm (f ≫ g) := |
| 244 | +by intros; rw [equiv.eq_symm_apply, he]; simp |
| 245 | + |
| 246 | +def right_adjoint_of_equiv : D ⥤ C := |
| 247 | +{ obj := G_obj, |
| 248 | + map := λ Y Y' g, (e (G_obj Y) Y') ((e (G_obj Y) Y).symm (𝟙 _) ≫ g), |
| 249 | + map_comp' := λ Y Y' Y'' g g', begin |
| 250 | + rw [← equiv.eq_symm_apply, ← he' e he, equiv.inverse_apply_apply], |
| 251 | + conv { to_rhs, rw [← assoc, he' e he, comp_id, equiv.inverse_apply_apply] }, |
| 252 | + simp |
| 253 | + end } |
| 254 | + |
| 255 | +def adjunction_of_equiv_right : adjunction F (right_adjoint_of_equiv e he) := |
| 256 | +mk_of_hom_equiv F (right_adjoint_of_equiv e he) |
| 257 | +{ hom_equiv := e, |
| 258 | + hom_equiv_naturality_left_symm' := by intros; rw [equiv.symm_apply_eq, he]; simp, |
| 259 | + hom_equiv_naturality_right' := |
| 260 | + begin |
| 261 | + intros X Y Y' g h, |
| 262 | + erw [←he, equiv.apply_eq_iff_eq, ←assoc, he' e he, comp_id, equiv.inverse_apply_apply] |
| 263 | + end } |
| 264 | + |
| 265 | +end construct_right |
| 266 | + |
| 267 | +end adjunction |
| 268 | + |
| 269 | +end category_theory |
| 270 | + |
| 271 | +namespace category_theory.adjunction |
| 272 | +open category_theory |
| 273 | +open category_theory.functor |
| 274 | +open category_theory.limits |
| 275 | + |
| 276 | +universes u₁ u₂ v |
| 277 | + |
| 278 | +variables {C : Type u₁} [𝒞 : category.{v} C] {D : Type u₂} [𝒟 : category.{v} D] |
| 279 | +include 𝒞 𝒟 |
| 280 | + |
| 281 | +variables {F : C ⥤ D} {G : D ⥤ C} (adj : adjunction F G) |
| 282 | +include adj |
| 283 | + |
| 284 | +section preservation_colimits |
| 285 | +variables {J : Type v} [small_category J] (K : J ⥤ C) |
| 286 | + |
| 287 | +def functoriality_is_left_adjoint : |
| 288 | + is_left_adjoint (@cocones.functoriality _ _ _ _ K _ _ F) := |
| 289 | +{ right := (cocones.functoriality G) ⋙ (cocones.precompose |
| 290 | + (K.right_unitor.inv ≫ (whisker_left K adj.unit) ≫ (associator _ _ _).inv)), |
| 291 | + adj := mk_of_unit_counit _ _ |
| 292 | + { unit := |
| 293 | + { app := λ c, |
| 294 | + { hom := adj.unit.app c.X, |
| 295 | + w' := λ j, by have := adj.unit.naturality (c.ι.app j); tidy }, |
| 296 | + naturality' := λ _ _ f, by have := adj.unit.naturality (f.hom); tidy }, |
| 297 | + counit := |
| 298 | + { app := λ c, |
| 299 | + { hom := adj.counit.app c.X, |
| 300 | + w' := |
| 301 | + begin |
| 302 | + intro j, |
| 303 | + dsimp, |
| 304 | + erw [category.comp_id, category.id_comp, F.map_comp, category.assoc, |
| 305 | + adj.counit.naturality (c.ι.app j), ← category.assoc, |
| 306 | + adj.left_triangle_components, category.id_comp], |
| 307 | + refl, |
| 308 | + end }, |
| 309 | + naturality' := λ _ _ f, by have := adj.counit.naturality (f.hom); tidy } } } |
| 310 | + |
| 311 | +/-- A left adjoint preserves colimits. -/ |
| 312 | +def left_adjoint_preserves_colimits : preserves_colimits F := |
| 313 | +λ J 𝒥 K, by resetI; exact |
| 314 | +{ preserves := λ c hc, is_colimit_iso_unique_cocone_morphism.inv |
| 315 | + (λ s, (((adj.functoriality_is_left_adjoint _).adj).hom_equiv _ _).unique_of_equiv $ |
| 316 | + is_colimit_iso_unique_cocone_morphism.hom hc _ ) } |
| 317 | + |
| 318 | +end preservation_colimits |
| 319 | + |
| 320 | +section preservation_limits |
| 321 | +variables {J : Type v} [small_category J] (K : J ⥤ D) |
| 322 | + |
| 323 | +def functoriality_is_right_adjoint : |
| 324 | + is_right_adjoint (@cones.functoriality _ _ _ _ K _ _ G) := |
| 325 | +{ left := (cones.functoriality F) ⋙ (cones.postcompose |
| 326 | + ((associator _ _ _).hom ≫ (whisker_left K adj.counit) ≫ K.right_unitor.hom)), |
| 327 | + adj := mk_of_unit_counit _ _ |
| 328 | + { unit := |
| 329 | + { app := λ c, |
| 330 | + { hom := adj.unit.app c.X, |
| 331 | + w' := |
| 332 | + begin |
| 333 | + intro j, |
| 334 | + dsimp, |
| 335 | + erw [category.comp_id, category.id_comp, G.map_comp, ← category.assoc, |
| 336 | + ← adj.unit.naturality (c.π.app j), category.assoc, |
| 337 | + adj.right_triangle_components, category.comp_id], |
| 338 | + refl, |
| 339 | + end }, |
| 340 | + naturality' := λ _ _ f, by have := adj.unit.naturality (f.hom); tidy }, |
| 341 | + counit := |
| 342 | + { app := λ c, |
| 343 | + { hom := adj.counit.app c.X, |
| 344 | + w' := λ j, by have := adj.counit.naturality (c.π.app j); tidy }, |
| 345 | + naturality' := λ _ _ f, by have := adj.counit.naturality (f.hom); tidy } } } |
| 346 | + |
| 347 | +/-- A right adjoint preserves limits. -/ |
| 348 | +def right_adjoint_preserves_limits : preserves_limits G := |
| 349 | +λ J 𝒥 K, by resetI; exact |
| 350 | +{ preserves := λ c hc, is_limit_iso_unique_cone_morphism.inv |
| 351 | + (λ s, (((adj.functoriality_is_right_adjoint _).adj).hom_equiv _ _).symm.unique_of_equiv $ |
| 352 | + is_limit_iso_unique_cone_morphism.hom hc _) } |
| 353 | + |
| 354 | +end preservation_limits |
| 355 | + |
| 356 | +-- Note: this is natural in K, but we do not yet have the tools to formulate that. |
| 357 | +def cocones_iso {J : Type v} [small_category J] {K : J ⥤ C} : |
| 358 | + (cocones J D).obj (K ⋙ F) ≅ G ⋙ ((cocones J C).obj K) := |
| 359 | +nat_iso.of_components (λ Y, |
| 360 | +{ hom := λ t, |
| 361 | + { app := λ j, (adj.hom_equiv (K.obj j) Y) (t.app j), |
| 362 | + naturality' := λ j j' f, by erw [← adj.hom_equiv_naturality_left, t.naturality]; dsimp; simp }, |
| 363 | + inv := λ t, |
| 364 | + { app := λ j, (adj.hom_equiv (K.obj j) Y).symm (t.app j), |
| 365 | + naturality' := λ j j' f, begin |
| 366 | + erw [← adj.hom_equiv_naturality_left_symm, ← adj.hom_equiv_naturality_right_symm, t.naturality], |
| 367 | + dsimp, simp |
| 368 | + end } } ) |
| 369 | +begin |
| 370 | + intros Y₁ Y₂ f, |
| 371 | + ext1 t, |
| 372 | + ext1 j, |
| 373 | + apply adj.hom_equiv_naturality_right |
| 374 | +end |
| 375 | + |
| 376 | +-- Note: this is natural in K, but we do not yet have the tools to formulate that. |
| 377 | +def cones_iso {J : Type v} [small_category J] {K : J ⥤ D} : |
| 378 | + F.op ⋙ ((cones J D).obj K) ≅ (cones J C).obj (K ⋙ G) := |
| 379 | +nat_iso.of_components (λ X, |
| 380 | +{ hom := λ t, |
| 381 | + { app := λ j, (adj.hom_equiv X (K.obj j)) (t.app j), |
| 382 | + naturality' := λ j j' f, begin |
| 383 | + erw [← adj.hom_equiv_naturality_right, ← t.naturality, category.id_comp, category.id_comp], |
| 384 | + refl |
| 385 | + end }, |
| 386 | + inv := λ t, |
| 387 | + { app := λ j, (adj.hom_equiv X (K.obj j)).symm (t.app j), |
| 388 | + naturality' := λ j j' f, begin |
| 389 | + erw [← adj.hom_equiv_naturality_right_symm, ← t.naturality, category.id_comp, category.id_comp] |
| 390 | + end } } ) |
| 391 | +(by tidy) |
| 392 | + |
| 393 | +end category_theory.adjunction |
0 commit comments