{-# OPTIONS --without-K --safe #-}
module Categories.Category.Construction.Properties.Presheaves.CartesianClosed where
open import Level using (Level; _⊔_)
open import Data.Unit.Polymorphic using (⊤)
open import Data.Product using (_,_; proj₁; proj₂)
open import Function.Bundles using (Func; _⟨$⟩_)
open import Relation.Binary using (Setoid)
open import Categories.Category.BinaryProducts using (BinaryProducts)
open import Categories.Category.Core using (Category)
open import Categories.Category.CartesianClosed using (CartesianClosed)
open import Categories.Category.CartesianClosed.Canonical renaming (CartesianClosed to CCartesianClosed)
open import Categories.Category.Construction.Presheaves using (Presheaves; Presheaves′)
open import Categories.Category.Instance.Setoids using (Setoids)
open import Categories.Functor.Core using (Functor)
open import Categories.Functor.Hom using (Hom[_][_,_]; Hom[_][-,_])
open import Categories.Functor.Presheaf using (Presheaf)
open import Categories.NaturalTransformation using (NaturalTransformation; ntHelper)
open import Categories.Object.Terminal using (Terminal)
import Categories.Category.Construction.Properties.Presheaves.Cartesian as Preₚ
import Categories.Morphism.Reasoning as MR
import Relation.Binary.Reasoning.Setoid as SetoidR
open Func
module HasClosed {o ℓ e} (C : Category o ℓ e) where
private
module C = Category C
open C
module _ (F G : Presheaf C (Setoids ℓ e)) where
private
module F = Functor F
module G = Functor G
open Preₚ C
open IsCartesian o o
Presheaf^ : Presheaf C (Setoids (o ⊔ ℓ ⊔ e) (o ⊔ ℓ ⊔ e))
Presheaf^ = record
{ F₀ = λ X → Hom[ Presheaves C ][ Presheaves× Hom[ C ][-, X ] G , F ]
; F₁ = λ {A B} f → record
{ to = λ α →
let module α = NaturalTransformation α using (η; commute)
in ntHelper record
{ η = λ X → record
{ to = λ where (g , S) → α.η X ⟨$⟩ (f ∘ g , S)
; cong = λ where (eq₁ , eq₂) → cong (α.η X) (∘-resp-≈ʳ eq₁ , eq₂)
}
; commute = λ { {Z} {W} g {h , x} →
let open SetoidR (F.₀ W)
in begin
α.η W ⟨$⟩ (f ∘ C.id ∘ h ∘ g , G.₁ g ⟨$⟩ x) ≈⟨ cong (α.η W) (Equiv.trans (pullˡ id-comm) (center Equiv.refl) , Setoid.refl (G.₀ W)) ⟩
α.η W ⟨$⟩ (C.id ∘ (f ∘ h) ∘ g , G.₁ g ⟨$⟩ x) ≈⟨ α.commute g ⟩
F.₁ g ⟨$⟩ (α.η Z ⟨$⟩ (f ∘ h , x)) ∎ }
}
; cong = λ eq → eq
}
; identity = λ {A} {α} {x} → cong (η α x) (identityˡ , Setoid.refl (G.F₀ x))
; homomorphism = λ {_} {_} {_} {f} {g} {α} {A} → cong (η α _) (assoc , Setoid.refl (G.F₀ _))
; F-resp-≈ = λ eq {α} {A} {x} → cong (η α _) (∘-resp-≈ˡ eq , Setoid.refl (G.F₀ _))
}
where
open MR C
open NaturalTransformation
module IsCartesianClosed {o} (C : Category o o o) where
private
module C = Category C using (id; _∘_; _≈_; identityˡ; identityʳ; module Equiv)
P = Presheaves′ o o C
open HasClosed C using (Presheaf^)
open Preₚ.IsCartesian C o o using (Presheaves-Cartesian)
open MR C
CanonicalCCC : CCartesianClosed P
CanonicalCCC = record
{ ⊤ = TPC.⊤
; _×_ = PPC._×_
; ! = TPC.!
; π₁ = PPC.π₁
; π₂ = PPC.π₂
; ⟨_,_⟩ = PPC.⟨_,_⟩
; !-unique = TPC.!-unique
; π₁-comp = λ {_ _ f} {_ g} → PPC.project₁ {h = f} {g}
; π₂-comp = λ {_ _ f} {_ g} → PPC.project₂ {h = f} {g}
; ⟨,⟩-unique = λ {_ _ _ f g h} → PPC.unique {h = h} {i = f} {j = g}
; _^_ = Presheaf^
; eval = λ {F G} →
let module F = Functor F
module G = Functor G
in ntHelper record
{ η = λ X → record
{ to = λ { (α , x) →
let module α = NaturalTransformation α
in α.η X ⟨$⟩ (C.id , x) }
; cong = λ { {α₁ , f₁} {α₂ , f₂} (eq₁ , eq₂) →
let module SR = SetoidR (F.F₀ X) in
let open SR
open NaturalTransformation
in begin
to (η α₁ X) (C.id , f₁) ≈⟨ eq₁ ⟩
to (η α₂ X) (C.id , f₁) ≈⟨ cong (η α₂ X) (C.Equiv.refl , eq₂) ⟩
to (η α₂ X) (C.id , f₂) ∎ }
}
; commute = λ { {Y} {Z} f {α , x} →
let module α = NaturalTransformation α
open SetoidR (F.₀ Z)
in begin
α.η Z ⟨$⟩ (f C.∘ C.id , G.₁ f ⟨$⟩ x) ≈⟨ cong (α.η Z) (C.Equiv.trans id-comm (C.Equiv.sym C.identityˡ) , Setoid.refl (G.F₀ Z)) ⟩
α.η Z ⟨$⟩ (C.id C.∘ C.id C.∘ f , G.₁ f ⟨$⟩ x) ≈⟨ α.commute f ⟩
F.₁ f ⟨$⟩ (α.η Y ⟨$⟩ (C.id , x)) ∎ }
}
; curry = λ {F G H} α →
let module F = Functor F
module G = Functor G
module H = Functor H
module α = NaturalTransformation α
in ntHelper record
{ η = λ X → record
{ to = λ x → ntHelper record
{ η = λ Y → record
{ to = λ where (f , y) → α.η Y ⟨$⟩ (F.₁ f ⟨$⟩ x , y)
; cong = λ {(eq₁ , eq₂) → cong (α.η Y) ((F.F-resp-≈ eq₁) , eq₂) }
}
; commute = λ { {Y} {Z} f {g , y} →
let open SetoidR (H.₀ Z)
open Setoid (G.₀ Z)
in begin
α.η Z ⟨$⟩ (F.F₁ (C.id C.∘ g C.∘ f) ⟨$⟩ x , G.F₁ f ⟨$⟩ y)
≈⟨ cong (α.η Z) (F.F-resp-≈ C.identityˡ , refl) ⟩
α.η Z ⟨$⟩ (F.F₁ (g C.∘ f) ⟨$⟩ x , G.F₁ f ⟨$⟩ y)
≈⟨ cong (α.η Z) (F.homomorphism , refl) ⟩
α.η Z ⟨$⟩ (F.F₁ f ⟨$⟩ (F.F₁ g ⟨$⟩ x) , G.F₁ f ⟨$⟩ y)
≈⟨ α.commute f ⟩
H.F₁ f ⟨$⟩ (α.η Y ⟨$⟩ (F.F₁ g ⟨$⟩ x , y))
∎ }
}
; cong = λ eq → cong (α.η _) ((cong (F.F₁ _) eq) , (Setoid.refl (G.F₀ _)))
}
; commute = λ { {X} {Y} f {x} {A} {g , z} →
let open Setoid (F.₀ A) in
cong (NaturalTransformation.η α A) (sym (F.homomorphism) , Setoid.refl (G.F₀ A)) }
}
; eval-comp = λ {F G H} {α} →
let module H = Functor H
module α = NaturalTransformation α
in cong (α.η _) (H.identity , (Setoid.refl (Functor.F₀ G _)))
; curry-unique = λ {F G H} {α β} eq {X} {x y} → λ { {f , z} →
let module F = Functor F
module G = Functor G
module α = NaturalTransformation α
module β = NaturalTransformation β
module αXx = NaturalTransformation (α.η X ⟨$⟩ x)
open Setoid (Functor.₀ H y)
open SetoidR (G.₀ y)
in begin
αXx.η y ⟨$⟩ (f , z) ≈⟨ cong (αXx.η _) (C.Equiv.sym C.identityʳ , refl) ⟩
αXx.η y ⟨$⟩ (f C.∘ C.id , z) ≈⟨ α.sym-commute f ⟩
NaturalTransformation.η (α.η y ⟨$⟩ (F.F₁ f ⟨$⟩ x)) y ⟨$⟩ (C.id , z) ≈⟨ eq ⟩
β.η y ⟨$⟩ (F.F₁ f ⟨$⟩ x , z)
∎ }
}
where
module PC = Presheaves-Cartesian
module PPC = BinaryProducts PC.products using (π₁; π₂; _×_; project₁; project₂; ⟨_,_⟩; unique)
module TPC = Terminal PC.terminal using (⊤; !; !-unique)
Presheaves-CartesianClosed : CartesianClosed P
Presheaves-CartesianClosed = Equivalence.fromCanonical P CanonicalCCC