{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.SecondPass.Unfolding where
open import Agda.Primitive using (Level; _⊔_)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Agda.Builtin.Sigma using (Σ; _,_)
open import Relation.Binary.Definitions using (Reflexive; Symmetric; Transitive)
open import Relation.Binary.PropositionalEquality.Core using (cong; subst)
open import Relation.Binary.PropositionalEquality.Properties using (setoid)
open import Relation.Binary.Bundles using (Setoid)
open import Function.Base using (id; _∘_)
open import Function.Bundles using (Func)
open import Data.Product.Base using (proj₁; proj₂)
open import Categories.Category.Core using (Category)
open import Categories.Category.Instance.Setoids using (Setoids)
open import Categories.Functor.Core using (Functor)
open import ALMA.Base.Equivalence using (module SubstTransport-Left)
open import ALMA.Cosmos.ContCategory using (ContCat)
open import ALMA.Cosmos.ContCategoryLemmas using (ShapeOf; PosOf; actSOf; actPOf)
open import ALMA.Cosmos.ContCatEquiv using (ShapeCat)
module _ {o h e s p u : Level}
{C : Category o h e}
(F : Functor C (ContCat s p))
(X : Set u) where
private
module C = Category C
module F = Functor F
ShapeCat′ : Category (o ⊔ s) (h ⊔ s) e
ShapeCat′ = ShapeCat C F
record Unfolding : Set (o ⊔ h ⊔ e ⊔ s ⊔ p ⊔ u) where
field
unfoldFunctor : Functor ShapeCat′ C
unfold-next : ∀ {A} → ShapeOf F A → X
pos-to-shape : ∀ {A} (s : ShapeOf F A) → PosOf F s → ShapeOf F (Functor.₀ unfoldFunctor (A , s))
pos-actS-compat : ∀ {A B} {s : ShapeOf F A} {t : ShapeOf F B}
→ (f : A C.⇒ B) (q : actSOf F f s ≡ t)
→ (p : PosOf F (actSOf F f s))
→ pos-to-shape t (subst (PosOf F) q p)
≡ actSOf F (Functor.₁ unfoldFunctor (f , q))
(pos-to-shape s (actPOf F f s p))
open Unfolding public
mapUnfolding : ∀ {o h e s p u v} {C : Category o h e} {F : Functor C (ContCat s p)} {X : Set u} {Y : Set v}
→ (X → Y) → Unfolding F X → Unfolding F Y
mapUnfolding f u = record
{ unfoldFunctor = unfoldFunctor u
; unfold-next = λ s → f (unfold-next u s)
; pos-to-shape = pos-to-shape u
; pos-actS-compat = pos-actS-compat u
}
mapUnfolding-id : ∀ {o h e s p u} {C : Category o h e} {F : Functor C (ContCat s p)} {X : Set u}
(u : Unfolding F X) → mapUnfolding id u ≡ u
mapUnfolding-id u = refl
mapUnfolding-∘ : ∀ {o h e s p u v w}
{C : Category o h e}
{F : Functor C (ContCat s p)}
{X : Set u} {Y : Set v} {Z : Set w}
(f : Y → Z) (g : X → Y)
(u : Unfolding F X)
→ mapUnfolding (f ∘ g) u ≡ mapUnfolding f (mapUnfolding g u)
mapUnfolding-∘ f g u = refl
module UnfoldingSetoid {o h e s p : Level}
{C : Category o h e}
{F : Functor C (ContCat s p)} where
private
module C = Category C
module F = Functor F
ShapeOf′ = ShapeOf F
PosOf′ = PosOf F
module _ {u v : Level} (X : Setoid u v) where
open SubstTransport-Left
{S = Σ (Category.Obj C) ShapeOf′}
{T = Category.Obj C}
ShapeOf′
(λ { (A , s) → PosOf′ s })
{F = Unfolding F (Setoid.Carrier X)}
(λ U → Functor.₀ (Unfolding.unfoldFunctor U))
(λ U {s} → Unfolding.pos-to-shape U {proj₁ s} (proj₂ s)) public
mapUnfolding-preserves-≈sl
: {u v : Level} {X Y : Setoid u v}
(f : Func X Y)
{u₁ u₂ : Unfolding F (Setoid.Carrier X)}
→ _≈sl_ X u₁ u₂
→ _≈sl_ Y (mapUnfolding (Func.to f) u₁) (mapUnfolding (Func.to f) u₂)
mapUnfolding-preserves-≈sl f
(record { shape-eq = se ; position-eq = pe }) =
record { shape-eq = se ; position-eq = pe }
record _≈U_ {u v : Level} {X : Setoid u v}
(u₁ u₂ : Unfolding F (Setoid.Carrier X))
: Set (o ⊔ s ⊔ p ⊔ v) where
private
module X = Setoid X
module U₁ = Unfolding u₁
module U₂ = Unfolding u₂
field
sl-eq : _≈sl_ X u₁ u₂
unfold-next-eq : ∀ {A} (s : ShapeOf′ A)
→ X._≈_ (U₁.unfold-next s) (U₂.unfold-next s)
open _≈U_
≈U-refl : {u v : Level} {X : Setoid u v} → Reflexive (_≈U_ {X = X})
≈U-refl {X = X} = record
{ sl-eq = ≈sl-refl X
; unfold-next-eq = λ _ → Setoid.refl X
}
≈U-sym : {u v : Level} (X : Setoid u v) → Symmetric (_≈U_ {X = X})
≈U-sym X {u₁} {u₂} eq = record
{ sl-eq = ≈sl-sym X (eq .sl-eq)
; unfold-next-eq = λ s → Setoid.sym X (eq .unfold-next-eq s)
}
≈U-trans : {u v : Level} (X : Setoid u v) → Transitive (_≈U_ {X = X})
≈U-trans X {u₁} {u₂} {u₃} eq₁ eq₂ = record
{ sl-eq = ≈sl-trans X (eq₁ .sl-eq) (eq₂ .sl-eq)
; unfold-next-eq = λ s → Setoid.trans X
(eq₁ .unfold-next-eq s) (eq₂ .unfold-next-eq s)
}
unfoldingSetoid : {u v : Level} → Setoid u v
→ Setoid (o ⊔ h ⊔ e ⊔ s ⊔ p ⊔ u) (o ⊔ s ⊔ p ⊔ v)
unfoldingSetoid X = record
{ Carrier = Unfolding F (Setoid.Carrier X)
; _≈_ = _≈U_ {X = X}
; isEquivalence = record
{ refl = ≈U-refl {X = X}
; sym = ≈U-sym X
; trans = ≈U-trans X
}
}
mapUnfolding-resp : {u v : Level} {X Y : Setoid u v} → Func X Y
→ Func (unfoldingSetoid X) (unfoldingSetoid Y)
mapUnfolding-resp {X = X} {Y = Y} f = record
{ to = λ u → mapUnfolding (Func.to f) u
; cong = λ {u₁ u₂} eq → helper eq
}
where
helper : {u₁ u₂ : Unfolding F (Setoid.Carrier X)}
→ _≈U_ {X = X} u₁ u₂
→ _≈U_ {X = Y} (mapUnfolding (Func.to f) u₁)
(mapUnfolding (Func.to f) u₂)
helper (record { sl-eq = sl ; unfold-next-eq = un }) = record
{ sl-eq = mapUnfolding-preserves-≈sl f sl
; unfold-next-eq = λ s → Func.cong f (un s)
}
mapUnfolding-resp-≈ : {u : Level} (A B : Set u)
(f g : A → B)
→ (∀ {x} → f x ≡ g x)
→ {u₁ u₂ : Unfolding F A}
→ _≈U_ {X = setoid A} u₁ u₂
→ _≈U_ {X = setoid B} (mapUnfolding f u₁) (mapUnfolding g u₂)
mapUnfolding-resp-≈ A B f g f≈g {u₁} {u₂} u₁≈u₂ =
let
SA = setoid A
SB = setoid B
sf : Func SA SB
sf = record { to = f ; cong = cong f }
module R = Func (mapUnfolding-resp {X = SA} {Y = SB} sf)
fg-eq : _≈U_ {X = SB} (mapUnfolding f u₂) (mapUnfolding g u₂)
fg-eq = record
{ sl-eq = record
{ shape-eq = λ _ → refl
; position-eq = λ _ _ → refl
}
; unfold-next-eq = λ s → f≈g {unfold-next u₂ s}
}
module SBS = Setoid (unfoldingSetoid SB)
in SBS.trans (R.cong u₁≈u₂) fg-eq
module UnfoldingEndoFunctor {o h e s p : Level} {C : Category o h e}
{FC : Functor C (ContCat s p)} where
open UnfoldingSetoid
private
L = o ⊔ h ⊔ e ⊔ s ⊔ p
Lʳ = o ⊔ s ⊔ p
S = Setoids L Lʳ
module S = Category S
F₀ : S.Obj → S.Obj
F₀ X = unfoldingSetoid {F = FC} X
private
mapUnfolding-cong : ∀ {X Y : S.Obj} (f : S._⇒_ X Y)
→ {u₁ u₂ : Unfolding FC (Setoid.Carrier X)}
→ Setoid._≈_ (F₀ X) u₁ u₂
→ Setoid._≈_ (F₀ Y) (mapUnfolding (Func.to f) u₁)
(mapUnfolding (Func.to f) u₂)
mapUnfolding-cong f = Func.cong (mapUnfolding-resp {F = FC} f)
F₁ : ∀ {X Y : S.Obj} → S._⇒_ X Y → S._⇒_ (F₀ X) (F₀ Y)
F₁ f = record
{ to = mapUnfolding (Func.to f)
; cong = mapUnfolding-cong f
}
private
identity-law : ∀ {X : S.Obj} → S._≈_ (F₁ (S.id {X})) (S.id {F₀ X})
identity-law {X} {u} = ≈U-refl {X = X} {u}
homomorphism-law : ∀ {X Y Z : S.Obj}
{f : S._⇒_ X Y} {g : S._⇒_ Y Z}
→ S._≈_ (F₁ (g S.∘ f)) (F₁ g S.∘ F₁ f)
homomorphism-law {X} {Y} {Z} {f} {g} {u} = ≈U-refl {X = Z}
F-resp-≈-law : ∀ {X Y : S.Obj} {f g : S._⇒_ X Y}
→ S._≈_ f g → S._≈_ (F₁ f) (F₁ g)
F-resp-≈-law {X} {Y} {f} {g} f≈g {u} = record
{ sl-eq = record
{ shape-eq = λ _ → refl
; position-eq = λ _ _ → refl
}
; unfold-next-eq = λ {A} s →
f≈g {x = Unfolding.unfold-next u {A = A} s}
}
UnfoldingEndoFunctor : Functor S S
UnfoldingEndoFunctor = record
{ F₀ = F₀
; F₁ = F₁
; identity = identity-law
; homomorphism = λ {X} {Y} {Z} {f} {g} {u} →
homomorphism-law {X} {Y} {Z} {f} {g} {u}
; F-resp-≈ = λ {X} {Y} {f} {g} f≈g {u} →
F-resp-≈-law {X} {Y} {f} {g} f≈g {u}
}