streamBisim
import equality (cong)
import stream (stream, hd, tl, mapS)
import streamEq (tlN, nth, obsEq, obsEqRefl, nthMap, mapIdObsEq, mapFuseObsEq)
def bisim : (a : 𝕌) → El (stream a) → El (stream a) → Ω ≔
λa. λs. λt.
∥(r : El (stream a) → El (stream a) → Ω) ⨯
((x : El (stream a)) (y : El (stream a)) → Prf (r x y) →
Prf (hd _ x ≡ hd _ y ∈ El a) ⨯ Prf (r (tl _ x) (tl _ y))) ⨯
Prf (r s t)∥
def bisimHd : (a : 𝕌) (s : El (stream a)) (t : El (stream a)) →
Prf (bisim _ s t) → Prf (hd _ s ≡ hd _ t ∈ El a) ≔
λa. λs. λt. λh. squash-elim h (w. ((w .π₂ .π₁) s t (w .π₂ .π₂)) .π₁)
def bisimTl : (a : 𝕌) (s : El (stream a)) (t : El (stream a)) →
Prf (bisim _ s t) → Prf (bisim _ (tl _ s) (tl _ t)) ≔
λa. λs. λt. λh.
squash-elim h (w.
⋆ ((w .π₁ , ((w .π₂ .π₁) , ((w .π₂ .π₁) s t (w .π₂ .π₂)) .π₂))))
def bisimRefl : (a : 𝕌) (s : El (stream a)) → Prf (bisim _ s s) ≔
λa. λs.
⋆ (((λx. λy. (x ≡ y ∈ El (stream a))) ,
((λx. λy. λp. (cong _ (λv. a) (λv. hd _ v) x y p ,
cong _ (λv. stream a) (λv. tl _ v) x y p)) ,
⋆)))
def obsEqBisim : (a : 𝕌) (s : El (stream a)) (t : El (stream a)) →
Prf (obsEq _ s t) → Prf (bisim _ s t) ≔
λa. λs. λt. λh.
⋆ (((λx. λy. obsEq _ x y) ,
((λx. λy. λp. (squash-elim p (w. w Z) ,
squash-elim p (w. ⋆ (λn. w (S n))))) ,
h)))
def bisimObsEq : (a : 𝕌) (s : El (stream a)) (t : El (stream a)) →
Prf (bisim _ s t) → Prf (obsEq _ s t) ≔
λa. λs. λt. λh.
⋆ (λn. (ℕ-elim (m. (x : El (stream a)) → (y : El (stream a)) →
Prf (bisim _ x y) → Prf (nth _ m x ≡ nth _ m y ∈ El a))
(λx. λy. λg. bisimHd _ x y g)
(m ih. λx. λy. λg. ih (tl _ x) (tl _ y) (bisimTl _ x y g))
n) s t h)
def mapIdBisim : (a : 𝕌) (s : El (stream a)) →
Prf (bisim _ (mapS _ _ (λx. x) s) s) ≔
λa. λs. obsEqBisim _ _ _ (mapIdObsEq _ s)
def bisimReflect : (a : 𝕌) (s : El (stream a)) (t : El (stream a)) →
Prf (bisim _ s t) → Prf (s ≡ t ∈ El (stream a)) ≔
λa. λs. λt. λh.
coind (x y. bisim _ x y) h
(x y hb. ⋆ ((bisimHd _ x y hb , bisimTl _ x y hb)))
def obsEqReflect : (a : 𝕌) (s : El (stream a)) (t : El (stream a)) →
Prf (obsEq _ s t) → Prf (s ≡ t ∈ El (stream a)) ≔
λa. λs. λt. λh. bisimReflect _ s t (obsEqBisim _ s t h)
def mapIdEq : (a : 𝕌) (s : El (stream a)) →
mapS _ _ (λx. x) s ≡ s ∈ El (stream a) ≔
λa. λs. bisimReflect _ _ _ (mapIdBisim _ s)
def mapFuseEq : (a : 𝕌) (b : 𝕌) (c : 𝕌) (f : El a → El b) (g : El b → El c)
(s : El (stream a)) →
mapS _ _ g (mapS _ _ f s) ≡ mapS _ _ (λx. g (f x)) s ∈ El (stream c) ≔
λa. λb. λc. λf. λg. λs.
obsEqReflect _ _ _ (mapFuseObsEq _ _ _ f g s)