open import Relation.Binary.Core
open import Relation.Binary
open import Refinement
open import Data.Product
open import Data.Sum hiding (map₂) renaming (swap to swap⊎)
open import Function
open import Helper
open import Relation.Binary.PropositionalEquality
open import Data.Empty
module CCSLRefinement (Support : Set)
{_≈₁_ _≈₂_ _≺₁_ _≺₂_ : Rel Support _}
(ispo₁ : IsStrictPartialOrder _≈₁_ _≺₁_)
(ispo₂ : IsStrictPartialOrder _≈₂_ _≺₂_)
(refines : (_≈₁_ , _≺₁_) ≺≈ (_≈₂_ , _≺₂_)) where
open import CCSL (record {isStrictPartialOrder = ispo₁}) as ₁
open import CCSL (record {isStrictPartialOrder = ispo₂}) as ₂
≼₁→₂ : ₁._≼_ ⇒ ₂._≼_
≼₁→₂ (inj₁ i≈₁j) = inj₁ (≈₁→₂ refines i≈₁j)
≼₁→₂ (inj₂ i≺₁j) = swap⊎ (≺₁→₂ refines i≺₁j)
_≲₁◅ₙ_ : REL ₁.Clock ₂.Clock _
(Ticks₁ ⌞ _) ≲₁◅ₙ (Ticks₂ ⌞ _) =
(∀ (y : ∃ Ticks₂) → ∃ λ (x : ∃ Ticks₁) → x ₂.≈' y) ×
(∀ (x : ∃ Ticks₁) → ∃ λ (y : ∃ Ticks₂) → y ₂.≈' x)
e∘a≡id : ∀ {c₁ c₂} (p : c₁ ≲₁◅ₙ c₂) → (∀ {i : ∃ (Ticks c₂)} →
i ₂.≡' (proj₁ ∘ proj₂ p ∘ proj₁ ∘ (proj₁ p)) i)
e∘a≡id (u , _) {i} with u i
e∘a≡id (_ , v) | j , j≈₂i with v j
e∘a≡id {c₂ = c₂} _ {i} | _ , j≈₂i | k , k≈₂j =
₂.≈→≡ {c₂} {i} {k} (₂.sym≈ (₂.trans≈ k≈₂j j≈₂i))
⊑≲₁◅ₙ : ∀ {c₁₁ c₁₂ c₂₁ c₂₂} →
c₁₁ ₁.⊑ c₁₂ → c₁₁ ≲₁◅ₙ c₂₁ → c₁₂ ≲₁◅ₙ c₂₂ → c₂₁ ₂.⊑ c₂₂
⊑≲₁◅ₙ o (p , _) (_ , s) i₂₁ = (i₂₁ , ₂.refl≈)
>[ id -⟦ ₂.trans≈ ⟧- ₂.sym≈ ]> p
>[ id -⟦ ₂.trans≈ ⟧- ≈₁→₂ refines ]> o
>[ id -⟦ ₂.trans≈ ⟧- ₂.sym≈ ]> s
♯≲₁◅ₙ : ∀ {c₁₁ c₁₂ c₂₁ c₂₂} →
c₂₁ ₂.♯ c₂₂ → c₁₁ ≲₁◅ₙ c₂₁ → c₁₂ ≲₁◅ₙ c₂₂ → c₁₁ ₁.♯ c₁₂
♯≲₁◅ₙ p (q , r) (s , t) x y x≈₁y with r x | t y
♯≲₁◅ₙ p (q , r) (s , t) x y x≈₁y | rx , rx≈₂x | ty , ty≈₂y =
p rx ty (₂.trans≈ (₂.trans≈ rx≈₂x (≈₁→₂ refines x≈₁y)) (₂.sym≈ ty≈₂y))
⋃≲₁◅ₙ : ∀ {c₁₁ c₁₀ c₁₂ c₂} →
c₁₁ ≲₁◅ₙ c₂ → c₁₂ ≲₁◅ₙ c₂ → c₁₀ ₁.≋ c₁₁ ⋃ c₁₂ → c₁₀ ≲₁◅ₙ c₂
⋃≲₁◅ₙ (p , _) _ (_ , u) .proj₁ x = (x , ₂.refl≈)
>[ flip ₂.trans≈ ]> p
>[ id -⟦ flip ₂.trans≈ ⟧- (₂.sym≈ ∘ ≈₁→₂ refines) ]> u ∘ map₂ inj₁
⋃≲₁◅ₙ _ _ (t , _) .proj₂ x with t x
⋃≲₁◅ₙ (_ , q) _ _ .proj₂ _ | ((i , inj₁ tc₁₁i) , i≈₁x) =
((i , tc₁₁i) , ≈₁→₂ refines i≈₁x) >[ flip ₂.trans≈ ]> q
⋃≲₁◅ₙ _ (_ , s) _ .proj₂ _ | ((i , inj₂ tc₁₂i) , i≈₁x) =
((i , tc₁₂i) , ≈₁→₂ refines i≈₁x) >[ flip ₂.trans≈ ]> s
∽≲₁◅ₙ : ∀ {c₁ c₂₁ c₂₂} → c₁ ≲₁◅ₙ c₂₁ → c₁ ≲₁◅ₙ c₂₂ → c₂₁ ₂.∽ c₂₂
∽≲₁◅ₙ (p , _) (_ , s) .proj₁ x = (x , ₂.refl≈)
>[ id -⟦ ₂.trans≈ ⟧- ₂.sym≈ ]> p
>[ id -⟦ ₂.trans≈ ⟧- ₂.sym≈ ]> s
∽≲₁◅ₙ (_ , q) (r , _) .proj₂ x = (x , ₂.refl≈)
>[ id -⟦ ₂.trans≈ ⟧- ₂.sym≈ ]> r
>[ id -⟦ ₂.trans≈ ⟧- ₂.sym≈ ]> q
_≲₁◅₁_ : REL ₁.Clock ₂.Clock _
(Ticks₁ ⌞ _) ≲₁◅₁ (Ticks₂ ⌞ _) =
(∀ (y : ∃ Ticks₂) → ∃! (₁._≈'_) λ (x : ∃ Ticks₁) → x ₂.≈' y) ×
(∀ (x : ∃ Ticks₁) → ∃ λ (y : ∃ Ticks₂) → y ₂.≈' x)
≲→≲₁◅₁ : ∀ {c₁ c₂} → c₁ ≲₁◅₁ c₂ → c₁ ≲₁◅ₙ c₂
≲→≲₁◅₁ (p , q) = ∃!→∃ ∘ p , q
≲₁◅₁→≈₂→₁ : ∀ {c₁₁ c₂₁} → c₁₁ ≲₁◅₁ c₂₁ → {k l : ∃ (Ticks c₁₁)}
→ k ₂.≈' l → k ₁.≈' l
≲₁◅₁→≈₂→₁ {c₁₁} {c₂₁} (p , q) {k} {l} k≈₂l with q k | q l
... | u , u≈₂k | v , v≈₂l with ₂.≈→≡ {c₂₁} {u} {v}
(₂.trans≈ (₂.trans≈ u≈₂k k≈₂l) (₂.sym≈ v≈₂l))
... | refl with p u
... | j , j≈₂u , ∃! =
₁.trans≈ (₁.sym≈ (∃! {k} (₂.sym≈ u≈₂k))) (∃! {l} (₂.sym≈ v≈₂l))
≲₁◅₁→≺₁→₂ : ∀ {c₁₁ c₂₁} → c₁₁ ≲₁◅₁ c₂₁ → {k l : ∃ (Ticks c₁₁)}
→ k ₁.≺' l → k ₂.≺' l
≲₁◅₁→≺₁→₂ {c₁₁} {c₂₁} p {k} {l} k≺₁l with ≺₁→₂ refines k≺₁l
... | inj₁ k≺₂l = k≺₂l
... | inj₂ k≈₂l =
⊥-elim (₁.irrefl≈≺ (≲₁◅₁→≈₂→₁ {c₁₁} {c₂₁} p {k} {l} k≈₂l) k≺₁l)
a∘e≡id : ∀ {c₁ c₂} (p : c₁ ≲₁◅₁ c₂) → (∀ {i : ∃ (Ticks c₁)} →
i ₂.≡' (proj₁ ∘ proj₁ p ∘ proj₁ ∘ (proj₂ p)) i)
a∘e≡id (_ , v) {i} with v i
a∘e≡id (u , _) | j , j≈₂i with u j
a∘e≡id {c₁} {c₂} p {i} | j , j≈₂i | k , k≈₂j , _ =
₁.≈→≡ {c₁} {i} {k} (≲₁◅₁→≈₂→₁ {c₁} {c₂} p {i} {k}
(₂.sym≈ (₂.trans≈ k≈₂j j≈₂i)))
≺≺₂→≺≺₁ : ∀ {c₁₁ c₁₂ c₂₁ c₂₂} → c₁₁ ≲₁◅₁ c₂₁ → c₁₂ ≲₁◅₁ c₂₂
→ c₂₁ ₂.≺≺ c₂₂ → c₁₁ ₁.≺≺ c₁₂
≺≺₂→≺≺₁ (p , _) (_ , q₁) prec .h = proj₁ ∘ p ∘ h prec ∘ proj₁ ∘ q₁
≺≺₂→≺≺₁ {c₁₁} {_} {c₂₁} (p , q) (_ , q₁) prec .congruent {i} {j} i≈₁j
with q₁ i | q₁ j ; ... | i₁ , i₁≈₂i | j₁ , j₁≈₂j with p (h prec i₁) | p (h prec j₁)
... | i₃ , i₃≈₂i₂ , _ | j₃ , j₃≈₂j₂ , _ with ≈₁→₂ refines i≈₁j
... | i≈₂j with ₂.trans≈ (₂.trans≈ i₁≈₂i i≈₂j) (₂.sym≈ j₁≈₂j)
... | i₁≈₂j₁ with congruent prec {i₁} {j₁} i₁≈₂j₁
... | i₂≈₂j₂ with ₂.trans≈ i₃≈₂i₂ (₂.trans≈ i₂≈₂j₂ (₂.sym≈ j₃≈₂j₂))
... | i₃≈₂j₃ = ≲₁◅₁→≈₂→₁ {c₁₁} {c₂₁} (p , q) {i₃} {j₃} i₃≈₂j₃
≺≺₂→≺≺₁ (p , _) (_ , q₁) prec .precedes i with q₁ i
... | j , j≈₂i with p (h prec j)
... | _ , k≈₂hj , _ with precedes prec j
... | hj≺₂j with ₂.≺≈≈→≺ hj≺₂j (₂.sym≈ k≈₂hj) j≈₂i
... | k≺₂i = ≺₂→₁ refines k≺₂i
≺≺₂→≺≺₁ {_} {c₁₂} {_} {c₂₂} _ q _ .preserves {i} {j} i≺₁j
with ≲₁◅₁→≺₁→₂ {c₁₂} {c₂₂} q {i} {j} i≺₁j
≺≺₂→≺≺₁ (p , _) (_ , q₁) prec .preserves {i} {j} _ | i≺₂j with q₁ i | q₁ j
... | i₁ , i₁≈i | j₁ , j₁≈j with p (h prec i₁) | p (h prec j₁)
... | _ , i₃≈₂i₂ , _ | _ , j₃≈₂j₂ , _
with ₂.≺≈≈→≺ i≺₂j (₂.sym≈ i₁≈i) (₂.sym≈ j₁≈j)
... | i₁≺₂j₁ with preserves prec {i₁} {j₁} i₁≺₂j₁
... | i₂≺₂j₂ with ₂.≺≈≈→≺ i₂≺₂j₂ (₂.sym≈ i₃≈₂i₂) (₂.sym≈ j₃≈₂j₂)
... | i₃≺₂j₃ = ≺₂→₁ refines i₃≺₂j₃
≺≺₂→≺≺₁ {c₁₁} {c₁₂} {c₂₁} {c₂₂} (p , q) (p₁ , q₁) prec .dense
{i₀} {j₀} {k₃} i₃≺₁k₃ k₃≺₁j₃ with q₁ i₀ | q₁ j₀ | q k₃
... | i₁ , i₁≈₂i | j₁ , j₁≈₂j | k₂ , k₂≈₂k₃
with p (h prec i₁) | p (h prec j₁)
... | i₃ , i₃≈₂i₂ , _ | j₃ , j₃≈₂j₂ , _
with ≲₁◅₁→≺₁→₂ {c₁₁} {c₂₁} (p , q) {i₃} {k₃} i₃≺₁k₃
... | i₃≺₂k₃ with ≲₁◅₁→≺₁→₂ {c₁₁} {c₂₁} (p , q) {k₃} {j₃} k₃≺₁j₃
... | k₃≺₂j₃ with ₂.≺≈≈→≺ i₃≺₂k₃ i₃≈₂i₂ (₂.sym≈ k₂≈₂k₃)
... | i₂≺₂k₂ with ₂.≺≈≈→≺ k₃≺₂j₃ (₂.sym≈ k₂≈₂k₃) j₃≈₂j₂
... | k₂≺₂j₂ with dense prec {i₁} {j₁} {k₂} i₂≺₂k₂ k₂≺₂j₂
... | k₁ , hk₁≈₂k₂ with p₁ k₁
... | k₀ , k₀≈₂k₁ , _ with ₂.trans≈ (proj₂ (q₁ k₀)) k₀≈₂k₁
... | qk₀≈₂k₁ with congruent prec {proj₁ (q₁ k₀)} {k₁} qk₀≈₂k₁
... | hqk₀≈₂hk₁ with ₂.trans≈ (₂.trans≈ hqk₀≈₂hk₁ hk₁≈₂k₂) k₂≈₂k₃
... | hqk₀≈₂k₃ with ₂.trans≈
(proj₁ (proj₂ (p (h prec (proj₁ (q₁ k₀)))))) hqk₀≈₂k₃
... | phqk₀≈₂k₃ = k₀ , ≲₁◅₁→≈₂→₁ {c₁₁} {c₂₁} (p , q)
{proj₁ (p (h prec (proj₁ (q₁ k₀))))} {k₃} phqk₀≈₂k₃
prec₁→≼≼₂ : ∀ {c₁₁ c₁₂ c₂₁ c₂₂} {_R_ : Rel ₁.Support _}
→ _R_ ⇒ ₁._≼_ → c₁₁ ≲₁◅₁ c₂₁ → c₁₂ ≲₁◅₁ c₂₂
→ ₁.Precedence _R_ c₁₁ c₁₂ → c₂₁ ₂.≼≼ c₂₂
prec₁→≼≼₂ _ (p , q) (p₁ , q₁) prec .h = proj₁ ∘ q ∘ h prec ∘ proj₁ ∘ p₁
prec₁→≼≼₂ {_} {c₁₂} {_} {c₂₂} _ (p , q) (p₁ , q₁) prec .congruent
{i₀} {j₀} i₀≈₂j₀ with p₁ i₀ | p₁ j₀
... | i₁ , i₁≈₂i₀ , _ | j₁ , j₁≈₂j₀ , _ with q (h prec i₁) | q (h prec j₁)
... | i₃ , i₃≈₂hi₁ | j₃ , j₂≈₂hj₁
with ₂.trans≈ i₁≈₂i₀ (₂.trans≈ i₀≈₂j₀ (₂.sym≈ j₁≈₂j₀))
... | i₁≈₂j₁ with ≲₁◅₁→≈₂→₁ {c₁₂} {c₂₂} (p₁ , q₁) {i₁} {j₁} i₁≈₂j₁
... | i₁≈₁j₁ with ≈₁→₂ refines (congruent prec {i₁} {j₁} i₁≈₁j₁)
... | hi₁≈₂hj₁ = ₂.trans≈ i₃≈₂hi₁ (₂.trans≈ hi₁≈₂hj₁ (₂.sym≈ j₂≈₂hj₁))
prec₁→≼≼₂ R⇒≼₁ (p , q) (p₁ , q₁) prec .precedes i₀ with p₁ i₀
... | i₁ , i₁≈₂i₀ , _ with precedes prec i₁
... | hi₁Ri₁ with ≼₁→₂ (R⇒≼₁ hi₁Ri₁)
... | hi₁≼₂i₁ with q (h prec i₁)
... | i₃ , i₃≈₂hi₁ = ₂.trans≼ (inj₁ i₃≈₂hi₁) (₂.trans≼ hi₁≼₂i₁ (inj₁ i₁≈₂i₀))
prec₁→≼≼₂ {c₁₁} {_} {c₂₁} _ (p , q) (p₁ , q₁) prec .preserves
{i₀} {j₀} i₀≺₂j₀ with p₁ i₀ | p₁ j₀
... | i₁ , i₁≈₂i₀ , _ | j₁ , j₁≈₂j₀ , _ with q (h prec i₁) | q (h prec j₁)
... | i₃ , i₃≈₂hi₁ | j₃ , j₂≈₂hj₁
with ₂.≺≈≈→≺ i₀≺₂j₀ (₂.sym≈ i₁≈₂i₀) (₂.sym≈ j₁≈₂j₀)
... | i₁≺₂j₁ with ≺₂→₁ refines i₁≺₂j₁
... | i₁≺₁j₁ with preserves prec {i₁} {j₁} i₁≺₁j₁
... | hi₁≺₁hj₁ with
≲₁◅₁→≺₁→₂ {c₁₁} {c₂₁} (p , q) {h prec i₁} {h prec j₁} hi₁≺₁hj₁
... | hi₁≺₂hj₁ = ₂.≺≈≈→≺ hi₁≺₂hj₁ (₂.sym≈ i₃≈₂hi₁) (₂.sym≈ j₂≈₂hj₁)
prec₁→≼≼₂ {_} {c₁₂} {_} {c₂₂} _ (p , q) (p₁ , q₁) prec .dense
{i₀} {j₀} {k₃} i₃≺₂k₃ k₃≺₂j₃ with p₁ i₀ | p₁ j₀ | p k₃
... | i₁ , i₁≈₂i₀ , _ | j₁ , j₁≈₂j₀ , _ | k₂ , k₂≈₂k₃ , _
with q (h prec i₁) | q (h prec j₁)
... | i₃ , i₃≈₂i₂ | j₃ , j₃≈₂j₂
with ≺₂→₁ refines (₂.≺≈≈→≺ i₃≺₂k₃ i₃≈₂i₂ (₂.sym≈ k₂≈₂k₃))
... | i₂≺₁k₂ with ≺₂→₁ refines (₂.≺≈≈→≺ k₃≺₂j₃ (₂.sym≈ k₂≈₂k₃) j₃≈₂j₂)
... | k₂≺₁j₂ with dense prec {i₁} {j₁} {k₂} i₂≺₁k₂ k₂≺₁j₂
... | k₁ , hk₁≈₁k₂ with q₁ k₁
... | k₀ , k₀≈₂k₁ with ₂.trans≈ (proj₁ (proj₂ (p₁ k₀))) k₀≈₂k₁
... | pk₀≈₂k₁
with ≲₁◅₁→≈₂→₁ {c₁₂} {c₂₂} (p₁ , q₁) {proj₁ (p₁ k₀)} {k₁} pk₀≈₂k₁
... | pk₀≈₁k₁ with congruent prec {proj₁ (p₁ k₀)} {k₁} pk₀≈₁k₁
... | hpk₀≈₁hk₁ with ₂.trans≈ (₂.trans≈ (≈₁→₂ refines hpk₀≈₁hk₁)
(≈₁→₂ refines hk₁≈₁k₂)) k₂≈₂k₃
... | hpk₀≈₂k₃ = k₀ , ₂.trans≈ (proj₂ (q (h prec (proj₁ (p₁ k₀))))) hpk₀≈₂k₃
≺≺₁→≼≼₂ : ∀ {c₁₁ c₁₂ c₂₁ c₂₂} → c₁₁ ≲₁◅₁ c₂₁ → c₁₂ ≲₁◅₁ c₂₂
→ c₁₁ ₁.≺≺ c₁₂ → c₂₁ ₂.≼≼ c₂₂
≺≺₁→≼≼₂ = prec₁→≼≼₂ inj₂
≼≼₁→≼≼₂ : ∀ {c₁₁ c₁₂ c₂₁ c₂₂} → c₁₁ ≲₁◅₁ c₂₁ → c₁₂ ≲₁◅₁ c₂₂
→ c₁₁ ₁.≼≼ c₁₂ → c₂₁ ₂.≼≼ c₂₂
≼≼₁→≼≼₂ = prec₁→≼≼₂ id