mathlib3 documentation

data.seq.wseq

def stream.wseq (α : Type u_1) :
Type u_1

Weak sequences.

While the seq structure allows for lists which may not be finite, a weak sequence also allows the computation of each element to involve an indeterminate amount of computation, including possibly an infinite loop. This is represented as a regular seq interspersed with none elements to indicate that computation is ongoing.

This model is appropriate for Haskell style lazy lists, and is closed under most interesting computation patterns on infinite lists, but conversely it is difficult to extract elements from it.

Equations
Instances for stream.wseq

Turn a sequence into a weak sequence

Equations
Instances for stream.wseq.of_seq
def stream.wseq.of_list {α : Type u} (l : list α) :

Turn a list into a weak sequence

Equations
def stream.wseq.of_stream {α : Type u} (l : stream α) :

Turn a stream into a weak sequence

Equations
@[protected, instance]
Equations
@[protected, instance]
def stream.wseq.coe_list {α : Type u} :
Equations
@[protected, instance]
Equations
def stream.wseq.nil {α : Type u} :

The empty weak sequence

Equations
@[protected, instance]
Equations
def stream.wseq.cons {α : Type u} (a : α) :

Prepend an element to a weak sequence

Equations

Compute for one tick, without producing any elements

Equations

Destruct a weak sequence, to (eventually possibly) produce either none for nil or some (a, s) if an element is produced.

Equations
def stream.wseq.rec_on {α : Type u} {C : stream.wseq α Sort v} (s : stream.wseq α) (h1 : C stream.wseq.nil) (h2 : Π (x : α) (s : stream.wseq α), C (stream.wseq.cons x s)) (h3 : Π (s : stream.wseq α), C s.think) :
C s

Recursion principle for weak sequences, compare with list.rec_on.

Equations
@[protected]
def stream.wseq.mem {α : Type u} (a : α) (s : stream.wseq α) :
Prop

membership for weak sequences

Equations
@[protected, instance]
def stream.wseq.has_mem {α : Type u} :
Equations
theorem stream.wseq.not_mem_nil {α : Type u} (a : α) :
def stream.wseq.head {α : Type u} (s : stream.wseq α) :

Get the head of a weak sequence. This involves a possibly infinite computation.

Equations
Instances for stream.wseq.head

Encode a computation yielding a weak sequence into additional think constructors in a weak sequence

Equations
def stream.wseq.tail {α : Type u} (s : stream.wseq α) :

Get the tail of a weak sequence. This doesn't need a computation wrapper, unlike head, because flatten allows us to hide this in the construction of the weak sequence itself.

Equations
Instances for stream.wseq.tail
@[simp]
def stream.wseq.drop {α : Type u} (s : stream.wseq α) :

drop the first n elements from s.

Equations
Instances for stream.wseq.drop
def stream.wseq.nth {α : Type u} (s : stream.wseq α) (n : ) :

Get the nth element of s.

Equations
Instances for stream.wseq.nth
def stream.wseq.to_list {α : Type u} (s : stream.wseq α) :

Convert s to a list (if it is finite and completes in finite time).

Equations
Instances for stream.wseq.to_list

Get the length of s (if it is finite and completes in finite time).

Equations
@[class]
structure stream.wseq.is_finite {α : Type u} (s : stream.wseq α) :
Prop

A weak sequence is finite if to_list s terminates. Equivalently, it is a finite number of think and cons applied to nil.

@[protected, instance]
def stream.wseq.get {α : Type u} (s : stream.wseq α) [s.is_finite] :
list α

Get the list corresponding to a finite weak sequence.

Equations
@[class]
structure stream.wseq.productive {α : Type u} (s : stream.wseq α) :
Prop

A weak sequence is productive if it never stalls forever - there are always a finite number of thinks between cons constructors. The sequence itself is allowed to be infinite though.

Instances of this typeclass
theorem stream.wseq.productive_iff {α : Type u} (s : stream.wseq α) :
@[protected, instance]
def stream.wseq.nth_terminates {α : Type u} (s : stream.wseq α) [h : s.productive] (n : ) :
@[protected, instance]
def stream.wseq.update_nth {α : Type u} (s : stream.wseq α) (n : ) (a : α) :

