{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.Cosmos.ContFunctor where
open import Agda.Primitive using (Level; lsuc; _⊔_)
open import Agda.Builtin.Equality using (refl)
open import Agda.Builtin.Sigma using (Σ; _,_)
open import Level using (Lift; lift; lower)
open import Data.Product.Base using (proj₁; proj₂)
open import Data.Container.Core using (Container; Shape; Position; map; _⇒_)
open import Data.Container.Morphism using (id) renaming (_∘_ to _∘Cont_)
open import Data.Container.Relation.Binary.Equality.Setoid using (setoid)
open import Data.Container.Relation.Binary.Pointwise as PW using (_,_; Pointwise)
open import Function.Base using (_∘_)
open import Function.Bundles using (Func; _⇔_; mk⇔)
open import Relation.Binary.PropositionalEquality.Core using (cong)
open import Relation.Binary.PropositionalEquality.Properties renaming
(setoid to discreteSetoid)
open import Relation.Binary.Bundles using (Setoid)
open import Categories.Adjoint.Equivalence using (⊣Equivalence)
open import Categories.Category.Core using (Category)
open import Categories.Category.Equivalence using (StrongEquivalence)
open import Categories.Category.Equivalence.Properties using (C≅D)
open import Categories.Category.Instance.Setoids using (Setoids)
open import Categories.Category.Construction.Functors using (Functors)
open import Categories.Functor.Core using (Functor)
open import Categories.Functor.Properties using (Faithful; Full; FullyFaithful)
open import Categories.NaturalTransformation.Core using
(NaturalTransformation; ntHelper; _∘ᵥ_) renaming (id to idNT)
open import Categories.NaturalTransformation.NaturalIsomorphism using
(_≃_; module ≃; module NaturalIsomorphism)
open import Categories.Morphism using (_≅_; Iso)
open import ALMA.Cosmos.ContCategory using (_≈sr_; ContCat)
open import ALMA.Base.Equivalence using (toStrongEquiv)
module _ {s p ℓ : Level} where
srcLevel = p ⊔ ℓ
tgtLevel = s ⊔ p ⊔ ℓ
SetoidFunctorCat = Functors (Setoids srcLevel srcLevel) (Setoids tgtLevel tgtLevel)
module FuncCat = Category SetoidFunctorCat
open import Categories.Category.SubCategory SetoidFunctorCat using (FullSubCategory)
module Src = Category (Setoids srcLevel srcLevel) renaming
( id to idS ; _∘_ to _∘S_ ; _⇒_ to _⇒S_ ; _≈_ to _≈S_ )
module Tgt = Category (Setoids tgtLevel tgtLevel) renaming
( id to idT ; _∘_ to _∘T_ ; _⇒_ to _⇒T_ ; _≈_ to _≈T_ )
private
ptw-cong :
{a : Level} {X : Setoid a a} {C : Container s p}
(s : Shape C)
{h k : Position C s → Setoid.Carrier X}
(eq : ∀ p → Setoid._≈_ X (h p) (k p))
→ Setoid._≈_ (setoid X C) (s , h) (s , k)
ptw-cong s eq = refl PW., eq
ptw-refl :
{a : Level} {X : Setoid a a} {C : Container s p}
(s : Shape C)
(h : Position C s → Setoid.Carrier X)
→ Setoid._≈_ (setoid X C) (s , h) (s , h)
ptw-refl {X = X} s h = ptw-cong {X = X} s (λ p → Setoid.refl X {x = h p})
record ContFunctor (C : Container s p) : Set where
private
⟦_⟧ₛ : Setoid srcLevel srcLevel → Setoid tgtLevel tgtLevel
⟦_⟧ₛ A = setoid A C
mapₛ : {A B : Setoid srcLevel srcLevel} → A Src.⇒S B → ⟦ A ⟧ₛ Tgt.⇒T ⟦ B ⟧ₛ
mapₛ {A} {B} f = record
{ to = map {C = C} {X = Setoid.Carrier A} {Y = Setoid.Carrier B} (Func.to f)
; cong = λ { (sh , ps) → sh , λ p → Func.cong f (ps p) }
}
map-id≗ : {A : Setoid srcLevel srcLevel}
→ mapₛ (Src.idS {A}) Tgt.≈T Tgt.idT {A = ⟦_⟧ₛ A}
map-id≗ {A} {x = (s , h)} = ptw-refl {X = A} s h
map-∘≗ : {A B D : Setoid srcLevel srcLevel} {f : A Src.⇒S B} {g : B Src.⇒S D}
→ mapₛ (g Src.∘S f) Tgt.≈T (mapₛ g Tgt.∘T mapₛ f)
map-∘≗ {A} {B} {D} {f = f} {g = g} {x = (s , h)} =
ptw-refl {X = D} s (λ p → Func.to g (Func.to f (h p)))
map-resp-≗ : {A B : Setoid srcLevel srcLevel} {f g : A Src.⇒S B}
→ f Src.≈S g → mapₛ f Tgt.≈T mapₛ g
map-resp-≗ {A} {B} {f} {g} f≈g {x = (s , h)} =
ptw-cong {X = B} s (λ p → f≈g {x = h p})
functor : Functor (Setoids srcLevel srcLevel) (Setoids tgtLevel tgtLevel)
functor = record
{ F₀ = ⟦_⟧ₛ
; F₁ = mapₛ
; identity = λ {A} → map-id≗ {A = A}
; homomorphism = λ {A} {B} {D} {f} {g}
→ map-∘≗ {A = A} {B = B} {D = D} {f = f} {g = g}
; F-resp-≈ = λ {A} {B} {f} {g} f≈g
→ map-resp-≗ {A = A} {B = B} {f = f} {g = g} f≈g
}
⟦_⟧ : Container s p → Functor (Setoids srcLevel srcLevel) (Setoids tgtLevel tgtLevel)
⟦ C ⟧ = ContFunctor.functor {C = C} (record {})
mapNT : {C D : Container s p} → (C ⇒ D) → NaturalTransformation ⟦ C ⟧ ⟦ D ⟧
mapNT {C} {D} m = ntHelper record
{ η = λ X → record
{ to = _⇒_.⟪_⟫ m
; cong = λ { {x = (s , k)} (refl , eq) →
let open _⇒_ m in
ptw-cong {X = X} (shape s) (λ p → eq (position p)) }
}
; commute = λ {X Y} f {x} →
let (s , k) = x
in ptw-refl {X = Y} {C = D} (_⇒_.shape m s)
(λ p → Func.to f (k (_⇒_.position m p)))
}
mapNT-id : {C : Container s p} → mapNT (id C) FuncCat.≈ idNT
mapNT-id {C} {X} {x = (s , k)} = ptw-refl {X = X} s k
mapNT-∘ : {C D E : Container s p} {m : D ⇒ E} {n : C ⇒ D}
→ mapNT (m ∘Cont n) FuncCat.≈ (mapNT m ∘ᵥ mapNT n)
mapNT-∘ {C} {D} {E} {m} {n} {X} {x = (s , k)} =
ptw-refl {X = X}
(_⇒_.shape m (_⇒_.shape n s))
(λ p → k (_⇒_.position n (_⇒_.position m p)))
mapNT-resp-≈ : {C D : Container s p} {m n : C ⇒ D}
→ m ≈sr n → mapNT m FuncCat.≈ mapNT n
mapNT-resp-≈ {C} {D} {m} {n} eq {X} {x = (s , k)} =
_≈sr_.shape-eq eq s , λ q → Setoid.reflexive X (cong k (_≈sr_.position-eq eq s q))
ContEmbedding : Functor (ContCat s p) SetoidFunctorCat
ContEmbedding = record
{ F₀ = ⟦_⟧
; F₁ = mapNT
; identity = λ {A} {X} {x} → mapNT-id {C = A} {X} {x}
; homomorphism = λ {X Y Z f g} {S} {x} → mapNT-∘ {m = g} {n = f} {S} {x}
; F-resp-≈ = λ {A B f g} eq {X} {x} → mapNT-resp-≈ eq {X} {x}
}
ContEmbedding-faithful : Faithful ContEmbedding
ContEmbedding-faithful {C} {D} {m} {n} nt-eq = record
{ shape-eq = λ s → Pointwise.shape (get-eq s)
; position-eq = λ s q → cong lower (Pointwise.position (get-eq s) q)
}
where
get-eq : (s : Shape C) → _
get-eq s = nt-eq {discreteSetoid (Lift srcLevel (Position C s))} { (s , lift) }
mapNT-iff-≈sr : {C D : Container s p} {m n : C ⇒ D}
→ (mapNT m FuncCat.≈ mapNT n) ⇔ (m ≈sr n)
mapNT-iff-≈sr = mk⇔ ContEmbedding-faithful mapNT-resp-≈
ContEmbedding-full : Full ContEmbedding
ContEmbedding-full {C} {D} η = m , mapNT≈η
where
module NT = NaturalTransformation η
testObj : Shape C → Setoid srcLevel srcLevel
testObj s = discreteSetoid (Lift srcLevel (Position C s))
η-at : (s : Shape C) →
Σ (Shape D) (λ t → Position D t → Lift srcLevel (Position C s))
η-at s = Func.to (NT.η (testObj s)) (s , lift)
m : C ⇒ D
m = record
{ shape = λ s → proj₁ (η-at s)
; position = λ {s} p → lower (proj₂ (η-at s) p)
}
promote : (s : Shape C) {X : Setoid srcLevel srcLevel}
→ (Position C s → Setoid.Carrier X)
→ testObj s Src.⇒S X
promote s {X} k = record
{ to = λ { (lift p) → k p }
; cong = λ { refl → Setoid.refl X }
}
η≈mapNT : η FuncCat.≈ mapNT m
η≈mapNT {X} {x = (s , k)} =
NT.commute (promote s k) {x = (s , lift)}
mapNT≈η : mapNT m FuncCat.≈ η
mapNT≈η {X} {x} = Setoid.sym (Functor.F₀ ⟦ D ⟧ X) (η≈mapNT {X} {x})
ContEmbedding-fully-faithful : FullyFaithful ContEmbedding
ContEmbedding-fully-faithful = ContEmbedding-full , ContEmbedding-faithful
PolyPred : Category.Obj SetoidFunctorCat → Set (lsuc (s ⊔ p ⊔ ℓ))
PolyPred F = Σ (Container s p) (λ C → F ≃ ⟦ C ⟧)
PolyObj : Set (lsuc (s ⊔ p ⊔ ℓ))
PolyObj = Σ (Category.Obj SetoidFunctorCat) PolyPred
pattern poly F C iso = F , C , iso
polyF : PolyObj → Functor (Setoids srcLevel srcLevel) (Setoids tgtLevel tgtLevel)
polyF (poly F _ _) = F
polyC : (A : PolyObj) → Container s p
polyC (poly _ C _) = C
polyIso : (A : PolyObj) → polyF A ≃ ⟦ polyC A ⟧
polyIso (poly _ _ iso) = iso
PolyFunctors :
Category (lsuc (s ⊔ p ⊔ ℓ)) (s ⊔ lsuc p ⊔ lsuc ℓ) (s ⊔ lsuc p ⊔ lsuc ℓ)
PolyFunctors = FullSubCategory {I = PolyObj} proj₁
Φ : Functor (ContCat s p) PolyFunctors
Φ = record
{ F₀ = λ C → poly (⟦ C ⟧) C (≃.refl)
; F₁ = λ {C} {D} m → mapNT {C = C} {D = D} m
; identity = λ {C} {X} {x} →
Functor.identity ContEmbedding {A = C} {X} {x}
; homomorphism = λ {A} {B} {C} {f} {g} {X} {x} →
Functor.homomorphism ContEmbedding
{X = A} {Y = B} {Z = C} {f = f} {g = g} {X} {x}
; F-resp-≈ = λ {A} {B} {f} {g} eq {X} {x} →
Functor.F-resp-≈ ContEmbedding
{A = A} {B = B} {f = f} {g = g} eq {X} {x}
}
Φ-full : Full Φ
Φ-full {C} {D} η = ContEmbedding-full {C} {D} η
Φ-faithful : Faithful Φ
Φ-faithful {C} {D} {m} {n} = ContEmbedding-faithful {C} {D} {m} {n}
Φ-fully-faithful : FullyFaithful Φ
Φ-fully-faithful = Φ-full , Φ-faithful
Φ-split-ess-surj :
(Y : Category.Obj PolyFunctors) →
Σ (Category.Obj (ContCat s p))
(λ X → _≅_ PolyFunctors (Functor.F₀ Φ X) Y)
Φ-split-ess-surj (poly F C iso) = C , record
{ from = NaturalIsomorphism.F⇐G iso
; to = NaturalIsomorphism.F⇒G iso
; iso = record
{ isoˡ = λ {X} → Iso.isoʳ (NaturalIsomorphism.iso iso X)
; isoʳ = λ {X} → Iso.isoˡ (NaturalIsomorphism.iso iso X)
}
}
ContCat≈PolyFunctors : StrongEquivalence (ContCat s p) PolyFunctors
ContCat≈PolyFunctors = toStrongEquiv Φ Φ-fully-faithful Φ-split-ess-surj
ContCat⊣EquivPolyFunctors : ⊣Equivalence (ContCat s p) PolyFunctors
ContCat⊣EquivPolyFunctors = C≅D ContCat≈PolyFunctors