{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.Cosmos.M.ListSwap where
open import Agda.Primitive using (lzero)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Agda.Builtin.Sigma using (Σ; _,_)
open import Axiom.UniquenessOfIdentityProofs using (module Decidable⇒UIP)
open import Data.Unit.Polymorphic.Base using (⊤; tt)
open import Data.Nat using (ℕ; zero; suc)
open import Data.Fin.Base using (Fin; toℕ; splitAt; join; opposite)
renaming (zero to fzero; suc to fsuc)
open import Data.Fin.Properties using (opposite-involutive; join-splitAt; splitAt-join)
open import Data.Sum.Base using (_⊎_; inj₁; inj₂)
open import Data.Product.Base using (proj₁)
open import Data.Product.Properties using (≡-dec)
open import Data.Nat using (_≟_)
open import Data.Unit.Polymorphic.Properties renaming (_≟_ to _⊤≟_)
open import Data.Container.Core using (Container)
open import Function.Base using (_∘_)
open import Relation.Binary.Definitions using (Irrelevant)
open import Relation.Binary.PropositionalEquality.Core using (cong; trans)
open import Relation.Binary.PropositionalEquality.Properties using (module ≡-Reasoning)
open ≡-Reasoning
open import Relation.Nullary.Negation using (¬_)
open import Categories.Category.Core using (Category)
open import Categories.Category.Instance.One using (One)
open import Categories.Functor using (id)
open import Categories.Functor.Core using (Functor)
open Functor using (F₀)
open import ALMA.Cosmos.ContCategory using (ContCat; ≈sr-refl)
open import ALMA.Cosmos.ContCatEquiv using (ShapeCat)
open import ALMA.Base.MCorrSetoid using (FiberAdjˢ; propEqOn)
open import ALMA.Base.MCorrSetoidCat using (FMˢ; FMapˢ)
import ALMA.Cosmos.M.Object as MO
import ALMA.Cosmos.M.GenCongruence as GC
C₀ : Category lzero lzero lzero
C₀ = One
ListContainer : Container lzero lzero
ListContainer = record { Shape = ℕ ; Position = Fin }
idFin : ∀ {n : ℕ} → Fin n → Fin n
idFin p = p
ListFC : Functor C₀ (ContCat lzero lzero)
ListFC = record
{ F₀ = λ _ → ListContainer
; F₁ = λ _ → record { shape = λ n → n ; position = idFin }
; identity = ≈sr-refl
; homomorphism = ≈sr-refl
; F-resp-≈ = λ _ → ≈sr-refl
}
open GC using (GenDet; genFMapˢ; genFMˢ)
L-I : Set lzero
L-I = MO.I C₀ ListFC
LData : Set lzero
LData = MO.CosmosData C₀ ListFC
LE : (i : L-I) (d : LData) (j : L-I) → Set lzero
LE = MO.E C₀ ListFC
uf0 : Functor (ShapeCat C₀ ListFC) C₀
uf0 = record
{ F₀ = proj₁
; F₁ = proj₁
; identity = Category.Equiv.refl C₀
; homomorphism = Category.Equiv.refl C₀
; F-resp-≈ = λ p → p
}
private
swapFin2 : Fin 2 → Fin 2
swapFin2 = opposite
swapSum : ∀ {n} → Fin 2 ⊎ Fin n → Fin 2 ⊎ Fin n
swapSum (inj₁ i) = inj₁ (swapFin2 i)
swapSum (inj₂ k) = inj₂ k
swapSum-invol : ∀ {n} (z : Fin 2 ⊎ Fin n) → swapSum (swapSum z) ≡ z
swapSum-invol (inj₁ i) = cong inj₁ (opposite-involutive i)
swapSum-invol (inj₂ k) = refl
swap01 : (n : ℕ) → Fin n → Fin n
swap01 zero ()
swap01 (suc zero) i = i
swap01 (suc (suc zero)) i = opposite i
swap01 (suc (suc (suc n))) i = join 2 (suc n) (swapSum (splitAt 2 i))
swap01-invol : ∀ {n : ℕ} (p : Fin n) → swap01 n (swap01 n p) ≡ p
swap01-invol {zero} ()
swap01-invol {suc zero} i = refl
swap01-invol {suc (suc zero)} i = opposite-involutive i
swap01-invol {suc (suc (suc n))} i =
begin
join 2 (suc n)
(swapSum (splitAt 2
(join 2 (suc n) (swapSum (splitAt 2 i)))))
≡⟨ cong (join 2 (suc n) ∘ swapSum)
(splitAt-join 2 (suc n) (swapSum (splitAt 2 i))) ⟩
join 2 (suc n) (swapSum (swapSum (splitAt 2 i)))
≡⟨ cong (join 2 (suc n)) (swapSum-invol (splitAt 2 i)) ⟩
join 2 (suc n) (splitAt 2 i)
≡⟨ join-splitAt 2 (suc n) i ⟩
i
∎
dList : LData
dList = record { uf = uf0 ; pts = λ { {A} n i → toℕ i } }
dSwap : LData
dSwap = record { uf = uf0 ; pts = λ { {A} n i → toℕ (swap01 n i) } }
σlabel : LData → LData
σlabel d = record
{ uf = MO.CosmosData.uf d
; pts = λ { {A} n q → MO.CosmosData.pts d n (swap01 n q) }
}
private
ρof : (ℓ : LData) (n : ℕ) → Fin n → ℕ
ρof ℓ n i = MO.CosmosData.pts ℓ n i
castTo : ∀ {n m : ℕ} (ℓ : LData) (ρ : Fin n → ℕ) {p₁ p₂ : Fin n}
→ p₁ ≡ p₂
→ (tt , m) ≡ (F₀ (MO.CosmosData.uf ℓ) (tt , n) , ρ p₂)
→ (tt , m) ≡ (F₀ (MO.CosmosData.uf ℓ) (tt , n) , ρ p₁)
castTo ℓ ρ refl eq = eq
edgeJ : ∀ {n m : ℕ} (ℓ : LData) (ρ : Fin n → ℕ) {p₁ p₂ : Fin n}
→ (ip : p₁ ≡ p₂)
→ (eq : (tt , m) ≡ (F₀ (MO.CosmosData.uf ℓ) (tt , n) , ρ p₂))
→ (p₁ , castTo ℓ ρ ip eq) ≡ (p₂ , eq)
edgeJ ℓ ρ refl eq = refl
index-eq? : Relation.Binary.Definitions.DecidableEquality (Σ ⊤ (λ _ → ℕ))
index-eq? = ≡-dec (_⊤≟_ {lzero}) _≟_
pair-eq-irr : Irrelevant {A = Σ ⊤ (λ _ → ℕ)} _≡_
pair-eq-irr = Decidable⇒UIP.≡-irrelevant index-eq?
toAdj : ∀ {n m} (d : LData)
→ LE (tt , n) d (tt , m) → LE (tt , n) (σlabel d) (tt , m)
toAdj {n = n} d (p , eq) =
swap01 n p , castTo d (ρof d n) (swap01-invol p) eq
froAdj : ∀ {n m} (d : LData)
→ LE (tt , n) (σlabel d) (tt , m) → LE (tt , n) d (tt , m)
froAdj {n = n} d (q , eq) = swap01 n q , eq
adjη : ∀ {n m} d (e : LE (tt , n) d (tt , m))
→ froAdj d (toAdj d e) ≡ e
adjη {n = n} d (p , eq) =
edgeJ d (ρof d n) (swap01-invol p) eq
adjε : ∀ {n m} d (e : LE (tt , n) (σlabel d) (tt , m))
→ toAdj d (froAdj d e) ≡ e
adjε {n = n} d (q , eq) =
let castA = castTo d (ρof d n) (swap01-invol (swap01 n q)) eq
castB = castTo (σlabel d) (ρof (σlabel d) n) (swap01-invol q) eq
in trans (cong (λ e0 → swap01 n (swap01 n q) , e0)
(pair-eq-irr castA castB))
(edgeJ (σlabel d) (ρof (σlabel d) n) (swap01-invol q) eq)
swapAdj : ∀ {n m} (d : LData)
→ FiberAdjˢ (propEqOn (LE (tt , n) (σlabel d) (tt , m)))
(propEqOn (LE (tt , n) d (tt , m)))
swapAdj {n = n} {m = m} d = record
{ to = toAdj d
; fro = froAdj d
; to-cong = λ eq → cong (toAdj d) eq
; fro-cong = λ eq → cong (froAdj d) eq
; η = adjη d
; ε = adjε d
}
swapGen : GenDet C₀ ListFC (id {C = ShapeCat C₀ ListFC})
GenDet.σ swapGen _ d = σlabel d
GenDet.pb swapGen v = v , refl
GenDet.adj swapGen (tt , n) d (tt , m) = swapAdj {n = n} {m = m} d
swapFMˢ : FMˢ (MO.sys C₀ ListFC (λ _ → propEqOn _))
(MO.sys C₀ ListFC (λ _ → propEqOn _))
swapFMˢ = genFMˢ C₀ ListFC (id {C = ShapeCat C₀ ListFC}) swapGen
private
e0 : LE (tt , 2) dList (tt , 0)
e0 = fzero , refl
e1 : LE (tt , 2) (σlabel dList) (tt , 0)
e1 = fsuc fzero , refl
private
adjAt : FiberAdjˢ (propEqOn (LE (tt , 2) (σlabel dList) (tt , 0)))
(propEqOn (LE (tt , 2) dList (tt , 0)))
adjAt = FMapˢ.adjFˢ (FMˢ.mor swapFMˢ) (tt , 2) dList (tt , 0)
fwd : LE (tt , 2) dList (tt , 0) → LE (tt , 2) (σlabel dList) (tt , 0)
fwd = FiberAdjˢ.to adjAt
swap-sends-0→1 : fwd e0 ≡ e1
swap-sends-0→1 = refl
swap-nonidentity : ¬ (proj₁ (fwd e0) ≡ fzero)
swap-nonidentity ()