
			List operations

*INTRO
Most objects that can be of variable size are represented as lists
(linked lists internally). Yacas does implement arrays, which are
faster when the number of elements in a collection of objects doesn't
change. Operations on lists have better support in the current
system.

*CMD Head --- the first element of a list
*CORE
*CALL
	Head(list)

*PARMS

{list} -- a list

*DESC

This function returns the first element of a list. If it is applied to
a general expression, it returns the first operand. An error is
returned if "list" is an atom.

*E.G.

	In> Head({a,b,c})
	Out> a;
	In> Head(f(a,b,c));
	Out> a;

*SEE Tail, Length

*CMD Tail --- returns a list without its first element
*CORE
*CALL
	Tail(list)

*PARMS

{list} -- a list

*DESC

This function returns "list" without its first element.

*E.G.

	In> Tail({a,b,c})
	Out> {b,c};

*SEE Head, Length

*CMD Length --- the length of a list or string
*CORE
*CALL
	Length(object)

*PARMS

{object} -- a list, array or string

*DESC

Length returns the length of a list.
This function also works on strings and arrays.

*E.G.

	In> Length({a,b,c})
	Out> 3;
	In> Length("abcdef");
	Out> 6;

*SEE Head, Tail, Nth, Count

*CMD Map --- apply an $n$-ary function to all entries in a list
*STD
*CALL
	Map(fn, list)

*PARMS

{fn} -- function to apply

{list} -- list of lists of arguments

*DESC

This function applies "fn" to every list of arguments to be found in
"list". So the first entry of "list" should be a list containing
the first, second, third, ... argument to "fn", and the same goes
for the other entries of "list". The function can either be given as
a string or as a pure function.

*E.G.

	In> MapSingle("Sin",{a,b,c});
	Out> {Sin(a),Sin(b),Sin(c)};
	In> Map("+",{{a,b},{c,d}});
	Out> {a+c,b+d};

*SEE MapSingle, MapArgs

*CMD MapSingle --- apply a unary function to all entries in a list
*STD
*CALL
	MapSingle(fn, list)

*PARMS

{fn} -- function to apply

{list} -- list of arguments

*DESC

The function "fn" is successively applied to all entries in
"list", and a list containing the respective results is
returned. The function can be given either as a string or as a pure
function.

The {/@} operator provides a shorthand for
{MapSingle}.

*E.G.

	In> MapSingle("Sin",{a,b,c});
	Out> {Sin(a),Sin(b),Sin(c)};
	In> MapSingle({{x},x^2}, {a,2,c});
	Out> {a^2,4,c^2};

*SEE Map, MapArgs, /@

*CMD RandomIntegerVector --- generate a vector of random integers

*STD

*CALL
	RandomIntegerVector(nr, from, to)

*PARMS

{nr} -- number of integers to generate

{from} -- lower bound

{to} -- upper bound

*DESC

This function generates a list with "nr" random integers. All
entries lie between "from" and "to", including the boundaries, and
are uniformly distributed in this interval.

*E.G.

	In> RandomIntegerVector(4,-3,3)
	Out> {0,3,2,-2};

*SEE Random, RandomPoly

*CMD MakeVector --- vector of uniquely numbered variable names
*STD
*CALL
	MakeVector(var,n)

*PARMS

{var} -- free variable

{n} -- length of the vector

*DESC

A list of length "n" is generated. The first entry contains the
identifier "var" with the number 1 appended to it, the second entry
contains "var" with the suffix 2, and so on until the last entry
which contains "var" with the number "n" appended to it.

*E.G.

	In> MakeVector(a,3)
	Out> {a1,a2,a3};

*SEE RandomIntegerVector, ZeroVector

*CMD Select --- select entries satisfying some predicate
*STD
*CALL
	Select(pred, list)

*PARMS

{pred} -- a predicate

{list} -- a list of elements to select from

*DESC

{Select} returns a sublist of "list" which contains all
the entries for which the predicate "pred" returns
{True} when applied to this entry.

*E.G.

	In> Select("IsInteger",{a,b,2,c,3,d,4,e,f})
	Out> {2,3,4};

*SEE Length, Find, Count

*CMD Nth --- return the $n$-th element of a list
*CORE
*CALL
	Nth(list, n)

*PARMS

{list} -- list to choose from

{n} -- index of entry to pick

*DESC

The entry with index "n" from "list" is returned. The first entry
has index 1. It is possible to pick several entries of the list by
taking "n" to be a list of indices.

More generally, {Nth} returns the n-th operand of the
expression passed as first argument.

An alternative but equivalent form of {Nth(list, n)} is
{list[n]}.