Replace the nth element of s with a.

Equations
def stream.wseq.remove_nth {α : Type u} (s : stream.wseq α) (n : ) :

Remove the nth element of s.

Equations
def stream.wseq.filter_map {α : Type u} {β : Type v} (f : α option β) :

Map the elements of s over f, removing any values that yield none.

Equations
def stream.wseq.filter {α : Type u} (p : α Prop) [decidable_pred p] :

Select the elements of s that satisfy p.

Equations
def stream.wseq.find {α : Type u} (p : α Prop) [decidable_pred p] (s : stream.wseq α) :

Get the first element of s satisfying p.

Equations
def stream.wseq.zip_with {α : Type u} {β : Type v} {γ : Type w} (f : α β γ) (s1 : stream.wseq α) (s2 : stream.wseq β) :

Zip a function over two weak sequences

Equations
def stream.wseq.zip {α : Type u} {β : Type v} :

Zip two weak sequences into a single sequence of pairs

Equations
def stream.wseq.find_indexes {α : Type u} (p : α Prop) [decidable_pred p] (s : stream.wseq α) :

Get the list of indexes of elements of s satisfying p

Equations
def stream.wseq.find_index {α : Type u} (p : α Prop) [decidable_pred p] (s : stream.wseq α) :

Get the index of the first element of s satisfying p

Equations

Get the index of the first occurrence of a in s

Equations

Get the indexes of occurrences of a in s

Equations
def stream.wseq.union {α : Type u} (s1 s2 : stream.wseq α) :

union s1 s2 is a weak sequence which interleaves s1 and s2 in some order (nondeterministically).

Equations

Returns tt if s is nil and ff if s has an element

Equations
def stream.wseq.compute {α : Type u} (s : stream.wseq α) :

Calculate one step of computation

Equations
def stream.wseq.take {α : Type u} (s : stream.wseq α) (n : ) :

Get the first n elements of a weak sequence

Equations
def stream.wseq.split_at {α : Type u} (s : stream.wseq α) (n : ) :

Split the sequence at position n into a finite initial segment and the weak sequence tail

Equations
def stream.wseq.any {α : Type u} (s : stream.wseq α) (p : α bool) :

Returns tt if any element of s satisfies p

Equations
def stream.wseq.all {α : Type u} (s : stream.wseq α) (p : α bool) :

Returns tt if every element of s satisfies p

Equations
def stream.wseq.scanl {α : Type u} {β : Type v} (f : α β α) (a : α) (s : stream.wseq β) :

Apply a function to the elements of the sequence to produce a sequence of partial results. (There is no scanr because this would require working from the end of the sequence, which may not exist.)

Equations
def stream.wseq.inits {α : Type u} (s : stream.wseq α) :

Get the weak sequence of initial segments of the input sequence

Equations
def stream.wseq.collect {α : Type u} (s : stream.wseq α) (n : ) :
list α

Like take, but does not wait for a result. Calculates n steps of computation and returns the sequence computed so far

Equations

Append two weak sequences. As with seq.append, this may not use the second sequence if the first one takes forever to compute

Equations
def stream.wseq.map {α : Type u} {β : Type v} (f : α β) :

Map a function over a weak sequence

Equations
def stream.wseq.join {α : Type u} (S : stream.wseq (stream.wseq α)) :

Flatten a sequence of weak sequences. (Note that this allows empty sequences, unlike seq.join.)

Equations
def stream.wseq.bind {α : Type u} {β : Type v} (s : stream.wseq α) (f : α stream.wseq β) :

Monadic bind operator for weak sequences

Equations
@[simp]
def stream.wseq.lift_rel_o {α : Type u} {β : Type v} (R : α β Prop) (C : stream.wseq α stream.wseq β Prop) :

lift a relation to a relation over weak sequences

Equations
theorem stream.wseq.lift_rel_o.imp {α : Type u} {β : Type v} {R S : α β Prop} {C D : stream.wseq α stream.wseq β Prop} (H1 : (a : α) (b : β), R a b S a b) (H2 : (s : stream.wseq α) (t : stream.wseq β), C s t D s t) {o : option × stream.wseq α)} {p : option × stream.wseq β)} :
theorem stream.wseq.lift_rel_o.imp_right {α : Type u} {β : Type v} (R : α β Prop) {C D : stream.wseq α stream.wseq β Prop} (H : (s : stream.wseq α) (t : stream.wseq β), C s t D s t) {o : option × stream.wseq α)} {p : option × stream.wseq β)} :
@[simp]
def stream.wseq.bisim_o {α : Type u} (R : stream.wseq α stream.wseq α Prop) :

