Codata.streamEq
import Core.prelude (id, ∘)
import Codata.stream (stream, hd, tl, map, iterate)
tlN : {a : 𝕌} → ℕ → stream a → stream a using (Codata.stream.stream.unfold)
tlN = λa n. ℕ-elim (λs. s) (m ih. λs. ih (tl s)) n
nth : {a : 𝕌} → ℕ → stream a → a
nth = λa n s. hd (tlN n s)
obsEq : {a : 𝕌} → stream a → stream a → Ω
obsEq = λa s t. ∥(n : ℕ) → nth n s ≡ nth n t∥
obsEqRefl : {a : 𝕌} (s : stream a) → obsEq s s using (Codata.streamEq.obsEq.unfold)
obsEqRefl = λa s. ⋆ (λn. ⋆)
nthMap : {a b : 𝕌} (f : a → b) (n : ℕ) (s : stream a) → nth n (map f s) ≡ f (nth n s)
using (nth.eq,
Codata.stream.hd.eq,
Codata.stream.map.eq,
Codata.stream.stream.eq,
Codata.stream.stream.unfold,
Codata.stream.tl.eq,
tlN.eq)
nthMap = λa b f n. ℕ-elim (λs. ⋆) (m ih. λs. ih (tl s)) n
mapIdObsEq : {a : 𝕌} (s : stream a) → obsEq (map (id {a}) s) s
using (Codata.streamEq.obsEq.unfold, Core.prelude.id.eq)
mapIdObsEq = λa s. ⋆ (λn. nthMap (id {a}) n s)
mapFuseObsEq : {a b c : 𝕌}
(f : a → b)
(g : b → c)
(s : stream a)
→ obsEq (map g (map f s)) (map (g ∘ f) s)
using (nth.eq,
Codata.stream.hd.eq,
Codata.stream.map.eq,
Core.prelude.∘.eq,
Codata.stream.stream.eq,
Codata.stream.stream.unfold,
Codata.stream.tl.eq,
Codata.streamEq.obsEq.unfold,
tlN.eq)
mapFuseObsEq =
λa b c f g s. ⋆
λn. ℕ-elim
m. (t : stream a) → nth m (map g (map f t)) ≡ nth m (map (g ∘ f) t)
λt. ⋆
m ih. λt. ih (tl t)
n
s
iterShiftObsEq : {a : 𝕌} (f : a → a) (x : a) → obsEq (tl (iterate f x)) (iterate f (f x))
using (hyp.rw,
Codata.stream.iterate.eq,
Codata.stream.stream.eq,
Codata.stream.tl.eq,
Codata.streamEq.obsEq.unfold)
iterShiftObsEq = λa f x. ⋆ (λn. ⋆)