*E.G.

	In> lst := {a,b,c,13,19};
	Out> {a,b,c,13,19};
	In> Nth(lst, 3);
	Out> c;
	In> lst[3];
	Out> c;
	In> Nth(lst, {3,4,1});
	Out> {c,13,a};
	In> Nth(b*(a+c), 2);
	Out> a+c;

*SEE Select, Nth

*CMD DestructiveReverse --- reverse a list destructively
*CORE
*CALL
	DestructiveReverse(list)

*PARMS

{list} -- list to reverse

*DESC

This command reverses "list" in place, so that the original is
destroyed. This means that any variable bound to "list" will now be
bound to the reversed list. The reversed list is also returned.

Destructive commands are faster than their nondestructive
counterparts. Strangely, there is no nondestructive command to reverse
a list. Use {FlatCopy} and
{DestructiveReverse} to achieve this.

*E.G.

	In> lst := {a,b,c,13,19};
	Out> {a,b,c,13,19};
	In> revlst := DestructiveReverse(lst);
	Out> {19,13,c,b,a};
	In> lst;
	Out> {a};

*SEE FlatCopy

*CMD List --- construct a list
*CORE
*CALL
	List(expr1, expr2, ...)

*PARMS

{expr1}, {expr2} -- expressions making up the list

*DESC

A list is constructed whose first entry is "expr1", the second entry
is "expr2", and so on. This command is equivalent to the expression
"{expr1, expr2, ...}".

*E.G.

	In> List();
	Out> {};
	In> List(a,b);
	Out> {a,b};
	In> List(a,{1,2},d);
	Out> {a,{1,2},d};

*SEE UnList, Listify

*CMD UnList --- convert a list to a function application
*CORE
*CALL
	UnList(list)

*PARMS

{list} -- list to be converted

*DESC

This command converts a list to a function application. The first
entry of "list" is treated as a function, and the following entries
are the arguments to this function. So the function refered to in the
first element of "list" is applied to the other elements.

Note that "list" is evaluated before the function application is
formed, but the resulting expression is left unevaluated. The functions {UnList()} and {Hold()} both stop the process of evaluation.

*E.G.

	In> UnList({Cos, x});
	Out> Cos(x);
	In> UnList({f});
	Out> f();
	In> UnList({Taylor,x,0,5,Cos(x)});
	Out> Taylor(x,0,5)Cos(x);
	In> Eval(%);
	Out> 1-x^2/2+x^4/24;

*SEE List, Listify, Hold

*CMD Listify --- convert a function application to a list
*CORE
*CALL
	Listify(expr)

*PARMS

{expr} -- expression to be converted

*DESC

The parameter "expr" is expected to be a compound object, i.e. not
an atom. It is evaluated and then converted to a list. The first entry
in the list is the top-level operator in the evaluated expression and
the other entries are the arguments to this operator. Finally, the
list is returned.

*E.G.

	In> Listify(Cos(x));
	Out> {Cos,x};
	In> Listify(3*a);
	Out> {*,3,a};

*SEE List, UnList, IsAtom

*CMD Concat --- concatenate lists
*CORE
*CALL
	Concat(list1, list2, ...)

*PARMS

{list1}, {list2}, ... -- lists to concatenate

*DESC

The lists "list1", "list2", ... are evaluated and
concatenated. The resulting big list is returned.

*E.G.

	In> Concat({a,b}, {c,d});
	Out> {a,b,c,d};
	In> Concat({5}, {a,b,c}, {{f(x)}});
	Out> {5,a,b,c,{f(x)}};

*SEE ConcatStrings, :, Insert

*CMD Delete --- delete an element from a list
*CORE
*CALL
	Delete(list, n)

*PARMS

{list} -- list from which an element should be removed

{n} -- index of the element to remove

*DESC

This command deletes the n-th element from "list". The first
parameter should be a list, while "n" should be a positive integer
less than or equal to the length of "list". The entry with index
"n" is removed (the first entry has index 1), and the resulting list
is returned.

*E.G.

	In> Delete({a,b,c,d,e,f}, 4);
	Out> {a,b,c,e,f};

*SEE DestructiveDelete, Insert, Replace

*CMD Insert --- insert an element into a list
*CORE
*CALL
	Insert(list, n, expr)

*PARMS

{list} -- list in which "expr" should be inserted

{n} -- index at which to insert

{expr} -- expression to insert in "list"

*DESC

The expression "expr" is inserted just before the n-th entry in
"list". The first parameter "list" should be a list, while "n"
should be a positive integer less than or equal to the length of
"list" plus one. The expression "expr" is placed between the
entries in "list" with entries "n-1" and "n". There are two
border line cases: if "n" is 1, the expression "expr" is placed in
front of the list (just as by the {:} operator); if "n"
equals the length of "list" plus one, the expression "expr" is
placed at the end of the list (just as by {Append}). In any
case, the resulting list is returned.

