Other Agda modules in this section (10)
# Mapping animae preserve terminal categories and products
The forward functor pairs the two postcomposition functors. Its inverse
uncurries both components on the whole product of mapping animae, pairs them,
and curries the result. No anima hypothesis is required on the domain E.
Reflection is used only at the displayed mapping anima parameters.
```agda
{-# OPTIONS --without-K #-}
module SCT.VolumeI.Chapter01.Section04.MappingProducts where
open import SCT.VolumeI.Chapter01.Section01.Vocabulary
open Operations
open import SCT.VolumeI.Chapter01.Section01.Terminal
open Constructions
open import SCT.VolumeI.Chapter01.Section02.Coherence
open Composition
open import SCT.VolumeI.Chapter01.Section02.Specialization
open import SCT.VolumeI.Chapter01.Section03.Equivalences
open import SCT.VolumeI.Chapter01.Section03.ProductConstructions
open import SCT.VolumeI.Chapter01.Section02.Products
open Calculus
open import SCT.VolumeI.Chapter01.Section04.MappingAnimae
open import SCT.VolumeI.Chapter01.Section04.Currying
open import SCT.VolumeI.Chapter01.Section04.Functoriality
module _ {Γ : Context} where
map-terminal-contractible : (C : CAT Γ) → IsContractible (Map C One)
map-terminal-contractible C = record
{ inverse = point
; left-inverse-law = uncurry-reflect (map-isAn C One)
(id (Map C One)) (point ∘ terminate (Map C One))
(terminal-identification _ _)
; right-inverse-law = terminal-identification _ _ }
where
point : MAP One (Map C One)
point = mapCurry one-isAn (terminate (One × C))
```
The terminal case is `lem:Mapping_Anima_Into_Terminal_Category`. Its chosen
point names the unique functor into One. Uncurrying reflects the contraction
at the mapping anima itself, so the source category need not be an anima.
```agda
module _ {Γ : Context} where
module ProductEquivalence (E C D : CAT Γ) where
Source : CAT Γ
Source = Map E (C × D)
Target : CAT Γ
Target = Map E C × Map E D
target-isAn : isAn Target
target-isAn = product-isAn (map-isAn E C) (map-isAn E D)
forward : MAP Source Target
forward = pair (mapPost pr₁) (mapPost pr₂)
backward : MAP Target Source
backward = mapCurry target-isAn (pair (uncurry pr₁) (uncurry pr₂))
backward-β : (uncurry backward) =₁
(pair (uncurry pr₁) (uncurry pr₂))
backward-β = mapCurry-β target-isAn _
```
The composite on the product is identified coordinatewise, retaining both
projection comparisons.
```agda
forward-backward-first : (mapPost pr₁ ∘ backward) =₁ pr₁
forward-backward-first = uncurry-reflect target-isAn _ _
(pair-β₁ (uncurry pr₁) (uncurry pr₂) ∙
((pr₁ ◁ backward-β) ∙ mapPost-uncurry pr₁ backward))
forward-backward-second : (mapPost pr₂ ∘ backward) =₁ pr₂
forward-backward-second = uncurry-reflect target-isAn _ _
(pair-β₂ (uncurry pr₁) (uncurry pr₂) ∙
((pr₂ ◁ backward-β) ∙ mapPost-uncurry pr₂ backward))
forward-backward : (forward ∘ backward) =₁ (id Target)
forward-backward = pair₌
((comp-unitʳ pr₁) ⁻¹ ∙
(forward-backward-first ∙ project-pair₁ (mapPost pr₁) (mapPost pr₂) backward))
((comp-unitʳ pr₂) ⁻¹ ∙
(forward-backward-second ∙ project-pair₂ (mapPost pr₁) (mapPost pr₂) backward))
```
The other composite is identified after uncurrying at the mapping anima
Source, using the primary uncurrying action on the projection comparisons.
```agda
substituted-pair :
(pair (uncurry pr₁) (uncurry pr₂) ∘ productMap forward (id E)) =₁
(pair (uncurry (mapPost pr₁)) (uncurry (mapPost pr₂)))
substituted-pair =
pair⁼ (uncurry⁼ (pair-β₁ (mapPost pr₁) (mapPost pr₂)))
(uncurry⁼ (pair-β₂ (mapPost pr₁) (mapPost pr₂))) ∙
(pair⁼ ((uncurry-restrict pr₁ forward) ⁻¹)
((uncurry-restrict pr₂ forward) ⁻¹) ∙
pair-pre (uncurry pr₁) (uncurry pr₂) (productMap forward (id E)))
backward-forward-uncurried : (uncurry (backward ∘ forward)) =₁ mapEval
backward-forward-uncurried = pair-η mapEval ∙
(pair⁼ (mapPost-β pr₁) (mapPost-β pr₂) ∙
(substituted-pair ∙
((backward-β ▷ productMap forward (id E)) ∙ uncurry-restrict backward forward)))
backward-forward : (backward ∘ forward) =₁ (id Source)
backward-forward = uncurry-reflect (map-isAn E (C × D)) _ _
((uncurry-id E (C × D)) ⁻¹ ∙ backward-forward-uncurried)
```
The two displayed inverse comparisons give the equivalence.
```agda
forward-isEquiv : IsEquiv forward
forward-isEquiv = record
{ inverse = backward
; left-inverse-law = backward-forward ⁻¹
; right-inverse-law = forward-backward ⁻¹
}
```
The public comparison is the pair of the two postcomposition maps. Its
equivalence needs no anima assumption on the testing category E.
```agda
module _ {Γ : Context} where
mapping-product : (E C D : CAT Γ)
→ MAP (Map E (C × D)) (Map E C × Map E D)
mapping-product = ProductEquivalence.forward
mapping-product-isEquiv : (E C D : CAT Γ) → IsEquiv (mapping-product E C D)
mapping-product-isEquiv = ProductEquivalence.forward-isEquiv
```