{-# OPTIONS --without-K --safe #-}
module Cats.Limit where
open import Level
open import Cats.Category.Base
open import Cats.Category.Cones as Cones using
(Cone ; Cones ; ConesF ; cone-iso→obj-iso)
open import Cats.Category.Constructions.Terminal using (HasTerminal)
open import Cats.Category.Constructions.Unique using (∃!′)
open import Cats.Category.Fun as Fun using (Trans ; _↝_)
open import Cats.Functor using (Functor)
open import Cats.Util.Conv
import Cats.Category.Constructions.Terminal as Terminal
import Cats.Category.Constructions.Iso as Iso
open Cone
open Cones._⇒_
open Functor
open Fun._≈_
open Trans
private
module Cs {lo la l≈ lo′ la′ l≈′} {C : Category lo la l≈}
{D : Category lo′ la′ l≈′} {F : Functor C D} = Category (Cones F)
module _ {lo la l≈ lo′ la′ l≈′}
{J : Category lo la l≈}
{Z : Category lo′ la′ l≈′}
where
private
module J = Category J
module Z = Category Z
IsLimit : {D : Functor J Z} → Cone D → Set (lo ⊔ la ⊔ lo′ ⊔ la′ ⊔ l≈′)
IsLimit {D} = Terminal.IsTerminal {C = Cones D}
record Limit (D : Functor J Z) : Set (lo ⊔ la ⊔ lo′ ⊔ la′ ⊔ l≈′) where
field
cone : Cone D
isLimit : IsLimit cone
open Cone cone using () renaming (arr to proj)
private
hasTerminal : HasTerminal (Cones D)
hasTerminal = record { ⊤ = cone ; isTerminal = isLimit }
open HasTerminal hasTerminal public using
( ! ; !-unique ) renaming
( ⊤-unique to cone-unique
; ⇒⊤-unique to ⇒cone-unique )
!! : (cone′ : Cone D) → cone′ .Cone.Apex Z.⇒ cone .Cone.Apex
!! cone′ = ! cone′ .arr
!!-unique : {cone′ : Cone D} (f : cone′ Cs.⇒ cone)
→ !! cone′ Z.≈ f .arr
!!-unique f = !-unique f
arr∘!! : ∀ cone′ {j} → proj j Z.∘ !! cone′ Z.≈ cone′ .Cone.arr j
arr∘!! cone′ = ! cone′ .commute _
!!∘ : ∀ {C D} (f : C Cs.⇒ D)
→ !! D Z.∘ f .arr Z.≈ !! C
!!∘ {C} {D} f = Z.≈.sym (!!-unique record
{ commute = λ j →
let open Z.≈-Reasoning in
begin
proj j Z.∘ !! D Z.∘ f .arr
≈⟨ Z.unassoc ⟩
(proj j Z.∘ !! D) Z.∘ f .arr
≈⟨ Z.∘-resp-l (arr∘!! D) ⟩
D .arr j Z.∘ f .arr
≈⟨ f .commute j ⟩
C .arr j
∎
})
open Cone cone public
open Limit public
instance
HasObj-Limit : ∀ {D} → HasObj (Limit D) _ _ _
HasObj-Limit {D} = record { Cat = Cones D ; _ᴼ = cone }
module _ {D : Functor J Z} where
unique : (l m : Limit D) → Iso.Build._≅_ (Cones D) (l ᴼ) (m ᴼ)
unique l m = Terminal.terminal-unique (isLimit l) (isLimit m)
obj-unique : (l m : Limit D) → Iso.Build._≅_ Z (l ᴼ ᴼ) (m ᴼ ᴼ)
obj-unique l m = cone-iso→obj-iso _ (unique l m)
module _ {F G : Functor J Z} where
trans : (ϑ : Trans F G) (l : Limit F) (m : Limit G)
→ l .Apex Z.⇒ m .Apex
trans ϑ l m = !! m (ConesF .fmap ϑ .fobj (l .cone))
arr∘trans : ∀ ϑ l m c
→ m .arr c Z.∘ trans ϑ l m
Z.≈ ϑ .component c Z.∘ l .arr c
arr∘trans ϑ l m c = arr∘!! m (ConesF .fmap ϑ .fobj (l .cone))
trans-resp : ∀ {ϑ ι} l m
→ ϑ Fun.≈ ι
→ trans ϑ l m Z.≈ trans ι l m
trans-resp {ϑ} {ι} l m ϑ≈ι = !!-unique m record
{ commute = λ j → Z.≈.trans (arr∘trans ι l m j)
(Z.∘-resp-l (Z.≈.sym (≈-elim ϑ≈ι)))
}
trans-id : {F : Functor J Z} (l : Limit F)
→ trans Fun.id l l Z.≈ Z.id
trans-id l = !!-unique l record
{ commute = λ j → Z.≈.trans Z.id-r (Z.≈.sym Z.id-l)
}
trans-∘ : {F G H : Functor J Z} (ϑ : Trans G H) (ι : Trans F G)
→ ∀ l m n
→ trans ϑ m n Z.∘ trans ι l m Z.≈ trans (ϑ Fun.∘ ι) l n
trans-∘ {F} {G} {H} ϑ ι l m n = Z.≈.sym (!!-unique n record
{ commute = λ j → let open Z.≈-Reasoning in
begin
n .arr j Z.∘ trans ϑ m n Z.∘ trans ι l m
≈⟨ Z.unassoc ⟩
(n .arr j Z.∘ trans ϑ m n) Z.∘ trans ι l m
≈⟨ Z.∘-resp-l (arr∘trans ϑ m n j ) ⟩
(ϑ .component j Z.∘ m .arr j) Z.∘ trans ι l m
≈⟨ Z.assoc ⟩
ϑ .component j Z.∘ m .arr j Z.∘ trans ι l m
≈⟨ Z.∘-resp-r (arr∘trans ι l m j) ⟩
ϑ .component j Z.∘ ι .component j Z.∘ l .arr j
≈⟨ Z.unassoc ⟩
(ϑ Fun.∘ ι) .component j Z.∘ l .arr j
∎
})
record _HasLimitsOf_
{lo la l≈} (C : Category lo la l≈) {lo′ la′ l≈′} (J : Category lo′ la′ l≈′)
: Set (lo ⊔ la ⊔ l≈ ⊔ lo′ ⊔ la′ ⊔ l≈′ )
where
private
module C = Category C
module J↝C = Category (J ↝ C)
field
lim′ : (F : Functor J C) → Limit F
lim : Functor J C → C.Obj
lim F = lim′ F .cone .Apex
limF : Functor (J ↝ C) C
limF = record
{ fobj = λ F → lim F
; fmap = λ {F} {G} ϑ → trans ϑ (lim′ _) (lim′ _)
; fmap-resp = λ ϑ≈ι → trans-resp (lim′ _) (lim′ _) ϑ≈ι
; fmap-id = trans-id (lim′ _)
; fmap-∘ = trans-∘ _ _ (lim′ _) (lim′ _) (lim′ _)
}
record Complete {lo la l≈} (C : Category lo la l≈) lo′ la′ l≈′
: Set (lo ⊔ la ⊔ l≈ ⊔ suc (lo′ ⊔ la′ ⊔ l≈′))
where
field
lim′ : ∀ {J : Category lo′ la′ l≈′} (F : Functor J C) → Limit F
hasLimitsOf : (J : Category lo′ la′ l≈′) → C HasLimitsOf J
hasLimitsOf J ._HasLimitsOf_.lim′ = lim′
private
open module HasLimitsOf {J} = _HasLimitsOf_ (hasLimitsOf J) public hiding (lim′)
preservesLimits : ∀ {lo la l≈ lo′ la′ l≈′}
→ {C : Category lo la l≈} {D : Category lo′ la′ l≈′}
→ Functor C D
→ (lo″ la″ l≈″ : Level)
→ Set _
preservesLimits {C = C} F lo″ la″ l≈″
= {J : Category lo″ la″ l≈″}
→ {D : Functor J C}
→ {c : Cone D}
→ IsLimit c
→ IsLimit (Cones.apFunctor F c)