{-# OPTIONS --safe --cubical-compatible --guardedness --exact-split --double-check #-}
module ALMA.Base.Equivalence.Properties where
open import Agda.Builtin.Equality using (_≡_; refl)
open import Relation.Binary.PropositionalEquality.Core using (trans; sym; cong; subst)
open import Relation.Binary.Structures using (IsEquivalence; IsPreorder)
open import ALMA.Base.IndexedMType using (Mᵢ)
open import ALMA.Base.Equivalence.Core using (LayeredEqGen; LayeredEq)
module LayeredEqGen-Properties
{a b c} {X : Set a}
{Obs : X → Set b}
{step : (x : X) → Obs x → X}
{layer : X → X → Set c}
{obs-map : (x y : X) → layer x y → Obs x → Obs y} where
le-refl
: (layer-refl : ∀ x → layer x x)
→ (obs-refl : ∀ x (s : Obs x) → obs-map x x (layer-refl x) s ≡ s)
→ ∀ x → LayeredEqGen Obs step layer obs-map x x
le-refl layer-refl obs-refl x .Mᵢ.fst = layer-refl x
le-refl layer-refl obs-refl x .Mᵢ.snd s
rewrite obs-refl x s = le-refl layer-refl obs-refl (step x s)
le-sym
: (layer-sym : ∀ {x y} → layer x y → layer y x)
→ (obs-sym : ∀ {x y} (l : layer x y) (s : Obs y)
→ obs-map x y l (obs-map y x (layer-sym l) s) ≡ s)
→ ∀ {x y} → LayeredEqGen Obs step layer obs-map x y
→ LayeredEqGen Obs step layer obs-map y x
le-sym layer-sym obs-sym {x} {y} p .Mᵢ.fst =
layer-sym (p .Mᵢ.fst)
le-sym layer-sym obs-sym {x} {y} p .Mᵢ.snd s =
le-sym layer-sym obs-sym
(subst (λ T → LayeredEqGen Obs step layer obs-map (step x s') T)
(cong (step y) (obs-sym {x} {y} l s))
(p .Mᵢ.snd s'))
where
l = p .Mᵢ.fst
s' = obs-map y x (layer-sym l) s
le-trans
: (layer-trans : ∀ {x y z} → layer x y → layer y z → layer x z)
→ (obs-trans : ∀ {x y z} (l : layer x y) (m : layer y z) (s : Obs x)
→ obs-map y z m (obs-map x y l s)
≡ obs-map x z (layer-trans l m) s)
→ ∀ {x y z} → LayeredEqGen Obs step layer obs-map x y
→ LayeredEqGen Obs step layer obs-map y z
→ LayeredEqGen Obs step layer obs-map x z
le-trans layer-trans obs-trans {x} {y} {z} p q .Mᵢ.fst =
layer-trans (p .Mᵢ.fst) (q .Mᵢ.fst)
le-trans layer-trans obs-trans {x} {y} {z} p q .Mᵢ.snd s =
le-trans layer-trans obs-trans
(p .Mᵢ.snd s)
(subst (λ T → LayeredEqGen Obs step layer obs-map (step y s_y) T)
(cong (step z) (obs-trans l_xy l_yz s))
(q .Mᵢ.snd s_y))
where
l_xy = p .Mᵢ.fst
l_yz = q .Mᵢ.fst
s_y = obs-map x y l_xy s
le-isPreorder
: (layer-refl : ∀ x → layer x x)
→ (layer-trans : ∀ {x y z} → layer x y → layer y z → layer x z)
→ (obs-refl : ∀ x (obs : Obs x)
→ obs-map x x (layer-refl x) obs ≡ obs)
→ (obs-trans : ∀ {x y z} (l : layer x y) (m : layer y z) (obs : Obs x)
→ obs-map y z m (obs-map x y l obs)
≡ obs-map x z (layer-trans l m) obs)
→ IsPreorder _≡_ (LayeredEqGen Obs step layer obs-map)
le-isPreorder layer-refl layer-trans obs-refl obs-trans = record
{ isEquivalence = record { refl = refl ; sym = sym ; trans = trans }
; reflexive = λ { {x} refl → le-refl layer-refl obs-refl x }
; trans = λ p q → le-trans layer-trans obs-trans p q
}
le-isEquivalence
: (layer-eq : IsEquivalence layer)
→ (obs-refl : ∀ x (s : Obs x)
→ obs-map x x (IsEquivalence.refl layer-eq) s ≡ s)
→ (obs-sym : ∀ {x y} (l : layer x y) (s : Obs y)
→ obs-map x y l
(obs-map y x (IsEquivalence.sym layer-eq l) s) ≡ s)
→ (obs-trans : ∀ {x y z} (l : layer x y) (m : layer y z) (s : Obs x)
→ obs-map y z m (obs-map x y l s)
≡ obs-map x z (IsEquivalence.trans layer-eq l m) s)
→ IsEquivalence (LayeredEqGen Obs step layer obs-map)
le-isEquivalence layer-eq obs-refl obs-sym obs-trans = record
{ refl = λ {x} →
le-refl (λ y → IsEquivalence.refl layer-eq {x = y}) obs-refl x
; sym = le-sym (IsEquivalence.sym layer-eq) obs-sym
; trans = le-trans (IsEquivalence.trans layer-eq) obs-trans
}
module LayeredEq-Equiv
{a b c} {X : Set a} {Obs : Set b} {step : X → Obs → X}
{layer : X → X → Set c}
(layer-equiv : IsEquivalence layer) where
open LayeredEqGen-Properties
{X = X} {Obs = λ _ → Obs} {step = step} {layer = layer}
{obs-map = λ _ _ _ o → o}
LE-isEquivalence : IsEquivalence (LayeredEq Obs step layer)
LE-isEquivalence =
le-isEquivalence layer-equiv
(λ _ _ → refl)
(λ _ _ → refl)
(λ _ _ _ → refl)