Other Agda modules in this section (54)

Complete compiler-highlighted source. Follow a symbol to its declaration.

Corresponding book passages
# The internal exponential law

This proves `lem:Internal_Adjunction_Product_Fun`. The preferred functor
curries double evaluation; the inverse curries evaluation twice. The
equivalence is proved by testing on mapping animae, uncurrying twice,
and reassociating the parameter product.

```agda
{-# OPTIONS --safe --without-K #-}
open import Agda.Primitive using (Level)
open import SCT.VolumeI.Chapter01.Theory using (Theory)
import SCT.VolumeI.Chapter01.Section04.MappingAnimae as Mapping
import SCT.VolumeI.Chapter01.Section07.FunctorCategories as Categories

module SCT.VolumeI.Chapter01.Section07.ExponentialLaw
  {c m a : Level} (𝒯 : Theory c m a) (M : Mapping.MappingAnimae 𝒯)
  (F : Categories.FunctorCategories 𝒯 M) where

open import SCT.VolumeI.Chapter01.Section05.Setup 𝒯 M
open import SCT.VolumeI.Chapter01.Section04.Uncurrying 𝒯 M using (module Reassociation)
open import SCT.VolumeI.Chapter01.Section07.Currying 𝒯 M F

open import SCT.VolumeI.Chapter01.Section07.EvaluationCalculus.MappingTests 𝒯 M F
  using (module Test; fourfold-regroup)
open import SCT.VolumeI.Chapter01.Section04.EquivalenceDetection 𝒯 M using (post-tests-all)

module ExponentialLaw (X C D : CAT) where
  Nested : CAT
  Nested = Fun X (Fun C D)

  Flat : CAT
  Flat = Fun (X Γ— C) D

  doubleUncurry : {Z : CAT} β†’ MAP Z Nested β†’ MAP ((Z Γ— X) Γ— C) D
  doubleUncurry f = funUncurry (funUncurry f)

  doubleEvaluation : MAP ((Nested Γ— X) Γ— C) D
  doubleEvaluation = funUncurry (funEval {X} {Fun C D})

  forwardEvaluation : MAP (Nested Γ— (X Γ— C)) D
  forwardEvaluation = doubleEvaluation ∘ Associativity.backward Nested X C

  forward : MAP Nested Flat
  forward = funCurry forwardEvaluation

  backwardEvaluation : MAP ((Flat Γ— X) Γ— C) D
  backwardEvaluation = funEval ∘ Associativity.forward Flat X C

  backwardFirstCurry : MAP (Flat Γ— X) (Fun C D)
  backwardFirstCurry = funCurry backwardEvaluation

  backward : MAP Flat Nested
  backward = funCurry backwardFirstCurry

  forward-Ξ² : (funUncurry forward) =₁ forwardEvaluation
  forward-Ξ² = funCurry-Ξ² forwardEvaluation

  backward-Ξ² : (doubleUncurry backward) =₁ backwardEvaluation
  backward-Ξ² = funCurry-Ξ² backwardEvaluation βˆ™
    funUncurry-cong (funCurry-Ξ² backwardFirstCurry)

  doubleUncurry-restrict : {R Z : CAT} (f : MAP Z Nested) (Οƒ : MAP R Z)
    β†’ (doubleUncurry (f ∘ Οƒ)) =₁
        (doubleUncurry f ∘ productMap (productMap Οƒ (id X)) (id C))
  doubleUncurry-restrict f Οƒ = funUncurry-restrict (funUncurry f) (productMap Οƒ (id X)) βˆ™
    funUncurry-cong (funUncurry-restrict f Οƒ)

  doubleReflect : {Z : CAT} (f g : MAP Z Nested)
    β†’ (doubleUncurry f) =₁ (doubleUncurry g) β†’ f =₁ g
  doubleReflect f g Ξ± = funReflect f g
    (funReflect (funUncurry f) (funUncurry g) Ξ±)

  doubleUncurry-id : (doubleUncurry (id Nested)) =₁ doubleEvaluation
  doubleUncurry-id = funUncurry-cong (funUncurry-id X (Fun C D))
```

Substitution into the two constructions gives their representing formulas.
Each proof separates beta reduction from reassociation of the three factors.

```agda
  forward-represents : {Z : CAT} (f : MAP Z Nested)
    β†’ (funUncurry (forward ∘ f)) =₁
        (doubleUncurry f ∘ Associativity.backward Z X C)
  forward-represents {Z} f =
    let changePair = productMap f (id (X Γ— C))
        changeTriple = productMap (productMap f (id X)) (id C)
        regroup = Associativity.backward Z X C

        substitute : (funUncurry (forward ∘ f)) =₁ (forwardEvaluation ∘ changePair)
        substitute = (forward-Ξ² β–· changePair) βˆ™ funUncurry-restrict forward f

        regroupParameters : (forwardEvaluation ∘ changePair) =₁
          ((doubleEvaluation ∘ changeTriple) ∘ regroup)
        regroupParameters = (comp-assoc regroup changeTriple doubleEvaluation) ⁻¹ βˆ™
          ((doubleEvaluation ◁ Reassociation.backward-natural f) βˆ™
            comp-assoc changePair (Associativity.backward Nested X C) doubleEvaluation)

        evaluate : (doubleEvaluation ∘ changeTriple) =₁ (doubleUncurry f)
        evaluate = (funUncurry-restrict (funEval {X} {Fun C D}) (productMap f (id X))) ⁻¹
    in (evaluate β–· regroup) βˆ™ (regroupParameters βˆ™ substitute)

  backward-represents : {Z : CAT} (f : MAP Z Flat)
    β†’ (doubleUncurry (backward ∘ f)) =₁
        (funUncurry f ∘ Associativity.forward Z X C)
  backward-represents {Z} f =
    let changePair = productMap f (id (X Γ— C))
        changeTriple = productMap (productMap f (id X)) (id C)
        regroup = Associativity.forward Z X C

        substitute : (doubleUncurry (backward ∘ f)) =₁ (backwardEvaluation ∘ changeTriple)
        substitute = (backward-Ξ² β–· changeTriple) βˆ™ doubleUncurry-restrict backward f

        regroupParameters : (backwardEvaluation ∘ changeTriple) =₁
          (funUncurry f ∘ regroup)
        regroupParameters = (comp-assoc regroup changePair funEval) ⁻¹ βˆ™
          ((funEval ◁ Reassociation.forward-natural f) βˆ™
            comp-assoc changeTriple (Associativity.forward Flat X C) funEval)
    in regroupParameters βˆ™ substitute
```