*E.G.

	In> Insert({a,b,c,d}, 4, x);
	Out> {a,b,c,x,d};
	In> Insert({a,b,c,d}, 5, x);
	Out> {a,b,c,d,x};
	In> Insert({a,b,c,d}, 1, x);
	Out> {x,a,b,c,d};

*SEE DestructiveInsert, :, Append, Delete, Remove

*CMD DestructiveDelete --- delete an element destructively from a list
*CORE
*CALL
	DestructiveDelete(list, n)

*PARMS

{list} -- list from which an element should be removed

{n} -- index of the element to remove

*DESC

This is the destructive counterpart of {Delete}. This
command yields the same result as the corresponding call to
{Delete}, but the original list is modified. So if a
variable is bound to "list", it will now be bound to the list with
the n-th entry removed.

Destructive commands run faster than their nondestructive counterparts
because the latter copy the list before they alter it.

*E.G.

	In> lst := {a,b,c,d,e,f};
	Out> {a,b,c,d,e,f};
	In> Delete(lst, 4);
	Out> {a,b,c,e,f};
	In> lst;
	Out> {a,b,c,d,e,f};
	In> DestructiveDelete(lst, 4);
	Out> {a,b,c,e,f};
	In> lst;
	Out> {a,b,c,e,f};

*SEE Delete, DestructiveInsert, DestructiveReplace

*CMD DestructiveInsert --- insert an element destructively into a list
*CORE
*CALL
	DestructiveInsert(list, n, expr)

*PARMS

{list} -- list in which "expr" should be inserted

{n} -- index at which to insert

{expr} -- expression to insert in "list"

*DESC

This is the destructive counterpart of {Insert}. This
command yields the same result as the corresponding call to
{Insert}, but the original list is modified. So if a
variable is bound to "list", it will now be bound to the list with
the expression "expr" inserted.

Destructive commands run faster than their nondestructive counterparts
because the latter copy the list before they alter it.

*E.G.

	In> lst := {a,b,c,d};
	Out> {a,b,c,d};
	In> Insert(lst, 2, x);
	Out> {a,x,b,c,d};
	In> lst;
	Out> {a,b,c,d};
	In> DestructiveInsert(lst, 2, x);
	Out> {a,x,b,c,d};
	In> lst;
	Out> {a,x,b,c,d};

*SEE Insert, DestructiveDelete, DestructiveReplace

*CMD Replace --- replace an entry in a list

*CORE

*CALL
	Replace(list, n, expr)

*PARMS

{list} -- list of which an entry should be replaced

{n} -- index of entry to replace

{expr} -- expression to replace the n-th entry with

*DESC

The n-th entry of "list" is replaced by the expression
"expr". This is equivalent to calling {Delete} and
{Insert} in sequence. To be precise, the expression
{Replace(list, n, expr)} has the same result as the
expression {Insert(Delete(list, n), n, expr)}.

*E.G.

	In> Replace({a,b,c,d,e,f}, 4, x);
	Out> {a,b,c,x,e,f};

*SEE Delete, Insert, DestructiveReplace

*CMD DestructiveReplace --- replace an entry destructively in a list

*CORE

*CALL
	DestructiveReplace(list, n, expr)

*PARMS

{list} -- list of which an entry should be replaced

{n} -- index of entry to replace

{expr} -- expression to replace the n-th entry with

*DESC

This is the destructive counterpart of {Replace}. This
command yields the same result as the corresponding call to
{Replace}, but the original list is modified. So if a
variable is bound to "list", it will now be bound to the list with
the expression "expr" inserted.

Destructive commands run faster than their nondestructive counterparts
because the latter copy the list before they alter it.

*E.G.

	In> lst := {a,b,c,d,e,f};
	Out> {a,b,c,d,e,f};
	In> Replace(lst, 4, x);
	Out> {a,b,c,x,e,f};
	In> lst;
	Out> {a,b,c,d,e,f};
	In> DestructiveReplace(lst, 4, x);
	Out> {a,b,c,x,e,f};
	In> lst;
	Out> {a,b,c,x,e,f};

*SEE Replace, DestructiveDelete, DestructiveInsert

*CMD FlatCopy --- copy the top level of a list
*CORE
*CALL
	FlatCopy(list)

*PARMS

{list} -- list to be copied

*DESC

A copy of "list" is made and returned. The list is not recursed
into, only the first level is copied. This is useful in combination
with the destructive commands that actually modify lists in place (for
efficiency).

*E.G.

The following shows a possible way to define a command that reverses a
list nondestructively.

	In> reverse(l_IsList) <-- DestructiveReverse \
	  (FlatCopy(l));
	Out> True;
	In> lst := {a,b,c,d,e};
	Out> {a,b,c,d,e};
	In> reverse(lst);
	Out> {e,d,c,b,a};
	In> lst;
	Out> {a,b,c,d,e};

