{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.Base.Equivalence.Map where
open import Agda.Primitive using (Level; _⊔_)
open import Agda.Builtin.Equality using (_≡_; refl)
open import Agda.Builtin.Sigma using (Σ; _,_)
open import Data.Product.Base using (_×_; proj₁; proj₂)
open import Data.Product.Properties using (Σ-≡,≡→≡)
open import Relation.Binary.PropositionalEquality.Core using
(sym; trans; cong; cong₂; subst)
open import Relation.Binary.PropositionalEquality.Properties using (subst-subst-sym)
open import ALMA.Base.IndexedMType using (Mᵢ)
open import ALMA.Base.Equivalence.Core using (LayeredEqGen; IndexedLayeredEq; LayeredEq)
module LayeredEqGen-Map
{a b cX cY e} {X : Set a} {Y : Set e}
{ObsX : X → Set b} {ObsY : Y → Set b}
{stepX : (x : X) → ObsX x → X}
{stepY : (y : Y) → ObsY y → Y}
{layerX : X → X → Set cX}
{layerY : Y → Y → Set cY}
(obs-mapX : (x y : X) → layerX x y → ObsX x → ObsX y)
(obs-mapY : (x y : Y) → layerY x y → ObsY x → ObsY y)
(f : X → Y)
(obs-cast : (x : X) → ObsX x → ObsY (f x))
(obs-cast-inv : (x : X) → ObsY (f x) → ObsX x)
(obs-cast-inv-right : (x : X) (q : ObsY (f x)) →
obs-cast x (obs-cast-inv x q) ≡ q)
(comm : (x : X) (s : ObsX x) →
f (stepX x s) ≡ stepY (f x) (obs-cast x s))
(layer-comm : ∀ {x y} → layerX x y → layerY (f x) (f y))
(obs-coherence : ∀ {x y} (l : layerX x y) (s : ObsX x) →
obs-cast y (obs-mapX x y l s)
≡ obs-mapY (f x) (f y) (layer-comm l) (obs-cast x s))
where
le-map : ∀ {x y} → LayeredEqGen ObsX stepX layerX obs-mapX x y
→ LayeredEqGen ObsY stepY layerY obs-mapY (f x) (f y)
le-map p .Mᵢ.fst = layer-comm (p .Mᵢ.fst)
le-map {x} {y} p .Mᵢ.snd q = body
where
s = obs-cast-inv x q
l = p .Mᵢ.fst
l' = layer-comm l
rec : LayeredEqGen ObsY stepY layerY obs-mapY
(f (stepX x s))
(f (stepX y (obs-mapX x y l s)))
rec = le-map (p .Mᵢ.snd s)
leftEq : f (stepX x s) ≡ stepY (f x) q
leftEq = trans (comm x s)
(cong (stepY (f x)) (obs-cast-inv-right x q))
rightEq : f (stepX y (obs-mapX x y l s))
≡ stepY (f y) (obs-mapY (f x) (f y) l' q)
rightEq = trans (comm y (obs-mapX x y l s))
(cong (stepY (f y))
(trans (obs-coherence l s)
(cong (obs-mapY (f x) (f y) l')
(obs-cast-inv-right x q))))
body : LayeredEqGen ObsY stepY layerY obs-mapY
(stepY (f x) q)
(stepY (f y) (obs-mapY (f x) (f y) l' q))
body rewrite sym leftEq | sym rightEq = rec
module IndexedLayeredEq-Map
{aI aJ bX bY c dI dJ : Level}
{I : Set aI} {J : Set aJ}
{X' : I → Set bX} {Y' : J → Set bY}
{nextX : I → I} {nextY : J → J}
{ObsI : I → Set c} {ObsJ : J → Set c}
{stepI : (i : I) → X' i → ObsI i → X' (nextX i)}
{stepJ : (j : J) → Y' j → ObsJ j → Y' (nextY j)}
{layerI : (i : I) → X' i → X' i → Set dI}
{layerJ : (j : J) → Y' j → Y' j → Set dJ}
(fI : I → J)
(f' : (i : I) → X' i → Y' (fI i))
(next-compat : (i : I) → fI (nextX i) ≡ nextY (fI i))
(obs-comm-I : (i : I) → ObsI i ≡ ObsJ (fI i))
(step-compat : (i : I) (x : X' i) (s : ObsI i) →
subst (λ j → Y' j) (next-compat i) (f' (nextX i) (stepI i x s))
≡ stepJ (fI i) (f' i x) (subst (λ T → T) (obs-comm-I i) s))
(layer-comm-I : (i : I) {x y : X' i} →
layerI i x y → layerJ (fI i) (f' i x) (f' i y))
where
private
P : Set c → Set c
P T = T
J' : Set (aJ ⊔ bY)
J' = Σ J (λ j → Y' j × Y' j)
A : J' → Set dJ
A (_ , x , y) = layerJ _ x y
B : (j' : J') → A j' → Set c
B (j , _ , _) _ = ObsJ j
next' : (j' : J') (p : A j') (s : B j' p) → J'
next' (j , x , y) p s = nextY j , stepJ j x s , stepJ j y s
subst-× : ∀ {j j' : J} (e : j ≡ j') (p : Y' j × Y' j)
→ subst (λ l → Y' l × Y' l) e p
≡ (subst Y' e (proj₁ p) , subst Y' e (proj₂ p))
subst-× refl p = refl
le-map : ∀ {i x y}
→ IndexedLayeredEq X' nextX ObsI stepI layerI i x y
→ IndexedLayeredEq Y' nextY ObsJ stepJ layerJ
(fI i) (f' i x) (f' i y)
le-map {i} {x} {y} p .Mᵢ.fst = layer-comm-I i (p .Mᵢ.fst)
le-map {i} {x} {y} p .Mᵢ.snd s = body
where
s' : ObsI i
s' = subst P (sym (obs-comm-I i)) s
s-eq : subst P (obs-comm-I i) s' ≡ s
s-eq = subst-subst-sym (obs-comm-I i) {p = s}
rec : Mᵢ A B next'
(fI (nextX i) ,
f' (nextX i) (stepI i x s') ,
f' (nextX i) (stepI i y s'))
rec = le-map (p .Mᵢ.snd s')
stepx : subst Y' (next-compat i) (f' (nextX i) (stepI i x s'))
≡ stepJ (fI i) (f' i x) s
stepx = trans (step-compat i x s')
(cong (stepJ (fI i) (f' i x)) s-eq)
stepy : subst Y' (next-compat i) (f' (nextX i) (stepI i y s'))
≡ stepJ (fI i) (f' i y) s
stepy = trans (step-compat i y s')
(cong (stepJ (fI i) (f' i y)) s-eq)
eq-pair : subst (λ j → Y' j × Y' j) (next-compat i)
(f' (nextX i) (stepI i x s') ,
f' (nextX i) (stepI i y s'))
≡ (stepJ (fI i) (f' i x) s ,
stepJ (fI i) (f' i y) s)
eq-pair = trans (subst-× (next-compat i) _)
(cong₂ _,_ stepx stepy)
i'-eq : (fI (nextX i) ,
f' (nextX i) (stepI i x s') ,
f' (nextX i) (stepI i y s'))
≡ (nextY (fI i) ,
stepJ (fI i) (f' i x) s ,
stepJ (fI i) (f' i y) s)
i'-eq = Σ-≡,≡→≡ (next-compat i , eq-pair)
body : Mᵢ A B next'
(nextY (fI i) ,
stepJ (fI i) (f' i x) s ,
stepJ (fI i) (f' i y) s)
body rewrite sym i'-eq = rec
module LayeredEq-Map
{a b c d} {X : Set a} {Y : Set d}
{ObsX : Set b} {ObsY : Set b}
{stepX : X → ObsX → X} {stepY : Y → ObsY → Y}
{layerX : X → X → Set c} {layerY : Y → Y → Set c}
(f : X → Y)
(obs-cast : ObsX → ObsY)
(obs-cast-inv : ObsY → ObsX)
(obs-cast-inv-right : (q : ObsY) → obs-cast (obs-cast-inv q) ≡ q)
(comm : (x : X) (s : ObsX) →
f (stepX x s) ≡ stepY (f x) (obs-cast s))
(layer-comm : ∀ {x y} → layerX x y → layerY (f x) (f y))
where
private
obs-coherence : ∀ {x y} (l : layerX x y) (s : ObsX) →
obs-cast s ≡ obs-cast s
obs-coherence l s = refl
module M = LayeredEqGen-Map
{X = X} {Y = Y}
{ObsX = λ _ → ObsX} {ObsY = λ _ → ObsY}
{stepX = stepX} {stepY = stepY}
{layerX = layerX} {layerY = layerY}
(λ _ _ _ o → o) (λ _ _ _ o → o) f
(λ _ → obs-cast) (λ _ → obs-cast-inv)
(λ _ → obs-cast-inv-right)
comm layer-comm obs-coherence
le-map : ∀ {x y} → LayeredEq ObsX stepX layerX x y
→ LayeredEq ObsY stepY layerY (f x) (f y)
le-map = M.le-map