Definitino of bisimilarity for weak sequences

Equations
theorem stream.wseq.bisim_o.imp {α : Type u} {R S : stream.wseq α stream.wseq α Prop} (H : (s t : stream.wseq α), R s t S s t) {o p : option × stream.wseq α)} :
def stream.wseq.lift_rel {α : Type u} {β : Type v} (R : α β Prop) (s : stream.wseq α) (t : stream.wseq β) :
Prop

Two weak sequences are lift_rel R related if they are either both empty, or they are both nonempty and the heads are R related and the tails are lift_rel R related. (This is a coinductive definition.)

Equations
def stream.wseq.equiv {α : Type u} :

If two sequences are equivalent, then they have the same values and the same computational behavior (i.e. if one loops forever then so does the other), although they may differ in the number of thinks needed to arrive at the answer.

Equations
theorem stream.wseq.lift_rel.refl {α : Type u} (R : α α Prop) (H : reflexive R) :
theorem stream.wseq.lift_rel.swap_lem {α : Type u} {β : Type v} {R : α β Prop} {s1 : stream.wseq α} {s2 : stream.wseq β} (h : stream.wseq.lift_rel R s1 s2) :
theorem stream.wseq.lift_rel.symm {α : Type u} (R : α α Prop) (H : symmetric R) :
theorem stream.wseq.lift_rel.trans {α : Type u} (R : α α Prop) (H : transitive R) :
@[refl]
theorem stream.wseq.equiv.refl {α : Type u} (s : stream.wseq α) :
s ~ s
@[symm]
theorem stream.wseq.equiv.symm {α : Type u} {s t : stream.wseq α} :
s ~ t t ~ s
@[trans]
theorem stream.wseq.equiv.trans {α : Type u} {s t u : stream.wseq α} :
s ~ t t ~ u s ~ u
@[simp]
@[simp]
@[simp]
@[simp]
theorem stream.wseq.head_think {α : Type u} (s : stream.wseq α) :
@[simp]
theorem stream.wseq.tail_cons {α : Type u} (a : α) (s : stream.wseq α) :
@[simp]
theorem stream.wseq.tail_think {α : Type u} (s : stream.wseq α) :
@[simp]
theorem stream.wseq.dropn_cons {α : Type u} (a : α) (s : stream.wseq α) (n : ) :
(stream.wseq.cons a s).drop (n + 1) = s.drop n
@[simp]
theorem stream.wseq.dropn_think {α : Type u} (s : stream.wseq α) (n : ) :
s.think.drop n = (s.drop n).think
theorem stream.wseq.dropn_add {α : Type u} (s : stream.wseq α) (m n : ) :
s.drop (m + n) = (s.drop m).drop n
theorem stream.wseq.dropn_tail {α : Type u} (s : stream.wseq α) (n : ) :
s.tail.drop n = s.drop (n + 1)
theorem stream.wseq.nth_add {α : Type u} (s : stream.wseq α) (m n : ) :
s.nth (m + n) = (s.drop m).nth n
theorem stream.wseq.nth_tail {α : Type u} (s : stream.wseq α) (n : ) :
s.tail.nth n = s.nth (n + 1)
@[simp]
theorem stream.wseq.join_think {α : Type u} (S : stream.wseq (stream.wseq α)) :
@[simp]
theorem stream.wseq.join_cons {α : Type u} (s : stream.wseq α) (S : stream.wseq (stream.wseq α)) :
@[simp]
theorem stream.wseq.nil_append {α : Type u} (s : stream.wseq α) :
@[simp]
theorem stream.wseq.cons_append {α : Type u} (a : α) (s t : stream.wseq α) :
@[simp]
theorem stream.wseq.think_append {α : Type u} (s t : stream.wseq α) :
@[simp]
theorem stream.wseq.append_nil {α : Type u} (s : stream.wseq α) :
@[simp]
theorem stream.wseq.append_assoc {α : Type u} (s t u : stream.wseq α) :
(s.append t).append u = s.append (t.append u)
@[simp]

