# The universal properties of cartesian product types ```agda module foundation.universal-property-cartesian-product-types where ``` <details><summary>Imports</summary> ```agda open import foundation.cones-over-cospan-diagrams open import foundation.dependent-pair-types open import foundation.logical-equivalences open import foundation.standard-pullbacks open import foundation.unit-type open import foundation.universal-property-dependent-pair-types open import foundation.universe-levels open import foundation-core.cartesian-product-types open import foundation-core.contractible-types open import foundation-core.equivalences open import foundation-core.function-types open import foundation-core.homotopies open import foundation-core.identity-types open import foundation-core.pullbacks open import foundation-core.retractions open import foundation-core.sections open import foundation-core.universal-property-pullbacks ``` </details> ## Idea [Cartesian products](foundation-core.cartesian-product-types.md) have universal properties both as limits and as colimits of types. The {{#concept "universal property of cartesian products as limits"}} states that, given types `A`, `B` and `X`, maps _into_ the cartesian product `X → A × B` are in [correspondence](foundation-core.equivalences.md) with pairs of maps `X → A` and `X → B`. The {{#concept "universal property of cartesian products as colimits"}} states that maps _out of_ the cartesian product `A × B → X` are in correspondence with "curried" maps `A → B → X`. Observe that the universal property of cartesian products as limits can be understood as a categorified version of the familiar distributivity of exponents over products $$ (A × B)^X ≃ A^X × B^X, $$ while the universal property of cartesian products as colimits are a categorified version of the identity $$ X^{(A × B)} ≃ {(X^B)}^A. $$ ## Theorems ### The universal property of cartesian products as limits ```agda module _ {l1 l2 l3 : Level} {X : UU l1} {A : X → UU l2} {B : X → UU l3} where map-up-product : ((x : X) → A x × B x) → ((x : X) → A x) × ((x : X) → B x) pr1 (map-up-product f) x = pr1 (f x) pr2 (map-up-product f) x = pr2 (f x) map-inv-up-product : (((x : X) → A x) × ((x : X) → B x)) → (x : X) → A x × B x pr1 (map-inv-up-product (f , g) x) = f x pr2 (map-inv-up-product (f , g) x) = g x iff-up-product : ((x : X) → A x × B x) ↔ ((x : X) → A x) × ((x : X) → B x) iff-up-product = (map-up-product , map-inv-up-product) up-product : is-equiv map-up-product up-product = is-equiv-is-invertible (map-inv-up-product) (refl-htpy) (refl-htpy) is-equiv-map-inv-up-product : is-equiv map-inv-up-product is-equiv-map-inv-up-product = is-equiv-map-inv-is-equiv up-product equiv-up-product : ((x : X) → A x × B x) ≃ (((x : X) → A x) × ((x : X) → B x)) pr1 equiv-up-product = map-up-product pr2 equiv-up-product = up-product inv-equiv-up-product : (((x : X) → A x) × ((x : X) → B x)) ≃ ((x : X) → A x × B x) inv-equiv-up-product = inv-equiv equiv-up-product ``` #### The universal property of cartesian products as pullbacks A different way to state the universal property of cartesian products as limits is to say that the canonical [cone](foundation.cones-over-cospan-diagrams.md) over the [terminal type `unit`](foundation.unit-type.md) ```text pr2 A × B ------> B | | pr1 | | ∨ ∨ A -------> unit ``` is a [pullback](foundation-core.pullbacks.md). The [universal property of pullbacks](foundation-core.universal-property-pullbacks.md) states in this case that maps into `A × B` are in correspondence with pairs of maps into `A` and `B` such that the square ```text X --------> B | | | | ∨ ∨ A -------> unit ``` [commutes](foundation-core.commuting-squares-of-maps.md). However, all parallel maps into the terminal type are [equal](foundation-core.identity-types.md), hence the coherence requirement is redundant. We start by constructing the cone for two maps into the unit type. ```agda module _ {l1 l2 : Level} (A : UU l1) (B : UU l2) where cone-cartesian-product : cone (terminal-map A) (terminal-map B) (A × B) pr1 cone-cartesian-product = pr1 pr1 (pr2 cone-cartesian-product) = pr2 pr2 (pr2 cone-cartesian-product) = refl-htpy ``` Next, we show that cartesian products are a special case of pullbacks. ```agda gap-cartesian-product : A × B → standard-pullback (terminal-map A) (terminal-map B) gap-cartesian-product = gap (terminal-map A) (terminal-map B) cone-cartesian-product inv-gap-cartesian-product : standard-pullback (terminal-map A) (terminal-map B) → A × B pr1 (inv-gap-cartesian-product (a , b , p)) = a pr2 (inv-gap-cartesian-product (a , b , p)) = b abstract is-section-inv-gap-cartesian-product : is-section gap-cartesian-product inv-gap-cartesian-product is-section-inv-gap-cartesian-product (a , b , p) = map-extensionality-standard-pullback ( terminal-map A) ( terminal-map B) ( refl) ( refl) ( eq-is-contr (is-prop-unit star star)) is-retraction-inv-gap-cartesian-product : is-retraction gap-cartesian-product inv-gap-cartesian-product is-retraction-inv-gap-cartesian-product (a , b) = refl abstract is-pullback-cartesian-product : is-pullback (terminal-map A) (terminal-map B) cone-cartesian-product is-pullback-cartesian-product = is-equiv-is-invertible inv-gap-cartesian-product is-section-inv-gap-cartesian-product is-retraction-inv-gap-cartesian-product ``` We conclude that cartesian products satisfy the universal property of pullbacks. ```agda abstract universal-property-pullback-cartesian-product : universal-property-pullback ( terminal-map A) ( terminal-map B) ( cone-cartesian-product) universal-property-pullback-cartesian-product = universal-property-pullback-is-pullback ( terminal-map A) ( terminal-map B) ( cone-cartesian-product) ( is-pullback-cartesian-product) ``` ### The universal property of cartesian products as colimits ```agda module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {C : A × B → UU l3} where equiv-ind-product : ((x : A) (y : B) → C (x , y)) ≃ ((t : A × B) → C t) equiv-ind-product = equiv-ind-Σ ```