{-# OPTIONS --without-K --safe #-}
module Categories.Category.Instance.Properties.Cats where
open import Data.Product using (_,_)
open import Categories.Category
open import Categories.Category.BinaryProducts using (BinaryProducts)
open import Categories.Category.Cartesian using (Cartesian)
import Categories.Category.CartesianClosed as CCC
import Categories.Category.CartesianClosed.Canonical as Canonical
open import Categories.Category.Construction.Functors
using (Functors; eval; module curry)
open import Categories.Category.Instance.Cats using (Cats)
open import Categories.Category.Monoidal.Instance.Cats
open import Categories.Functor using (Functor; _∘F_) renaming (id to idF)
open import Categories.Functor.Bifunctor using (Bifunctor)
open import Categories.Functor.Construction.Constant using (constNat)
import Categories.Morphism.Reasoning as MR
open import Categories.NaturalTransformation
using (NaturalTransformation; _∘ˡ_) renaming (id to idNT)
open import Categories.NaturalTransformation.NaturalIsomorphism
using (NaturalIsomorphism; _≃_; module LeftRightId)
open import Categories.Object.Terminal using (Terminal)
module CanonicallyCartesianClosed {l} where
private
module Cats = Category (Cats l l l)
module Cart = Cartesian (Product.Cats-is {l} {l} {l})
open Cats using (_⇒_) renaming (Obj to Cat)
open Cart using (products; terminal)
open Terminal terminal
open BinaryProducts products using (_×_; _⁂_; π₁; π₂; ⟨_,_⟩; project₁; project₂; unique)
infixr 9 _^_
_^_ : Cat → Cat → Cat
B ^ A = Functors A B
eval-comp : ∀ {A B C} {G : C × A ⇒ B} → eval ∘F (curry.F₀ G ⁂ idF) ≃ G
eval-comp {A} {B} {C} {G} = record
{ F⇒G = record
{ η = λ _ → id B
; commute = λ _ → ∘-resp-≈ʳ B commute ○ MR.id-comm-sym B
; sym-commute = λ _ → ⟺ (∘-resp-≈ʳ B commute ○ MR.id-comm-sym B)
}
; F⇐G = record
{ η = λ _ → id B
; commute = λ _ → ⟺ (MR.id-comm B ○ ∘-resp-≈ʳ B commute)
; sym-commute = λ _ → MR.id-comm B ○ ∘-resp-≈ʳ B commute
}
; iso = iso-id-id
}
where
open Functor G renaming (F₀ to G₀; F₁ to G₁)
open Category hiding (_∘_)
open Category B using (_∘_)
open HomReasoning B
open LeftRightId G
commute : ∀ {a₁ a₂ b₁ b₂} {f₁ : C [ a₁ , b₁ ]} {f₂ : A [ a₂ , b₂ ]} →
B [ (G₁ (f₁ , id A) ∘ G₁ (id C , f₂)) ≈ G₁ (f₁ , f₂) ]
commute {_} {_} {_} {_} {f₁} {f₂} = begin
G₁ (f₁ , id A) ∘ G₁ (id C , f₂)
≈˘⟨ homomorphism ⟩
G₁ (C [ f₁ ∘ id C ] , A [ id A ∘ f₂ ])
≈⟨ F-resp-≈ (identityʳ C , identityˡ A) ⟩
G₁ (f₁ , f₂)
∎
η-exp : ∀ {A B C} {H : C ⇒ B ^ A} → H ≃ curry.F₀ (eval ∘F (H ⁂ idF))
η-exp {A} {B} {C} {H} = record
{ F⇒G = record
{ η = λ _ → record
{ η = λ _ → id B
; commute = λ f → ⟺ (MR.id-comm B ○ ∘-resp-≈ʳ B (commute₁ f))
; sym-commute = λ f → MR.id-comm B ○ ∘-resp-≈ʳ B (commute₁ f)
}
; commute = λ f → ⟺ (MR.id-comm B ○ ∘-resp-≈ʳ B (commute₂ f))
; sym-commute = λ f → MR.id-comm B ○ ∘-resp-≈ʳ B (commute₂ f)
}
; F⇐G = record
{ η = λ _ → record
{ η = λ _ → id B
; commute = λ f → ∘-resp-≈ʳ B (commute₁ f) ○ MR.id-comm-sym B
; sym-commute = λ f → ⟺ (∘-resp-≈ʳ B (commute₁ f) ○ MR.id-comm-sym B)
}
; commute = λ f → ∘-resp-≈ʳ B (commute₂ f) ○ MR.id-comm-sym B
; sym-commute = λ f → ⟺ (∘-resp-≈ʳ B (commute₂ f) ○ MR.id-comm-sym B)
}
; iso = λ _ → record { isoˡ = identity² B; isoʳ = identity² B }
}
where
open Functor using (identity) renaming (F₁ to _$₁_)
open Functor H hiding (identity) renaming (F₀ to H₀; F₁ to H₁)
open Category hiding (_∘_)
open Category B using (_∘_)
open HomReasoning B
open NaturalTransformation
open LeftRightId H
commute₁ : ∀ {a b c} (f : A [ a , b ]) →
B [ (η (H₁ (id C)) b ∘ (H₀ c $₁ f)) ≈ H₀ c $₁ f ]
commute₁ {_} {b} {c} f = begin
η (H₁ (id C)) b ∘ (H₀ c $₁ f) ≈⟨ ∘-resp-≈ˡ B (identity H) ⟩
id B ∘ (H₀ c $₁ f) ≈⟨ identityˡ B ⟩
H₀ c $₁ f ∎
commute₂ : ∀ {c₁ c₂} (f : C [ c₁ , c₂ ]) {a} →
B [ (η (H₁ f) a ∘ (H₀ c₁ $₁ id A)) ≈ η (H₁ f) a ]
commute₂ {c} {_} f {a} = begin
η (H₁ f) a ∘ (H₀ c $₁ id A) ≈⟨ ∘-resp-≈ʳ B (identity (H₀ c)) ⟩
η (H₁ f) a ∘ id B ≈⟨ identityʳ B ⟩
η (H₁ f) a ∎
curry-unique : ∀ {A B C} {G : C ⇒ B ^ A} {H : C × A ⇒ B} →
eval ∘F (G ⁂ idF) ≃ H → G ≃ curry.F₀ H
curry-unique {A} {B} {C} {G} {H} hyp =
begin
G
≈⟨ η-exp {A} {B} {C} {G} ⟩
curry.F₀ (eval ∘F (G ⁂ idF))
≈⟨ curry.resp-NI {F = eval ∘F (G ⁂ idF)} {H} hyp ⟩
curry.F₀ H
∎
where
open Functor
open Cats.HomReasoning
Cats-CCC : Canonical.CartesianClosed (Cats l l l)
Cats-CCC = record
{ ! = !
; π₁ = π₁
; π₂ = π₂
; ⟨_,_⟩ = ⟨_,_⟩
; !-unique = !-unique
; π₁-comp = λ {_} {_} {F} {_} {G} → project₁ {h = F} {i = G}
; π₂-comp = λ {_} {_} {F} {_} {G} → project₂ {h = F} {i = G}
; ⟨,⟩-unique = unique
; eval = eval
; curry = curry.F₀
; eval-comp = λ {_} {_} {_} {G} → eval-comp {G = G}
; curry-unique = λ {_} {_} {_} {G} {H} → curry-unique {G = G} {H}
}
open Canonical.CartesianClosed Cats-CCC
Cats-CCC : ∀ {l} → CCC.CartesianClosed (Cats l l l)
Cats-CCC =
Canonical.Equivalence.fromCanonical _ CanonicallyCartesianClosed.Cats-CCC
module CartesianClosed {l} = CCC.CartesianClosed (Cats-CCC {l})