Possibly infinite lists #
This file provides a Seq α
type representing possibly infinite lists (referred here as sequences).
It is encoded as an infinite stream of options such that if f n = none
, then
f m = none
for all m ≥ n
.
Seq α
is the type of possibly infinite lists (referred here as sequences).
It is encoded as an infinite stream of options such that if f n = none
, then
f m = none
for all m ≥ n
.
Equations
- Stream'.Seq α = { f : Stream' (Option α) // Stream'.IsSeq f }
Instances For
The empty sequence
Equations
- Stream'.Seq.nil = { val := Stream'.const none, property := (_ : ∀ {x : ℕ}, Stream'.const none x = none → Stream'.const none (x + 1) = Stream'.const none (x + 1)) }
Instances For
Equations
- Stream'.Seq.instInhabitedSeq = { default := Stream'.Seq.nil }
Prepend an element to a sequence
Equations
- Stream'.Seq.cons a s = { val := Stream'.cons (some a) ↑s, property := (_ : ∀ {n : ℕ}, Stream'.cons (some a) (↑s) n = none → Stream'.cons (some a) (↑s) (n + 1) = none) }
Instances For
Get the nth element of a sequence (if it exists)
Equations
- Stream'.Seq.get? = Subtype.val
Instances For
A sequence has terminated at position n
if the value at position n
equals none
.
Equations
- Stream'.Seq.TerminatedAt s n = (Stream'.Seq.get? s n = none)
Instances For
It is decidable whether a sequence terminates at a given position.
Equations
- Stream'.Seq.terminatedAtDecidable s n = decidable_of_iff' (Option.isNone (Stream'.Seq.get? s n) = true) (_ : Stream'.Seq.TerminatedAt s n ↔ Option.isNone (Stream'.Seq.get? s n) = true)
A sequence terminates if there is some position n
at which it has terminated.
Equations
- Stream'.Seq.Terminates s = ∃ (n : ℕ), Stream'.Seq.TerminatedAt s n
Instances For
Get the first element of a sequence
Equations
Instances For
Get the tail of a sequence (or nil
if the sequence is nil
)
Equations
- Stream'.Seq.tail s = { val := Stream'.tail ↑s, property := (_ : ∀ {n : ℕ}, Stream'.tail (↑s) n = none → Stream'.tail (↑s) (n + 1) = none) }
Instances For
Equations
- Stream'.Seq.instMembershipSeq = { mem := Stream'.Seq.Mem }
If a sequence terminated at position n
, it also terminated at m ≥ n
.
If s.get? n = some aₙ
for some value aₙ
, then there is also some value aₘ
such
that s.get? = some aₘ
for m ≤ n
.
Destructor for a sequence, resulting in either none
(for nil
) or
some (a, s)
(for cons a s
).
Equations
- Stream'.Seq.destruct s = (fun (a' : α) => (a', Stream'.Seq.tail s)) <$> Stream'.Seq.get? s 0
Instances For
Recursion principle for sequences, compare with List.recOn
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Bisimilarity relation over Option
of Seq1 α
Equations
Instances For
a relation is bisimilar if it meets the BisimO
test
Equations
- Stream'.Seq.IsBisimulation R = ∀ ⦃s₁ s₂ : Stream'.Seq α⦄, R s₁ s₂ → Stream'.Seq.BisimO R (Stream'.Seq.destruct s₁) (Stream'.Seq.destruct s₂)
Instances For
Equations
- Stream'.Seq.coeList = { coe := Stream'.Seq.ofList }
Embed an infinite stream as a sequence
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Stream'.Seq.coeStream = { coe := Stream'.Seq.ofStream }
Embed a LazyList α
as a sequence. Note that even though this
is non-meta, it will produce infinite sequences if used with
cyclic LazyList
s created by meta constructions.
Equations
- Stream'.Seq.ofLazyList = Stream'.Seq.corec fun (l : LazyList α) => match l with | LazyList.nil => none | LazyList.cons a l' => some (a, Thunk.get l')
Instances For
Equations
- Stream'.Seq.coeLazyList = { coe := Stream'.Seq.ofLazyList }
Translate a sequence to a list. This function will run forever if run on an infinite sequence.
Equations
Instances For
The sequence of natural numbers some 0, some 1, ...
Equations
Instances For
Append two sequences. If s₁
is infinite, then s₁ ++ s₂ = s₁
,
otherwise it puts s₂
at the location of the nil
in s₁
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Map a function over a sequence.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Flatten a sequence of sequences. (It is required that the
sequences be nonempty to ensure productivity; in the case
of an infinite sequence of nil
, the first element is never
generated.)
Equations
- One or more equations did not get rendered due to their size.
Instances For
Remove the first n
elements from the sequence.
Equations
- Stream'.Seq.drop s 0 = s
- Stream'.Seq.drop s (Nat.succ n) = Stream'.Seq.tail (Stream'.Seq.drop s n)
Instances For
Take the first n
elements of the sequence (producing a list)
Equations
- Stream'.Seq.take 0 x = []
- Stream'.Seq.take (Nat.succ n) x = match Stream'.Seq.destruct x with | none => [] | some (x, r) => x :: Stream'.Seq.take n r
Instances For
Split a sequence at n
, producing a finite initial segment
and an infinite tail.
Equations
- One or more equations did not get rendered due to their size.
- Stream'.Seq.splitAt 0 x = ([], x)
Instances For
Combine two sequences with a function
Equations
- One or more equations did not get rendered due to their size.
Instances For
Pair two sequences into a sequence of pairs
Equations
- Stream'.Seq.zip = Stream'.Seq.zipWith Prod.mk
Instances For
Separate a sequence of pairs into two sequences
Equations
- Stream'.Seq.unzip s = (Stream'.Seq.map Prod.fst s, Stream'.Seq.map Prod.snd s)
Instances For
Enumerate a sequence by tagging each element with its index.
Equations
Instances For
Convert a sequence which is known to terminate into a list
Equations
- Stream'.Seq.toList s h = Stream'.Seq.take (Nat.find h) s
Instances For
Convert a sequence which is known not to terminate into a stream
Equations
- Stream'.Seq.toStream s h n = Option.get (Stream'.Seq.get? s n) (_ : Option.isSome (Stream'.Seq.get? s n) = true)
Instances For
Convert a sequence into either a list or a stream depending on whether it is finite or infinite. (Without decidability of the infiniteness predicate, this is not constructively possible.)
Equations
- Stream'.Seq.toListOrStream s = if h : Stream'.Seq.Terminates s then Sum.inl (Stream'.Seq.toList s h) else Sum.inr (Stream'.Seq.toStream s h)
Instances For
Equations
- Stream'.Seq.instFunctorSeq = { map := @Stream'.Seq.map, mapConst := fun {α β : Type u_1} => Stream'.Seq.map ∘ Function.const β }
Convert a sequence into a list, embedded in a computation to allow for the possibility of infinite sequences (in which case the computation never returns anything).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Convert a Seq1
to a sequence.
Equations
- Stream'.Seq1.toSeq x = match x with | (a, s) => Stream'.Seq.cons a s
Instances For
Equations
- Stream'.Seq1.coeSeq = { coe := Stream'.Seq1.toSeq }
Map a function on a Seq1
Equations
- Stream'.Seq1.map f x = match x with | (a, s) => (f a, Stream'.Seq.map f s)
Instances For
Flatten a nonempty sequence of nonempty sequences
Equations
- One or more equations did not get rendered due to their size.
Instances For
The return
operator for the Seq1
monad,
which produces a singleton sequence.
Equations
- Stream'.Seq1.ret a = (a, Stream'.Seq.nil)
Instances For
Equations
- Stream'.Seq1.instInhabitedSeq1 = { default := Stream'.Seq1.ret default }
The bind
operator for the Seq1
monad,
which maps f
on each element of s
and appends the results together.
(Not all of s
may be evaluated, because the first few elements of s
may already produce an infinite result.)
Equations
- Stream'.Seq1.bind s f = Stream'.Seq1.join (Stream'.Seq1.map f s)