{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.SecondPass.FinCatInfinityTowerCompat where
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; _⊓_)
open import Data.Nat.Properties
using ( ≤-refl; ≤-trans; ≤-antisym; ≤-pred
; m≤n⇒m≤1+n; m≤n⇒m<n∨m≡n; m≥n⇒m⊓n≡n
; ⊓-assoc; ⊓-comm; 1+n≰n; n≮n )
open import Data.Fin.Base using (Fin; toℕ; inject₁)
open import Data.Fin.Properties using (toℕ-inject₁; toℕ-injective; toℕ<n)
open import Data.Sum.Base using (inj₁; inj₂)
open import Data.Product.Base using (_,_)
open import Data.Empty using (⊥; ⊥-elim)
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 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.SecondPass.FinCatInfinityProjection
open import ALMA.Cosmos.Carried.LimitSystem
using (n-at; cl; cl-toℕ; ≤-or->)
open import ALMA.Cosmos.Carried.FinProj using (clamp-val)
open import ALMA.Cosmos.Carried.FinColimit using (inj-cl)
open import ALMA.Cosmos.Carried.FinEmbed
using (embedF; embedF-newtop; toℕ-embedF-inject₁)
module FinCatTowerCompat (m : ℕ) where
module M = FinCatN m
module S = FinCatN (suc m)
module PM = FinCatNColimitProjection m
module PS = FinCatNColimitProjection (suc m)
open M
open S using () renaming (n to n′; FinCatN to FinCatN′; TrivialFCN to TrivialFCN′)
open PM using ( extendFin; defaultFin; projCosmos; cosmos-mapN
; projCosmos-F₀-spec )
open PS using () renaming ( extendFin to extendFin′; defaultFin to defaultFin′
; projCosmos to projCosmos′; cosmos-mapN to cosmos-mapN′ )
embedF₀ : (Fin n → Fin n) → Fin n′ → Fin n′
embedF₀ f = embedF {m = m} f
embedF-fixes-top : ∀ (f : Fin n → Fin n)
→ embedF₀ f (cl (suc m) (n-at m)) ≡ cl (suc m) (n-at m)
embedF-fixes-top f =
embedF-newtop f (cl (suc m) (n-at m))
(cl-toℕ (suc m) (n-at m) ≤-refl)
toℕ-embedF-top : ∀ (f : Fin n → Fin n)
→ toℕ (embedF₀ f (cl (suc m) (n-at m))) ≡ n-at m
toℕ-embedF-top f
rewrite embedF-fixes-top f = cl-toℕ (suc m) (n-at m) ≤-refl
embedCosmos : Cosmos FinCatN TrivialFCN → Cosmos FinCatN′ TrivialFCN′
embedCosmos x .out = record
{ unfoldFunctor = record
{ F₀ = λ { (A , _) →
embedF₀ (λ A₁ → Functor.F₀ UX.unfoldFunctor (A₁ , lift tt)) A }
; F₁ = λ _ → tt
; identity = refl
; homomorphism = refl
; F-resp-≈ = λ _ → refl
}
; unfold-next = λ { {A} _ →
embedCosmos (UX.unfold-next {A = cl m (toℕ A)} (lift tt)) }
; pos-to-shape = λ _ _ → lift tt
; pos-actS-compat = λ _ _ _ → refl
}
where
UX = out x
module UX = Unfolding UX
extendFin-embedF₀ : ∀ (f : Fin n → Fin n) (k : ℕ)
→ extendFin′ (embedF₀ f) k ≡ extendFin f k
extendFin-embedF₀ f k
with ≤-or-> (n-at m) k | ≤-or-> (suc m) k
... | inj₁ k≤n | inj₁ k≤sm =
begin
toℕ (embedF₀ f (cl (suc m) k))
≡⟨ cong (λ z → toℕ (embedF₀ f z)) (inj-cl m k k≤sm) ⟩
toℕ (embedF₀ f (inject₁ (cl m k)))
≡⟨ toℕ-embedF-inject₁ f (cl m k) ⟩
toℕ (f (cl m k))
∎
... | inj₁ k≤n | inj₂ sm<k =
let eq : k ≡ n-at m
eq = ≤-antisym k≤n sm<k
in begin
toℕ (embedF₀ f (cl (suc m) k))
≡⟨ cong (λ z → toℕ (embedF₀ f (cl (suc m) z))) eq ⟩
toℕ (embedF₀ f (cl (suc m) (n-at m)))
≡⟨ cong toℕ (embedF-fixes-top f) ⟩
toℕ (cl (suc m) (n-at m))
≡⟨ cl-toℕ (suc m) (n-at m) ≤-refl ⟩
n-at m
≡˘⟨ eq ⟩
k
∎
... | inj₂ _ | inj₂ _ = refl
... | inj₂ n<k | inj₁ k≤sm =
⊥-elim (1+n≰n {n = n-at m}
(≤-trans n<k
(≤-trans k≤sm (m≤n⇒m≤1+n (≤-refl {x = suc m})))))
cl-embed-default : ∀ (k : ℕ)
→ cl m (toℕ (cl (suc m) k)) ≡ cl m k
cl-embed-default k =
toℕ-injective (begin
toℕ (cl m (toℕ (cl (suc m) k)))
≡⟨ clamp-val {k = suc m} (toℕ (cl (suc m) k)) ⟩
suc m ⊓ toℕ (cl (suc m) k)
≡⟨ cong (suc m ⊓_) (clamp-val {k = suc (suc m)} k) ⟩
suc m ⊓ (suc (suc m) ⊓ k)
≡˘⟨ ⊓-assoc (suc m) (suc (suc m)) k ⟩
(suc m ⊓ suc (suc m)) ⊓ k
≡⟨ cong (_⊓ k)
(trans (⊓-comm (suc m) (suc (suc m)))
(m≥n⇒m⊓n≡n {m = suc (suc m)} {n = suc m}
(s≤s (m≤n⇒m≤1+n (≤-refl {x = m}))))) ⟩
suc m ⊓ k
≡˘⟨ clamp-val {k = suc m} k ⟩
toℕ (cl m k)
∎)
projCosmos-embed-compat : ∀ (x : Cosmos FinCatN TrivialFCN)
→ projCosmos′ (embedCosmos x) ≈C projCosmos x
projCosmos-embed-compat x .unfoldFunctor₀-eq {A = k} _ =
begin
Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos′ (embedCosmos x)))) (k , lift tt)
≡⟨ PS.projCosmos-F₀-spec (embedCosmos x) k ⟩
extendFin′ (embedF₀ (λ A₁ → Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A₁ , lift tt))) k
≡⟨ extendFin-embedF₀ (λ A₁ → Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A₁ , lift tt)) k ⟩
extendFin (λ A₁ → Functor.F₀ (Unfolding.unfoldFunctor (out x)) (A₁ , lift tt)) k
≡⟨ sym (projCosmos-F₀-spec x k) ⟩
Functor.F₀ (Unfolding.unfoldFunctor (out (projCosmos x))) (k , lift tt)
∎
projCosmos-embed-compat x .pos-to-shape-eq _ _ = refl
projCosmos-embed-compat x .unfold-next-eq {A = k} _
with cl m (toℕ (cl (suc m) k)) | cl-embed-default k
... | w | eq rewrite eq =
projCosmos-embed-compat (UX.unfold-next {A = defaultFin k} (lift tt))
where
UX = out x
module UX = Unfolding UX
projCosmos-mapN-embed
: ∀ (f : Fin n → Fin n)
→ projCosmos′ (embedCosmos (cosmos-mapN f)) ≈C projCosmos (cosmos-mapN f)
projCosmos-mapN-embed f = projCosmos-embed-compat (cosmos-mapN f)