# Functoriality of cartesian product types ```agda module foundation.functoriality-cartesian-product-types where ``` <details><summary>Imports</summary> ```agda open import foundation.dependent-pair-types open import foundation.equality-cartesian-product-types open import foundation.universe-levels open import foundation-core.cartesian-product-types open import foundation-core.commuting-squares-of-maps open import foundation-core.contractible-maps open import foundation-core.contractible-types open import foundation-core.equivalences open import foundation-core.fibers-of-maps open import foundation-core.function-types open import foundation-core.homotopies open import foundation-core.identity-types ``` </details> ## Idea The **functorial action** of the [cartesian product](foundation-core.cartesian-product-types.md) takes two maps `f : A → B` and `g : C → D` and returns a map ```text f × g : A × B → C × D` ``` between the cartesian product types. This functorial action is _bifunctorial_ in the sense that for any two maps `f : A → B` and `g : C → D` the diagram ```text f×1 A × C ---> B × C | \ | 1×g | \f×g | 1×g | \ | V > V A × D ---> B × D f×1 ``` commutes. ## Definitions ### The functorial action of cartesian product types ```agda module _ {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} (f : A → B) (g : C → D) where map-prod : (A × C) → (B × D) pr1 (map-prod t) = f (pr1 t) pr2 (map-prod t) = g (pr2 t) map-prod-pr1 : pr1 ∘ map-prod ~ f ∘ pr1 map-prod-pr1 (a , c) = refl map-prod-pr2 : pr2 ∘ map-prod ~ g ∘ pr2 map-prod-pr2 (a , c) = refl module _ {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} (f : A → B) (g : C → D) where coherence-square-map-prod : coherence-square-maps ( map-prod f id) ( map-prod id g) ( map-prod id g) ( map-prod f id) coherence-square-map-prod t = refl ``` ## Properties ### Functoriality of products preserves identity maps ```agda map-prod-id : {l1 l2 : Level} {A : UU l1} {B : UU l2} → map-prod (id {A = A}) (id {A = B}) ~ id map-prod-id (a , b) = refl ``` ### Functoriality of products preserves composition ```agda map-prod-comp : {l1 l2 l3 l4 l5 l6 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} {E : UU l5} {F : UU l6} (f : A → C) (g : B → D) (h : C → E) (k : D → F) → map-prod (h ∘ f) (k ∘ g) ~ map-prod h k ∘ map-prod f g map-prod-comp f g h k t = refl ``` ### Functoriality of products preserves homotopies ```agda htpy-map-prod : {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} {f f' : A → C} (H : f ~ f') {g g' : B → D} (K : g ~ g') → map-prod f g ~ map-prod f' g' htpy-map-prod H K (a , b) = eq-pair (H a) (K b) ``` ### Functoriality of products preserves equivalences ```agda module _ {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} where map-inv-map-prod : (f : A → C) (g : B → D) → is-equiv f → is-equiv g → C × D → A × B pr1 (map-inv-map-prod f g H K (c , d)) = map-inv-is-equiv H c pr2 (map-inv-map-prod f g H K (c , d)) = map-inv-is-equiv K d is-section-map-inv-map-prod : (f : A → C) (g : B → D) (H : is-equiv f) (K : is-equiv g) → map-prod f g ∘ map-inv-map-prod f g H K ~ id is-section-map-inv-map-prod f g H K = htpy-map-prod ( is-section-map-inv-is-equiv H) ( is-section-map-inv-is-equiv K) is-retraction-map-inv-map-prod : (f : A → C) (g : B → D) (H : is-equiv f) (K : is-equiv g) → map-inv-map-prod f g H K ∘ map-prod f g ~ id is-retraction-map-inv-map-prod f g H K = htpy-map-prod ( is-retraction-map-inv-is-equiv H) ( is-retraction-map-inv-is-equiv K) is-equiv-map-prod : (f : A → C) (g : B → D) → is-equiv f → is-equiv g → is-equiv (map-prod f g) is-equiv-map-prod f g H K = is-equiv-is-invertible ( map-inv-map-prod f g H K) ( is-section-map-inv-map-prod f g H K) ( is-retraction-map-inv-map-prod f g H K) equiv-prod : A ≃ C → B ≃ D → A × B ≃ C × D pr1 (equiv-prod (f , is-equiv-f) (g , is-equiv-g)) = map-prod f g pr2 (equiv-prod (f , is-equiv-f) (g , is-equiv-g)) = is-equiv-map-prod f g is-equiv-f is-equiv-g ``` ### Functoriality of products preserves equivalences in either factor ```agda module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {C : UU l3} where equiv-prod-left : A ≃ C → A × B ≃ C × B equiv-prod-left f = equiv-prod f id-equiv equiv-prod-right : B ≃ C → A × B ≃ A × C equiv-prod-right = equiv-prod id-equiv ``` ### The fibers of `map-prod f g` ```agda module _ {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} (f : A → C) (g : B → D) (t : C × D) where map-compute-fiber-map-prod : fiber (map-prod f g) t → fiber f (pr1 t) × fiber g (pr2 t) pr1 (pr1 (map-compute-fiber-map-prod ((a , b) , refl))) = a pr2 (pr1 (map-compute-fiber-map-prod ((a , b) , refl))) = refl pr1 (pr2 (map-compute-fiber-map-prod ((a , b) , refl))) = b pr2 (pr2 (map-compute-fiber-map-prod ((a , b) , refl))) = refl map-inv-compute-fiber-map-prod : fiber f (pr1 t) × fiber g (pr2 t) → fiber (map-prod f g) t pr1 (pr1 (map-inv-compute-fiber-map-prod ((x , refl) , (y , refl)))) = x pr2 (pr1 (map-inv-compute-fiber-map-prod ((x , refl) , (y , refl)))) = y pr2 (map-inv-compute-fiber-map-prod ((x , refl) , (y , refl))) = refl is-section-map-inv-compute-fiber-map-prod : map-compute-fiber-map-prod ∘ map-inv-compute-fiber-map-prod ~ id is-section-map-inv-compute-fiber-map-prod ((x , refl) , (y , refl)) = refl is-retraction-map-inv-compute-fiber-map-prod : map-inv-compute-fiber-map-prod ∘ map-compute-fiber-map-prod ~ id is-retraction-map-inv-compute-fiber-map-prod ((a , b) , refl) = refl is-equiv-map-compute-fiber-map-prod : is-equiv map-compute-fiber-map-prod is-equiv-map-compute-fiber-map-prod = is-equiv-is-invertible ( map-inv-compute-fiber-map-prod) ( is-section-map-inv-compute-fiber-map-prod) ( is-retraction-map-inv-compute-fiber-map-prod) compute-fiber-map-prod : fiber (map-prod f g) t ≃ (fiber f (pr1 t) × fiber g (pr2 t)) pr1 compute-fiber-map-prod = map-compute-fiber-map-prod pr2 compute-fiber-map-prod = is-equiv-map-compute-fiber-map-prod ``` ### If `map-prod f g : A × B → C × D` is an equivalence, then we have `D → is-equiv f` and `C → is-equiv g` ```agda module _ {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} (f : A → C) (g : B → D) where is-equiv-left-factor-is-equiv-map-prod : (d : D) → is-equiv (map-prod f g) → is-equiv f is-equiv-left-factor-is-equiv-map-prod d is-equiv-fg = is-equiv-is-contr-map ( λ x → is-contr-left-factor-prod ( fiber f x) ( fiber g d) ( is-contr-is-equiv' ( fiber (map-prod f g) (x , d)) ( map-compute-fiber-map-prod f g (x , d)) ( is-equiv-map-compute-fiber-map-prod f g (x , d)) ( is-contr-map-is-equiv is-equiv-fg (x , d)))) is-equiv-right-factor-is-equiv-map-prod : (c : C) → is-equiv (map-prod f g) → is-equiv g is-equiv-right-factor-is-equiv-map-prod c is-equiv-fg = is-equiv-is-contr-map ( λ y → is-contr-right-factor-prod ( fiber f c) ( fiber g y) ( is-contr-is-equiv' ( fiber (map-prod f g) (c , y)) ( map-compute-fiber-map-prod f g (c , y)) ( is-equiv-map-compute-fiber-map-prod f g (c , y)) ( is-contr-map-is-equiv is-equiv-fg (c , y)))) ``` ## See also - Arithmetical laws involving cartesian product types are recorded in [`foundation.type-arithmetic-cartesian-product-types`](foundation.type-arithmetic-cartesian-product-types.md). - Equality proofs in cartesian product types are characterized in [`foundation.equality-cartesian-product-types`](foundation.equality-cartesian-product-types.md). - The universal property of cartesian product types is treated in [`foundation.universal-property-cartesian-product-types`](foundation.universal-property-cartesian-product-types.md). - Functorial properties of dependent pair types are recorded in [`foundation.functoriality-dependent-pair-types`](foundation.functoriality-dependent-pair-types.md). - Functorial properties of dependent product types are recorded in [`foundation.functoriality-dependent-function-types`](foundation.functoriality-dependent-function-types.md). - Functorial properties of coproduct types are recorded in [`foundation.functoriality-coproduct-types`](foundation.functoriality-coproduct-types.md).