*CMD Contains --- test whether a list contains a certain element
*STD
*CALL
	Contains(list, expr)

*PARMS

{list} -- list to examine

{expr} -- expression to look for in "list"

*DESC

This command tests whether "list" contains the expression "expr"
as an entry. It returns {True} if it does and
{False} otherwise. Only the top level of "list" is
examined. The parameter "list" may also be a general expression, in
that case the top-level operands are tested for the occurence of
"expr".

*E.G.

	In> Contains({a,b,c,d}, b);
	Out> True;
	In> Contains({a,b,c,d}, x);
	Out> False;
	In> Contains({a,{1,2,3},z}, 1);
	Out> False;
	In> Contains(a*b, b);
	Out> True;

*SEE Find, Count

*CMD Find --- get the index at which a certain element occurs
*STD
*CALL
	Find(list, expr)

*PARMS

{list} -- the list to examine

{expr} -- expression to look for in "list"

*DESC

This commands returns the index at which the expression "expr"
occurs in "list". If "expr" occurs more than once, the lowest
index is returned. If "expr" does not occur at all,
{-1} is returned.

*E.G.

	In> Find({a,b,c,d,e,f}, d);
	Out> 4;
	In> Find({1,2,3,2,1}, 2);
	Out> 2;
	In> Find({1,2,3,2,1}, 4);
	Out> -1;

*SEE Contains

*CMD Append --- append an entry at the end of a list
*STD
*CALL
	Append(list, expr)

*PARMS

{list} -- list to append "expr" to

{expr} -- expression to append to the list

*DESC

The expression "expr" is appended at the end of "list" and the
resulting list is returned.

Note that due to the underlying data structure, the time it takes to
append an entry at the end of a list grows linearly with the length of
the list, while the time for prepending an entry at the beginning is
constant.

*E.G.

	In> Append({a,b,c,d}, 1);
	Out> {a,b,c,d,1};

*SEE Concat, :, DestructiveAppend

*CMD DestructiveAppend --- destructively append an entry to a list
*CORE
CALL
	DestructiveAppend(list, expr)

*PARMS

{list} -- list to append "expr" to

{expr} -- expression to append to the list

*DESC

This is the destructive counterpart of {Append}. This
command yields the same result as the corresponding call to
{Append}, but the original list is modified. So if a
variable is bound to "list", it will now be bound to the list with
the expression "expr" inserted.

Destructive commands run faster than their nondestructive counterparts
because the latter copy the list before they alter it.

*E.G.

	In> lst := {a,b,c,d};
	Out> {a,b,c,d};
	In> Append(lst, 1);
	Out> {a,b,c,d,1};
	In> lst
	Out> {a,b,c,d};
	In> DestructiveAppend(lst, 1);
	Out> {a,b,c,d,1};
	In> lst;
	Out> {a,b,c,d,1};

*SEE Concat, :, Append

*CMD RemoveDuplicates --- remove any duplicates from a list
*STD
*CALL
	RemoveDuplicates(list)

*PARMS

{list} -- list to act on

*DESC

This command returns "list" after all duplicates are removed. To be
precise, the second occurence of any entry is deleted, as are the
third, the fourth, etcetera.

*E.G.

	In> RemoveDuplicates({1,2,3,2,1});
	Out> {1,2,3};
	In> RemoveDuplicates({a,1,b,1,c,1});
	Out> {a,1,b,c};

*CMD Push --- add an element on top of a stack
*STD
*CALL
	Push(stack, expr)

*PARMS

{stack} -- a list (which serves as the stack container)

{expr} -- expression to push on "stack"

*DESC

This is part of a simple implementation of a stack, internally
represented as a list. This command pushes the expression "expr" on
top of the stack, and returns the stack afterwards.

*E.G.

	In> stack := {};
	Out> {};
	In> Push(stack, x);
	Out> {x};
	In> Push(stack, x2);
	Out> {x2,x};
	In> PopFront(stack);
	Out> x2;

*SEE Pop, PopFront, PopBack

*CMD Pop --- remove an element from a stack
*STD
*CALL
	Pop(stack, n)

*PARMS

{stack} -- a list (which serves as the stack container)

{n} -- index of the element to remove

*DESC

This is part of a simple implementation of a stack, internally
represented as a list. This command removes the element with index
"n" from the stack and returns this element. The top of the stack is
represented by the index 1. Invalid indices, for example indices
greater than the number of element on the stack, lead to an error.

*E.G.

	In> stack := {};
	Out> {};
	In> Push(stack, x);
	Out> {x};
	In> Push(stack, x2);
	Out> {x2,x};
	In> Push(stack, x3);
	Out> {x3,x2,x};
	In> Pop(stack, 2);
	Out> x2;
	In> stack;
	Out> {x3,x};