auxilary defintion of tail over weak sequences

Equations
@[simp]

auxilary defintion of drop over weak sequences

Equations
theorem stream.wseq.head_some_of_head_tail_some {α : Type u} {s : stream.wseq α} {a : α} (h : option.some a s.tail.head) :
(a' : α), option.some a' s.head
theorem stream.wseq.head_some_of_nth_some {α : Type u} {s : stream.wseq α} {a : α} {n : } (h : option.some a s.nth n) :
(a' : α), option.some a' s.head
@[protected, instance]
@[protected, instance]
def stream.wseq.productive_dropn {α : Type u} (s : stream.wseq α) [s.productive] (n : ) :
def stream.wseq.to_seq {α : Type u} (s : stream.wseq α) [s.productive] :

Given a productive weak sequence, we can collapse all the thinks to produce a sequence.

Equations
theorem stream.wseq.nth_terminates_le {α : Type u} {s : stream.wseq α} {m n : } (h : m n) :
theorem stream.wseq.mem_rec_on {α : Type u} {C : stream.wseq α Prop} {a : α} {s : stream.wseq α} (M : a s) (h1 : (b : α) (s' : stream.wseq α), a = b C s' C (stream.wseq.cons b s')) (h2 : (s : stream.wseq α), C s C s.think) :
C s
@[simp]
theorem stream.wseq.mem_think {α : Type u} (s : stream.wseq α) (a : α) :
a s.think a s
theorem stream.wseq.eq_or_mem_iff_mem {α : Type u} {s : stream.wseq α} {a a' : α} {s' : stream.wseq α} :
option.some (a', s') s.destruct (a s a = a' a s')
@[simp]
theorem stream.wseq.mem_cons_iff {α : Type u} (s : stream.wseq α) (b : α) {a : α} :
theorem stream.wseq.mem_cons_of_mem {α : Type u} {s : stream.wseq α} (b : α) {a : α} (h : a s) :
theorem stream.wseq.mem_cons {α : Type u} (s : stream.wseq α) (a : α) :
theorem stream.wseq.mem_of_mem_tail {α : Type u} {s : stream.wseq α} {a : α} :
a s.tail a s
theorem stream.wseq.mem_of_mem_dropn {α : Type u} {s : stream.wseq α} {a : α} {n : } :
a s.drop n a s
theorem stream.wseq.nth_mem {α : Type u} {s : stream.wseq α} {a : α} {n : } :
theorem stream.wseq.exists_nth_of_mem {α : Type u} {s : stream.wseq α} {a : α} (h : a s) :
(n : ), option.some a s.nth n
theorem stream.wseq.exists_dropn_of_mem {α : Type u} {s : stream.wseq α} {a : α} (h : a s) :
(n : ) (s' : stream.wseq α), option.some (a, s') (s.drop n).destruct
theorem stream.wseq.exists_of_lift_rel_left {α : Type u} {β : Type v} {R : α β Prop} {s : stream.wseq α} {t : stream.wseq β} (H : stream.wseq.lift_rel R s t) {a : α} (h : a s) :
{b : β}, b t R a b
theorem stream.wseq.exists_of_lift_rel_right {α : Type u} {β : Type v} {R : α β Prop} {s : stream.wseq α} {t : stream.wseq β} (H : stream.wseq.lift_rel R s t) {b : β} (h : b t) :
{a : α}, a s R a b
theorem stream.wseq.head_terminates_of_mem {α : Type u} {s : stream.wseq α} {a : α} (h : a s) :
theorem stream.wseq.of_mem_append {α : Type u} {s₁ s₂ : stream.wseq α} {a : α} :
a s₁.append s₂ a s₁ a s₂
theorem stream.wseq.mem_append_left {α : Type u} {s₁ s₂ : stream.wseq α} {a : α} :
a s₁ a s₁.append s₂
theorem stream.wseq.exists_of_mem_map {α : Type u} {β : Type v} {f : α β} {b : β} {s : stream.wseq α} :
b stream.wseq.map f s ( (a : α), a s f a = b)
@[simp]
@[simp]
theorem stream.wseq.lift_rel_cons {α : Type u} {β : Type v} (R : α β Prop) (a : α) (b : β) (s : stream.wseq α) (t : stream.wseq β) :
@[simp]
theorem stream.wseq.lift_rel_think_left {α : Type u} {β : Type v} (R : α β Prop) (s : stream.wseq α) (t : stream.wseq β) :
@[simp]
theorem stream.wseq.lift_rel_think_right {α : Type u} {β : Type v} (R : α β Prop) (s : stream.wseq α) (t : stream.wseq β) :
theorem stream.wseq.cons_congr {α : Type u} {s t : stream.wseq α} (a : α) (h : s ~ t) :
theorem stream.wseq.think_equiv {α : Type u} (s : stream.wseq α) :
s.think ~ s
theorem stream.wseq.think_congr {α : Type u} {s t : stream.wseq α} (h : s ~ t) :
theorem stream.wseq.head_congr {α : Type u} {s t : stream.wseq α} :
s ~ t s.head ~ t.head
theorem stream.wseq.flatten_equiv {α : Type u} {c : computation (stream.wseq α)} {s : stream.wseq α} (h : s c) :
theorem stream.wseq.tail_congr {α : Type u} {s t : stream.wseq α} (h : s ~ t) :
s.tail ~ t.tail
theorem stream.wseq.dropn_congr {α : Type u} {s t : stream.wseq α} (h : s ~ t) (n : ) :
s.drop n ~ t.drop n
theorem stream.wseq.nth_congr {α : Type u} {s t : stream.wseq α} (h : s ~ t) (n : ) :
s.nth n ~ t.nth n
theorem stream.wseq.mem_congr {α : Type u} {s t : stream.wseq α} (h : s ~ t) (a : α) :
a s a t
theorem stream.wseq.productive_congr {α : Type u} {s t : stream.wseq α} (h : s ~ t) :
theorem stream.wseq.equiv.ext {α : Type u} {s t : stream.wseq α} (h : (n : ), s.nth n ~ t.nth n) :
s ~ t
@[simp]
@[simp]
theorem stream.wseq.to_list'_nil {α : Type u} (l : list α) :
computation.corec stream.wseq.to_list._match_2 (l, stream.wseq.nil α) = computation.return l.reverse
@[simp]
theorem stream.wseq.to_list'_cons {α : Type u} (l : list α) (s : stream.wseq α) (a : α) :
computation.corec stream.wseq.to_list._match_2 (l, stream.wseq.cons a s) = (computation.corec stream.wseq.to_list._match_2 (a :: l, s)).think
@[simp]
theorem stream.wseq.to_list'_think {α : Type u} (l : list α) (s : stream.wseq α) :
computation.corec stream.wseq.to_list._match_2 (l, s.think) = (computation.corec stream.wseq.to_list._match_2 (l, s)).think
theorem stream.wseq.to_list'_map {α : Type u} (l : list α) (s : stream.wseq α) :
computation.corec stream.wseq.to_list._match_2 (l, s) = has_append.append l.reverse <$> s.to_list
@[simp]
theorem stream.wseq.to_list_cons {α : Type u} (a : α) (s : stream.wseq α) :
@[simp]
@[protected, instance]
def stream.wseq.ret {α : Type u} (a : α) :

The monadic return a is a singleton list containing a.

Equations
@[simp]
theorem stream.wseq.map_nil {α : Type u} {β : Type v} (f : α β) :
@[simp]
theorem stream.wseq.map_cons {α : Type u} {β : Type v} (f : α β) (a : α) (s : stream.wseq α) :
@[simp]
theorem stream.wseq.map_think {α : Type u} {β : Type v} (f : α β) (s : stream.wseq α) :
@[simp]
theorem stream.wseq.map_id {α : Type u} (s : stream.wseq α) :
@[simp]
theorem stream.wseq.map_ret {α : Type u} {β : Type v} (f : α β) (a : α) :
@[simp]
theorem stream.wseq.map_append {α : Type u} {β : Type v} (f : α β) (s t : stream.wseq α) :
theorem stream.wseq.map_comp {α : Type u} {β : Type v} {γ : Type w} (f : α β) (g : β γ) (s : stream.wseq α) :
theorem stream.wseq.mem_map {α : Type u} {β : Type v} (f : α β) {a : α} {s : stream.wseq α} :
theorem stream.wseq.exists_of_mem_join {α : Type u} {a : α} {S : stream.wseq (stream.wseq α)} :
a S.join ( (s : stream.wseq α), s S a s)
theorem stream.wseq.exists_of_mem_bind {α : Type u} {β : Type v} {s : stream.wseq α} {f : α stream.wseq β} {b : β} (h : b s.bind f) :
(a : α) (H : a s), b f a
theorem stream.wseq.lift_rel_map {α : Type u} {β : Type v} {γ : Type w} {δ : Type u_1} (R : α β Prop) (S : γ δ Prop) {s1 : stream.wseq α} {s2 : stream.wseq β} {f1 : α γ} {f2 : β δ} (h1 : stream.wseq.lift_rel R s1 s2) (h2 : {a : α} {b : β}, R a b S (f1 a) (f2 b)) :
theorem stream.wseq.map_congr {α : Type u} {β : Type v} (f : α β) {s t : stream.wseq α} (h : s ~ t) :
@[simp]

auxilary defintion of destruct_append over weak sequences

Equations
theorem stream.wseq.lift_rel_append {α : Type u} {β : Type v} (R : α β Prop) {s1 s2 : stream.wseq α} {t1 t2 : stream.wseq β} (h1 : stream.wseq.lift_rel R s1 t1) (h2 : stream.wseq.lift_rel R s2 t2) :
theorem stream.wseq.lift_rel_join.lem {α : Type u} {β : Type v} (R : α β Prop) {S : stream.wseq (stream.wseq α)} {T : stream.wseq (stream.wseq β)} {U : stream.wseq α stream.wseq β Prop} (ST : stream.wseq.lift_rel (stream.wseq.lift_rel R) S T) (HU : (s1 : stream.wseq α) (s2 : stream.wseq β), ( (s : stream.wseq α) (t : stream.wseq β) (S : stream.wseq (stream.wseq α)) (T : stream.wseq (stream.wseq β)), s1 = s.append S.join s2 = t.append T.join stream.wseq.lift_rel R s t stream.wseq.lift_rel (stream.wseq.lift_rel R) S T) U s1 s2) {a : option × stream.wseq α)} (ma : a S.join.destruct) :
theorem stream.wseq.lift_rel_bind {α : Type u} {β : Type v} {γ : Type w} {δ : Type u_1} (R : α β Prop) (S : γ δ Prop) {s1 : stream.wseq α} {s2 : stream.wseq β} {f1 : α stream.wseq γ} {f2 : β stream.wseq δ} (h1 : stream.wseq.lift_rel R s1 s2) (h2 : {a : α} {b : β}, R a b stream.wseq.lift_rel S (f1 a) (f2 b)) :
stream.wseq.lift_rel S (s1.bind f1) (s2.bind f2)
theorem stream.wseq.bind_congr {α : Type u} {β : Type v} {s1 s2 : stream.wseq α} {f1 f2 : α stream.wseq β} (h1 : s1 ~ s2) (h2 : (a : α), f1 a ~ f2 a) :
s1.bind f1 ~ s2.bind f2
@[simp]
theorem stream.wseq.join_ret {α : Type u} (s : stream.wseq α) :
@[simp]
theorem stream.wseq.join_append {α : Type u} (S T : stream.wseq (stream.wseq α)) :
@[simp]
theorem stream.wseq.bind_ret {α : Type u} {β : Type v} (f : α β) (s : stream.wseq α) :
@[simp]
theorem stream.wseq.ret_bind {α : Type u} {β : Type v} (a : α) (f : α stream.wseq β) :
@[simp]
theorem stream.wseq.map_join {α : Type u} {β : Type v} (f : α β) (S : stream.wseq (stream.wseq α)) :
@[simp]
theorem stream.wseq.bind_assoc {α : Type u} {β : Type v} {γ : Type w} (s : stream.wseq α) (f : α stream.wseq β) (g : β stream.wseq γ) :
(s.bind f).bind g ~ s.bind (λ (x : α), (f x).bind g)
@[protected, instance]
Equations