{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.SecondPass.MorphismCorrespondence where
open import Agda.Primitive using (Level; lsuc; _⊔_)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Relation.Binary.PropositionalEquality.Core using (cong; sym; trans; subst)
open import Relation.Nullary using (¬_)
open import Data.Product.Base using (_,_; ∃)
open import Function.Bundles using (Func)
open import Categories.Category.Core using (Category)
open import Categories.Functor.Core using (Functor)
open import ALMA.Cosmos.ContCategory using (ContCat)
open import ALMA.Cosmos.ContCategoryLemmas using (ShapeOf; PosOf)
open import ALMA.SecondPass.Unfolding using (Unfolding; mapUnfolding)
open import ALMA.SecondPass.MorphismObject using (MorphismObject)
open import ALMA.SecondPass.Cosmos using (Cosmos; out; _⇒ℱ[_]_; _⇒ℱ_; ⇒ℱLayer[_])
open import ALMA.SecondPass.Terminal using (Coalgebra; CoalgHom; cosmosCoalg; _≈C_)
open import ALMA.SecondPass.CoalgCat using (_≈Coalg_)
module _ {o h e s p : Level}
{C : Category o h e}
{FC : Functor C (ContCat s p)} where
open _≈C_
private
L = o ⊔ h ⊔ e ⊔ s ⊔ p
T = Cosmos C FC
CC = cosmosCoalg {C = C} {FC = FC}
≈C→⇒ℱ : ∀ {x y : T} → x ≈C y → x ⇒ℱ y
≈C→⇒ℱ {x} {y} eq ._⇒ℱ[_]_.out = record
{ shapeTrans = λ {A} {s} p → UY.pos-to-shape s p
; morphismObj = record
{ onPos = λ p → p
; pts-compat = λ p → refl
}
; morphismMor = record
{ onActP = λ f s p → refl
}
; onunfold-next = λ {A} s → ≈C→⇒ℱ (eq .unfold-next-eq s)
}
where
UY = out y
module UY = Unfolding UY
⇒ℱ-respˡ : ∀ {x x' y : T} → x ≡ x' → x ⇒ℱ y → x' ⇒ℱ y
⇒ℱ-respˡ refl m = m
⇒ℱ-respʳ : ∀ {x y y' : T} → y ≡ y' → x ⇒ℱ y → x ⇒ℱ y'
⇒ℱ-respʳ refl m = m
forget-helper : (h : CoalgHom CC CC)
→ ∀ {b : T} (x : T) (b≡fx : b ≡ Func.to (CoalgHom.f h) x)
→ x ⇒ℱ b
forget-helper h {b} x b≡fx ._⇒ℱ[_]_.out = record
{ shapeTrans = λ {A} {s} p → UB.pos-to-shape s p
; morphismObj = record
{ onPos = λ p → p
; pts-compat = λ p → refl
}
; morphismMor = record
{ onActP = λ f s p → refl
}
; onunfold-next = λ {A} s →
let seed = UX.unfold-next s
commute-next = cong (λ u → Unfolding.unfold-next u s)
(fh.commute x)
b-next = cong (λ u → Unfolding.unfold-next u s)
(cong out b≡fx)
b'≡fseed = trans b-next (sym commute-next)
in forget-helper h seed b'≡fseed
}
where
f = Func.to (CoalgHom.f h)
module fh = CoalgHom h
UX = out x
UFX = out (f x)
UB = out b
module UX = Unfolding UX
module UB = Unfolding UB
forget : (h : CoalgHom CC CC) → ∀ x → x ⇒ℱ Func.to (CoalgHom.f h) x
forget h x = forget-helper h x refl
record StructuredFunc : Set (lsuc L) where
field
f : T → T
witness : ∀ x → x ⇒ℱ f x
forget→structured : (h : CoalgHom CC CC) → StructuredFunc
forget→structured h = record
{ f = Func.to (CoalgHom.f h)
; witness = forget h
}
forget-faithful : ∀ {h h' : CoalgHom CC CC}
→ Func.to (CoalgHom.f h) ≡ Func.to (CoalgHom.f h')
→ h ≈Coalg h'
forget-faithful {h} {h'} f≡ x = cong (λ g → g x) f≡
record StandardConditions {x y : T} (m : x ⇒ℱ y) : Set L where
coinductive
private
UX = out x
UY = out y
module UX = Unfolding UX
module UY = Unfolding UY
module ml = ⇒ℱLayer[_] (m .out)
module mo = MorphismObject ml.morphismObj
field
uf-eq : UX.unfoldFunctor ≡ UY.unfoldFunctor
pts-preserved : ∀ {A} {s : ShapeOf FC A} (p : PosOf FC s)
→ subst (λ G → ShapeOf FC (Functor.₀ G (A , s)))
uf-eq (UX.pos-to-shape s p)
≡ UY.pos-to-shape s (mo.onPos p)
recursive : ∀ {A} (s : ShapeOf FC A)
→ StandardConditions (ml.onunfold-next s)
private
pts-lemma2 : ∀ {f : T → T} {UX UFX UB : Unfolding FC T}
→ (eq1 : mapUnfolding f UX ≡ UFX)
→ (eq2 : UB ≡ UFX)
→ ∀ {A : Category.Obj C} {sh : ShapeOf FC A} (p : PosOf FC sh)
→ subst (λ G → ShapeOf FC (Functor.₀ G (A , sh)))
(trans (cong Unfolding.unfoldFunctor eq1)
(cong Unfolding.unfoldFunctor (sym eq2)))
(Unfolding.pos-to-shape UX sh p)
≡ Unfolding.pos-to-shape UB sh p
pts-lemma2 refl refl _ = refl
forget→standard : ∀ (h : CoalgHom CC CC) (x : T)
→ StandardConditions (forget h x)
forget→standard h x = helper x refl
where
f = Func.to (CoalgHom.f h)
module fh = CoalgHom h
helper : ∀ {b : T} (x : T) (b≡fx : b ≡ f x)
→ StandardConditions (forget-helper h x b≡fx)
helper {b} x b≡fx .StandardConditions.uf-eq =
let UX = out x
UFX = out (f x)
UB = out b
eq-commute = fh.commute x
eq-b = cong out b≡fx
in trans (cong Unfolding.unfoldFunctor eq-commute)
(cong Unfolding.unfoldFunctor (sym eq-b))
helper {b} x b≡fx .StandardConditions.pts-preserved {A} {sh} p =
let UX = out x
UFX = out (f x)
UB = out b
eq-commute = fh.commute x
eq-b = cong out b≡fx
in pts-lemma2 {f = f} {UX = UX} {UFX = UFX} {UB = UB}
eq-commute eq-b {A = A} {sh = sh} p
helper {b} x b≡fx .StandardConditions.recursive {A} sh =
let UX = out x
UFX = out (f x)
UB = out b
eq-commute = fh.commute x
eq-b = cong out b≡fx
b-next = cong (λ u → Unfolding.unfold-next u sh) eq-b
commute-next = cong (λ u → Unfolding.unfold-next u sh) eq-commute
b'≡fseed = trans b-next (sym commute-next)
in helper (Unfolding.unfold-next UX sh) b'≡fseed
record NontrivialCosmos : Set (lsuc L) where
field
sf : StructuredFunc
x : T
not-commute : ¬ (mapUnfolding (StructuredFunc.f sf) (out x)
≡ out (StructuredFunc.f sf x))
not-full : NontrivialCosmos
→ ∃ λ (sf : StructuredFunc)
→ ¬ (∀ z → mapUnfolding (StructuredFunc.f sf) (out z)
≡ out (StructuredFunc.f sf z))
not-full nc =
( NontrivialCosmos.sf nc
, λ h → NontrivialCosmos.not-commute nc (h (NontrivialCosmos.x nc))
)