module Prelude.Category.WCat where
open import Prelude.Category
open import Prelude.Category.Isomorphism
open import Level
open import Relation.Binary using (module Setoid)
open Category
open Functor
WCat : {ℓ₀ ℓ₁ ℓ₂ : Level} → Category
WCat {ℓ₀} {ℓ₁} {ℓ₂} = record
{ Object = Category {ℓ₀} {ℓ₁} {ℓ₂}
; Morphism = λ C D → IsoSetoid (Funct C D)
; _·_ = _⋆_
; id = λ {C} → idF C
; id-l = λ {C} {D} F → record
{ to = record { comp = λ _ → id D
; naturality = λ {X} {Y} f → Setoid.trans (Morphism D (object F X) (object F Y))
(id-r D (morphism F f))
(Setoid.sym (Morphism D (object F X) (object F Y)) (id-l D (morphism F f))) }
; from = record { comp = λ _ → id D
; naturality = λ {X} {Y} f → Setoid.trans (Morphism D (object F X) (object F Y))
(id-r D (morphism F f))
(Setoid.sym (Morphism D (object F X) (object F Y)) (id-l D (morphism F f))) }
; from-to-inverse = λ _ → id-l D (id D)
; to-from-inverse = λ _ → id-l D (id D) }
; id-r = λ {C} {D} F → record
{ to = record { comp = λ _ → id D
; naturality = λ {X} {Y} f → Setoid.trans (Morphism D (object F X) (object F Y))
(id-r D (morphism F f))
(Setoid.sym (Morphism D (object F X) (object F Y)) (id-l D (morphism F f))) }
; from = record { comp = λ _ → id D
; naturality = λ {X} {Y} f → Setoid.trans (Morphism D (object F X) (object F Y))
(id-r D (morphism F f))
(Setoid.sym (Morphism D (object F X) (object F Y)) (id-l D (morphism F f))) }
; from-to-inverse = λ _ → id-l D (id D)
; to-from-inverse = λ _ → id-l D (id D) }
; assoc = λ {_} {_} {_} {C} F G H → record
{ to = record { comp = λ _ → id C
; naturality = λ {X} {Y} f → Setoid.trans (Morphism C _ _)
(id-r C (morphism F (morphism G (morphism H f))))
(Setoid.sym (Morphism C _ _) (id-l C (morphism F (morphism G (morphism H f))))) }
; from = record { comp = λ _ → id C
; naturality = λ {X} {Y} f → Setoid.trans (Morphism C _ _)
(id-r C (morphism F (morphism G (morphism H f))))
(Setoid.sym (Morphism C _ _) (id-l C (morphism F (morphism G (morphism H f))))) }
; from-to-inverse = λ _ → id-l C (id C)
; to-from-inverse = λ _ → id-l C (id C) }
; cong-l = λ {C} {D} {E} {F} {G} H iso → record
{ to = record { comp = λ X → morphism H (NatTrans.comp (Iso.to iso) X)
; naturality = λ {X} {Y} f → Setoid.trans (Morphism E _ _)
(Setoid.sym (Morphism E _ _)
(comp-preserving H (morphism G f) (NatTrans.comp (Iso.to iso) X)))
(Setoid.trans (Morphism E _ _)
(≈-respecting H (NatTrans.naturality (Iso.to iso) f))
(comp-preserving H (NatTrans.comp (Iso.to iso) Y) (morphism F f))) }
; from = record { comp = λ X → morphism H (NatTrans.comp (Iso.from iso) X)
; naturality = λ {X} {Y} f →
Setoid.trans (Morphism E _ _)
(Setoid.sym (Morphism E _ _)
(comp-preserving H (morphism F f) (NatTrans.comp (Iso.from iso) X)))
(Setoid.trans (Morphism E _ _)
(≈-respecting H (NatTrans.naturality (Iso.from iso) f))
(comp-preserving H (NatTrans.comp (Iso.from iso) Y) (morphism G f))) }
; from-to-inverse = λ X → Setoid.trans (Morphism E _ _)
(Setoid.sym (Morphism E _ _)
(comp-preserving H (NatTrans.comp (Iso.from iso) X) (NatTrans.comp (Iso.to iso) X)))
(Setoid.trans (Morphism E _ _) (≈-respecting H (Iso.from-to-inverse iso X)) (id-preserving H))
; to-from-inverse = λ X → Setoid.trans (Morphism E _ _)
(Setoid.sym (Morphism E _ _)
(comp-preserving H (NatTrans.comp (Iso.to iso) X) (NatTrans.comp (Iso.from iso) X)))
(Setoid.trans (Morphism E _ _) (≈-respecting H (Iso.to-from-inverse iso X)) (id-preserving H)) }
; cong-r = λ {C} {D} {E} {F} {G} H iso → record
{ to = record { comp = λ X → NatTrans.comp (Iso.to iso) (object H X)
; naturality = λ f → NatTrans.naturality (Iso.to iso) (morphism H f) }
; from = record { comp = λ X → NatTrans.comp (Iso.from iso) (object H X)
; naturality = λ f → NatTrans.naturality (Iso.from iso) (morphism H f) }
; from-to-inverse = λ X → Iso.from-to-inverse iso (object H X)
; to-from-inverse = λ X → Iso.to-from-inverse iso (object H X) } }
CatEquiv : {ℓ₀ ℓ₁ ℓ₂ : Level} → (C D : Category {ℓ₀} {ℓ₁} {ℓ₂}) → Set (ℓ₀ ⊔ ℓ₁ ⊔ ℓ₂)
CatEquiv = Iso WCat