Streams a.k.a. infinite lists a.k.a. infinite sequences #
Porting note:
This file used to be in the core library. It was moved to mathlib
and renamed to init
to avoid
name clashes.
Equations
- Stream'.instInhabited = { default := Stream'.const default }
@[simp]
@[simp]
@[simp]
@[simp]
theorem
Stream'.get_drop
{α : Type u}
(n m : ℕ)
(s : Stream' α)
:
(Stream'.drop m s).get n = s.get (n + m)
@[simp]
theorem
Stream'.drop_drop
{α : Type u}
(n m : ℕ)
(s : Stream' α)
:
Stream'.drop n (Stream'.drop m s) = Stream'.drop (n + m) s
@[simp]
theorem
Stream'.tail_drop'
{α : Type u}
{i : ℕ}
{s : Stream' α}
:
(Stream'.drop i s).tail = Stream'.drop (i + 1) s
@[simp]
theorem
Stream'.drop_tail'
{α : Type u}
{i : ℕ}
{s : Stream' α}
:
Stream'.drop i s.tail = Stream'.drop (i + 1) s
theorem
Stream'.tail_drop
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
(Stream'.drop n s).tail = Stream'.drop n s.tail
@[simp]
theorem
Stream'.get_succ_cons
{α : Type u}
(n : ℕ)
(s : Stream' α)
(x : α)
:
(Stream'.cons x s).get n.succ = s.get n
theorem
Stream'.drop_succ
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
Stream'.drop n.succ s = Stream'.drop n s.tail
theorem
Stream'.cons_injective_left
{α : Type u}
(s : Stream' α)
:
Function.Injective fun (x : α) => Stream'.cons x s
theorem
Stream'.all_def
{α : Type u}
(p : α → Prop)
(s : Stream' α)
:
Stream'.All p s = ∀ (n : ℕ), p (s.get n)
theorem
Stream'.any_def
{α : Type u}
(p : α → Prop)
(s : Stream' α)
:
Stream'.Any p s = ∃ (n : ℕ), p (s.get n)
theorem
Stream'.mem_cons_of_mem
{α : Type u}
{a : α}
{s : Stream' α}
(b : α)
:
a ∈ s → a ∈ Stream'.cons b s
theorem
Stream'.eq_or_mem_of_mem_cons
{α : Type u}
{a b : α}
{s : Stream' α}
:
a ∈ Stream'.cons b s → a = b ∨ a ∈ s
theorem
Stream'.drop_map
{α : Type u}
{β : Type v}
(f : α → β)
(n : ℕ)
(s : Stream' α)
:
Stream'.drop n (Stream'.map f s) = Stream'.map f (Stream'.drop n s)
@[simp]
theorem
Stream'.get_map
{α : Type u}
{β : Type v}
(f : α → β)
(n : ℕ)
(s : Stream' α)
:
(Stream'.map f s).get n = f (s.get n)
theorem
Stream'.tail_map
{α : Type u}
{β : Type v}
(f : α → β)
(s : Stream' α)
:
(Stream'.map f s).tail = Stream'.map f s.tail
@[simp]
theorem
Stream'.head_map
{α : Type u}
{β : Type v}
(f : α → β)
(s : Stream' α)
:
(Stream'.map f s).head = f s.head
theorem
Stream'.map_eq
{α : Type u}
{β : Type v}
(f : α → β)
(s : Stream' α)
:
Stream'.map f s = Stream'.cons (f s.head) (Stream'.map f s.tail)
theorem
Stream'.map_cons
{α : Type u}
{β : Type v}
(f : α → β)
(a : α)
(s : Stream' α)
:
Stream'.map f (Stream'.cons a s) = Stream'.cons (f a) (Stream'.map f s)
@[simp]
theorem
Stream'.map_map
{α : Type u}
{β : Type v}
{δ : Type w}
(g : β → δ)
(f : α → β)
(s : Stream' α)
:
Stream'.map g (Stream'.map f s) = Stream'.map (g ∘ f) s
@[simp]
theorem
Stream'.map_tail
{α : Type u}
{β : Type v}
(f : α → β)
(s : Stream' α)
:
Stream'.map f s.tail = (Stream'.map f s).tail
theorem
Stream'.mem_map
{α : Type u}
{β : Type v}
(f : α → β)
{a : α}
{s : Stream' α}
:
a ∈ s → f a ∈ Stream'.map f s
theorem
Stream'.exists_of_mem_map
{α : Type u}
{β : Type v}
{f : α → β}
{b : β}
{s : Stream' α}
:
b ∈ Stream'.map f s → ∃ (a : α), a ∈ s ∧ f a = b
theorem
Stream'.drop_zip
{α : Type u}
{β : Type v}
{δ : Type w}
(f : α → β → δ)
(n : ℕ)
(s₁ : Stream' α)
(s₂ : Stream' β)
:
Stream'.drop n (Stream'.zip f s₁ s₂) = Stream'.zip f (Stream'.drop n s₁) (Stream'.drop n s₂)
@[simp]
theorem
Stream'.get_zip
{α : Type u}
{β : Type v}
{δ : Type w}
(f : α → β → δ)
(n : ℕ)
(s₁ : Stream' α)
(s₂ : Stream' β)
:
(Stream'.zip f s₁ s₂).get n = f (s₁.get n) (s₂.get n)
theorem
Stream'.head_zip
{α : Type u}
{β : Type v}
{δ : Type w}
(f : α → β → δ)
(s₁ : Stream' α)
(s₂ : Stream' β)
:
(Stream'.zip f s₁ s₂).head = f s₁.head s₂.head
theorem
Stream'.tail_zip
{α : Type u}
{β : Type v}
{δ : Type w}
(f : α → β → δ)
(s₁ : Stream' α)
(s₂ : Stream' β)
:
(Stream'.zip f s₁ s₂).tail = Stream'.zip f s₁.tail s₂.tail
theorem
Stream'.zip_eq
{α : Type u}
{β : Type v}
{δ : Type w}
(f : α → β → δ)
(s₁ : Stream' α)
(s₂ : Stream' β)
:
Stream'.zip f s₁ s₂ = Stream'.cons (f s₁.head s₂.head) (Stream'.zip f s₁.tail s₂.tail)
theorem
Stream'.enum_eq_zip
{α : Type u}
(s : Stream' α)
:
s.enum = Stream'.zip Prod.mk Stream'.nats s
@[simp]
@[simp]
theorem
Stream'.map_const
{α : Type u}
{β : Type v}
(f : α → β)
(a : α)
:
Stream'.map f (Stream'.const a) = Stream'.const (f a)
@[simp]
theorem
Stream'.drop_const
{α : Type u}
(n : ℕ)
(a : α)
:
Stream'.drop n (Stream'.const a) = Stream'.const a
@[simp]
theorem
Stream'.get_succ_iterate'
{α : Type u}
(n : ℕ)
(f : α → α)
(a : α)
:
(Stream'.iterate f a).get n.succ = f ((Stream'.iterate f a).get n)
theorem
Stream'.tail_iterate
{α : Type u}
(f : α → α)
(a : α)
:
(Stream'.iterate f a).tail = Stream'.iterate f (f a)
theorem
Stream'.iterate_eq
{α : Type u}
(f : α → α)
(a : α)
:
Stream'.iterate f a = Stream'.cons a (Stream'.iterate f (f a))
@[simp]
theorem
Stream'.get_succ_iterate
{α : Type u}
(n : ℕ)
(f : α → α)
(a : α)
:
(Stream'.iterate f a).get n.succ = (Stream'.iterate f (f a)).get n
Streams s₁
and s₂
are defined to be bisimulations if
their heads are equal and tails are bisimulations.
Equations
- Stream'.IsBisimulation R = ∀ ⦃s₁ s₂ : Stream' α⦄, R s₁ s₂ → s₁.head = s₂.head ∧ R s₁.tail s₂.tail
Instances For
theorem
Stream'.get_of_bisim
{α : Type u}
(R : Stream' α → Stream' α → Prop)
(bisim : Stream'.IsBisimulation R)
{s₁ s₂ : Stream' α}
(n : ℕ)
:
R s₁ s₂ → s₁.get n = s₂.get n ∧ R (Stream'.drop (n + 1) s₁) (Stream'.drop (n + 1) s₂)
theorem
Stream'.eq_of_bisim
{α : Type u}
(R : Stream' α → Stream' α → Prop)
(bisim : Stream'.IsBisimulation R)
{s₁ s₂ : Stream' α}
:
R s₁ s₂ → s₁ = s₂
@[simp]
theorem
Stream'.map_iterate
{α : Type u}
(f : α → α)
(a : α)
:
Stream'.iterate f (f a) = Stream'.map f (Stream'.iterate f a)
theorem
Stream'.corec_def
{α : Type u}
{β : Type v}
(f : α → β)
(g : α → α)
(a : α)
:
Stream'.corec f g a = Stream'.map f (Stream'.iterate g a)
theorem
Stream'.corec_eq
{α : Type u}
{β : Type v}
(f : α → β)
(g : α → α)
(a : α)
:
Stream'.corec f g a = Stream'.cons (f a) (Stream'.corec f g (g a))
theorem
Stream'.corec_id_f_eq_iterate
{α : Type u}
(f : α → α)
(a : α)
:
Stream'.corec id f a = Stream'.iterate f a
theorem
Stream'.corec'_eq
{α : Type u}
{β : Type v}
(f : α → β × α)
(a : α)
:
Stream'.corec' f a = Stream'.cons (f a).1 (Stream'.corec' f (f a).2)
theorem
Stream'.unfolds_eq
{α : Type u}
{β : Type v}
(g : α → β)
(f : α → α)
(a : α)
:
Stream'.unfolds g f a = Stream'.cons (g a) (Stream'.unfolds g f (f a))
theorem
Stream'.get_unfolds_head_tail
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
(Stream'.unfolds Stream'.head Stream'.tail s).get n = s.get n
theorem
Stream'.unfolds_head_eq
{α : Type u}
(s : Stream' α)
:
Stream'.unfolds Stream'.head Stream'.tail s = s
theorem
Stream'.interleave_eq
{α : Type u}
(s₁ s₂ : Stream' α)
:
s₁ ⋈ s₂ = Stream'.cons s₁.head (Stream'.cons s₂.head (s₁.tail ⋈ s₂.tail))
theorem
Stream'.even_cons_cons
{α : Type u}
(a₁ a₂ : α)
(s : Stream' α)
:
(Stream'.cons a₁ (Stream'.cons a₂ s)).even = Stream'.cons a₁ s.even
theorem
Stream'.cons_append_stream
{α : Type u}
(a : α)
(l : List α)
(s : Stream' α)
:
a :: l ++ₛ s = Stream'.cons a (l ++ₛ s)
theorem
Stream'.map_append_stream
{α : Type u}
{β : Type v}
(f : α → β)
(l : List α)
(s : Stream' α)
:
Stream'.map f (l ++ₛ s) = List.map f l ++ₛ Stream'.map f s
theorem
Stream'.drop_append_stream
{α : Type u}
(l : List α)
(s : Stream' α)
:
Stream'.drop l.length (l ++ₛ s) = s
theorem
Stream'.take_succ
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
Stream'.take n.succ s = s.head :: Stream'.take n s.tail
@[simp]
theorem
Stream'.take_succ_cons
{α : Type u}
{a : α}
(n : ℕ)
(s : Stream' α)
:
Stream'.take (n + 1) (Stream'.cons a s) = a :: Stream'.take n s
theorem
Stream'.take_succ'
{α : Type u}
{s : Stream' α}
(n : ℕ)
:
Stream'.take (n + 1) s = Stream'.take n s ++ [s.get n]
@[simp]
@[simp]
theorem
Stream'.take_take
{α : Type u}
{s : Stream' α}
{m n : ℕ}
:
List.take m (Stream'.take n s) = Stream'.take (n ⊓ m) s
@[simp]
theorem
Stream'.concat_take_get
{α : Type u}
{n : ℕ}
{s : Stream' α}
:
Stream'.take n s ++ [s.get n] = Stream'.take (n + 1) s
theorem
Stream'.get?_take
{α : Type u}
{s : Stream' α}
{k n : ℕ}
:
k < n → (Stream'.take n s).get? k = some (s.get k)
theorem
Stream'.get?_take_succ
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
(Stream'.take n.succ s).get? n = some (s.get n)
@[simp]
theorem
Stream'.dropLast_take
{α : Type u}
{n : ℕ}
{xs : Stream' α}
:
(Stream'.take n xs).dropLast = Stream'.take (n - 1) xs
@[simp]
theorem
Stream'.append_take_drop
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
Stream'.take n s ++ₛ Stream'.drop n s = s
theorem
Stream'.take_theorem
{α : Type u}
(s₁ s₂ : Stream' α)
:
(∀ (n : ℕ), Stream'.take n s₁ = Stream'.take n s₂) → s₁ = s₂
theorem
Stream'.cycle_g_cons
{α : Type u}
(a a₁ : α)
(l₁ : List α)
(a₀ : α)
(l₀ : List α)
:
Stream'.cycleG (a, a₁ :: l₁, a₀, l₀) = (a₁, l₁, a₀, l₀)
theorem
Stream'.cycle_eq
{α : Type u}
(l : List α)
(h : l ≠ [])
:
Stream'.cycle l h = l ++ₛ Stream'.cycle l h
theorem
Stream'.mem_cycle
{α : Type u}
{a : α}
{l : List α}
(h : l ≠ [])
:
a ∈ l → a ∈ Stream'.cycle l h
@[simp]
@[simp]
theorem
Stream'.get_tails
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
s.tails.get n = Stream'.drop n s.tail
theorem
Stream'.tails_eq_iterate
{α : Type u}
(s : Stream' α)
:
s.tails = Stream'.iterate Stream'.tail s.tail
theorem
Stream'.inits_core_eq
{α : Type u}
(l : List α)
(s : Stream' α)
:
Stream'.initsCore l s = Stream'.cons l (Stream'.initsCore (l ++ [s.head]) s.tail)
theorem
Stream'.tail_inits
{α : Type u}
(s : Stream' α)
:
s.inits.tail = Stream'.initsCore [s.head, s.tail.head] s.tail.tail
theorem
Stream'.inits_tail
{α : Type u}
(s : Stream' α)
:
s.tail.inits = Stream'.initsCore [s.tail.head] s.tail.tail
theorem
Stream'.cons_get_inits_core
{α : Type u}
(a : α)
(n : ℕ)
(l : List α)
(s : Stream' α)
:
a :: (Stream'.initsCore l s).get n = (Stream'.initsCore (a :: l) s).get n
@[simp]
theorem
Stream'.get_inits
{α : Type u}
(n : ℕ)
(s : Stream' α)
:
s.inits.get n = Stream'.take n.succ s
theorem
Stream'.inits_eq
{α : Type u}
(s : Stream' α)
:
s.inits = Stream'.cons [s.head] (Stream'.map (List.cons s.head) s.tail.inits)
theorem
Stream'.zip_inits_tails
{α : Type u}
(s : Stream' α)
:
Stream'.zip Stream'.appendStream' s.inits s.tails = Stream'.const s
theorem
Stream'.homomorphism
{α : Type u}
{β : Type v}
(f : α → β)
(a : α)
:
Stream'.pure f ⊛ Stream'.pure a = Stream'.pure (f a)
theorem
Stream'.interchange
{α : Type u}
{β : Type v}
(fs : Stream' (α → β))
(a : α)
:
fs ⊛ Stream'.pure a = (Stream'.pure fun (f : α → β) => f a) ⊛ fs
theorem
Stream'.map_eq_apply
{α : Type u}
{β : Type v}
(f : α → β)
(s : Stream' α)
:
Stream'.map f s = Stream'.pure f ⊛ s