349 lines
11 KiB
Plaintext
349 lines
11 KiB
Plaintext
|
sunterlib/s48/sequences -- Finite Sequences
|
||
|
|
||
|
A sequence library in various structures dealing with
|
||
|
* abstract sequences defined by their behaviour
|
||
|
* general sequences or a union type of built-in and abstract sequences
|
||
|
* vectors in particular
|
||
|
[ for list and string libraries ,open srfi-1 resp. srfi-13 ]
|
||
|
|
||
|
The library comes in three structures:
|
||
|
* BEHAVED-SEQUENCES -- basic procedures for abstract sequences
|
||
|
* SEQUENCE-LIB -- B.S. + procedures for general sequences
|
||
|
* VECTOR-LIB -- procedures for vectors
|
||
|
|
||
|
The VECTOR-LIB exports some SCHEME bindings such as VECTOR-REF, but
|
||
|
consists mainly of generic sequence code compiled with the basic
|
||
|
sequence operation names bound to the corresponding vector procedures.
|
||
|
The library is neither complete nor tweaked. (The idea to recycle parts
|
||
|
of the srfi-13 code came too late.) It contains the folllowing procedures
|
||
|
(in the categories of srfi-13):
|
||
|
|
||
|
VECTOR-LIB SEQUENCE-LIB BEHAVED-SEQUENCES, also SL
|
||
|
* Predicates or so
|
||
|
vector? sequence? behaved-sequence?
|
||
|
sequence-type?
|
||
|
[ versions with 1 sequence and optional start & end parameters ]
|
||
|
vector-every sequence-every
|
||
|
vector-any sequence-any
|
||
|
[ versions with >1 sequence but no optional start & end parameters ]
|
||
|
vectors-every sequences-every
|
||
|
vectors-any sequences-any
|
||
|
|
||
|
* Constructors
|
||
|
make-vector make-another-sequence make-behaved-sequence/type
|
||
|
vector behaved-sequence/type
|
||
|
make-sequence-type
|
||
|
make-behaved-sequence-record
|
||
|
|
||
|
* List & Sequence Conversion
|
||
|
list->vector list->behaved-sequence/type
|
||
|
vector->list sequence->list
|
||
|
|
||
|
* Selection
|
||
|
vector-length sequence-length behaved-sequence-length
|
||
|
vector-ref sequence-ref behaved-sequence-ref
|
||
|
behaved-sequence:type
|
||
|
vector-copy sequence-copy
|
||
|
subvector subsequence
|
||
|
|
||
|
* Modification
|
||
|
vector-set! sequence-set! behaved-sequence-set!
|
||
|
sequence-fill! vector-fill! behaved-sequence-fill!
|
||
|
|
||
|
* Reverse & Append
|
||
|
vector-append sequence-append
|
||
|
|
||
|
* Fold, Unfold & Map
|
||
|
[ versions with 1 sequence and optional start & end parameters ]
|
||
|
vector-map sequence-map
|
||
|
vector-for-each sequence-for-each
|
||
|
vector-fold sequence-fold
|
||
|
vector-fold-right sequence-fold-right
|
||
|
[ versions with >1 sequence but no start & end parameters ]
|
||
|
vectors-map sequences-map
|
||
|
vectors-for-each sequences-for-each
|
||
|
vectors-fold sequences-fold
|
||
|
vectors-fold-right sequences-fold-right
|
||
|
|
||
|
NOTE -- Some procedures take several sequence arguments and create a
|
||
|
new sequence with the concrete type of the first one: SEQUENCE-APPEND
|
||
|
and the SEQUENCES-procedures in the Map etc. category. Problem: the
|
||
|
target sequence may accept only elemens of a particular type (think
|
||
|
of strings and characters). Solution: Provide a vector, say, as first
|
||
|
arg sequence:
|
||
|
(sequence-append "aber" '(1) '#(3 3)) breaks, but
|
||
|
(sequence-append '#() "aber" '(1) '#(3 3)) succeeds.
|
||
|
|
||
|
I concede, that's not totally satisfying. A shallow aftertaste of cat
|
||
|
pee remains in my mouth.
|
||
|
|
||
|
*
|
||
|
|
||
|
Prelude
|
||
|
|
||
|
For our purposes, (each valid state of) a sequence with length n maps a
|
||
|
bounded segment of integers [0:n) into a set of Scheme values, typically
|
||
|
Anything or Character. Any kind Se of sequences with elements in T
|
||
|
supports the following basic operations:
|
||
|
|
||
|
maker : make n [x] ==> s
|
||
|
n in [0:oo), optional x : T, s : Se
|
||
|
The fresh sequence s represents a sequence of length n (mapping to x)
|
||
|
predicate : x ==> b
|
||
|
x : Anything, b : Boolean
|
||
|
the type predicate `x in Se'
|
||
|
getter : ref s k ==> s[k]
|
||
|
s in Se, k in [0:n) with n = length s, s[k] in T
|
||
|
setter : set! s k x ==> unspec
|
||
|
s in Se, x in T, k in [0:n) with n = length s
|
||
|
effect: s[k] = x, s[other] as before
|
||
|
meter : length s ==> n
|
||
|
s in ST, n in [0:oo) length of sequence
|
||
|
|
||
|
|
||
|
This sequence facility supports the following kinds of sequences:
|
||
|
|
||
|
Vector
|
||
|
Behaved-Sequence := a record type (record packages data + behaviour)
|
||
|
Sequence := Vector | Byte-Vector | String | Proper-List | Behaved-Sequence
|
||
|
|
||
|
Behaved-Sequences carry a SEQUENCE-TYPE record that contains MAKER,
|
||
|
PREDICATE, etc. procedures with the properties sketched above.
|
||
|
They are the official backdoor where user-defined sequence types enter
|
||
|
the general sequence lib. There are Examples.
|
||
|
|
||
|
[ Wouldn't ABSEQUENCE have been much more beautiful than BEHAVED-SEQUENCE? ]
|
||
|
|
||
|
*
|
||
|
|
||
|
The Procedures
|
||
|
|
||
|
Optional [START END] (abbreviating [START [END]]) arguments default to 0
|
||
|
resp. the sequence length.
|
||
|
|
||
|
* Predicates
|
||
|
|
||
|
(vector? x) ==> b
|
||
|
(sequence? x) ==> b
|
||
|
(behaved-sequence? x) ==> b
|
||
|
(sequence-type? x) ==> b
|
||
|
|
||
|
Synopsis: The obvious type predicates. Note that behaved-sequences
|
||
|
are sequences and carry a sequence-type with them. Sequence-types
|
||
|
are not sequences but package the behaviour of concrete sequence types.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-every foo? s [start end]) ==> x
|
||
|
(sequence-every foo? s [start end]) ==> x
|
||
|
|
||
|
Synopsis: Return the value x of (and (foo? s[start]) ... (foo? s[end-1])).
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-any foo? s [start end]) ==> x
|
||
|
(sequence-any foo? s [start end]) ==> x
|
||
|
|
||
|
Synopsis: Return the value x of (or (foo? s[start]) ... (foo? s[end-1])).
|
||
|
|
||
|
*
|
||
|
|
||
|
(vectors-every foo? s0 ...) ==> b
|
||
|
(sequences-every foo? s [start end]) ==> b
|
||
|
|
||
|
Synopsis: Return the value x of (and[0<=i<n] (foo? s0[i] ...)) with
|
||
|
n := min.k sequence-length sk.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vectors-any foo? s0 ...) ==> b
|
||
|
(sequences-any foo? s [start end]) ==> b
|
||
|
|
||
|
Synopsis: Return the value x of (or[0<=i<n] (foo? s0[i] ...)) with
|
||
|
n := min.k sequence-length sk.
|
||
|
|
||
|
*
|
||
|
|
||
|
Constructors
|
||
|
|
||
|
(make-vector len [fill]) ==> v
|
||
|
(make-behaved-sequence/type st len [fill]) ==> bs
|
||
|
|
||
|
Synopsis: Make a fresh vector V (behaved-sequence BS with sequence-type
|
||
|
ST) of length LEN (and all elements = FILL).
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector x0 ...) ==> v
|
||
|
(behaved-sequence/type st x0 ...) ==> bs
|
||
|
|
||
|
Synopsis: Make a fresh vector V (behaved-sequence BS with sequence-type
|
||
|
ST) of minimal length with the elements V[0] = X0, ... (BS[0] = X0, ...).
|
||
|
|
||
|
*
|
||
|
|
||
|
(make-sequence-type maker predicate getter setter meter) ==> st
|
||
|
|
||
|
Synopsis: Package the concrete sequence behaviour (basic procedures
|
||
|
described in the prelude) in the sequence-type record ST.
|
||
|
|
||
|
(make-behaved-sequence-record st data) ==> bs
|
||
|
Synopsis: Package the sequence-type ST and the concrete sequence DATA
|
||
|
in the behaved-sequence record BS.
|
||
|
|
||
|
*
|
||
|
|
||
|
List & Sequence Conversion
|
||
|
|
||
|
(list->vector xs [start end]) ==> v
|
||
|
(list->behaved-sequence/type st xs [start end]) ==> bs
|
||
|
|
||
|
Synopsis: Make a new vector V (behaved-sequence BS with sequence-type ST)
|
||
|
representing the sequence xs[start],..,xs[end-1].
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector->list v [start end]) ==> xs
|
||
|
(sequence->list s [start end]) ==> xs
|
||
|
|
||
|
Synopsis: Return xs = (list v[start] ... v[end-1]) etc.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-length v) ==> n
|
||
|
(sequence-length s) ==> n
|
||
|
(behaved-sequence-length bs) ==> n
|
||
|
|
||
|
Synopsis: Return length N of sequence represented by V : Vector, S :
|
||
|
Sequence, BS : Behaved-Sequence. You knew that, didn't you?
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-ref v k) ==> v[k]
|
||
|
(sequence-ref s k) ==> s[k]
|
||
|
(behaved-sequence-ref bs k) ==> bs[k]
|
||
|
|
||
|
*
|
||
|
|
||
|
(behaved-sequence:type bs) ==> st
|
||
|
|
||
|
Synopsis: Return sequence-type ST for concrete sequence packaged in
|
||
|
behaved-sequence BS.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-copy v0 [start end]) ==> v1
|
||
|
(sequence-copy s0 [start end]) ==> s1
|
||
|
|
||
|
Synopsis: Copy v0[start],..,v0[end-1] into a new vector v1 of minimal
|
||
|
length. Resp. represent s0[start],...,s0[end-1] as a new sequence S1 of
|
||
|
the same type.
|
||
|
|
||
|
*
|
||
|
|
||
|
(subvector v0 start end) ==> v1
|
||
|
(subsequence s0 start end) ==> s1
|
||
|
|
||
|
Synopsis: Like xxx-copy with obligatory source index bounds.
|
||
|
|
||
|
*
|
||
|
|
||
|
Modification
|
||
|
|
||
|
(vector-set! v i x) ==> unspec
|
||
|
(sequence-set! s i x) ==> unspec
|
||
|
(behaved-sequence-set! bs i x) ==> unspec
|
||
|
|
||
|
Synopsis: Set v[i] := x etc.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-fill! v x [start end]) ==> unspec
|
||
|
(sequence-fill! s x [start end]]) ==> unspec
|
||
|
(behaved-sequence-fill! bs x [start end]) ==> unspec
|
||
|
|
||
|
Synopsis: Set v[i] := x for all i in [start:end) etc.
|
||
|
|
||
|
*
|
||
|
|
||
|
Reverse & Append
|
||
|
|
||
|
(vector-append v0 ...) ==> v
|
||
|
(sequence-append s0 s1 ...) ==> s
|
||
|
|
||
|
Synoposis: Make a new vector V (sequence S of type(S0)) representing
|
||
|
you know what. See the NOTE above.
|
||
|
|
||
|
*
|
||
|
|
||
|
Fold, Unfold & Map
|
||
|
|
||
|
(vector-map f v [start end]) ==> fv
|
||
|
(vectors-map f v0 ...) ==> fv*
|
||
|
(sequence-map f s [start end]) ==> fs
|
||
|
(sequences-map f s0 s1 ...) ==> fs*
|
||
|
|
||
|
Synopsis: Make new vector FV (FV*, sequence FS of type(S), FS* of type(S0))
|
||
|
representing the sequence f(v[start]),...,f(v[end-1]), resp. the
|
||
|
sequence (f(v0[i],...) : 0<=i<n) with n = min.k sequence-length sk, etc.
|
||
|
See the NOTE above.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-for-each proc v [start end]) ==> unspec
|
||
|
(vectors-for-each f v0 ...) ==> unspec
|
||
|
(sequence-for-each proc s [start end]) ==> unspec
|
||
|
(sequences-for-each proc v0 ...) ==> unspec
|
||
|
|
||
|
Synopsis: Call (proc v[i]) for all i in [start:end) in some order, resp.
|
||
|
call (proc v0[i] ...) for all i in [0:n) in some order with
|
||
|
n = min.k sequence-length vk, etc.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-fold kons nil v [start end]) ==> w
|
||
|
(vectors-fold kons nil v0 ...) ==> w
|
||
|
(sequence-fold kons nil s0 [start end]) ==> s
|
||
|
(sequences-fold kons nil s0 ...) ==> s
|
||
|
|
||
|
Synopsis: Let y o x := (kons x y) resp.
|
||
|
y o (x0 ...) := (kons x0 ... y),
|
||
|
|
||
|
and let o be left-associative (so that we can spare us the brackets).
|
||
|
Compute
|
||
|
w = nil o v[start] o ... o v[end-1], resp.
|
||
|
w = nil o (v0[0] ...) o ... o (v0[n-1] ...)
|
||
|
with
|
||
|
n := min.k sequence-length vk;
|
||
|
|
||
|
etc., and see the NOTE above.
|
||
|
|
||
|
*
|
||
|
|
||
|
(vector-fold-right kons nil v [start end]) ==> w
|
||
|
(vectors-fold-right kons nil v0 ...) ==> w
|
||
|
(sequence-fold-right kons nil s0 [start end]) ==> s
|
||
|
(sequences-fold-right kons nil s0 ...) ==> s
|
||
|
|
||
|
Synopsis: Let x o y := (kons x y) resp.
|
||
|
(x0 ...) o y := (kons x0 ... y),
|
||
|
|
||
|
and let o be right-associative (so that we can spare us the brackets).
|
||
|
Compute
|
||
|
w = v[start] o ... o v[end-1] o nil, resp.
|
||
|
w = (v0[0] ...) o ... o (v0[n-1] ...) o nil
|
||
|
with
|
||
|
n := min.k sequence-length vk;
|
||
|
|
||
|
etc., and see the NOTE above.
|
||
|
|
||
|
*
|
||
|
|
||
|
Examples: forthcoming
|
||
|
|
||
|
*
|
||
|
|
||
|
Sela (for now).
|
||
|
|
||
|
oOo
|