```------------------------------------------------------------------------
-- Another coinductive definition of weak bisimilarity
------------------------------------------------------------------------

{-# OPTIONS --without-K #-}

open import Labelled-transition-system

module Bisimilarity.Weak.Coinductive.Other (lts : LTS) where

open import Prelude

import Bisimilarity.Coinductive
import Bisimilarity.Coinductive.Equational-reasoning-instances
import Bisimilarity.Coinductive.General
open import Equational-reasoning
import Expansion
import Expansion.Equational-reasoning-instances
open import Relation

open LTS lts
private
open module SB = Bisimilarity.Coinductive lts
using (_∼_; _∼′_; [_]_∼_; [_]_∼′_)
open module E = Expansion lts
using (_≳_; _≳′_; _≲_; [_]_≳_; [_]_≳′_)

private
module General =
Bisimilarity.Coinductive.General lts _[_]⇒̂_ _[_]⇒̂_ ⟶→⇒̂ ⟶→⇒̂

open General public
using (S̲t̲e̲p̲; ⟨_,_⟩; left-to-right; right-to-left; force;
[_]_≡_; [_]_≡′_; []≡↔;
Extensionality; extensionality)
renaming ( reflexive-∼ to reflexive-≈
; reflexive-∼′ to reflexive-≈′
; ≡⇒∼ to ≡⇒≈
; ∼:_ to ≈:_
; ∼′:_ to ≈′:_
)

-- Some definitions are given in the following way, rather than via
-- open public, to make hyperlinks to these definitions more
-- informative.

Weak-bisimilarity : Size → Rel₂ (# 0) Proc
Weak-bisimilarity = General.Bisimilarity

Weak-bisimilarity′ : Size → Rel₂ (# 0) Proc
Weak-bisimilarity′ = General.Bisimilarity′

infix 4 _≈_ _≈′_ [_]_≈_ [_]_≈′_

[_]_≈_ : Size → Proc → Proc → Set
[_]_≈_ = General.[_]_∼_

[_]_≈′_ : Size → Proc → Proc → Set
[_]_≈′_ = General.[_]_∼′_

_≈_ : Proc → Proc → Set
_≈_ = General._∼_

_≈′_ : Proc → Proc → Set
_≈′_ = General._∼′_

-- Combinators that can perhaps make the code a bit nicer to read.

infix -3 lr-result rl-result

lr-result : ∀ {i p′ q q′} μ → [ i ] p′ ≈′ q′ → q [ μ ]⇒̂ q′ →
∃ λ q′ → q [ μ ]⇒̂ q′ × [ i ] p′ ≈′ q′
lr-result _ p′≈′q′ q⇒̂q′ = _ , q⇒̂q′ , p′≈′q′

rl-result : ∀ {i p p′ q′} μ → p [ μ ]⇒̂ p′ → [ i ] p′ ≈′ q′ →
∃ λ p′ → p [ μ ]⇒̂ p′ × [ i ] p′ ≈′ q′
rl-result _ p⇒̂p′ p′≈′q′ = _ , p⇒̂p′ , p′≈′q′

syntax lr-result μ p′≈′q′ q⇒̂q′ = p′≈′q′ ⇐̂[ μ ] q⇒̂q′
syntax rl-result μ p⇒̂p′ p′≈′q′ = p⇒̂p′ ⇒̂[ μ ] p′≈′q′

-- Processes that are related by the expansion ordering are weakly
-- bisimilar.

mutual

≳⇒≈ : ∀ {i p q} → [ i ] p ≳ q → [ i ] p ≈ q
≳⇒≈ {i} = λ p≳q → S̲t̲e̲p̲.⟨ lr p≳q , rl p≳q ⟩
where
lr : ∀ {p p′ q μ} →
[ i ] p ≳ q → p [ μ ]⟶ p′ →
∃ λ q′ → q [ μ ]⇒̂ q′ × [ i ] p′ ≈′ q′
lr p≳q q⟶q′ =
let p′ , p⟶̂p′ , p′≳′q′ = E.left-to-right p≳q q⟶q′
in p′ , ⟶̂→⇒̂ p⟶̂p′ , ≳⇒≈′ p′≳′q′

rl : ∀ {p q q′ μ} →
[ i ] p ≳ q → q [ μ ]⟶ q′ →
∃ λ p′ → p [ μ ]⇒̂ p′ × [ i ] p′ ≈′ q′
rl p≳q q⟶q′ =
let p′ , p⇒̂p′ , p′≳′q′ = E.right-to-left p≳q q⟶q′
in p′ , p⇒̂p′ , ≳⇒≈′ p′≳′q′

≳⇒≈′ : ∀ {i p q} → [ i ] p ≳′ q → [ i ] p ≈′ q
force (≳⇒≈′ p≳′q) = ≳⇒≈ (SB.force p≳′q)

-- Strongly bisimilar processes are weakly bisimilar.

∼⇒≈ : ∀ {i p q} → [ i ] p ∼ q → [ i ] p ≈ q
∼⇒≈ = ≳⇒≈ ∘ convert

∼⇒≈′ : ∀ {i p q} → [ i ] p ∼′ q → [ i ] p ≈′ q
∼⇒≈′ = ≳⇒≈′ ∘ convert

-- Weak bisimilarity is a weak simulation (of a certain kind).

weak-is-weak :
∀ {p p′ q μ} →
p ≈ q → p [ μ ]⇒̂ p′ →
∃ λ q′ → q [ μ ]⇒̂ q′ × p′ ≈ q′
weak-is-weak = is-weak S̲t̲e̲p̲.left-to-right (λ p≈′q → force p≈′q) ⇒̂→⇒ id

mutual

-- Weak bisimilarity is symmetric.

symmetric-≈ : ∀ {i p q} → [ i ] p ≈ q → [ i ] q ≈ p
symmetric-≈ p≈q =
S̲t̲e̲p̲.⟨ Σ-map id (Σ-map id symmetric-≈′) ∘ S̲t̲e̲p̲.right-to-left p≈q
, Σ-map id (Σ-map id symmetric-≈′) ∘ S̲t̲e̲p̲.left-to-right p≈q
⟩

symmetric-≈′ : ∀ {i p q} → [ i ] p ≈′ q → [ i ] q ≈′ p
force (symmetric-≈′ p≈q) = symmetric-≈ (force p≈q)

mutual

-- Weak bisimilarity is transitive.
--
-- Note that the transitivity proof is not claimed to be
-- size-preserving. For proofs showing that transitivity cannot, in
-- general, be size-preserving in any of its arguments, see
-- and size-preserving-transitivityˡ⇔uninhabited.

transitive-≈ : ∀ {i p q r} → p ≈ q → q ≈ r → [ i ] p ≈ r
transitive-≈ {i} = λ p≈q q≈r →
S̲t̲e̲p̲.⟨ lr p≈q q≈r
, Σ-map id (Σ-map id symmetric-≈′) ∘
lr (symmetric-≈ q≈r) (symmetric-≈ p≈q)
⟩
where
lr : ∀ {p p′ q r μ} →
p ≈ q → q ≈ r → p [ μ ]⟶ p′ →
∃ λ r′ → r [ μ ]⇒̂ r′ × [ i ] p′ ≈′ r′
lr p≈q q≈r p⟶p′ =
let q′ , q⇒̂q′ , p′≈′q′ = S̲t̲e̲p̲.left-to-right p≈q p⟶p′
r′ , r⇒̂r′ , q′≈r′  = weak-is-weak q≈r q⇒̂q′
in r′ , r⇒̂r′ , transitive-≈′ p′≈′q′ q′≈r′

transitive-≈′ : ∀ {i p q r} → p ≈′ q → q ≈ r → [ i ] p ≈′ r
force (transitive-≈′ p≈q q≈r) = transitive-≈ (force p≈q) q≈r

-- The following variants of transitivity are partially
-- size-preserving.
--
-- For proofs showing that they cannot, in general, be size-preserving
-- in the "other" argument, see the following lemmas in
-- size-preserving-transitivity-≳≈ˡ⇔uninhabited,
-- size-preserving-transitivity-≈≲ʳ⇔uninhabited and
-- size-preserving-transitivity-≈∼ʳ⇔uninhabited.

mutual

transitive-≳≈ : ∀ {i p q r} →
p ≳ q → [ i ] q ≈ r → [ i ] p ≈ r
transitive-≳≈ {i} {p} {r = r} p≳q q≈r = S̲t̲e̲p̲.⟨ lr , rl ⟩
where
lr : ∀ {p′ μ} → p [ μ ]⟶ p′ →
∃ λ r′ → r [ μ ]⇒̂ r′ × [ i ] p′ ≈′ r′
lr p⟶p′ with E.left-to-right p≳q p⟶p′
... | _  , done s , p≳′q′  =
r , silent s done
, transitive-≳≈′ p≳′q′ (record { force = λ { {_} → q≈r } })
... | q′ , step q⟶q′ , p′≳′q′ =
let r′ , r⇒̂r′ , q′≈′r′ = S̲t̲e̲p̲.left-to-right q≈r q⟶q′
in r′ , r⇒̂r′ , transitive-≳≈′ p′≳′q′ q′≈′r′

rl : ∀ {r′ μ} → r [ μ ]⟶ r′ →
∃ λ p′ → p [ μ ]⇒̂ p′ × [ i ] p′ ≈′ r′
rl r⟶r′ =
let q′ , q⇒̂q′ , q′≈′r′ = S̲t̲e̲p̲.right-to-left q≈r r⟶r′
p′ , p⇒̂p′ , p′≳q′  = E.converse-of-expansion-is-weak p≳q q⇒̂q′
in p′ , p⇒̂p′ , transitive-≳≈′ (record { force = p′≳q′ }) q′≈′r′

transitive-≳≈′ : ∀ {i p q r} →
p ≳′ q → [ i ] q ≈′ r → [ i ] p ≈′ r
force (transitive-≳≈′ p≳′q q≈′r) =
transitive-≳≈ (force p≳′q) (force q≈′r)

transitive-≈≲ : ∀ {i p q r} →
[ i ] p ≈ q → q ≲ r → [ i ] p ≈ r
transitive-≈≲ p≈q q≲r =
symmetric-≈ (transitive-≳≈ q≲r (symmetric-≈ p≈q))

transitive-≈∼ : ∀ {i p q r} →
[ i ] p ≈ q → q ∼ r → [ i ] p ≈ r
transitive-≈∼ p≈q q∼r =
symmetric-≈ \$
transitive-≳≈ (convert (symmetric q∼r)) (symmetric-≈ p≈q)
```