{-# OPTIONS --sized-types #-}
module A201605.AbelChapmanExtended.StrongBisimilarity where
open import Function using (_∘_)
open import Relation.Binary using (Setoid)
open import Relation.Binary.PropositionalEquality using (_≡_ ; refl ; sym ; trans)
open import Size using (Size ; Size<_ ; ∞)
open import A201605.Prelude
open import A201605.AbelChapmanExtended.Delay
mutual
data _≈_ {i A} : Delay ∞ A → Delay ∞ A → Set where
≈now : (a : A) → now a ≈ now a
≈later : ∀ {a∞ a∞′} → a∞ ∞≈⟨ i ⟩≈ a∞′ → later a∞ ≈ later a∞′
_≈⟨_⟩≈_ : ∀ {A} → Delay ∞ A → Size → Delay ∞ A → Set
_≈⟨_⟩≈_ {A} a? i a?′ = _≈_ {i} {A} a? a?′
record _∞≈⟨_⟩≈_ {A} (a∞ : ∞Delay ∞ A) (i : Size) (a∞′ : ∞Delay ∞ A) : Set where
coinductive
field
≈force : {j : Size< i} → force a∞ ≈⟨ j ⟩≈ force a∞′
_∞≈_ : ∀ {i A} → ∞Delay ∞ A → ∞Delay ∞ A → Set
_∞≈_ {i} {A} a∞ a∞′ = _∞≈⟨_⟩≈_ {A} a∞ i a∞′
infix 5 _≈⟨_⟩≈_ _∞≈⟨_⟩≈_ _∞≈_
open _∞≈⟨_⟩≈_ public
mutual
≈refl : ∀ {i A} {a? : Delay ∞ A} → a? ≈⟨ i ⟩≈ a?
≈refl {a? = now a} = ≈now a
≈refl {a? = later a∞} = ≈later ∞≈refl
∞≈refl : ∀ {i A} {a∞ : ∞Delay ∞ A} → a∞ ∞≈⟨ i ⟩≈ a∞
≈force (∞≈refl) = ≈refl
mutual
≈sym : ∀ {i A} {a? a?′ : Delay ∞ A} → a? ≈⟨ i ⟩≈ a?′ → a?′ ≈⟨ i ⟩≈ a?
≈sym (≈now a) = ≈now a
≈sym (≈later a≈a′) = ≈later (∞≈sym a≈a′)
∞≈sym : ∀ {i A} {a∞ a∞′ : ∞Delay ∞ A} → a∞ ∞≈⟨ i ⟩≈ a∞′ → a∞′ ∞≈⟨ i ⟩≈ a∞
≈force (∞≈sym a≈a′) = ≈sym (≈force a≈a′)
mutual
≈trans : ∀ {i A} {a? a?′ a?″ : Delay ∞ A} →
a? ≈⟨ i ⟩≈ a?′ → a?′ ≈⟨ i ⟩≈ a?″ → a? ≈⟨ i ⟩≈ a?″
≈trans (≈now a) (≈now .a) = ≈now a
≈trans (≈later a≈a′) (≈later a′≈a″) = ≈later (∞≈trans a≈a′ a′≈a″)
∞≈trans : ∀ {i A} {a∞ a∞′ a∞″ : ∞Delay ∞ A} →
a∞ ∞≈⟨ i ⟩≈ a∞′ → a∞′ ∞≈⟨ i ⟩≈ a∞″ → a∞ ∞≈⟨ i ⟩≈ a∞″
≈force (∞≈trans a≈a′ a′≈a″) = ≈trans (≈force a≈a′) (≈force a′≈a″)
mutual
bind-assoc : ∀ {i A B C} (a? : Delay ∞ A) →
{f : A → Delay ∞ B} {g : B → Delay ∞ C} →
((a? >>= f) >>= g) ≈⟨ i ⟩≈ (a? >>= λ a → f a >>= g)
bind-assoc (now a) = ≈refl
bind-assoc (later a∞) = ≈later (∞bind-assoc a∞)
∞bind-assoc : ∀ {i A B C} (a∞ : ∞Delay ∞ A) →
{f : A → Delay ∞ B} {g : B → Delay ∞ C} →
((a∞ ∞>>= f) ∞>>= g) ∞≈⟨ i ⟩≈ (a∞ ∞>>= λ a → f a >>= g)
≈force (∞bind-assoc a∞) = bind-assoc (force a∞)
mutual
bind-cong-l : ∀ {i A B} {a? a?′ : Delay ∞ A} →
a? ≈⟨ i ⟩≈ a?′ → {f : A → Delay ∞ B} →
(a? >>= f) ≈⟨ i ⟩≈ (a?′ >>= f)
bind-cong-l (≈now a) = ≈refl
bind-cong-l (≈later a≈a′) = ≈later (∞bind-cong-l a≈a′)
∞bind-cong-l : ∀ {i A B} {a∞ a∞′ : ∞Delay ∞ A} →
a∞ ∞≈⟨ i ⟩≈ a∞′ → {f : A → Delay ∞ B} →
(a∞ ∞>>= f) ∞≈⟨ i ⟩≈ (a∞′ ∞>>= f)
≈force (∞bind-cong-l a≈a′) = bind-cong-l (≈force a≈a′)
mutual
bind-cong-r : ∀ {i A B} (a? : Delay ∞ A) {f g : A → Delay ∞ B} →
(∀ a → (f a) ≈⟨ i ⟩≈ (g a)) →
(a? >>= f) ≈⟨ i ⟩≈ (a? >>= g)
bind-cong-r (now a) h = h a
bind-cong-r (later a∞) h = ≈later (∞bind-cong-r a∞ h)
∞bind-cong-r : ∀ {i A B} (a∞ : ∞Delay ∞ A) {f g : A → Delay ∞ B} →
(∀ a → (f a) ≈⟨ i ⟩≈ (g a)) →
(a∞ ∞>>= f) ∞≈⟨ i ⟩≈ (a∞ ∞>>= g)
≈force (∞bind-cong-r a∞ h) = bind-cong-r (force a∞) h
≈setoid : (i : Size) (A : Set) → Setoid _ _
≈setoid i A = record
{ Carrier = Delay ∞ A
; _≈_ = _≈_ {i}
; isEquivalence = record
{ refl = ≈refl
; sym = ≈sym
; trans = ≈trans
}
}
∞≈setoid : (i : Size) (A : Set) → Setoid _ _
∞≈setoid i A = record
{ Carrier = ∞Delay ∞ A
; _≈_ = _∞≈_ {i}
; isEquivalence = record
{ refl = ∞≈refl
; sym = ∞≈sym
; trans = ∞≈trans
}
}
module ≈-Reasoning {i A} where
open PR (preorder (≈setoid i A)) public
using (_∎)
renaming (_≈⟨⟩_ to _≡⟨⟩_ ; _≈⟨_⟩_ to _≡⟨_⟩_ ; _∼⟨_⟩_ to _≈⟨_⟩_ ; begin_ to proof_)
module ∞≈-Reasoning {i A} where
open PR (preorder (∞≈setoid i A)) public
using (_∎)
renaming (_≈⟨⟩_ to _≡⟨⟩_ ; _≈⟨_⟩_ to _≡⟨_⟩_ ; _∼⟨_⟩_ to _∞≈⟨_⟩_ ; begin_ to proof_)
sym-bind-assoc : ∀ {i A B C} (a? : Delay ∞ A) →
{f : A → Delay ∞ B} {g : B → Delay ∞ C} →
(a? >>= λ a → f a >>= g) ≈⟨ i ⟩≈ ((a? >>= f) >>= g)
sym-bind-assoc a? = ≈sym (bind-assoc a?)
syntax bind-assoc a? = ⋘ a?
syntax sym-bind-assoc a? = ⋙ a?
syntax bind-cong-r a? (λ a → b?) = a ⇚ a? ⁏ b?
syntax bind-cong-l a≈a′ = ∵ a≈a′
infix 35 bind-assoc sym-bind-assoc
infix 30 bind-cong-r bind-cong-l