{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.SecondPass.Closure where
open import Agda.Primitive using (Level; _⊔_)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Agda.Builtin.Sigma using (_,_)
open import Relation.Binary.PropositionalEquality.Core using (cong; trans)
open import Relation.Binary.Bundles using (Setoid)
import Relation.Binary.Reasoning.Setoid as SetoidReasoning
open import Data.Unit.Polymorphic.Base using (⊤)
open import Function.Bundles using (Func)
open import Function.Base using (_∘_)
open import Function.Construct.Composition using (function)
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)
open import ALMA.SecondPass.Unfolding using (Unfolding; mapUnfolding; mapUnfolding-id; mapUnfolding-∘; module UnfoldingSetoid)
open import ALMA.SecondPass.Cosmos
using (Cosmos; out; UnitCosmos; UnitCat; UnitContainerFunctor)
open import ALMA.SecondPass.Terminal
using (Coalgebra; cosmosCoalg; _≈C_; ≈C-refl; ≈C-trans; cosmosSetoid)
open import ALMA.SecondPass.Lambek using (in-F; in-F-resp-≈F; in∘out≈id; out∘in≈Fid)
module _ {o h e s p : Level}
{C : Category o h e}
{FC : Functor C (ContCat s p)} where
private
L = o ⊔ h ⊔ e ⊔ s ⊔ p
Lʳ = o ⊔ s ⊔ p
T = Cosmos C FC
FT = Unfolding FC T
CS : Setoid L Lʳ
CS = cosmosSetoid {C = C} {FC = FC}
module US = UnfoldingSetoid
{o = o} {h = h} {e = e} {s = s} {p = p} {C = C} {F = FC}
module Coal = Coalgebra
_≈C′_ : T → T → Set Lʳ
_≈C′_ = _≈C_ {o = o} {h = h} {e = e} {s = s} {p = p} {C = C} {FC = FC}
outFunc : Func CS (US.unfoldingSetoid CS)
outFunc = Coal.α cosmosCoalg
inFFunc : Func (US.unfoldingSetoid CS) CS
inFFunc = record { to = in-F ; cong = in-F-resp-≈F }
unit : ∀ x → in-F (out x) ≈C′ x
unit = in∘out≈id
counit : ∀ y → US._≈U_ {X = CS} (out (in-F y)) y
counit = out∘in≈Fid
private
idCS : Func CS CS
idCS = record { to = λ x → x ; cong = λ x≈y → x≈y }
mapℱ : Func CS CS → Func CS CS
mapℱ F = record
{ to = λ x → in-F (mapUnfolding (Func.to F) (out x))
; cong = λ {x} {y} x≈y →
in-F-resp-≈F
(Func.cong (US.mapUnfolding-resp F) (Func.cong outFunc x≈y))
}
mapℱ-id : ∀ x → Func.to (mapℱ idCS) x ≈C′ x
mapℱ-id x =
let open SetoidReasoning CS
in begin
Func.to (mapℱ idCS) x
≡⟨ refl ⟩
in-F (mapUnfolding (λ z → z) (out x))
≡⟨ cong in-F (mapUnfolding-id (out x)) ⟩
in-F (out x)
≈⟨ in∘out≈id x ⟩
x
∎
mapℱ-comp : ∀ (F G : Func CS CS) x
→ Func.to (mapℱ (function F G)) x
≈C′ Func.to (mapℱ G) (Func.to (mapℱ F) x)
mapℱ-comp F G x =
let open SetoidReasoning CS
in begin
Func.to (mapℱ (function F G)) x
≡⟨ refl ⟩
in-F (mapUnfolding (Func.to G ∘ Func.to F) (out x))
≡⟨ cong in-F (mapUnfolding-∘ (Func.to G) (Func.to F) (out x)) ⟩
in-F (mapUnfolding (Func.to G) (mapUnfolding (Func.to F) (out x)))
≈⟨ in-F-resp-≈F
(Func.cong (US.mapUnfolding-resp G)
(US.≈U-sym CS (out∘in≈Fid (mapUnfolding (Func.to F) (out x))))) ⟩
in-F (mapUnfolding (Func.to G) (out (in-F (mapUnfolding (Func.to F) (out x)))))
≡⟨ refl ⟩
Func.to (mapℱ G) (Func.to (mapℱ F) x)
∎
out-mapℱ : ∀ (F : Func CS CS) x
→ US._≈U_ {X = CS} (out (Func.to (mapℱ F) x)) (mapUnfolding (Func.to F) (out x))
out-mapℱ F x = counit (mapUnfolding (Func.to F) (out x))
triangle-left : ∀ (x : T) → US._≈U_ {X = CS} (out (in-F (out x))) (out x)
triangle-left x = counit (out x)
triangle-right : ∀ (y : FT) → in-F (out (in-F y)) ≈C′ in-F y
triangle-right y = unit (in-F y)
module _ {ℓ : Level} where
private
C₀ = UnitCat {ℓ}
FC₀ = UnitContainerFunctor {ℓ}
T₀ = Cosmos C₀ FC₀
_≈C₀_ : T₀ → T₀ → Set ℓ
_≈C₀_ = _≈C_ {C = C₀} {FC = FC₀}
≈C₀-trans : ∀ {x y z} → x ≈C₀ y → y ≈C₀ z → x ≈C₀ z
≈C₀-trans = ≈C-trans {C = C₀} {FC = FC₀}
record UnitLike (x : T₀) : Set ℓ where
field
unfoldFunctor₀-eq : ∀ {A} (s : ShapeOf {C = C₀} FC₀ A)
→ Functor.₀ (Unfolding.unfoldFunctor (out x)) (A , s)
≡ Functor.₀ (Unfolding.unfoldFunctor (out UnitCosmos)) (A , s)
next-self : ∀ {A} (s : ShapeOf {C = C₀} FC₀ A)
→ Unfolding.unfold-next (out x) s ≈C₀ x
unitcosmos-unique : ∀ (x : T₀) → UnitLike x → x ≈C₀ UnitCosmos
unitcosmos-unique x ul = helper ≈C₀-refl
where
open _≈C_
module UL = UnitLike ul
≈C₀-refl : ∀ {z} → z ≈C₀ z
≈C₀-refl = ≈C-refl {C = C₀} {FC = FC₀}
⊤-≡ : ∀ {a b : ⊤ {ℓ}} → a ≡ b
⊤-≡ {a = tt} {b = tt} = refl
helper : ∀ {a : T₀} → a ≈C₀ x → a ≈C₀ UnitCosmos
helper {a} p .unfoldFunctor₀-eq s =
trans (p .unfoldFunctor₀-eq s) (UL.unfoldFunctor₀-eq s)
helper {a} p .pos-to-shape-eq {A} s q = ⊤-≡
helper {a} p .unfold-next-eq {A} s =
helper (≈C₀-trans (p .unfold-next-eq s) (UL.next-self s))