*SEE Push, PopFront, PopBack

*CMD PopFront --- remove an element from the top of a stack
*STD
*CALL
	PopFront(stack)

*PARMS

{stack} -- a list (which serves as the stack container)

*DESC

This is part of a simple implementation of a stack, internally
represented as a list. This command removes the element on the top of
the stack and returns it. This is the last element that is pushed onto
the stack.

*E.G.

	In> stack := {};
	Out> {};
	In> Push(stack, x);
	Out> {x};
	In> Push(stack, x2);
	Out> {x2,x};
	In> Push(stack, x3);
	Out> {x3,x2,x};
	In> PopFront(stack);
	Out> x3;
	In> stack;
	Out> {x2,x};

*SEE Push, Pop, PopBack

*CMD PopBack --- remove an element from the bottom of a stack
*STD
*CALL
	PopBack(stack)

*PARMS

{stack} -- a list (which serves as the stack container)

*DESC

This is part of a simple implementation of a stack, internally
represented as a list. This command removes the element at the bottom
of the stack and returns this element. Of course, the stack should not
be empty.

*E.G.

	In> stack := {};
	Out> {};
	In> Push(stack, x);
	Out> {x};
	In> Push(stack, x2);
	Out> {x2,x};
	In> Push(stack, x3);
	Out> {x3,x2,x};
	In> PopBack(stack);
	Out> x;
	In> stack;
	Out> {x3,x2};

*SEE Push, Pop, PopFront

*CMD Swap --- swap two elements in a list
*STD
*CALL
	Swap(list, i1, i2)

*PARMS

{list} -- the list in which a pair of entries should be swapped

{i1, i2} -- indices of the entries in "list" to swap

*DESC

This command swaps the pair of entries with entries "i1" and "i2"
in "list". So the element at index "i1" ends up at index "i2"
and the entry at "i2" is put at index "i1". Both indices should be
valid to address elements in the list. Then the updated list is
returned.

{Swap()} works also on generic arrays.

*E.G.

	In> lst := {a,b,c,d,e,f};
	Out> {a,b,c,d,e,f};
	In> Swap(lst, 2, 4);
	Out> {a,d,c,b,e,f};

*SEE Replace, DestructiveReplace, ArrayCreate

*CMD Count --- count the number of occurrences of an expression
*STD
*CALL
	Count(list, expr)

*PARMS

{list} -- the list to examine

{expr} -- expression to look for in "list"

*DESC

This command counts the number of times that the expression "expr"
occurs in "list" and returns this number.

*E.G.

	In> lst := {a,b,c,b,a};
	Out> {a,b,c,b,a};
	In> Count(lst, a);
	Out> 2;
	In> Count(lst, c);
	Out> 1;
	In> Count(lst, x);
	Out> 0;

*SEE Length, Select, Contains

*CMD Intersection --- return the intersection of two lists
*STD
*CALL
	Intersection(l1, l2)

*PARMS

{l1}, {l2} -- two lists

*DESC

The intersection of the lists "l1" and "l2" is determined and
returned. The intersection contains all elements that occur in both
lists. The entries in the result are listed in the same order as in
"l1". If an expression occurs multiple times in both "l1" and
"l2", then it will occur the same number of times in the result.

*E.G.

	In> Intersection({a,b,c}, {b,c,d});
	Out> {b,c};
	In> Intersection({a,e,i,o,u}, {f,o,u,r,t,e,e,n});
	Out> {e,o,u};
	In> Intersection({1,2,2,3,3,3}, {1,1,2,2,3,3});
	Out> {1,2,2,3,3};

*SEE Union, Difference

*CMD Union --- return the union of two lists
*STD
*CALL
	Union(l1, l2)

*PARMS

{l1}, {l2} -- two lists

*DESC

The union of the lists "l1" and "l2" is determined and
returned. The union contains all elements that occur in one or both of
the lists. In the resulting list, any element will occur only once.

*E.G.

	In> Union({a,b,c}, {b,c,d});
	Out> {a,b,c,d};
	In> Union({a,e,i,o,u}, {f,o,u,r,t,e,e,n});
	Out> {a,e,i,o,u,f,r,t,n};
	In> Union({1,2,2,3,3,3}, {2,2,3,3,4,4});
	Out> {1,2,3,4};

*SEE Intersection, Difference

*CMD Difference --- return the difference of two lists
*STD
*CALL
	Difference(l1, l2)

*PARMS

{l1}, {l2} -- two lists

*DESC

