{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.Cosmos.Carried.FinPushColimitCat where
open import Agda.Primitive using (lzero; lsuc)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Data.Nat.Base using (ℕ; zero; suc; _≤_; _<_; z≤n)
open import Data.Nat.Properties using
(≤-pred; ≤-refl; m≤n⇒m≤1+n; m≤n⇒m<n∨m≡n; n≤0⇒n≡0)
open import Data.Fin.Base using (Fin; inject₁; toℕ)
open import Data.Fin.Properties using (toℕ-injective; toℕ-inject₁; toℕ<n)
open import Data.Sum.Base using (inj₁; inj₂)
open import Relation.Binary.PropositionalEquality.Core using (cong; cong₂; trans; sym)
open import Categories.Category.Core using (Category)
open import Categories.Functor using (Functor)
open import ALMA.Base.DetCat using (DetSys; DM; idDM; compDM; _≈DM_; DetCat)
open import ALMA.Cosmos.Carried.LimitSystemS using (n-at; natToFin; toℕ-natToFin)
import ALMA.Cosmos.Carried.LimitSystemS as LS
open DetSys using (I) renaming (step to step-det)
open DM
data Chain⇒ (m : ℕ) : ℕ → Set where
stop : Chain⇒ m m
step : ∀ {n} → Chain⇒ m n → Chain⇒ m (suc n)
infixl 7 _∘ch_
_∘ch_ : ∀ {m y n} → Chain⇒ y n → Chain⇒ m y → Chain⇒ m n
stop ∘ch f = f
step g ∘ch f = step (g ∘ch f)
succ : ∀ {m} → Chain⇒ m (suc m)
succ = step stop
private
idʳ-ch : ∀ {m y} (f : Chain⇒ m y) → f ∘ch stop ≡ f
idʳ-ch stop = refl
idʳ-ch (step g) = cong step (idʳ-ch g)
assoc-ch : ∀ {a b c d} (f : Chain⇒ a b) (g : Chain⇒ b c)
(h : Chain⇒ c d)
→ (h ∘ch g) ∘ch f ≡ h ∘ch (g ∘ch f)
assoc-ch f g stop = refl
assoc-ch f g (step h') = cong step (assoc-ch f g h')
ωCat : Category lzero lzero lzero
ωCat = record
{ Obj = ℕ
; _⇒_ = Chain⇒
; _≈_ = λ {_ _} → _≡_
; id = stop
; _∘_ = _∘ch_
; assoc = λ {_ _ _ _ f g h} → assoc-ch f g h
; sym-assoc = λ {_ _ _ _ f g h} → sym (assoc-ch f g h)
; identityˡ = λ {_ _ f} → refl
; identityʳ = λ {_ _ f} → idʳ-ch f
; identity² = refl
; equiv = record { refl = refl ; sym = sym ; trans = trans }
; ∘-resp-≈ = λ {_ _ _ f h g i} eqfh eqgi → cong₂ _∘ch_ eqfh eqgi
}
module FinColimit
(t : (m : ℕ) → Fin (n-at m) → Fin (n-at m))
(embed-compat :
(m : ℕ) (x : Fin (n-at m))
→ t (suc m) (inject₁ x) ≡ inject₁ (t m x))
where
open LS.LimitSystemS t embed-compat using (s∞; read-coh; cl; cl-toℕ)
C : Category (lsuc lzero) lzero lzero
C = DetCat lzero
StageD : ℕ → DetSys lzero
StageD m = record { I = Fin (n-at m) ; step = t m }
Apex : DetSys lzero
Apex = record { I = ℕ ; step = s∞ }
emb : (m : ℕ) → DM (StageD m) (StageD (suc m))
emb m = record { q = inject₁ ; coh = λ x → sym (embed-compat m x) }
foldD : ∀ {m n} → Chain⇒ m n → DM (StageD m) (StageD n)
foldD stop = idDM _
foldD (step {n = n} p) = compDM (emb n) (foldD p)
foldD-hom : ∀ {m y n} (g : Chain⇒ y n) (f : Chain⇒ m y)
→ foldD (g ∘ch f) ≈DM compDM (foldD g) (foldD f)
foldD-hom stop f _ = refl
foldD-hom (step {n = n} g) f x =
cong (q (emb n)) (foldD-hom g f x)
foldD-resp : ∀ {m n} {f g : Chain⇒ m n}
→ f ≡ g → foldD f ≈DM foldD g
foldD-resp {f = f} {g = g} eq rewrite eq = λ _ → refl
chainF : Functor ωCat C
chainF = record
{ F₀ = StageD
; F₁ = foldD
; identity = λ _ → refl
; homomorphism = λ {_ _ _ f g} → foldD-hom g f
; F-resp-≈ = λ {_ _ f g} eq → foldD-resp eq
}
leg : (m : ℕ) → DM (StageD m) Apex
leg m = record { q = toℕ ; coh = read-coh m }
module WithCocone (Z : DetSys lzero)
(ψ : (m : ℕ) → DM (StageD m) Z)
(emb-eq : (m : ℕ) (x : Fin (n-at m))
→ q (ψ (suc m)) (inject₁ x) ≡ q (ψ m) x)
where
Q : (m : ℕ) → Fin (n-at m) → I Z
Q m = q (ψ m)
q∞ : ℕ → I Z
q∞ v = Q v (natToFin v)
private
cl-suc : ∀ v k (le : k ≤ v) → cl (suc v) k ≡ inject₁ (cl v k)
cl-suc v k le =
toℕ-injective
(trans (cl-toℕ (suc v) k (m≤n⇒m≤1+n (m≤n⇒m≤1+n le)))
(sym (trans (toℕ-inject₁ (cl v k))
(cl-toℕ v k (m≤n⇒m≤1+n le)))))
cl-top : ∀ v → cl (suc v) (suc v) ≡ natToFin (suc v)
cl-top v =
toℕ-injective
(trans (cl-toℕ (suc v) (suc v) (m≤n⇒m≤1+n ≤-refl))
(sym (toℕ-natToFin (suc v))))
q-cl : ∀ v k (le : k ≤ v) → Q v (cl v k) ≡ q∞ k
q-cl zero k le rewrite n≤0⇒n≡0 le =
cong (Q zero)
(toℕ-injective
(trans (cl-toℕ zero zero z≤n) (sym (toℕ-natToFin zero))))
q-cl (suc v) k le with m≤n⇒m<n∨m≡n le
... | inj₁ lt =
trans (cong (Q (suc v)) (cl-suc v k (≤-pred lt)))
(trans (emb-eq v (cl v k)) (q-cl v k (≤-pred lt)))
... | inj₂ eq rewrite eq =
cong (Q (suc v)) (cl-top v)
align-down : ∀ v k (le : k ≤ v) (x' : Fin (n-at v))
→ toℕ x' ≡ k → Q v x' ≡ q∞ k
align-down v k le x' eqx =
let eqfin : x' ≡ cl v k
eqfin = toℕ-injective
(trans eqx (sym (cl-toℕ v k (m≤n⇒m≤1+n le))))
in trans (cong (Q v) eqfin) (q-cl v k le)
align-up : ∀ v (x' : Fin (n-at v)) → toℕ x' ≡ suc v
→ q∞ (suc v) ≡ Q v x'
align-up v x' eqk =
let eqfin : natToFin (suc v) ≡ inject₁ x'
eqfin = toℕ-injective
(trans (toℕ-natToFin (suc v))
(sym (trans (toℕ-inject₁ x') eqk)))
in trans (cong (Q (suc v)) eqfin) (emb-eq v x')
coh-case : ∀ v k (ek : toℕ (t v (natToFin v)) ≡ k)
(lek : k ≤ suc v)
→ q∞ k ≡ step-det Z (q∞ v)
coh-case v k ek lek with m≤n⇒m<n∨m≡n lek
... | inj₁ lt =
trans (sym (align-down v k (≤-pred lt) (t v (natToFin v)) ek))
(coh (ψ v) (natToFin v))
... | inj₂ eqk rewrite eqk =
trans (align-up v (t v (natToFin v)) ek)
(coh (ψ v) (natToFin v))
tri-case : ∀ m (x : Fin (n-at m)) k (ek : toℕ x ≡ k)
(lek : k ≤ suc m)
→ q∞ k ≡ Q m x
tri-case m x k ek lek with m≤n⇒m<n∨m≡n lek
... | inj₁ lt = sym (align-down m k (≤-pred lt) x ek)
... | inj₂ eqk rewrite eqk = align-up m x ek
q∞-coh : (v : ℕ) → q∞ (s∞ v) ≡ step-det Z (q∞ v)
q∞-coh v = coh-case v (s∞ v) refl (≤-pred (toℕ<n (t v (natToFin v))))
mediate : DM Apex Z
mediate = record { q = q∞ ; coh = q∞-coh }
triangle : (m : ℕ) → compDM mediate (leg m) ≈DM ψ m
triangle m x =
tri-case m x (toℕ x) refl (≤-pred (toℕ<n x))
unique : (f : DM Apex Z)
→ ((m : ℕ) → compDM f (leg m) ≈DM ψ m)
→ ∀ v → q f v ≡ q∞ v
unique f tri v =
trans (cong (q f) (sym (toℕ-natToFin v)))
(tri v (natToFin v))
private
leg-emb-eq : (m : ℕ) (x : Fin (n-at m))
→ q (leg (suc m)) (inject₁ x) ≡ q (leg m) x
leg-emb-eq m x = toℕ-inject₁ x
coh-path : (Z : DetSys lzero) (ψ : (m : ℕ) → DM (StageD m) Z)
(emb-eq : (m : ℕ) (x : Fin (n-at m))
→ q (ψ (suc m)) (inject₁ x) ≡ q (ψ m) x)
{m n : ℕ} (p : Chain⇒ m n)
→ compDM (ψ n) (foldD p) ≈DM ψ m
coh-path Z ψ emb-eq stop _ = refl
coh-path Z ψ emb-eq (step {n = n} p) x =
trans (emb-eq n (q (foldD p) x)) (coh-path Z ψ emb-eq p x)
open import Categories.Diagram.Cocone chainF
open import Categories.Category.Construction.Cocones chainF using (Cocones)
open import Categories.Object.Initial Cocones
open import Categories.Diagram.Colimit chainF using (Colimit)
mkCocone : Cocone
mkCocone = record
{ coapex = record
{ ψ = leg
; commute = λ {m n} p → coh-path Apex leg leg-emb-eq p
}
}
private
module Rep (K : Cocone) where
embK : (m : ℕ) (x : Fin (n-at m))
→ q (Cocone.ψ K (suc m)) (inject₁ x) ≡ q (Cocone.ψ K m) x
embK m x = Cocone.commute K (succ {m = m}) x
open WithCocone (Cocone.N K) (Cocone.ψ K) embK public
colimit : Colimit
colimit = record
{ initial = record
{ ⊥ = mkCocone
; ⊥-is-initial = record
{ ! = λ {K} → record
{ arr = Rep.mediate K
; commute = λ {m} → Rep.triangle K m
}
; !-unique = λ {K} f v →
sym (Rep.unique K (Cocone⇒.arr f)
(λ m → Cocone⇒.commute f {X = m}) v)
}
}
}