module Category where
open import Function hiding (_∘_; id)
open import Level
open import Data.Product
open import Relation.Binary
open import Relation.Binary.Core using (_≡_)
open Setoid renaming (_≈_ to eqSetoid)
open import Basic
record Category (C₀ C₁ ℓ : Level) : Set (suc (C₀ ⊔ C₁ ⊔ ℓ)) where
field
Obj : Set C₀
Homsetoid : Obj → Obj → Setoid C₁ ℓ
Hom : Obj → Obj → Set C₁
Hom A B = Carrier (Homsetoid A B)
equal : {A B : Obj} → Hom A B → Hom A B → Set ℓ
equal {A} {B} f g = eqSetoid (Homsetoid A B) f g
field
comp : {A B C : Obj} → Hom B C → Hom A B → Hom A C
id : {A : Obj} → Hom A A
field
leftId : {A B : Obj} {f : Hom A B} → equal (comp id f) f
rightId : {A B : Obj} {f : Hom A B} → equal (comp f id) f
assoc : {A B C D : Obj} {f : Hom A B} {g : Hom B C} {h : Hom C D}
→ equal (comp (comp h g) f) (comp h (comp g f))
≈-composite : {A B C : Obj} {f g : Hom B C} {h i : Hom A B}
→ equal f g → equal h i → equal (comp f h) (comp g i)
dom : {A B : Obj} → Hom A B → Obj
dom {A} _ = A
cod : {A B : Obj} → Hom A B → Obj
cod {B} _ = B
op : Category C₀ C₁ ℓ
op = record
{ Obj = Obj
; Homsetoid = flip Homsetoid
; comp = flip comp
; id = id
; leftId = rightId
; rightId = leftId
; assoc = λ{A B C D} → IsEquivalence.sym (isEquivalence (Homsetoid D A)) assoc
; ≈-composite = flip ≈-composite
}
open Category
infixr 9 _∘_
infixr 7 _[_∘_]
infixr 2 _≈_
infixr 2 _[_≈_]
infix 4 _[_≅_]
_[_∘_] : ∀{C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {a b c : Obj C} → Hom C b c → Hom C a b → Hom C a c
C [ f ∘ g ] = comp C f g
_∘_ : ∀{C₀ C₁ ℓ} {C : Category C₀ C₁ ℓ} {a b c : Obj C} → Hom C b c → Hom C a b → Hom C a c
_∘_ {C = C} = _[_∘_] C
_[_≈_] : ∀{C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {A B : Obj C} → Rel (Hom C A B) ℓ
C [ f ≈ g ] = equal C f g
_≈_ : ∀{C₀ C₁ ℓ} {C : Category C₀ C₁ ℓ} {A B : Obj C} → Rel (Hom C A B) ℓ
_≈_ {C = C} = equal C
equiv : ∀{C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {A B : Obj C} → IsEquivalence (eqSetoid (Homsetoid C A B))
equiv C {A} {B} = isEquivalence (Homsetoid C A B)
refl-hom : ∀{C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {A B : Obj C} {f : Hom C A B} → C [ f ≈ f ]
refl-hom C = IsEquivalence.refl (equiv C)
sym-hom : ∀{C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {A B : Obj C} {f g : Hom C A B} → C [ f ≈ g ] → C [ g ≈ f ]
sym-hom C = IsEquivalence.sym (equiv C)
trans-hom : ∀{C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {A B : Obj C} {f g h : Hom C A B} → C [ f ≈ g ] → C [ g ≈ h ] → C [ f ≈ h ]
trans-hom C = IsEquivalence.trans (equiv C)
record _[_≅_] {C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) (a b : Obj C) : Set (C₀ ⊔ C₁ ⊔ ℓ) where
field
map-→ : Hom C a b
map-← : Hom C b a
proof : (C [ C [ map-→ ∘ map-← ] ≈ id C ]) × (C [ C [ map-← ∘ map-→ ] ≈ id C ])
record isomorphism {C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {a b : Obj C} (f : Hom C a b) : Set (C₀ ⊔ C₁ ⊔ ℓ) where
field
inverse-map : Hom C b a
proof : (C [ C [ f ∘ inverse-map ] ≈ id C ]) × (C [ C [ inverse-map ∘ f ] ≈ id C ])
iso-≅ : ∀ {C₀ C₁ ℓ} (C : Category C₀ C₁ ℓ) {a b : Obj C} {f : Hom C a b} → isomorphism C f → C [ a ≅ b ]
iso-≅ C {f = f} iso = record {
map-→ = f ;
map-← = isomorphism.inverse-map iso ;
proof = isomorphism.proof iso }
Setoids : {c₀ ℓ : Level} → Category (suc (c₀ ⊔ ℓ)) (suc (c₀ ⊔ ℓ)) (c₀ ⊔ ℓ)
Setoids {c₀} {ℓ} = record {
Obj = Setoid c₀ ℓ;
Homsetoid = λ A B → record { Carrier = Map.Map A B; _≈_ = Map.equality; isEquivalence = Map-Equal-Equiv A B };
comp = Map.compose;
id = Map.identity;
leftId = λ {_ B} _ → refl B;
rightId = λ {_ B} _ → refl B;
assoc = λ {_ _ _ D} x → refl D;
≈-composite = λ {_ _ C f g h} x x₁ x₂ → trans C (x (Map.Map.mapping h x₂)) (Map.Map.preserveEq g (x₁ x₂)) }
where
Map-Equal-Equiv : (A B : Setoid _ _) → IsEquivalence Map.equality
Map-Equal-Equiv A B = record { refl = λ _ → refl B ; sym = λ x x₁ → sym B (x x₁) ; trans = λ x x₁ x₂ → trans B (x x₂) (x₁ x₂) }
module CategoryReasoning where
infix 1 begin⟨_⟩_
infixr 2 _≈⟨_⟩_ _≡⟨_⟩_
infix 3 _∎
data IsRelatedTo[_] {c₀ c₁ ℓ} (C : Category c₀ c₁ ℓ) (a b : Obj C) (x y : Hom C a b) : Set ℓ where
relTo : C [ x ≈ y ] → IsRelatedTo[ C ] a b x y
begin⟨_⟩_ : ∀ {c₀ c₁ ℓ} (C : Category c₀ c₁ ℓ) → {A B : Obj C} {f g : Hom C A B} → IsRelatedTo[ C ] A B f g → equal C f g
begin⟨_⟩_ C {A} {B} (relTo x≈y) = x≈y
_∎ : ∀ {c₀ c₁ ℓ} {C : Category c₀ c₁ ℓ} {A B : Obj C} (f : Hom C A B) → IsRelatedTo[ C ] A B f f
_∎ {C = C} f = relTo (refl-hom C)
_≈⟨_⟩_ : ∀ {c₀ c₁ ℓ} {C : Category c₀ c₁ ℓ} → {A B : Obj C} (f : Hom C A B) → {g h : Hom C A B} → equal C f g → IsRelatedTo[ C ] A B g h → IsRelatedTo[ C ] A B f h
_≈⟨_⟩_ {C = C} f f≈g (relTo g≈h) = relTo (trans-hom C f≈g g≈h)
_≡⟨_⟩_ : ∀ {c₀ c₁ ℓ} {C : Category c₀ c₁ ℓ} → {A B : Obj C} (f : Hom C A B) → {g h : Hom C A B} → f ≡ g → IsRelatedTo[ C ] A B g h → IsRelatedTo[ C ] A B f h
_≡⟨_⟩_ {C = C} f _≡_.refl (relTo g≈h) = relTo g≈h
open CategoryReasoning public