The difference of the lists "l1" and "l2" is determined and
returned. The difference contains all elements that occur in "l1"
but not in "l2". The order of elements in "l1" is preserved. If a
certain expression occurs "n1" times in the first list and "n2"
times in the second list, it will occur "n1-n2" times in the result
if "n1" is greater than "n2" and not at all otherwise.

*E.G.

	In> Difference({a,b,c}, {b,c,d});
	Out> {a};
	In> Difference({a,e,i,o,u}, {f,o,u,r,t,e,e,n});
	Out> {a,i};
	In> Difference({1,2,2,3,3,3}, {2,2,3,4,4});
	Out> {1,3,3};

*SEE Intersection, Union

*CMD FillList --- fill a list with a certain expression
*STD
*CALL
	FillList(expr, n)

*PARMS

{expr} -- expression to fill the list with

{n} -- the length of the list to construct

*DESC

This command creates a list of length "n" in which all slots contain
the expression "expr" and returns this list.

*E.G.

	In> FillList(x, 5);
	Out> {x,x,x,x,x};

*SEE MakeVector, ZeroVector, RandomIntegerVector

*CMD Drop --- drop a range of elements from a list

*STD

*CALL
	Drop(list, n)
	Drop(list, -n)
	Drop(list, {m,n})

*PARMS

{list} -- list to act on

{n}, {m} -- positive integers describing the entries to drop

*DESC

This command removes a sublist of "list" and returns a list
containing the remaining entries. The first calling sequence drops the
first "n" entries in "list". The second form drops the last "n"
entries. The last invocation drops the elements with indices "m"
through "n".

*E.G.

	In> lst := {a,b,c,d,e,f,g};
	Out> {a,b,c,d,e,f,g};
	In> Drop(lst, 2);
	Out> {c,d,e,f,g};
	In> Drop(lst, -3);
	Out> {a,b,c,d};
	In> Drop(lst, {2,4});
	Out> {a,e,f,g};

*SEE Take, Select, Remove

*CMD Take --- take a sublist from a list, dropping the rest
*STD
*CALL
	Take(list, n)
	Take(list, -n)
	Take(list, {m,n})

*PARMS

{list} -- list to act on

{n}, {m} -- positive integers describing the entries to drop

*DESC

This command takes a sublist of "list", drops the rest, and returns
the selected sublist. The first calling sequence selects the first
"n" entries in "list". The second form takes the last "n"
entries. The last invocation selects the sublist beginning with entry
number "m" and ending with the "n"-th entry.

*E.G.

	In> lst := {a,b,c,d,e,f,g};
	Out> {a,b,c,d,e,f,g};
	In> Take(lst, 2);
	Out> {a,b};
	In> Take(lst, -3);
	Out> {e,f,g};
	In> Take(lst, {2,4});
	Out> {b,c,d};

*SEE Drop, Select, Remove

*CMD Partition --- partition a list in sublists of equal length
*STD
*CALL
	Partition(list, n)

*PARMS

{list} -- list to partition

{n} -- length of partitions

*DESC

This command partitions "list" into non-overlapping sublists of
length "n" and returns a list of these sublists. The first "n"
entries in "list" form the first partition, the entries from
position "n+1" upto "2n" form the second partition, and so on. If
"n" does not divide the length of "list", the remaining entries
will be thrown away. If "n" equals zero, an empty list is
returned.

*E.G.

	In> Partition({a,b,c,d,e,f,}, 2);
	Out> {{a,b},{c,d},{e,f}};
	In> Partition(1 .. 11, 3);
	Out> {{1,2,3},{4,5,6},{7,8,9}};

*SEE Take, Permutations

*CMD Assoc --- return element stored in association list
*STD
*CALL
	Assoc(key, alist)

*PARMS

{key} -- key under which element is stored

{alist} -- association list to examine

*DESC

The association list "alist" is searched for an entry stored with
index "key". If such an entry is found, it is returned. Otherwise
the atom {Empty} is returned.

Association lists are represented as a list of two-entry lists. The
first element in the two-entry list is the key, the second element is
the value stored under this key.

The call {Assoc(key, alist)} can (probably more
intuitively) be accessed as {alist[key]}.

*E.G.

	In> writer := {};
	Out> {};
	In> writer["Iliad"] := "Homer";
	Out> True;
	In> writer["Henry IV"] := "Shakespeare";
	Out> True;
	In> writer["Ulysses"] := "James Joyce";
	Out> True;
	In> Assoc("Henry IV", writer);
	Out> {"Henry IV","Shakespeare"};
	In> Assoc("War and Peace", writer);
	Out> Empty;

*SEE AssocIndices, [], :=

*CMD AssocIndices --- return the keys in an association list
*STD
*CALL
	AssocIndices(alist)

*PARMS

{alist} -- association list to examine

*DESC

All the keys in the association list "alist" are assembled in a list
and this list is returned.

