{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.SecondPass.FinCatInfinityProjection where
open import Agda.Primitive using (_⊔_)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Level using (lift)
open import Data.Unit.Polymorphic.Base using (⊤; tt)
open import Data.Nat using (ℕ; zero; suc; _∸_; _≤_; _<_; z≤n; s≤s; ≤-pred)
open import Data.Nat.Properties
using (≤-trans; 1+n≢n; 1+n≰n)
open import Data.Fin.Base using (Fin; toℕ; inject₁)
renaming (zero to fzero; suc to fsuc)
open import Data.Fin.Properties using (toℕ-inject₁; toℕ-injective; toℕ<n)
open import Data.Product.Base using (Σ; _,_; proj₁)
open import Data.Sum.Base using (inj₁; inj₂)
open import Data.Empty using (⊥; ⊥-elim)
open import Relation.Nullary using (¬_)
open import Relation.Binary.PropositionalEquality.Core
using (cong; sym; trans; _≢_)
open import Relation.Binary.PropositionalEquality.Properties using (module ≡-Reasoning)
open ≡-Reasoning
open import Function.Base using (_∘_)
open import Categories.Functor.Core using (Functor)
open import Categories.NaturalTransformation.Core using (ntHelper)
open import Categories.NaturalTransformation.NaturalIsomorphism
using (NaturalIsomorphism)
open import ALMA.SecondPass.Cosmos using (Cosmos; out)
open import ALMA.SecondPass.Unfolding using (Unfolding; module Unfolding)
open import ALMA.SecondPass.Terminal using (_≈C_)
open _≈C_
open import ALMA.SecondPass.FinCatNWitness
open import ALMA.SecondPass.FinCatInfinity
open import ALMA.Cosmos.Carried.LimitSystem using (cl; cl-toℕ; ≤-or->)
module FinCatInfinityEmbedding (m : ℕ) where
module M = FinCatN m
module S = FinCatN (suc m)
open M
embedN : Functor M.FinCatN S.FinCatN
embedN = record
{ F₀ = inject₁
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
projN : Functor M.FinCatN FinCat∞
projN = record
{ F₀ = toℕ
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
projN-suc : Functor S.FinCatN FinCat∞
projN-suc = record
{ F₀ = toℕ
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
projN∘embedN : Functor M.FinCatN FinCat∞
projN∘embedN = record
{ F₀ = λ x → toℕ (inject₁ x)
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
embedN-projN-F₀
: ∀ (x : Fin M.n)
→ Functor.F₀ projN∘embedN x ≡ Functor.F₀ projN x
embedN-projN-F₀ x =
begin
toℕ (inject₁ x) ≡⟨ toℕ-inject₁ x ⟩
toℕ x ∎
embedN-projN-iso : NaturalIsomorphism projN∘embedN projN
embedN-projN-iso = record
{ F⇒G = ntHelper record
{ η = λ _ → tt
; commute = λ _ → refl
}
; F⇐G = ntHelper record
{ η = λ _ → tt
; commute = λ _ → refl
}
; iso = λ _ → record { isoˡ = refl ; isoʳ = refl }
}
module FinCatNColimitProjection (m : ℕ) where
open FinCatN m
extendFin : (Fin n → Fin n) → ℕ → ℕ
extendFin f k with ≤-or-> (suc m) k
... | inj₁ _ = toℕ (f (cl m k))
... | inj₂ _ = k
defaultFin : ℕ → Fin n
defaultFin k = cl m k
extendFin-id : ∀ k → extendFin (λ x → x) k ≡ k
extendFin-id k with ≤-or-> (suc m) k
... | inj₁ le = cl-toℕ m k le
... | inj₂ _ = refl
cl-self : ∀ (A : Fin n) → cl m (toℕ A) ≡ A
cl-self A =
toℕ-injective (cl-toℕ m (toℕ A) (≤-pred (toℕ<n A)))
extendFin-at-toℕ : ∀ (f : Fin n → Fin n) (A : Fin n)
→ extendFin f (toℕ A) ≡ toℕ (f A)
extendFin-at-toℕ f A with ≤-or-> (suc m) (toℕ A)
... | inj₁ _ = cong (toℕ ∘ f) (cl-self A)
... | inj₂ gt =
⊥-elim (1+n≰n {n = suc m}
(≤-trans gt (≤-pred (toℕ<n A))))
defaultFin-toℕ-self : ∀ (A : Fin n) → defaultFin (toℕ A) ≡ A
defaultFin-toℕ-self A = cl-self A
cosmos-id∞ : Cosmos FinCat∞ TrivialFC∞
cosmos-id∞ .out = record
{ unfoldFunctor = record
{ F₀ = proj₁
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
; unfold-next = λ _ → cosmos-id∞
; pos-to-shape = λ _ _ → lift tt
; pos-actS-compat = λ _ _ _ → refl
}
cosmos-mapN : (Fin n → Fin n) → Cosmos FinCatN TrivialFCN
cosmos-mapN f .out = record
{ unfoldFunctor = record
{ F₀ = λ { (A , _) → f A }
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
; unfold-next = λ _ → cosmos-mapN f
; pos-to-shape = λ _ _ → lift tt
; pos-actS-compat = λ _ _ _ → refl
}
projCosmos : Cosmos FinCatN TrivialFCN → Cosmos FinCat∞ TrivialFC∞
projCosmos x .out = record
{ unfoldFunctor = record
{ F₀ = λ { (k , _) →
extendFin (λ A → Functor.F₀ UX.unfoldFunctor (A , lift tt)) k }
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
; unfold-next = λ { {k} _ →
projCosmos (UX.unfold-next {A = defaultFin k} (lift tt)) }
; pos-to-shape = λ _ _ → lift tt
; pos-actS-compat = λ _ _ _ → refl
}
where
UX = out x
module UX = Unfolding UX
projCosmos-F₀-spec
: ∀ (x : Cosmos FinCatN TrivialFCN) (k : ℕ)
→ Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos x))) (k , lift tt)
≡ extendFin (λ A → Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A , lift tt)) k
projCosmos-F₀-spec x k = refl
projCosmos-id : projCosmos cosmos-idN ≈C cosmos-id∞
projCosmos-id .unfoldFunctor₀-eq {A} _ =
begin
extendFin (λ x → x) A ≡⟨ extendFin-id A ⟩
A ∎
projCosmos-id .pos-to-shape-eq _ _ = refl
projCosmos-id .unfold-next-eq _ = projCosmos-id
faithfulness
: ∀ (f g : Fin n → Fin n)
→ Σ ℕ (λ k → extendFin f k ≢ extendFin g k)
→ ¬ (projCosmos (cosmos-mapN f) ≈C projCosmos (cosmos-mapN g))
faithfulness f g (k , neq) eq =
neq (begin
extendFin f k
≡˘⟨ specF ⟩
Ff
≡⟨ eqF ⟩
Fg
≡⟨ specG ⟩
extendFin g k
∎)
where
Ff = Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos (cosmos-mapN f))))
(k , lift tt)
Fg = Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos (cosmos-mapN g))))
(k , lift tt)
eqF : Ff ≡ Fg
eqF = unfoldFunctor₀-eq eq {A = k} (lift tt)
specF : Ff ≡ extendFin f k
specF = projCosmos-F₀-spec (cosmos-mapN f) k
specG : Fg ≡ extendFin g k
specG = projCosmos-F₀-spec (cosmos-mapN g) k
projCosmos-conservative
: ∀ (x y : Cosmos FinCatN TrivialFCN)
→ projCosmos x ≈C projCosmos y → x ≈C y
projCosmos-conservative x y eq .unfoldFunctor₀-eq {A = A} (lift tt) =
toℕ-injective (begin
toℕ (Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A , lift tt))
≡˘⟨ extendFin-at-toℕ
(λ A' → Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A' , lift tt)) A ⟩
extendFin (λ A' → Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A' , lift tt)) (toℕ A)
≡˘⟨ projCosmos-F₀-spec x (toℕ A) ⟩
Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos x))) (toℕ A , lift tt)
≡⟨ eq .unfoldFunctor₀-eq {A = toℕ A} (lift tt) ⟩
Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos y))) (toℕ A , lift tt)
≡⟨ projCosmos-F₀-spec y (toℕ A) ⟩
extendFin (λ A' → Functor.F₀ (Unfolding.unfoldFunctor (out y)) (A' , lift tt)) (toℕ A)
≡⟨ extendFin-at-toℕ
(λ A' → Functor.F₀ (Unfolding.unfoldFunctor (out y)) (A' , lift tt)) A ⟩
toℕ (Functor.F₀ (Unfolding.unfoldFunctor (out y)) (A , lift tt))
∎)
projCosmos-conservative x y eq .pos-to-shape-eq _ _ = refl
projCosmos-conservative x y eq .unfold-next-eq {A = k} s
rewrite sym (defaultFin-toℕ-self k)
= projCosmos-conservative
(Unfolding.unfold-next (out x) {A = defaultFin (toℕ k)} (lift tt))
(Unfolding.unfold-next (out y) {A = defaultFin (toℕ k)} (lift tt))
(eq .unfold-next-eq {A = toℕ k} s)
module _ (m=1 : m ≡ 1) where
private
swap01 : Fin n → Fin n
swap01 x rewrite m=1 with toℕ x
... | zero = fsuc fzero
... | suc zero = fzero
... | suc (suc _) = fsuc (fsuc fzero)
swap12 : Fin n → Fin n
swap12 x rewrite m=1 with toℕ x
... | zero = fzero
... | suc zero = fsuc (fsuc fzero)
... | suc (suc _) = fsuc fzero
swap01∘swap12 : Fin n → Fin n
swap01∘swap12 = swap01 ∘ swap12
swap12∘swap01 : Fin n → Fin n
swap12∘swap01 = swap12 ∘ swap01
swap01≢swap12-at-1
: extendFin swap01 1 ≢ extendFin swap12 1
swap01≢swap12-at-1 rewrite m=1 = λ ()
swap01∞≉swap12∞
: ¬ (projCosmos (cosmos-mapN swap01)
≈C
projCosmos (cosmos-mapN swap12))
swap01∞≉swap12∞ =
faithfulness _ _ (1 , swap01≢swap12-at-1)
swap01∘swap12≠swap12∘swap01-at-0
: extendFin swap01∘swap12 0 ≢ extendFin swap12∘swap01 0
swap01∘swap12≠swap12∘swap01-at-0 rewrite m=1 =
λ eq → 1+n≢n {1} (sym eq)
swap01∘swap12∞≉swap12∘swap01∞
: ¬ (projCosmos (cosmos-mapN swap01∘swap12)
≈C
projCosmos (cosmos-mapN swap12∘swap01))
swap01∘swap12∞≉swap12∘swap01∞ =
faithfulness _ _ (0 , swap01∘swap12≠swap12∘swap01-at-0)