For each test category, the source route uncurries twice and restricts
along the product associator. The target route uncurries once. The
representing formula above identifies `mapPost forward` with this chain.
The four-factor calculation only identifies functors; it does not assert
an unstated higher coherence for the product associators.

```agda
  module OnMaps (T : CAT) where
    module First = Test T X (Fun C D)
    module Second = Test (T Γ— X) C D
    module FlatTest = Test T (X Γ— C) D
    A = Map T Nested
    r = Associativity.backward T X C
    k = productMap (id A) r
    b₁ = Associativity.backward A T (X Γ— C)
    bβ‚‚ = Associativity.backward (A Γ— T) X C
    b₃ = Associativity.backward A (T Γ— X) C
    e = productMap (Associativity.backward A T X) (id C)
    evaluation = doubleUncurry (mapEval {T} {Nested})
    normal = evaluation ∘ (bβ‚‚ ∘ b₁)

    sourceComparison = mapPre r ∘ (Second.forward ∘ First.forward)

    source-isEquiv : IsEquiv sourceComparison
    source-isEquiv = equiv-compose (Second.forward ∘ First.forward) (mapPre r)
      (equiv-compose First.forward Second.forward First.forward-isEquiv Second.forward-isEquiv)
      (mapPre-isEquiv r (equiv-inverse (Associativity.forward-isEquiv T X C)))

    source-evaluation : (mapUncurry sourceComparison) =₁ normal
    source-evaluation = (evaluation ◁ (fourfold-regroup A T X C) ⁻¹) βˆ™
      (comp-assoc (b₃ ∘ k) e evaluation βˆ™
      (((funUncurry-restrict (funUncurry mapEval) (Associativity.backward A T X) βˆ™
          funUncurry-cong (mapCurry-Ξ² (map-isAn T Nested) First.evaluation)) β–· (b₃ ∘ k)) βˆ™
      (comp-assoc k b₃ (funUncurry (mapUncurry First.forward)) βˆ™
      ((Second.represents First.forward β–· k) βˆ™
        mapPre-uncurry r (Second.forward ∘ First.forward)))))

    tested-evaluation : (mapUncurry (FlatTest.forward ∘ mapPost forward)) =₁ normal
    tested-evaluation = comp-assoc b₁ bβ‚‚ evaluation βˆ™
      ((forward-represents mapEval β–· b₁) βˆ™
      ((funUncurry-cong (mapPost-Ξ² forward) β–· b₁) βˆ™
        FlatTest.represents (mapPost forward)))

    comparison-square : (FlatTest.forward ∘ mapPost forward) =₁ sourceComparison
    comparison-square = mapReflect (map-isAn T Nested) _ _
      (source-evaluation ⁻¹ βˆ™ tested-evaluation)

    comparison-isEquiv : IsEquiv (mapPost {C = T} forward)
    comparison-isEquiv = equiv-cancel-left (mapPost forward) FlatTest.forward
      FlatTest.forward-isEquiv (equiv-transport (comparison-square ⁻¹) source-isEquiv)

  forward-isEquiv : IsEquiv forward
  forward-isEquiv = post-tests-all forward OnMaps.comparison-isEquiv
```

The backward functor described in the manuscript is indeed an inverse.
Its evaluation formula gives the first comparison; the second follows by
reflection through the equivalence already proved on mapping animae.
These computations are not used to establish that equivalence.

```agda
  forward-backward : (forward ∘ backward) =₁ (id Flat)
  forward-backward = funReflect _ _
    ((funUncurry-id (X Γ— C) D) ⁻¹ βˆ™
    (comp-unitΚ³ funEval βˆ™
    ((funEval ◁ Associativity.forward-backward Flat X C) βˆ™
    (comp-assoc (Associativity.backward Flat X C) (Associativity.forward Flat X C) funEval βˆ™
    ((backward-Ξ² β–· Associativity.backward Flat X C) βˆ™ forward-represents backward)))))

  backward-forward : (backward ∘ forward) =₁ (id Nested)
  backward-forward = equiv-reflect forward-isEquiv _ _
    ((comp-unitΚ³ forward) ⁻¹ βˆ™
    (comp-unitΛ‘ forward βˆ™
    ((forward-backward β–· forward) βˆ™ (comp-assoc forward backward forward) ⁻¹)))
```