*E.G.

	In> writer := {};
	Out> {};
	In> writer["Iliad"] := "Homer";
	Out> True;
	In> writer["Henry IV"] := "Shakespeare";
	Out> True;
	In> writer["Ulysses"] := "James Joyce";
	Out> True;
	In> AssocIndices(writer);
	Out> {"Iliad","Henry IV","Ulysses"};

*SEE Assoc

*CMD Flatten --- flatten expression w.r.t. some operator
*STD
*CALL
	Flatten(expression,operator)

*PARMS

{expression} -- an expression

{operator} -- string with the contents of an infix operator.

*DESC

Flatten flattens an expression with respect to a specific
operator, converting the result into a list.
This is useful for unnesting an expression. Flatten is typically
used in simple simplification schemes.

*E.G.

	In> Flatten(a+b*c+d,"+");
	Out> {a,b*c,d};
	In> Flatten({a,{b,c},d},"List");
	Out> {a,b,c,d};

*SEE UnFlatten

*CMD UnFlatten --- inverse operation of Flatten
*STD
*CALL
	UnFlatten(list,operator,identity)

*PARMS

{list} -- list of objects the operator is to work on

{operator} -- infix operator

{identity} -- identity of the operator

*DESC

UnFlatten is the inverse operation of Flatten. Given
a list, it can be turned into an expression representing
for instance the addition of these elements by calling
UnFlatten with "+" as argument to operator, and 0 as
argument to identity (0 is the identity for addition, since
a+0=a). For multiplication the identity element would be 1.

*E.G.

	In> UnFlatten({a,b,c},"+",0)
	Out> a+b+c;
	In> UnFlatten({a,b,c},"*",1)
	Out> a*b*c;

*SEE Flatten

*CMD Type --- return the type of an expression
*CORE
*CALL
	Type(expr)

*PARMS

{expr} -- expression to examine

*DESC

The type of the expression "expr" is represented as a string and
returned. So, if "expr" is a list, the string {"List"} is returned. In general, the top-level
operator of "expr" is returned. If the argument "expr" is an atom,
the result is the empty string {""}.

*E.G.

	In> Type({a,b,c});
	Out> "List";
	In> Type(a*(b+c));
	Out> "*";
	In> Type(123);
	Out> "";

*SEE IsAtom, NrArgs

*CMD NrArgs --- return number of top-level arguments
*STD
*CALL
	NrArgs(expr)

*PARMS

{expr} -- expression to examine

*DESC

This function evaluates to the number of top-level arguments of the
expression "expr". The argument "expr" may not be an atom, since
that would lead to an error.

*E.G.

	In> NrArgs(f(a,b,c))
	Out> 3;
	In> NrArgs(Sin(x));
	Out> 1;
	In> NrArgs(a*(b+c));
	Out> 2;

*SEE Type, Length

*CMD VarList, VarListArith, VarListSome --- list of variables appearing in an expression
*STD
*CALL
	VarList(expr)
	VarListArith(expr)
	VarListSome(expr, list)

*PARMS

{expr} -- an expression

{list} -- a list of function atoms

*DESC

The command {VarList(expr)} returns a list of all variables that appear in the
expression {expr}. The expression is traversed recursively.

The command {VarListSome} looks only at arguments of functions in the {list}. All other functions are considered "opaque" (as if they do not contain any variables) and their arguments are not checked.
For example, {VarListSome(a + Sin(b-c))} will return {{a, b, c}}, but {VarListSome(a*Sin(b-c), {*})} will not look at arguments of {Sin()} and will return {{a,Sin(b-c)}}. Here {Sin(b-c)} is considered a "variable" because the function {Sin} does not belong to {list}.


The command {VarListArith} returns a list of all variables that appear
arithmetically in the expression {expr}. This is implemented through
{VarListSome} by resticting to the arithmetic functions {+}, {-}, {*}, {/}.
Arguments of other functions are not checked.

Note that since the operators "{+}" and "{-}" are prefix as well as infix operators, it is currently required to use {Atom("+")} to obtain the unevaluated atom "{+}".

*E.G.

	In> VarList(Sin(x))
	Out> {x};
	In> VarList(x+a*y)
	Out> {x,a,y};
	In> VarListSome(x+a*y, {Atom("+")})
	Out> {x,a*y};
	In> VarListArith(x+y*Cos(Ln(x)/x))
	Out> {x,y,Cos(Ln(x)/x)}
	In> VarListArith(x+a*y^2-1)
	Out> {x,a,y^2};

*SEE IsFreeOf, IsVariable, FuncList, HasExpr, HasFunc


*CMD FuncList, FuncListArith, FuncListSome --- list of functions used in an expression
*STD
*CALL
	FuncList(expr)
	FuncListArith(expr)
	FuncListSome(expr, list)

