# 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.morphisms-arrows 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 | \ | ∨ ∨ ∨ 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-product : (A × C) → (B × D) pr1 (map-product t) = f (pr1 t) pr2 (map-product t) = g (pr2 t) map-product-pr1 : pr1 ∘ map-product ~ f ∘ pr1 map-product-pr1 (a , c) = refl map-product-pr2 : pr2 ∘ map-product ~ g ∘ pr2 map-product-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-product : coherence-square-maps ( map-product f id) ( map-product id g) ( map-product id g) ( map-product f id) coherence-square-map-product t = refl ``` ## Properties ### Functoriality of products preserves identity maps ```agda map-product-id : {l1 l2 : Level} {A : UU l1} {B : UU l2} → map-product (id {A = A}) (id {A = B}) ~ id map-product-id (a , b) = refl ``` ### Functoriality of products preserves composition ```agda preserves-comp-map-product : {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-product (h ∘ f) (k ∘ g) ~ map-product h k ∘ map-product f g preserves-comp-map-product f g h k t = refl ``` ### Functoriality of products preserves homotopies ```agda htpy-map-product : {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-product f g ~ map-product f' g' htpy-map-product 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-product : (f : A → C) (g : B → D) → is-equiv f → is-equiv g → C × D → A × B pr1 (map-inv-map-product f g H K (c , d)) = map-inv-is-equiv H c pr2 (map-inv-map-product f g H K (c , d)) = map-inv-is-equiv K d is-section-map-inv-map-product : (f : A → C) (g : B → D) (H : is-equiv f) (K : is-equiv g) → map-product f g ∘ map-inv-map-product f g H K ~ id is-section-map-inv-map-product f g H K = htpy-map-product ( is-section-map-inv-is-equiv H) ( is-section-map-inv-is-equiv K) is-retraction-map-inv-map-product : (f : A → C) (g : B → D) (H : is-equiv f) (K : is-equiv g) → map-inv-map-product f g H K ∘ map-product f g ~ id is-retraction-map-inv-map-product f g H K = htpy-map-product ( is-retraction-map-inv-is-equiv H) ( is-retraction-map-inv-is-equiv K) is-equiv-map-product : (f : A → C) (g : B → D) → is-equiv f → is-equiv g → is-equiv (map-product f g) is-equiv-map-product f g H K = is-equiv-is-invertible ( map-inv-map-product f g H K) ( is-section-map-inv-map-product f g H K) ( is-retraction-map-inv-map-product f g H K) equiv-product : A ≃ C → B ≃ D → A × B ≃ C × D pr1 (equiv-product (f , is-equiv-f) (g , is-equiv-g)) = map-product f g pr2 (equiv-product (f , is-equiv-f) (g , is-equiv-g)) = is-equiv-map-product 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-product-left : A ≃ C → A × B ≃ C × B equiv-product-left f = equiv-product f id-equiv equiv-product-right : B ≃ C → A × B ≃ A × C equiv-product-right = equiv-product id-equiv ``` ### The fibers of `map-product 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-product : fiber (map-product f g) t → fiber f (pr1 t) × fiber g (pr2 t) pr1 (pr1 (map-compute-fiber-map-product ((a , b) , refl))) = a pr2 (pr1 (map-compute-fiber-map-product ((a , b) , refl))) = refl pr1 (pr2 (map-compute-fiber-map-product ((a , b) , refl))) = b pr2 (pr2 (map-compute-fiber-map-product ((a , b) , refl))) = refl map-inv-compute-fiber-map-product : fiber f (pr1 t) × fiber g (pr2 t) → fiber (map-product f g) t pr1 (pr1 (map-inv-compute-fiber-map-product ((x , refl) , (y , refl)))) = x pr2 (pr1 (map-inv-compute-fiber-map-product ((x , refl) , (y , refl)))) = y pr2 (map-inv-compute-fiber-map-product ((x , refl) , (y , refl))) = refl is-section-map-inv-compute-fiber-map-product : map-compute-fiber-map-product ∘ map-inv-compute-fiber-map-product ~ id is-section-map-inv-compute-fiber-map-product ((x , refl) , (y , refl)) = refl is-retraction-map-inv-compute-fiber-map-product : map-inv-compute-fiber-map-product ∘ map-compute-fiber-map-product ~ id is-retraction-map-inv-compute-fiber-map-product ((a , b) , refl) = refl is-equiv-map-compute-fiber-map-product : is-equiv map-compute-fiber-map-product is-equiv-map-compute-fiber-map-product = is-equiv-is-invertible ( map-inv-compute-fiber-map-product) ( is-section-map-inv-compute-fiber-map-product) ( is-retraction-map-inv-compute-fiber-map-product) compute-fiber-map-product : fiber (map-product f g) t ≃ (fiber f (pr1 t) × fiber g (pr2 t)) pr1 compute-fiber-map-product = map-compute-fiber-map-product pr2 compute-fiber-map-product = is-equiv-map-compute-fiber-map-product ``` ### If `map-product 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-product' : D → is-equiv (map-product f g) → is-equiv f is-equiv-left-factor-is-equiv-map-product' d is-equiv-fg = is-equiv-is-contr-map ( λ x → is-contr-left-factor-product ( fiber f x) ( fiber g d) ( is-contr-is-equiv' ( fiber (map-product f g) (x , d)) ( map-compute-fiber-map-product f g (x , d)) ( is-equiv-map-compute-fiber-map-product f g (x , d)) ( is-contr-map-is-equiv is-equiv-fg (x , d)))) is-equiv-right-factor-is-equiv-map-product' : C → is-equiv (map-product f g) → is-equiv g is-equiv-right-factor-is-equiv-map-product' c is-equiv-fg = is-equiv-is-contr-map ( λ y → is-contr-right-factor-product ( fiber f c) ( fiber g y) ( is-contr-is-equiv' ( fiber (map-product f g) (c , y)) ( map-compute-fiber-map-product f g (c , y)) ( is-equiv-map-compute-fiber-map-product f g (c , y)) ( is-contr-map-is-equiv is-equiv-fg (c , y)))) ``` ### The functorial action of products on arrows Given a pair of [morphisms of arrows](foundation.morphisms-arrows.md) `α : f → g` and `β : h → i`, there is an induced morphism of arrows `α × β : f × h → g × i` and this construction is functorial. ```agda module _ {l1 l2 l3 l4 l5 l6 l7 l8 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {Y : UU l4} {C : UU l5} {D : UU l6} {Z : UU l7} {W : UU l8} (f : A → B) (g : X → Y) (h : C → D) (i : Z → W) (α : hom-arrow f g) (β : hom-arrow h i) where product-hom-arrow : hom-arrow (map-product f h) (map-product g i) product-hom-arrow = ( ( map-product ( map-domain-hom-arrow f g α) ( map-domain-hom-arrow h i β)) , ( map-product ( map-codomain-hom-arrow f g α) ( map-codomain-hom-arrow h i β)) , ( htpy-map-product ( coh-hom-arrow f g α) ( coh-hom-arrow h i β))) ``` ## 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).