|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Bhavik Mehta, Edward Ayers, Thomas Read. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Bhavik Mehta, Edward Ayers, Thomas Read |
| 5 | +-/ |
| 6 | + |
| 7 | +import category_theory.limits.shapes.binary_products |
| 8 | +import category_theory.limits.shapes.constructions.preserve_binary_products |
| 9 | +import category_theory.closed.monoidal |
| 10 | +import category_theory.monoidal.of_has_finite_products |
| 11 | +import category_theory.adjunction |
| 12 | +import category_theory.epi_mono |
| 13 | + |
| 14 | +/-! |
| 15 | +# Cartesian closed categories |
| 16 | +
|
| 17 | +Given a category with finite products, the cartesian monoidal structure is provided by the local |
| 18 | +instance `monoidal_of_has_finite_products`. |
| 19 | +
|
| 20 | +We define exponentiable objects to be closed objects with respect to this monoidal structure, |
| 21 | +i.e. `(X × -)` is a left adjoint. |
| 22 | +
|
| 23 | +We say a category is cartesian closed if every object is exponentiable |
| 24 | +(equivalently, that the category equipped with the cartesian monoidal structure is closed monoidal). |
| 25 | +
|
| 26 | +Show that exponential forms a difunctor and define the exponential comparison morphisms. |
| 27 | +
|
| 28 | +## TODO |
| 29 | +Some of the results here are true more generally for closed objects and |
| 30 | +for closed monoidal categories, and these could be generalised. |
| 31 | +-/ |
| 32 | +universes v u u₂ |
| 33 | + |
| 34 | +namespace category_theory |
| 35 | + |
| 36 | +open category_theory category_theory.category category_theory.limits |
| 37 | + |
| 38 | +local attribute [instance] monoidal_of_has_finite_products |
| 39 | + |
| 40 | +/-- |
| 41 | +An object `X` is *exponentiable* if `(X × -)` is a left adjoint. |
| 42 | +We define this as being `closed` in the cartesian monoidal structure. |
| 43 | +-/ |
| 44 | +abbreviation exponentiable {C : Type u} [category.{v} C] [has_finite_products.{v} C] (X : C) := |
| 45 | +closed X |
| 46 | + |
| 47 | +/-- |
| 48 | +If `X` and `Y` are exponentiable then `X ⨯ Y` is. |
| 49 | +This isn't an instance because it's not usually how we want to construct exponentials, we'll usually |
| 50 | +prove all objects are exponential uniformly. |
| 51 | +-/ |
| 52 | +def binary_product_exponentiable {C : Type u} [category.{v} C] [has_finite_products.{v} C] {X Y : C} |
| 53 | + (hX : exponentiable X) (hY : exponentiable Y) : exponentiable (X ⨯ Y) := |
| 54 | +{ is_adj := |
| 55 | + begin |
| 56 | + haveI := hX.is_adj, |
| 57 | + haveI := hY.is_adj, |
| 58 | + exact adjunction.left_adjoint_of_nat_iso (monoidal_category.tensor_left_tensor _ _).symm |
| 59 | + end } |
| 60 | + |
| 61 | +/-- |
| 62 | +The terminal object is always exponentiable. |
| 63 | +This isn't an instance because most of the time we'll prove cartesian closed for all objects |
| 64 | +at once, rather than just for this one. |
| 65 | +-/ |
| 66 | +def terminal_exponentiable {C : Type u} [category.{v} C] [has_finite_products.{v} C] : exponentiable ⊤_C := |
| 67 | +{ is_adj := |
| 68 | + { right := 𝟭 C, |
| 69 | + adj := adjunction.mk_of_hom_equiv |
| 70 | + { hom_equiv := λ X _, have unitor : _, from prod.left_unitor X, |
| 71 | + ⟨λ a, unitor.inv ≫ a, λ a, unitor.hom ≫ a, by tidy, by tidy⟩ } } } |
| 72 | + |
| 73 | +/-- |
| 74 | +A category `C` is cartesian closed if it has finite products and every object is exponentiable. |
| 75 | +We define this as `monoidal_closed` with respect to the cartesian monoidal structure. |
| 76 | +-/ |
| 77 | +abbreviation cartesian_closed (C : Type u) [category.{v} C] [has_finite_products.{v} C] := |
| 78 | +monoidal_closed C |
| 79 | + |
| 80 | +variables {C : Type u} [category.{v} C] (A B : C) {X X' Y Y' Z : C} |
| 81 | + |
| 82 | +section exp |
| 83 | +variables [has_finite_products.{v} C] [exponentiable A] |
| 84 | + |
| 85 | +/-- This is (-)^A. -/ |
| 86 | +def exp : C ⥤ C := |
| 87 | +(@closed.is_adj _ _ _ A _).right |
| 88 | + |
| 89 | +/-- The adjunction between A ⨯ - and (-)^A. -/ |
| 90 | +def exp.adjunction : prod_functor.obj A ⊣ exp A := |
| 91 | +closed.is_adj.adj |
| 92 | + |
| 93 | +/-- The evaluation natural transformation. -/ |
| 94 | +def ev : exp A ⋙ prod_functor.obj A ⟶ 𝟭 C := |
| 95 | +closed.is_adj.adj.counit |
| 96 | + |
| 97 | +/-- The coevaluation natural transformation. -/ |
| 98 | +def coev : 𝟭 C ⟶ prod_functor.obj A ⋙ exp A := |
| 99 | +closed.is_adj.adj.unit |
| 100 | + |
| 101 | +notation A ` ⟹ `:20 B:20 := (exp A).obj B |
| 102 | +notation A ` ^^ `:30 B:30 := (exp A).obj B |
| 103 | + |
| 104 | +@[simp, reassoc] lemma ev_coev : limits.prod.map (𝟙 A) ((coev A).app B) ≫ (ev A).app (A ⨯ B) = 𝟙 (A ⨯ B) := |
| 105 | +adjunction.left_triangle_components (exp.adjunction A) |
| 106 | + |
| 107 | +@[simp, reassoc] lemma coev_ev : (coev A).app (A⟹B) ≫ (exp A).map ((ev A).app B) = 𝟙 (A⟹B) := |
| 108 | +adjunction.right_triangle_components (exp.adjunction A) |
| 109 | + |
| 110 | +end exp |
| 111 | + |
| 112 | +variables {A} |
| 113 | + |
| 114 | +-- Wrap these in a namespace so we don't clash with the core versions. |
| 115 | +namespace is_cartesian_closed |
| 116 | + |
| 117 | +variables [has_finite_products.{v} C] [exponentiable A] |
| 118 | + |
| 119 | +/-- Currying in a cartesian closed category. -/ |
| 120 | +def curry : (A ⨯ Y ⟶ X) → (Y ⟶ A ⟹ X) := |
| 121 | +(closed.is_adj.adj.hom_equiv _ _).to_fun |
| 122 | +/-- Uncurrying in a cartesian closed category. -/ |
| 123 | +def uncurry : (Y ⟶ A ⟹ X) → (A ⨯ Y ⟶ X) := |
| 124 | +(closed.is_adj.adj.hom_equiv _ _).inv_fun |
| 125 | + |
| 126 | +end is_cartesian_closed |
| 127 | + |
| 128 | +open is_cartesian_closed |
| 129 | + |
| 130 | +variables [has_finite_products.{v} C] [exponentiable A] |
| 131 | + |
| 132 | +@[reassoc] |
| 133 | +lemma curry_natural_left (f : X ⟶ X') (g : A ⨯ X' ⟶ Y) : |
| 134 | + curry (limits.prod.map (𝟙 _) f ≫ g) = f ≫ curry g := |
| 135 | +adjunction.hom_equiv_naturality_left _ _ _ |
| 136 | + |
| 137 | +@[reassoc] |
| 138 | +lemma curry_natural_right (f : A ⨯ X ⟶ Y) (g : Y ⟶ Y') : |
| 139 | + curry (f ≫ g) = curry f ≫ (exp _).map g := |
| 140 | +adjunction.hom_equiv_naturality_right _ _ _ |
| 141 | + |
| 142 | +@[reassoc] |
| 143 | +lemma uncurry_natural_right (f : X ⟶ A⟹Y) (g : Y ⟶ Y') : |
| 144 | + uncurry (f ≫ (exp _).map g) = uncurry f ≫ g := |
| 145 | +adjunction.hom_equiv_naturality_right_symm _ _ _ |
| 146 | + |
| 147 | +@[reassoc] |
| 148 | +lemma uncurry_natural_left (f : X ⟶ X') (g : X' ⟶ A⟹Y) : |
| 149 | + uncurry (f ≫ g) = limits.prod.map (𝟙 _) f ≫ uncurry g := |
| 150 | +adjunction.hom_equiv_naturality_left_symm _ _ _ |
| 151 | + |
| 152 | +@[simp] |
| 153 | +lemma uncurry_curry (f : A ⨯ X ⟶ Y) : uncurry (curry f) = f := |
| 154 | +(closed.is_adj.adj.hom_equiv _ _).left_inv f |
| 155 | + |
| 156 | +@[simp] |
| 157 | +lemma curry_uncurry (f : X ⟶ A⟹Y) : curry (uncurry f) = f := |
| 158 | +(closed.is_adj.adj.hom_equiv _ _).right_inv f |
| 159 | + |
| 160 | +lemma curry_eq_iff (f : A ⨯ Y ⟶ X) (g : Y ⟶ A ⟹ X) : |
| 161 | + curry f = g ↔ f = uncurry g := |
| 162 | +adjunction.hom_equiv_apply_eq _ f g |
| 163 | + |
| 164 | +lemma eq_curry_iff (f : A ⨯ Y ⟶ X) (g : Y ⟶ A ⟹ X) : |
| 165 | + g = curry f ↔ uncurry g = f := |
| 166 | +adjunction.eq_hom_equiv_apply _ f g |
| 167 | + |
| 168 | +-- I don't think these two should be simp. |
| 169 | +lemma uncurry_eq (g : Y ⟶ A ⟹ X) : uncurry g = limits.prod.map (𝟙 A) g ≫ (ev A).app X := |
| 170 | +adjunction.hom_equiv_counit _ |
| 171 | + |
| 172 | +lemma curry_eq (g : A ⨯ Y ⟶ X) : curry g = (coev A).app Y ≫ (exp A).map g := |
| 173 | +adjunction.hom_equiv_unit _ |
| 174 | + |
| 175 | +lemma uncurry_id_eq_ev (A X : C) [exponentiable A] : uncurry (𝟙 (A ⟹ X)) = (ev A).app X := |
| 176 | +by rw [uncurry_eq, prod_map_id_id, id_comp] |
| 177 | + |
| 178 | +lemma curry_id_eq_coev (A X : C) [exponentiable A] : curry (𝟙 _) = (coev A).app X := |
| 179 | +by { rw [curry_eq, (exp A).map_id (A ⨯ _)], apply comp_id } |
| 180 | + |
| 181 | +lemma curry_injective : function.injective (curry : (A ⨯ Y ⟶ X) → (Y ⟶ A ⟹ X)) := |
| 182 | +(closed.is_adj.adj.hom_equiv _ _).injective |
| 183 | + |
| 184 | +lemma uncurry_injective : function.injective (uncurry : (Y ⟶ A ⟹ X) → (A ⨯ Y ⟶ X)) := |
| 185 | +(closed.is_adj.adj.hom_equiv _ _).symm.injective |
| 186 | + |
| 187 | +/-- |
| 188 | +Show that the exponential of the terminal object is isomorphic to itself, i.e. `X^1 ≅ X`. |
| 189 | +
|
| 190 | +The typeclass argument is explicit: any instance can be used. |
| 191 | +-/ |
| 192 | +def exp_terminal_iso_self [exponentiable ⊤_C] : (⊤_C ⟹ X) ≅ X := |
| 193 | +yoneda.ext (⊤_ C ⟹ X) X |
| 194 | + (λ Y f, (prod.left_unitor Y).inv ≫ uncurry f) |
| 195 | + (λ Y f, curry ((prod.left_unitor Y).hom ≫ f)) |
| 196 | + (λ Z g, by rw [curry_eq_iff, iso.hom_inv_id_assoc] ) |
| 197 | + (λ Z g, by simp) |
| 198 | + (λ Z W f g, by rw [uncurry_natural_left, prod_left_unitor_inv_naturality_assoc f] ) |
| 199 | + |
| 200 | +/-- The internal element which points at the given morphism. -/ |
| 201 | +def internalize_hom (f : A ⟶ Y) : ⊤_C ⟶ (A ⟹ Y) := |
| 202 | +curry (limits.prod.fst ≫ f) |
| 203 | + |
| 204 | +section pre |
| 205 | + |
| 206 | +variables {B} |
| 207 | + |
| 208 | +/-- Pre-compose an internal hom with an external hom. -/ |
| 209 | +def pre (X : C) (f : B ⟶ A) [exponentiable B] : (A⟹X) ⟶ B⟹X := |
| 210 | +curry (limits.prod.map f (𝟙 _) ≫ (ev A).app X) |
| 211 | + |
| 212 | +lemma pre_id (A X : C) [exponentiable A] : pre X (𝟙 A) = 𝟙 (A⟹X) := |
| 213 | +by { rw [pre, prod_map_id_id, id_comp, ← uncurry_id_eq_ev], simp } |
| 214 | + |
| 215 | +-- There's probably a better proof of this somehow |
| 216 | +/-- Precomposition is contrafunctorial. -/ |
| 217 | +lemma pre_map [exponentiable B] {D : C} [exponentiable D] (f : A ⟶ B) (g : B ⟶ D) : |
| 218 | + pre X (f ≫ g) = pre X g ≫ pre X f := |
| 219 | +begin |
| 220 | + rw [pre, curry_eq_iff, pre, pre, uncurry_natural_left, uncurry_curry, prod_map_map_assoc, |
| 221 | + prod_map_comp_id, assoc, ← uncurry_id_eq_ev, ← uncurry_id_eq_ev, ← uncurry_natural_left, |
| 222 | + curry_natural_right, comp_id, uncurry_natural_right, uncurry_curry], |
| 223 | +end |
| 224 | + |
| 225 | +end pre |
| 226 | + |
| 227 | +lemma pre_post_comm [cartesian_closed C] {A B : C} {X Y : Cᵒᵖ} (f : A ⟶ B) (g : X ⟶ Y) : |
| 228 | + pre A g.unop ≫ (exp Y.unop).map f = (exp X.unop).map f ≫ pre B g.unop := |
| 229 | +begin |
| 230 | + erw [← curry_natural_left, eq_curry_iff, uncurry_natural_right, uncurry_curry, prod_map_map_assoc, |
| 231 | + (ev _).naturality, assoc], refl |
| 232 | +end |
| 233 | + |
| 234 | +/-- The internal hom functor given by the cartesian closed structure. -/ |
| 235 | +def internal_hom [cartesian_closed C] : C ⥤ Cᵒᵖ ⥤ C := |
| 236 | +{ obj := λ X, |
| 237 | + { obj := λ Y, Y.unop ⟹ X, |
| 238 | + map := λ Y Y' f, pre _ f.unop, |
| 239 | + map_id' := λ Y, pre_id _ _, |
| 240 | + map_comp' := λ Y Y' Y'' f g, pre_map _ _ }, |
| 241 | + map := λ A B f, { app := λ X, (exp X.unop).map f, naturality' := λ X Y g, pre_post_comm _ _ }, |
| 242 | + map_id' := λ X, by { ext, apply functor.map_id }, |
| 243 | + map_comp' := λ X Y Z f g, by { ext, apply functor.map_comp } } |
| 244 | + |
| 245 | +/-- If an initial object `0` exists in a CCC, then `A ⨯ 0 ≅ 0`. -/ |
| 246 | +@[simps] |
| 247 | +def zero_mul [has_initial.{v} C] : A ⨯ ⊥_ C ≅ ⊥_ C := |
| 248 | +{ hom := limits.prod.snd, |
| 249 | + inv := default (⊥_ C ⟶ A ⨯ ⊥_ C), |
| 250 | + hom_inv_id' := |
| 251 | + begin |
| 252 | + have: (limits.prod.snd : A ⨯ ⊥_ C ⟶ ⊥_ C) = uncurry (default _), |
| 253 | + rw ← curry_eq_iff, |
| 254 | + apply subsingleton.elim, |
| 255 | + rw [this, ← uncurry_natural_right, ← eq_curry_iff], |
| 256 | + apply subsingleton.elim |
| 257 | + end, |
| 258 | + } |
| 259 | + |
| 260 | +/-- If an initial object `0` exists in a CCC, then `0 ⨯ A ≅ 0`. -/ |
| 261 | +def mul_zero [has_initial.{v} C] : ⊥_ C ⨯ A ≅ ⊥_ C := |
| 262 | +limits.prod.braiding _ _ ≪≫ zero_mul |
| 263 | + |
| 264 | +/-- If an initial object `0` exists in a CCC then `0^B ≅ 1` for any `B`. -/ |
| 265 | +def pow_zero [has_initial.{v} C] [cartesian_closed C] : ⊥_C ⟹ B ≅ ⊤_ C := |
| 266 | +{ hom := default _, |
| 267 | + inv := curry (mul_zero.hom ≫ default (⊥_ C ⟶ B)), |
| 268 | + hom_inv_id' := |
| 269 | + begin |
| 270 | + rw [← curry_natural_left, curry_eq_iff, ← cancel_epi mul_zero.inv], |
| 271 | + { apply subsingleton.elim }, |
| 272 | + { apply_instance }, |
| 273 | + { apply_instance } |
| 274 | + end } |
| 275 | + |
| 276 | +-- TODO: Generalise the below to its commutated variants. |
| 277 | +-- TODO: Define a distributive category, so that zero_mul and friends can be derived from this. |
| 278 | +/-- In a CCC with binary coproducts, the distribution morphism is an isomorphism. -/ |
| 279 | +def prod_coprod_distrib [has_binary_coproducts.{v} C] [cartesian_closed C] (X Y Z : C) : |
| 280 | + (Z ⨯ X) ⨿ (Z ⨯ Y) ≅ Z ⨯ (X ⨿ Y) := |
| 281 | +{ hom := coprod.desc (limits.prod.map (𝟙 _) coprod.inl) (limits.prod.map (𝟙 _) coprod.inr), |
| 282 | + inv := uncurry (coprod.desc (curry coprod.inl) (curry coprod.inr)), |
| 283 | + hom_inv_id' := |
| 284 | + begin |
| 285 | + apply coprod.hom_ext, |
| 286 | + rw [coprod.inl_desc_assoc, comp_id, ← uncurry_natural_left, coprod.inl_desc, uncurry_curry], |
| 287 | + rw [coprod.inr_desc_assoc, comp_id, ← uncurry_natural_left, coprod.inr_desc, uncurry_curry], |
| 288 | + end, |
| 289 | + inv_hom_id' := |
| 290 | + begin |
| 291 | + rw [← uncurry_natural_right, ← eq_curry_iff], |
| 292 | + apply coprod.hom_ext, |
| 293 | + rw [coprod.inl_desc_assoc, ← curry_natural_right, coprod.inl_desc, ← curry_natural_left, comp_id], |
| 294 | + rw [coprod.inr_desc_assoc, ← curry_natural_right, coprod.inr_desc, ← curry_natural_left, comp_id], |
| 295 | + end } |
| 296 | + |
| 297 | +/-- |
| 298 | +If an initial object `0` exists in a CCC then it is a strict initial object, |
| 299 | +i.e. any morphism to `0` is an iso. |
| 300 | +-/ |
| 301 | +instance strict_initial [has_initial.{v} C] {f : A ⟶ ⊥_ C} : is_iso f := |
| 302 | +begin |
| 303 | + haveI : mono (limits.prod.lift (𝟙 A) f ≫ zero_mul.hom) := mono_comp _ _, |
| 304 | + rw [zero_mul_hom, prod.lift_snd] at _inst, |
| 305 | + haveI: split_epi f := ⟨default _, subsingleton.elim _ _⟩, |
| 306 | + apply is_iso_of_mono_of_split_epi |
| 307 | +end |
| 308 | + |
| 309 | +/-- If an initial object `0` exists in a CCC then every morphism from it is monic. -/ |
| 310 | +instance initial_mono (B : C) [has_initial.{v} C] [cartesian_closed C] : mono (initial.to B) := |
| 311 | +⟨λ B g h _, eq_of_inv_eq_inv (subsingleton.elim (inv g) (inv h))⟩ |
| 312 | + |
| 313 | +variables {D : Type u₂} [category.{v} D] |
| 314 | +section functor |
| 315 | + |
| 316 | +variables [has_finite_products.{v} D] |
| 317 | + |
| 318 | +/-- |
| 319 | +Transport the property of being cartesian closed across an equivalence of categories. |
| 320 | +
|
| 321 | +Note we didn't require any coherence between the choice of finite products here, since we transport |
| 322 | +along the `prod_comparison` isomorphism. |
| 323 | +-/ |
| 324 | +def cartesian_closed_of_equiv (e : C ≌ D) [h : cartesian_closed C] : cartesian_closed D := |
| 325 | +{ closed := λ X, |
| 326 | + { is_adj := |
| 327 | + begin |
| 328 | + haveI q : exponentiable (e.inverse.obj X) := infer_instance, |
| 329 | + have : is_left_adjoint (prod_functor.obj (e.inverse.obj X)) := q.is_adj, |
| 330 | + have: e.functor ⋙ prod_functor.obj X ⋙ e.inverse ≅ prod_functor.obj (e.inverse.obj X), |
| 331 | + apply nat_iso.of_components _ _, |
| 332 | + intro Y, |
| 333 | + apply as_iso (prod_comparison e.inverse X (e.functor.obj Y)) ≪≫ _, |
| 334 | + refine ⟨limits.prod.map (𝟙 _) (e.unit_inv.app _), |
| 335 | + limits.prod.map (𝟙 _) (e.unit.app _), |
| 336 | + by simpa [← prod_map_id_comp, prod_map_id_id], |
| 337 | + by simpa [← prod_map_id_comp, prod_map_id_id]⟩, |
| 338 | + intros Y Z g, |
| 339 | + simp only [prod_comparison, inv_prod_comparison_map_fst, inv_prod_comparison_map_snd, |
| 340 | + prod.lift_map, equivalence.unit_inv, functor.comp_map, |
| 341 | + prod_functor_obj_map, assoc, comp_id, iso.trans_hom, as_iso_hom], |
| 342 | + apply prod.hom_ext, |
| 343 | + rw [assoc, prod.lift_fst, prod.lift_fst, ← functor.map_comp, limits.prod.map_fst, comp_id], |
| 344 | + rw [assoc, prod.lift_snd, prod.lift_snd, ← functor.map_comp_assoc, limits.prod.map_snd], |
| 345 | + simp only [equivalence.unit, equivalence.unit_inv, nat_iso.hom_inv_id_app, assoc, equivalence.inv_fun_map, functor.map_comp, comp_id], |
| 346 | + erw comp_id, |
| 347 | + haveI : is_left_adjoint (e.functor ⋙ prod_functor.obj X ⋙ e.inverse) := adjunction.left_adjoint_of_nat_iso this.symm, |
| 348 | + haveI : is_left_adjoint (e.inverse ⋙ e.functor ⋙ prod_functor.obj X ⋙ e.inverse) := adjunction.left_adjoint_of_comp e.inverse _, |
| 349 | + have : (e.inverse ⋙ e.functor ⋙ prod_functor.obj X ⋙ e.inverse) ⋙ e.functor ≅ prod_functor.obj X, |
| 350 | + apply iso_whisker_right e.counit_iso (prod_functor.obj X ⋙ e.inverse ⋙ e.functor) ≪≫ _, |
| 351 | + change prod_functor.obj X ⋙ e.inverse ⋙ e.functor ≅ prod_functor.obj X, |
| 352 | + apply iso_whisker_left (prod_functor.obj X) e.counit_iso, |
| 353 | + apply adjunction.left_adjoint_of_nat_iso this, |
| 354 | + end } } |
| 355 | + |
| 356 | +variables [cartesian_closed C] [cartesian_closed D] |
| 357 | +variables (F : C ⥤ D) [preserves_limits_of_shape (discrete walking_pair) F] |
| 358 | + |
| 359 | +/-- |
| 360 | +The exponential comparison map. |
| 361 | +`F` is a cartesian closed functor if this is an iso for all `A,B`. |
| 362 | +-/ |
| 363 | +def exp_comparison (A B : C) : |
| 364 | + F.obj (A ⟹ B) ⟶ F.obj A ⟹ F.obj B := |
| 365 | +curry (inv (prod_comparison F A _) ≫ F.map ((ev _).app _)) |
| 366 | + |
| 367 | +/-- The exponential comparison map is natural in its left argument. -/ |
| 368 | +lemma exp_comparison_natural_left (A A' B : C) (f : A' ⟶ A) : |
| 369 | + exp_comparison F A B ≫ pre (F.obj B) (F.map f) = F.map (pre B f) ≫ exp_comparison F A' B := |
| 370 | +begin |
| 371 | + rw [exp_comparison, exp_comparison, ← curry_natural_left, eq_curry_iff, uncurry_natural_left, |
| 372 | + pre, uncurry_curry, prod_map_map_assoc, curry_eq, prod_map_id_comp, assoc], |
| 373 | + erw [(ev _).naturality, ev_coev_assoc, ← F.map_id, ← prod_comparison_inv_natural_assoc, |
| 374 | + ← F.map_id, ← prod_comparison_inv_natural_assoc, ← F.map_comp, ← F.map_comp, pre, curry_eq, |
| 375 | + prod_map_id_comp, assoc, (ev _).naturality, ev_coev_assoc], refl, |
| 376 | +end |
| 377 | + |
| 378 | +/-- The exponential comparison map is natural in its right argument. -/ |
| 379 | +lemma exp_comparison_natural_right (A B B' : C) (f : B ⟶ B') : |
| 380 | + exp_comparison F A B ≫ (exp (F.obj A)).map (F.map f) = F.map ((exp A).map f) ≫ exp_comparison F A B' := |
| 381 | +by |
| 382 | + erw [exp_comparison, ← curry_natural_right, curry_eq_iff, exp_comparison, uncurry_natural_left, |
| 383 | + uncurry_curry, assoc, ← F.map_comp, ← (ev _).naturality, F.map_comp, |
| 384 | + prod_comparison_inv_natural_assoc, F.map_id] |
| 385 | + |
| 386 | +-- TODO: If F has a left adjoint L, then F is cartesian closed if and only if |
| 387 | +-- L (B ⨯ F A) ⟶ L B ⨯ L F A ⟶ L B ⨯ A |
| 388 | +-- is an iso for all A ∈ D, B ∈ C. |
| 389 | +-- Corollary: If F has a left adjoint L which preserves finite products, F is cartesian closed iff |
| 390 | +-- F is full and faithful. |
| 391 | + |
| 392 | +end functor |
| 393 | + |
| 394 | +end category_theory |
0 commit comments