*PARMS

{expr} -- an expression

{list} -- list of function atoms to be considered "transparent"

*DESC

The command {FuncList(expr)} returns a list of all function atoms that appear
in the expression {expr}. The expression is recursively traversed.

The command {FuncListSome(expr, list)} does the same, except it only looks at arguments of a given {list} of functions. All other functions become "opaque" (as if they do not contain any other functions).
For example, {FuncListSome(a + Sin(b-c))} will see that the expression has a "{-}" operation and return {{+,Sin,-}}, but {FuncListSome(a + Sin(b-c), {+})} will not look at arguments of {Sin()} and will return {{+,Sin}}.

{FuncListArith} is defined through {FuncListSome} to look only at arithmetic operations {+}, {-}, {*}, {/}.

Note that since the operators "{+}" and "{-}" are prefix as well as infix operators, it is currently required to use {Atom("+")} to obtain the unevaluated atom "{+}".

*E.G.

	In> FuncList(x+y*Cos(Ln(x)/x))
	Out> {+,*,Cos,/,Ln};
	In> FuncListArith(x+y*Cos(Ln(x)/x))
	Out> {+,*,Cos};
	In> FuncListSome({a+b*2,c/d},{List})
	Out> {List,+,/};

*SEE VarList, HasExpr, HasFunc

*CMD BubbleSort, HeapSort --- sort a list
*STD
*CALL
	BubbleSort(list, compare)
	HeapSort(list, compare)

*PARMS

{list} -- list to sort

{compare} -- function used to compare elements of {list}

*DESC

This command returns {list} after it is sorted using {compare} to
compare elements. The function {compare} should accept two arguments,
which will be elements of {list}, and compare them. It should return
{True} if in the sorted list the second argument
should come after the first one, and {False}
otherwise.

The function {BubbleSort} uses the so-called "bubble sort" algorithm to do the
sorting by swapping elements that are out of order. This algorithm is easy to
implement, though it is not particularly fast. The sorting time is proportional
to $n^2$ where $n$ is the length of the list.

The function {HeapSort} uses a recursive algorithm "heapsort" and is much
faster for large lists. The sorting time is proportional to $n*Ln(n)$ where $n$
is the length of the list.

*E.G.

	In> BubbleSort({4,7,23,53,-2,1}, "<");
	Out> {-2,1,4,7,23,53};
	In> HeapSort({4,7,23,53,-2,1}, ">");
	Out> {53,23,7,4,1,-2};

*CMD PrintList --- print list with padding
*STD
*CALL
	PrintList(list)
	PrintList(list, padding);

*PARMS

{list} -- a list to be printed

{padding} -- (optional) a string

*DESC

Prints {list} and inserts the {padding} string between each pair of items of the list. Items of the list which are strings are printed without quotes, unlike {Write()}. Items of the list which are themselves lists are printed inside braces {{}}. If padding is not specified, a standard one is used (comma, space).

*E.G.

	In> PrintList({a,b,{c, d}}, " .. ")
	Out> " a ..  b .. { c ..  d}";

*SEE Write, WriteString

*CMD Table --- evaluate while some variable ranges over interval
*STD
*CALL
	Table(body, var, from, to, step)

*PARMS

{body} -- expression to evaluate multiple times

{var} -- variable to use as loop variable

{from} -- initial value for "var"

{to} -- final value for "var"

{step} -- step size with which "var" is incremented

*DESC

This command generates a list of values from "body", by assigning
variable "var" values from "from" upto "to", incrementing
"step" each time. So, the variable "var" first gets the value
"from", and the expression "body" is evaluated. Then the value
"from"+"step" is assigned to "var" and the expression "body"
is again evaluated. This continues, incrementing "var" with "step"
on every iteration, until "var" exceeds "to". At that moment, all
the results are assembled in a list and this list is returned.

*E.G.

	In> Table(i!, i, 1, 10, 1);
	Out> {1,2,6,24,120,720,5040,40320,362880,3628800};
	In> Table(i, i, 3, 16, 4);
	Out> {3,7,11,15};
	In> Table(i^2, i, 10, 1, -1);
	Out> {100,81,64,49,36,25,16,9,4,1};

*SEE For, MapSingle, .., TableForm

*CMD TableForm --- print each entry in a list on a line
*STD
*CALL
	TableForm(list)

*PARMS

{list} -- list to print

*DESC

This functions writes out "list" in a nicer readable form, by
printing every element in the list on a seperate line.

*E.G.

	In> TableForm(Table(i!, i, 1, 10, 1));
	1
	 2
	 6
	 24
	 120
	 720
	 5040
	 40320
	 362880
	 3628800
	Out> True;

*SEE PrettyForm, Echo, Table

