-- The sum of a sequence of numerics.
sum: seqofreal +> real
sum(s) == fold[real](Numeric`add,0,s);
-- The product of a sequence of numerics.
prod: seqofreal +> real
prod(s) == fold[real](Numeric`mult,1,s);
-- The minimum of a sequence of numerics.
min: seq1ofreal +> real
min(s) == fold1[real](Numeric`min,s) postRESULTinsetelems s andforall e insetelems s & RESULT <= e;
-- The maximum of a sequence of numerics.
max: seq1ofreal +> real
max(s) == fold1[real](Numeric`max,s) postRESULTinsetelems s andforall e insetelems s & RESULT >= e;
-- Does an element appear in a sequence?
inSeq[@a]: @a * seqof @a +> bool
inSeq(e,s) == e insetelems s;
-- The position an item appears in a sequence?
indexOf[@a]: @a * seq1of @a +> nat1
indexOf(e,s) == cases s:
[-] -> 1,
[f]^ss -> if e=f then 1 else 1 + indexOf[@a](e,ss) end pre inSeq[@a](e,s) measure size0;
-- The position a subsequence appears in a sequence.
indexOfSeq[@a]: seq1of @a * seq1of @a +> nat1
indexOfSeq(r,s) == if preSeq[@a](r,s) then 1 else 1 + indexOfSeq[@a](r, tl s) pre subSeq[@a](r,s) measure size3;
-- The position a subsequence appears in a sequence?
indexOfSeqOpt[@a]: seq1of @a * seq1of @a +> [nat1]
indexOfSeqOpt(r,s) == if subSeq[@a](r,s) then indexOfSeq[@a](r, s) elsenil;
-- The number of times an element appears in a sequence.
numOccurs[@a]: @a * seqof @a +> nat
numOccurs(e,sq) == len [ 0 | i inseq sq & i = e ];
-- Is one sequence a permutation of another?
permutation[@a]: seqof @a * seqof @a +> bool
permutation(sq1,sq2) == len sq1 = len sq2 and forall x inseq sq1 & numOccurs[@a](x,sq1) = numOccurs[@a](x,sq2);
-- Is one sequence a prefix of another?
preSeq[@a]: seqof @a * seqof @a +> bool
preSeq(pres,full) == pres = full(1,...,len pres);
-- Is one sequence a suffix of another?
postSeq[@a]: seqof @a * seqof @a +> bool
postSeq(posts,full) == preSeq[@a](reverse posts, reverse full);
-- Is one sequence a subsequence of another sequence?
subSeq[@a]: seqof @a * seqof @a +> bool
subSeq(sub,full) == sub = [] or (exists i,j insetinds full & sub = full(i,...,j));
-- Create a sequence of identical elements.
replicate[@a]: nat * @a +> seqof @a
replicate(n,x) == [ x | i inset {1,...,n} ] postlenRESULT = n andforall y inseqRESULT & y = x;
-- Pad a sequence on the left with a given item up to a specified length.
padLeft[@a]: seqof @a * @a * nat +> seqof @a
padLeft(sq,x,n) == replicate[@a](n-len sq, x) ^ sq pre n >= len sq postlenRESULT = n and postSeq[@a](sq, RESULT);
-- Pad a sequence on the right with a given item up to a specified length.
padRight[@a]: seqof @a * @a * nat +> seqof @a
padRight(sq,x,n) == sq ^ replicate[@a](n-len sq, x) pre n >= len sq postlenRESULT = n and preSeq[@a](sq, RESULT);
-- Pad a sequence with a given item such that it is centred in a specified length. -- If padded by an odd number, add the extra item on the right.
padCentre[@a]: seqof @a * @a * nat +> seqof @a
padCentre(sq,x,n) == let space = if n <= len sq then 0 else n - len sq in padRight[@a](padLeft[@a](sq,x,len sq + (space div 2)),x,n);
-- trim[@a]: seq of @a * (@a +> bool) +> seq of @a -- trim(s, p) == trimpre(reverse(trimpre(reverse s, p)), p); -- post exists s1,s2: seq of char & s = s1 ^ RESULT ^ s2 and isDigits(s1) and isDigits(s2);
-- Drop items from a sequence while a predicate is true.
dropWhile[@a]: (@a +> bool) * seqof @a +> seqof @a
dropWhile(p, s) == cases s:
[] -> [],
[x] ^ t -> if p(x) then dropWhile[@a](p, t) else s end post postSeq[@a](RESULT, s) and
(RESULT = [] ornot p(RESULT(1))) and forall i inset {1,...,(len s - lenRESULT)} & p(s(i)) measure size5;
-- Apply a function to all elements of a sequence.
xform[@a,@b]: (@a+>@b) * seqof @a +> seqof @b
xform(f,s) == [ f(x) | x inseq s ] postlenRESULT = len s and
(forall i insetinds s & RESULT(i) = f(s(i)));
-- Fold (iterate, accumulate, reduce) a binary function over a sequence. -- The function is assumed to be associative and have an identity element.
fold[@a]: (@a * @a +> @a) * @a * seqof @a +> @a
fold(f, e, s) == cases s:
[] -> e,
[x] -> x,
s1^s2 -> f(fold[@a](f,e,s1), fold[@a](f,e,s2)) end --pre (forall x:@a & f(x,e) = x and f(e,x) = x) --and forall x,y,z:@a & f(x,f(y,z)) = f(f(x,y),z) measure size2;
-- Fold (iterate, accumulate, reduce) a binary function over a non-empty sequence. -- The function is assumed to be associative.
fold1[@a]: (@a * @a +> @a) * seq1of @a +> @a
fold1(f, s) == cases s:
[e] -> e,
s1^s2 -> f(fold1[@a](f,s1), fold1[@a](f,s2)) end --pre forall x,y,z:@a & f(x,f(y,z)) = f(f(x,y),z) measure size1;
-- Pair the corresponding elements of two lists of equal length.
zip[@a,@b]: seqof @a * seqof @b +> seqof (@a * @b)
zip(s,t) == [ mk_(s(i),t(i)) | i insetinds s ] prelen s = len t postlenRESULT = len s and mk_(s,t) = unzip[@a,@b](RESULT);
-- Split a list of pairs into a list of firsts and a list of seconds.
unzip[@a,@b]: seqof (@a * @b) +> seqof @a * seqof @b
unzip(s) == mk_([ x.#1 | x inseq s], [ x.#2 | x inseq s]) postlet mk_(t,u) = RESULTinlen t = len s andlen u = len s; -- and s = zip[@a,@b](RESULT.#1,RESULT.#2);
-- Are the elements of a list distinct (no duplicates).
isDistinct[@a]: seqof @a +> bool
isDistinct(s) == len s = cardelems s;
-- Create a string presentation of a set.
format[@a]: (@a +> seqofchar) * seqofchar * seqof @a +> seqofchar
format(f,sep,s) == cases s:
[] -> "",
[x] -> f(x),
t ^ u -> format[@a](f,sep,t) ^ sep ^ format[@a](f,sep,u) end measure size4;
-- The following functions wrap primitives for convenience, to allow them for example to -- serve as function arguments.
-- Concatenation of two sequences.
app[@a]: seqof @a * seqof @a +> seqof @a
app(m,n) == m^n;
-- Set of sequence elements.
setOf[@a]: seqof @a +> setof @a
setOf(s) == elems(s);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.