wseq

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.

wseq.of_seq

Turn a sequence into a weak sequence

wseq.of_list

Turn a list into a weak sequence

wseq.of_stream

Turn a stream into a weak sequence

wseq.nil

The empty weak sequence

wseq.cons

Prepend an element to a weak sequence

wseq.think

Compute for one tick, without producing any elements

wseq.destruct

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

wseq.head

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

wseq.flatten

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

wseq.tail

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.

wseq.drop

drop the first n elements from s.

wseq.nth

Get the nth element of s.

wseq.to_list

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

wseq.length

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

wseq.is_finite

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

wseq.get

Get the list corresponding to a finite weak sequence.

wseq.productive

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.

wseq.update_nth

Replace the nth element of s with a.

wseq.remove_nth

Remove the nth element of s.

wseq.filter_map

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

wseq.filter

Select the elements of s that satisfy p.

wseq.find

Get the first element of s satisfying p.

wseq.zip_with

Zip a function over two weak sequences

wseq.zip

Zip two weak sequences into a single sequence of pairs

wseq.find_indexes

Get the list of indexes of elements of s satisfying p

wseq.find_index

Get the index of the first element of s satisfying p

wseq.index_of

Get the index of the first occurrence of a in s

wseq.indexes_of

Get the indexes of occurrences of a in s

wseq.union

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

wseq.is_empty

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

wseq.compute

Calculate one step of computation

wseq.take

Get the first n elements of a weak sequence

wseq.split_at

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

wseq.any

Returns tt if any element of s satisfies p

wseq.all

Returns tt if every element of s satisfies p

wseq.scanl

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.)

wseq.inits

Get the weak sequence of initial segments of the input sequence

wseq.collect

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

wseq.append

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

wseq.map

Map a function over a weak sequence

wseq.join

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

wseq.bind

Monadic bind operator for weak sequences

wseq.lift_rel

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.)

wseq.equiv

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.

wseq.to_seq

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

wseq.ret

The monadic return a is a singleton list containing a.