Other Agda modules in this section (15)
# Pairing indexed functors and the product comparison
Pairing curries the pair of native evaluations. Its evaluation triangle,
projection comparisons and substitution law provide the constructions used
by the actual product comparison (`lem:FunctorCategoryIntoProduct`).
```agda
{-# OPTIONS --without-K #-}
module SCT.VolumeI.Chapter01.Section07.FunctorProducts where
open import SCT.VolumeI.Chapter01.Section01.Vocabulary hiding (_=_)
import SCT.VolumeI.Chapter01.Section01.Terms as Terms
open Terms using (Equal)
open Operations
open import SCT.VolumeI.Chapter01.Section01.Terminal
open Constructions
open import SCT.VolumeI.Chapter01.Section02.Coherence
using (comp-unitʳ; module Composition; module Boundaries)
open Composition
open Boundaries using (SquareCell₌)
open import SCT.VolumeI.Chapter01.Section02.Products using (module Calculus)
open Calculus
open import SCT.VolumeI.Chapter01.Section03.ProductConstructions
open import SCT.VolumeI.Chapter01.Section07.Evaluation
open import SCT.VolumeI.Chapter01.Section07.FunctorCategories
open import SCT.VolumeI.Chapter01.Section07.Currying
open import SCT.VolumeI.Chapter01.Section07.Functoriality
module _ {Γ : Context} {E C D : CAT Γ} where
funPair : {T : CAT Γ} → MAP T (Fun E C) → MAP T (Fun E D) → MAP T (Fun E (C × D))
funPair f g = funCurry {C = E} {D = C × D}
(pair (funUncurry {C = E} {D = C} f) (funUncurry {C = E} {D = D} g))
funPair-β : {T : CAT Γ} (f : MAP T (Fun E C)) (g : MAP T (Fun E D))
→ funUncurry {C = E} {D = C × D} (funPair f g) =₁
pair (funUncurry {C = E} {D = C} f) (funUncurry {C = E} {D = D} g)
funPair-β f g = funCurry-β {C = E} {D = C × D} _
module _ {X T : CAT Γ} where
open Terms.Equalities X using (_=_)
funPair⁼ : {f f′ : MAP T (Fun E C)} {g g′ : MAP T (Fun E D)}
→ f = f′ → g = g′ → funPair f g = funPair f′ g′
funPair⁼ α β = curry⁼ (funEval {C = E} {D = C × D}) (funUniversal E (C × D))
(pair⁼ (evaluate⁼ (funEval {C = E} {D = C}) α) (evaluate⁼ (funEval {C = E} {D = D}) β))
funPair⁼-evaluation : {f f′ : MAP T (Fun E C)} {g g′ : MAP T (Fun E D)}
(α : f = f′) (β : g = g′)
→ SquareCell₌ (evaluate⁼ (funEval {C = E} {D = C × D}) (funPair⁼ α β))
(pair⁼ (evaluate⁼ (funEval {C = E} {D = C}) α) (evaluate⁼ (funEval {C = E} {D = D}) β))
(const (funPair-β f g)) (const (funPair-β f′ g′))
funPair⁼-evaluation α β = curry⁼-evaluation (funEval {C = E} {D = C × D})
(funUniversal E (C × D)) _
funPair-projection₁ : {T : CAT Γ} (f : MAP T (Fun E C)) (g : MAP T (Fun E D))
→ (funPost {C = E} pr₁ ∘ funPair f g) =₁ f
funPair-projection₁ f g = reflect (funEval {C = E} {D = C}) (funUniversal E C) _ _
(pair-β₁ (funUncurry {C = E} {D = C} f) (funUncurry {C = E} {D = D} g) ∙
((pr₁ ◁ funPair-β f g) ∙ funPost-uncurry pr₁ (funPair f g)))
funPair-projection₂ : {T : CAT Γ} (f : MAP T (Fun E C)) (g : MAP T (Fun E D))
→ (funPost {C = E} pr₂ ∘ funPair f g) =₁ g
funPair-projection₂ f g = reflect (funEval {C = E} {D = D}) (funUniversal E D) _ _
(pair-β₂ (funUncurry {C = E} {D = C} f) (funUncurry {C = E} {D = D} g) ∙
((pr₂ ◁ funPair-β f g) ∙ funPost-uncurry pr₂ (funPair f g)))
funPair-η : {T : CAT Γ} (h : MAP T (Fun E (C × D)))
→ funPair (funPost {C = E} pr₁ ∘ h) (funPost {C = E} pr₂ ∘ h) =₁ h
funPair-η h = reflect (funEval {C = E} {D = C × D}) (funUniversal E (C × D)) _ _
(pair-η (funUncurry {C = E} {D = C × D} h) ∙
(pair⁼ (funPost-uncurry pr₁ h) (funPost-uncurry pr₂ h) ∙
funPair-β (funPost {C = E} pr₁ ∘ h) (funPost {C = E} pr₂ ∘ h)))
funPair-restrict : {R T : CAT Γ} (f : MAP T (Fun E C)) (g : MAP T (Fun E D)) (r : MAP R T)
→ (funPair f g ∘ r) =₁ funPair (f ∘ r) (g ∘ r)
funPair-restrict f g r = reflect (funEval {C = E} {D = C × D}) (funUniversal E (C × D)) _ _
((funPair-β (f ∘ r) (g ∘ r)) ⁻¹ ∙
(pair⁼ ((evaluate-restrict (funEval {C = E} {D = C}) f r) ⁻¹)
((evaluate-restrict (funEval {C = E} {D = D}) g r) ⁻¹) ∙
(pair-pre (funUncurry {C = E} {D = C} f) (funUncurry {C = E} {D = D} g) (productMap r (id E)) ∙
((funPair-β f g ▷ productMap r (id E)) ∙
evaluate-restrict (funEval {C = E} {D = C × D}) (funPair f g) r))))
```
## The actual product comparison
Its forward functor is the pair of the two specified postcomposition
functors. Pairing the two projections gives its chosen inverse. Projection,
substitution and eta prove both inverse laws.
```agda
module ProductComparison {Γ : Context} (E C D : CAT Γ) where
Source = Fun E (C × D)
Target = Fun E C × Fun E D
private
left : MAP Source (Fun E C)
left = funPost {C = E} pr₁
right : MAP Source (Fun E D)
right = funPost {C = E} pr₂
forward : MAP Source Target
forward = pair left right
backward : MAP Target Source
backward = funPair {E = E} {C = C} {D = D} pr₁ pr₂
forward-backward : (forward ∘ backward) =₁ id Target
forward-backward = pair-projections ∙
(pair⁼ (funPair-projection₁ pr₁ pr₂) (funPair-projection₂ pr₁ pr₂) ∙ pair-pre left right backward)
backward-forward : (backward ∘ forward) =₁ id Source
backward-forward = funPair-η (id Source) ∙
(funPair⁼ ((comp-unitʳ left) ⁻¹ ∙ pair-β₁ left right)
((comp-unitʳ right) ⁻¹ ∙ pair-β₂ left right) ∙ funPair-restrict pr₁ pr₂ forward)
forward-isEquiv : IsEquiv forward
forward-isEquiv = record
{ inverse = backward
; left-inverse-law = backward-forward ⁻¹
; right-inverse-law = forward-backward ⁻¹ }
```