{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.SecondPass.FinCatNSurjectivity where
open import Agda.Builtin.Equality using (_≡_; refl)
open import Agda.Builtin.Sigma using (Σ; _,_)
open import Level using (Lift; lift; lower)
open import Relation.Binary.PropositionalEquality.Core using (cong; subst)
open import Relation.Binary.PropositionalEquality.Properties using (module ≡-Reasoning)
open ≡-Reasoning
open import Data.Nat using (ℕ; suc)
open import Data.Product.Base using (proj₁; proj₂)
open import Categories.Category.Core using (Category)
open import Categories.Functor.Core using (Functor)
open import ALMA.Cosmos.ContCategoryLemmas using (ShapeOf; PosOf; actSOf)
open import ALMA.Cosmos.ContCatEquiv using (ShapeCat)
open import ALMA.SecondPass.Unfolding using (Unfolding; unfold-next)
open import ALMA.SecondPass.Cosmos using (Cosmos; out)
open import ALMA.SecondPass.Terminal using (_≈C_)
open import ALMA.SecondPass.CumulativeHierarchy using (EmbeddingData; UniformEmbeddingFamily)
open import ALMA.SecondPass.StrictLift using (StrictLayer)
open import ALMA.SecondPass.CumulativeHierarchyLimit using (Tower)
open import ALMA.SecondPass.FinCatNWitness
open import ALMA.SecondPass.FinCatNTowerLemmas
open import ALMA.SecondPass.FinCatNColimit
open import ALMA.SecondPass.FinCatNColimitWithDep
module FinCatNSurjectivity (m : ℕ) where
open FinCatN m
open FinCatNTowerLemmas m
open FinCatNColimit m
open FinCatNColimitWithDep m
using (SurjectivityForTower; UniformEmbeddingFamilyForTower; dep-embed-tower)
y-F₀ : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
(A : Category.Obj (StrictLayer.C (Tower.layer nTower k)))
(s : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) A)
→ Category.Obj (StrictLayer.C (Tower.layer nTower k))
y-F₀ k x A s =
proj₁ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s))
y-F₁ : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
{A B : Category.Obj (StrictLayer.C (Tower.layer nTower k))}
{s : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) A}
{t : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) B}
(f : Category._⇒_ (StrictLayer.C (Tower.layer nTower k)) A B)
(q : actSOf (StrictLayer.FC (Tower.layer nTower k)) f s ≡ t)
→ Category._⇒_ (StrictLayer.C (Tower.layer nTower k))
(y-F₀ k x A s) (y-F₀ k x B t)
y-F₁ k x {A} {B} {s} {t} f q =
proj₁ (Unfolding.unfoldFunctor (out x) .Functor.F₁
{A = ((A , s) , lift s)}
{B = ((B , t) , lift t)}
((f , q) , cong lift q))
y-unfoldFunctor : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
→ Functor (ShapeCat
(StrictLayer.C (Tower.layer nTower k))
(StrictLayer.FC (Tower.layer nTower k)))
(StrictLayer.C (Tower.layer nTower k))
y-unfoldFunctor k x = record
{ F₀ = λ { (A , s) → y-F₀ k x A s }
; F₁ = λ { {A , s} {B , t} (f , q) →
y-F₁ k x {A = A} {B = B} {s = s} {t = t} f q }
; identity = λ { {A , s} →
let
module SCₖ = Category (ShapeCat
(StrictLayer.C (Tower.layer nTower k))
(StrictLayer.FC (Tower.layer nTower k)))
module SC₊ = Category (ShapeCat
(StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
module Cₖ = Category (StrictLayer.C (Tower.layer nTower k))
UF = Unfolding.unfoldFunctor (out x)
id-k = SCₖ.id {A = (A , s)}
diag-id = (id-k , cong lift (proj₂ id-k))
coh-id : SC₊._≈_ diag-id (SC₊.id {A = ((A , s) , lift s)})
coh-id = Cₖ.Equiv.refl
in
Cₖ.Equiv.trans
(Functor.F-resp-≈ UF {f = diag-id} coh-id)
(Functor.identity UF {A = ((A , s) , lift s)}) }
; homomorphism = λ { {X = (A , s)} {Y = (B , t)} {Z = (C , u)}
{f = (f₁ , q₁)} {g = (g₁ , q₂)} →
let
module Cₖ = Category (StrictLayer.C (Tower.layer nTower k))
module SCₖ = Category (ShapeCat
(StrictLayer.C (Tower.layer nTower k))
(StrictLayer.FC (Tower.layer nTower k)))
module SC₊ = Category (ShapeCat
(StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
UF = Unfolding.unfoldFunctor (out x)
f-sc : SCₖ._⇒_ (A , s) (B , t)
f-sc = (f₁ , q₁)
g-sc : SCₖ._⇒_ (B , t) (C , u)
g-sc = (g₁ , q₂)
g∘f : SCₖ._⇒_ (A , s) (C , u)
g∘f = g-sc SCₖ.∘ f-sc
f' = (f-sc , cong lift q₁)
g' = (g-sc , cong lift q₂)
diag-g∘f = (g∘f , cong lift (proj₂ g∘f))
g'∘f' = g' SC₊.∘ f'
coh-hom : SC₊._≈_ diag-g∘f g'∘f'
coh-hom = Cₖ.Equiv.refl
in
Cₖ.Equiv.trans
(Functor.F-resp-≈ UF {f = diag-g∘f} {g = g'∘f'} coh-hom)
(Functor.homomorphism UF {f = f'} {g = g'}) }
; F-resp-≈ = λ { {A , s} {B , t}
{f = (f₁ , q₁)} {g = (f₂ , q₂)} eq-f →
Unfolding.unfoldFunctor (out x) .Functor.F-resp-≈
{A = ((A , s) , lift s)}
{B = ((B , t) , lift t)}
{f = ((f₁ , q₁) , cong lift q₁)}
{g = ((f₂ , q₂) , cong lift q₂)}
eq-f }
}
pos-actS-y : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
{A B : Category.Obj (StrictLayer.C (Tower.layer nTower k))}
{s : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) A}
{t : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) B}
(f : Category._⇒_ (StrictLayer.C (Tower.layer nTower k)) A B)
(q : actSOf (StrictLayer.FC (Tower.layer nTower k)) f s ≡ t)
(p : PosOf (StrictLayer.FC (Tower.layer nTower k)) {A = A} s)
→ proj₂ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((B , t) , lift t))
≡ actSOf (StrictLayer.FC (Tower.layer nTower k))
(proj₁ (Unfolding.unfoldFunctor (out x) .Functor.F₁
{A = ((A , s) , lift s)}
{B = ((B , t) , lift t)}
((f , q) , cong lift q)))
(proj₂ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s)))
pos-actS-y k x {A} {B} {s} {t} f q p =
shape-singleton-at k
(proj₁ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((B , t) , lift t)))
(proj₂ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((B , t) , lift t)))
(actSOf (StrictLayer.FC (Tower.layer nTower k))
(proj₁ (Unfolding.unfoldFunctor (out x) .Functor.F₁
{A = ((A , s) , lift s)}
{B = ((B , t) , lift t)}
((f , q) , cong lift q)))
(proj₂ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s))))
surj-y : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
→ Cosmos (StrictLayer.C (Tower.layer nTower k))
(StrictLayer.FC (Tower.layer nTower k))
surj-y k x .out = record
{ unfoldFunctor = y-unfoldFunctor k x
; unfold-next = λ {A} s →
surj-y k (x .out .unfold-next {A = (A , s)} (lift s))
; pos-to-shape = λ {A} s _ →
proj₂ (Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s))
; pos-actS-compat = λ {A} {B} {s} {t} f q _ →
pos-actS-y k x f q (pos-inhabited-tower k A s)
}
x-F₀-shape-irrelevant : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
(A : Category.Obj (StrictLayer.C (Tower.layer nTower k)))
(s : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) A)
(u v : ShapeOf (StrictLayer.FC (Tower.layer nTower (suc k))) (A , s))
→ Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , u)
≡ Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , v)
x-F₀-shape-irrelevant k x A s u v =
cong F (begin
u
≡˘⟨ lift-lower-eq u ⟩
lift (lower u)
≡⟨ cong lift (shape-singleton-at k A (lower u) (lower v)) ⟩
lift (lower v)
≡⟨ lift-lower-eq v ⟩
v
∎)
where
F = λ w → Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , w)
lift-lower-eq
: (w : ShapeOf (StrictLayer.FC (Tower.layer nTower (suc k))) (A , s))
→ lift (lower w) ≡ w
lift-lower-eq (lift _) = refl
dep-F₀-reduce : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
(ed : EmbeddingData (surj-y k x))
(A : Category.Obj (StrictLayer.C (Tower.layer nTower k)))
(s : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) A)
(s'' : ShapeOf (StrictLayer.FC (Tower.layer nTower k)) A)
→ Unfolding.unfoldFunctor
(out (dep-embed-tower k (surj-y k x) ed))
.Functor.F₀ ((A , s) , lift s'')
≡ Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s)
dep-F₀-reduce k x ed A s s'' = refl
subst-Σ-Lift-≡ : ∀ {a b ℓ} {A : Set a} {B : A → Set b}
{p q : Σ A B} (e : p ≡ q)
→ subst (λ z → Lift ℓ (B (proj₁ z))) e (lift (proj₂ p))
≡ lift (proj₂ q)
subst-Σ-Lift-≡ refl = refl
surj-bisim : ∀ k
(x : Cosmos (StrictLayer.C (Tower.layer nTower (suc k)))
(StrictLayer.FC (Tower.layer nTower (suc k))))
(ed : EmbeddingData (surj-y k x))
→ x ≈C dep-embed-tower k (surj-y k x) ed
surj-bisim k x ed ._≈C_.unfoldFunctor₀-eq {A = (A , s)} (lift s'') = begin
Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s'')
≡˘⟨ x-F₀-shape-irrelevant k x A s (lift s) (lift s'') ⟩
Unfolding.unfoldFunctor (out x) .Functor.F₀ ((A , s) , lift s)
≡˘⟨ dep-F₀-reduce k x ed A s s'' ⟩
Unfolding.unfoldFunctor (out (dep-embed-tower k (surj-y k x) ed))
.Functor.F₀ ((A , s) , lift s'')
∎
surj-bisim k x ed ._≈C_.pos-to-shape-eq {A = (A , s)} (lift s'') p =
shape-singleton-at (suc k)
(Unfolding.unfoldFunctor (out (dep-embed-tower k (surj-y k x) ed))
.Functor.F₀ ((A , s) , lift s'')) _ _
surj-bisim k x ed ._≈C_.unfold-next-eq {A = (A , s)} (lift s'')
rewrite shape-singleton-at (suc k) (A , s) (lift s'') (lift s) =
surj-bisim k
(x .out .unfold-next {A = (A , s)} (lift s))
(EmbeddingData.next ed {A = A} s)
surj : (unif : UniformEmbeddingFamilyForTower)
→ SurjectivityForTower unif
surj unif k x =
surj-y k x ,
surj-bisim k x (UniformEmbeddingFamily.getData (unif k) (surj-y k x))