.<<< to run this off, do  deqn newmacs primer1.n | ditroff -me -Pip  {or equivalent}
.Lc MACSYMA\ Primer\ for\ UNIX 1
.(l C
adapted and edited by

Richard J. Fateman
\fIUniversity of California
Berkeley \fP

from material by
Joel Moses
\fI Massachusetts Institute of Technology\fP
.pp
.sh 2 Introduction
.pp
.EQ
delim @@
.EN
.Ma
(pronounced ``maxima''\**)
.(f
\**
(The acronym stands for Project MAC's SYmbolic MAnipulation System. ``MAC''
itself is an acronym, usually cited as meaning Man and Computer or
Machine Aided Cognition. The
Laboratory for Computer Science at the Massachusetts Institute of Technology
was known as Project MAC during the initial development of MACSYMA.)
.)f
is a large computer program designed for the manipulation
of algebraic expressions. You can use
.Ma
for manipulation of algebraic expressions involving
constants, variables, and functions. It can
differentiate, integrate, take limits, solve equations,
factor polynomials, expand functions in power series, and perform many other
operations.  You can use a programming language to extend
.Ma 's
capabilities to new domains.
.pp
A few of the system's most-used capabilities are described in
this primer.  A more complete discussion of these features and others
for more specialized interests
may be found in the 
.Ma
Reference Manual.
Additionally, information about each command is 
available through an on-line documentation retrieval command,
\f(CWdescribe.\fP
To see a blurb on, for example,
\f(CWexpand,\fP
type
\f(CWdescribe(expand);\fP
to the system. For some commands, an
\f(CWexample\fP
is also available, and can be viewed by typing, for instance,
\f(CWexample(expand);\fP
.sh 2 Starting\ Up 
.pp
On most UNIX systems, the system may be loaded by typing \f(CWvaxima\fP
to the shell prompt. It may be necessary to type \f(CW/usr/mac/vaxima\fP or some
similar pathname on your system.
Your computer system manager should know where the program is
installed.
If you expect to be using vaxima frequently, you should
include in your .login script, a line setting the system variable VAXIMA
to the home directory for vaxima documentation and programs.  For example,
.br
\f(CW
setenv VAXIMA /usr/mac
\fP
.pp
If you are just starting to use
.Ma
now, you could just type this in now. (This assume you are using the
usual ``C-shell'' command-line interpreter.)
A few seconds after typing \f(CWvaxima\fP, the system will return with a heading and prompt resembling
the text below.
.eB
\f(CW
% vaxima
..  set tabs in case they appear in fixed width displays below
.ta
.ta 41p +41p +41p +41p +41p +41p +41p +41p +41p +41p 
   vaxima 2.04
Sun Jul 12 23:25:20 1982

(c1)
\fP
.eE
The number 2.04 is a version identification number which will change
from time to time, as will the day and date of the system construction.
The label (c1) is a name being assigned
automatically to your first command. (c labels are used for user-input
commands, d-labels for
.Ma
output expressions.)
.sh 2 Typing\ Expressions
.pp
Suppose you wanted to work with the expression @(x + 1) sup 3@. You
could type it in by using Fortran-style syntax as follows:
.eB
\f(CW
(c1) (x+1)**3;
\fP
.eE
The ``;'' and the (invisible) ``carriage return'' terminates your command, and
prompts
.Ma
to evaluate your expression, simplify it, and display the result.
The character ``$'' may also be used to end a command line, in which
case the result will be computed but not displayed.
.pp
In this case of command c1 above, the evaluation and simplification processes leave the
expression unchanged, and
.Ma
responds with the display below.
.eB
\f(CW
                                          3
(d1)                               (x + 1)

(c2)
\fP
.eE
.pp
Note that the expression is normally printed in a two-dimensional
format with raised superscripts.  This usually makes the expression
easier to understand than a linear format, although as you will see in later displays,
it sometimes requires some effort.
There is a more readable (but slower) typesetting display facility which
requires more a elaborate computer terminal than the usual character-display
type.
.pp
The result is assigned a label \f(CWd1\fP which may be used
in subsequent commands. An important observation: the system is assigning
values to the names \f(CWc1\fP, \f(CWd1\fP, etc.  You should avoid using these same names
for other purposes in your computations.
.pp
If you choose to leave
.Ma
at this point, or any time a \f(CWc-line\fP prompt appears, type \f(CW quit();\fP.
If you wish to stop in the midst of a computation and quit in a less orderly fashion, type
<control>-z (that's one character), to get back to the UNIX shell, and \f(CW kill % \fP.
.pp
After the display,
.Ma
prompts you with the next line label, \f(CWc2\fP.
.sh 2 Your\ Next\ Command
.pp
One of the many commands available in 
.Ma
is the \f(CWexpand\fP command, which converts an expression to
an mathematically equivalent one, but with certain changes in the form.
Most commands have the form of a ``function'' being applied to
some arguments.  In this case, the expression labelled \f(CWd1\fP above
is the single argument to \f(CWexpand\fP.
.eB
\f(CW
(c2) expand(d1);
                               3      2
(d2)                          x  + 3 x  + 3 x + 1
\fP
.eE
.sh 2 Typing\ Errors
.pp
Before getting too involved, you should realize
that if you make a mistake in typing, you can delete erroneous
characters by using your standard UNIX erase, kill, word-kill, etc. characters.
(Typically these are backspace, control-U, control-W, respectively)
If you wish to delete all lines of a multi-line command, typing ??
will give you a freshly re-typed line label.
.pp
If you make a mistake but 
type the semi-colon and return before you notice,
the system will provide a message:
.eB
\f(CW
(c2) expand((d1);

expand (( d1) ***$***
syntax error
please rephrase or edit.
(c2)
\fP
.eE
If you are a novice at using the computer, you should probably
retype the expression.  Editing involves the use of one of the system
text editors, and is described in the manual.
.sh 2 More\ Commands
.pp
Let us consider a few additional commands and facilities.
To differentiate an expression, use the \f(CWdiff\fP command.
\f(CWDiff(expr,var)\fP differentiates an expression with respect to
the variable \f(CWvar\fP. 
.eB
\f(CW
(c3) sin(x)*cos(x);
(d3)                             cos(x) sin(x)

(c4) diff(%,x);
                                  2         2
(d4)                           cos (x) - sin (x)
\fP
.eE
.pp
Note the use of the symbol \f(CW%\fP in line \f(CWc4\fP.  This symbol is a shorthand
for 
the previous expression computed, which in this case is \f(CWd3.\fP
.pp
To differentiate an expression twice, use \f(CWdiff(expr,var,2)\fP.
.eB
\f(CW
(c5) diff(d3,x,2);
(d5)                           - 4 cos(x) sin(x)
\fP
.eE
The concept of differentiation is actually a good deal more general than is
illustrated by this example.  Application of the chain rule is generally supported, and
a large repertoire of built-in functions and operations are provided.
.sh 2 Substitution
.pp
There are a number of ways of producing a new expression from an
old one by substitution.
For example, to substitute @x sup 2 @ for every occurrence of @z@ in
the expression @ z e sup z @ you could type
.eB
\f(CW
(c6) z*%e**z;
                                         z
(d6)                                 z %e

(c7) d6,z=x**2;
                                          2
                                     2   x
(d7)                                x  %e
\fP
.eE
In
.Ma ,
the base of the natural logarithms is written \f(CW%e\fP, to distinguish it from
a simple variable named \f(CWe\fP.
@ sqrt -1 @ is written as \f(CW%i\fP and @pi @ is written \f(CW%pi.\fP
.pp
An alternative syntax for exactly the same command as that on line \f(CWc7\fP is
to explicitly invoke the \f(CWev\fP command (for evaluation in a context
where @ z = x sup 2 @ ).
.Eb
\f(CW
(c8) ev(d6,z=x**2);
                                          2
                                     2   x
(d8)                                x  %e
\fP
.eE
.pp
The \f(CWev\fP command has more elaborate options and uses.  \f(CWEv\fP
``evaluates'' the first expression (leftmost argument)
in an environment specified
by the additional expressions which are either equations
as shown above, or built-in ``switches'' which control
.Ma .
.pp
An equivalent command in this particular case, is \f(CWsubstitute\fP,
which is limited to the simpler semantics we use.  You can abbreviate
the command as \f(CWsubst\fP: 
.eB
\f(CW
(c9) subst(x**2,z,d6);
                                          2
                                     2   x
(d9)                                x  %e
\fP
.eE
Note the order of arguments to \f(CWsubstitute\fP: substitute \f(CWa\fP for \f(CWb\fP in \f(CWc\fP
is written \f(CWsubst(a,b,c);\fP.
.sh 2 Assignments
.pp
Although some very sophisticated linguistic facilities 
are available in
.Ma ,
we will describe only a few of the basic features in this chapter.
Assignment is very familiar to programmers, and associates a ``value''
with a name.
.pp
To assign a value
to a variable, used a colon (:) as follows:
.eB
\f(CW
(c10) a:%;
                                          2
                                     2   x
(d10)                               x  %e

(c11) a+1;
                                        2
                                   2   x
(d11)                             x  %e   + 1
\fP
.eE
.pp
Many users are surprised when such values are
used when they themselves have forgotten the existence of such
assignments and reuse the same name as an ``indeterminate''.
To ``unassign'' a value from \f(CWa\fP, say:
.eB
\f(CW
(c12) kill(a);
(d12)                                done
\fP
.eE
Now if you ask for the value of \f(CWa\fP, you get:
.eB
\f(CW
(c13) a;
(d13)                                  a
\fP
.eE
.sh 2 Defining\ Functions
.pp
The process of function definition is similar to assignment, but associates
``parameters'' or ``arguments'' with the name, and associates
a computation with the use of the name: the value which is produced is
basically the result of substituting values with names in
the associated expression.
For example,
to define a function @f ( z )@ which will be, essentially, a short-hand for
@sin sup 2 z + 1 @ you use ``:='' as follows:
.eB
\f(CW
(c14) f(z) := sin(z)**2+1;
                                         2
(d14)                         f(z) := sin (z) + 1

(c15) f(x+1);
                                   2
(d15)                           sin (x + 1) + 1
\fP
.eE
It is possible to define functions which use any of
the built-in
.Ma
commands, or use user-defined functions.
Although we have illustrated only a few simple built-in commands,
.Ma
provides you with a
complete programming language. 
This may not be a comfort to you if you are totally unfamiliar with
programming, but if you want to use 
.Ma
for elaborate processing of mathematical equations or data,
you may have to learn some of this.  
If you have some familiarity with some conventional programming
languages, you may be pleasantly surprised by the additional
generality afforded by ``symbolic'' computation.
Further on in this primer
we give some examples of the language of
.Ma .
.pp
If you type a command such as \f(CWg(z)\fP, where \f(CWg\f(CW is otherwise
undefined, 
.Ma
will treat it as an ``unknown'' function, similar to an indeterminate.
.sh 2 Equations,\ Parts,\ and\ Solve
.pp
Sometimes it is convenient to compute with equations in
.Ma .
An equation is not the same as an assignment, a function definition, or
a test for equality.  Some programming languages overuse the symbol
``='' for some of these, but
.Ma 
does not.
In
.Ma , 
an equation is just an expression containing two subexpressions separated
by an ``=''.
Certain simplification and evaluation operations are defined
to work in (usually) conventional ways on equations,
as illustrated below.  Line \f(CWc16\fP
shows how to type in an equation.
.eB
\f(CW
(c16) x**2+2*x=y**2;
                                  2          2
(d16)                            x  + 2 x = y
(c17) d16+1;
                              2              2
(d17)                        x  + 2 x + 1 = y  + 1
\fP
.eE
The left-hand-side of an equation can be selected with the \f(CWlhs\fP command,
or by the more general \f(CWpart\fP command which can be used to pick apart
expressions such as sums, products, etc.
.eB
\f(CW
(c18) lhs(%);
                                  2
(d18)                            x  + 2 x + 1

(c19) part(d17,2);
                                     2
(d19)                               y  + 1

(c20) part(%,1);
                                       2
(d20)                                 y

\fP
.eE
To save typing, the same result as \f(CWd20\fP could have been obtained from 
\f(CWpart(part(d17,2),1)\fP or even more simply, \f(CWpart(d17,2,1)\fP.
.pp
Equations are used by some commands, and are, for example,
used by the \f(CWsolve\fP command. They are returned in a \f(CWlist\fP, that
is, a sequence separated by commas and enclosed in square brackets:
.eB
\f(CW
(c21) x**2-1;
                                     2
(d21)                               x  - 1

(c22) solve(%,x);
(d22)                          [x = - 1, x = 1]
\fP
.eE
Notice the way the list of the two solutions is displayed.  We can substitute
the first of the two answers in \f(CWd21\fP, and evaluate:
.eB
\f(CW
(c23) d21,part(%,1);
(d23)                                  0
\fP
.eE
.sh 2 Sums,\ Programs,\ Ev\ revisited
.pp
The sum of the first five positive integers, squared, can be computed by:
.eB
\f(CW
(c24) sum(i**2,i,1,5);
(d24)                                 55
\fP
.eE
Another way of providing a similar result by writing a small program,
is to use a \f(CWfor\fP statement.
.eB
\f(CW
(c25) for i:1 step 1 thru 5 do s:s+i**2 ;
(d25)                                done
\fP
.eE
The result is stored as the value of the variable \f(CWs\fP.  If \f(CWs\fP had been 0
previously, the current value of \f(CWs\fP would be 55.  Actually,
.eB
\f(CW
(c26) s;
(d26)                               s + 55
\fP
.eE
This reflects the fact that the value of \f(CWs\fP initially was just \f(CWs\fP.
We can, of course, substitute 0 for the original value:
.eB
\f(CW
(c27) %,s=0;
(d27)                                 55
\fP
.eE
Note that this substitution does not affect the value of \f(CWs\fP. It just
sets \f(CWd27\fP to 55.
A more mysterious case is to see what happens
if we type
.eB
\f(CW
(c28) ev(s+55);
(d28)                               s + 165
\fP
.eE
[explanation: if we had typed merely s+55, it would
evaluate to  (s+55)+55, or s+110.  But \f(CWev\fP evaluates
``once more'' to get (s+55)+110.  \f(CWEv\fP is a puzzle and an addiction.]
.pp
In spite of the previous example,
summations are not \f(CWreally\fP the same as the programming languages' ``for loops''. Sometimes summations
are merely placeholders for computations which for one reason or another
cannot be done.
This is an example:
.eB
\f(CW
(c29) 'sum(g(i),i,0,n);
                                   n
                                  ====
                                  \e
(d29)                              >    g(i)
                                  /
                                  ====
                                  i = 0
\fP
.eE
There are three reasons for this summation to be returned ``unsummed''. We have
not provided a ``function definition'' for \f(CWg\fP; the variable
\f(CWn\fP is not some
fixed integer value; and finally the
``quote'' symbol or apostrophe (') to the left of the \f(CWsum\fP on line \f(CWc29\fP
inhibits evaluation.
The effect of the quote is, in most circumstances the prevention of
evaluation.  Sometimes
.Ma
can deduce the value of a summation in closed form even though it
cannot be evaluated, because of built-in simplification capabilities.
Some summations can, for example,
be solved by a fairly general procedure analogous
to symbolic integration.
.pp
In
.Ma
a distinction is sometimes
drawn between ``noun'' and ``verb'' forms of commands.
Most functions are ``verbs'' in that they will be evaluated ``away'' in
an effort to eliminate them from expressions.
To prevent such evaluation, the ``quote'' illustrated
above can generally be
used.  Some functions are nouns or verbs depending upon context such as the nature of
their arguments. The trigonometric functions are this way, being nouns
if they are given integer arguments, but verbs if they are given
floating-point arguments, or \f(CWev\fP'd with the \f(CWnumer\fP option set:
.eB
\f(CW
(c30) sin(1);
(d30)                               sin(1)

(c31) sin(1),numer;
(d31)                         0.8414709848078965
\fP
.eE
Floating-point numbers are carried to double precision.
There is also an implementation of higher (arbitrarily higher!) precision ``bigfloats'' available
and described in the manual.
.sh 2 More\ Expansion
.pp
Let us return to our very first example of a command,
and provide some more details and techniques for expansion, or
application of the distributive law of multiplication.  In some
computations where an indeterminate represents a quantity of small magnitude,
you might wish to automatically drop higher-degree terms from an expansion.
In some cases you might wish to drop terms in several variables, e.g.
all terms in @q@ with exponent
greater than 7, and terms in @p@ with exponent greater than 4, or
terms of @p sup n @ and @q sup m @ combined so that their ``weight'' @2 n + m@
exceeds 7.  This sequence of commands does that:
.eB
\f(CW
(c32) ratwtlvl:7$

(c33) ratweight(q,1,p,2);
(d33)                            [q, 1, p, 2]

(c34) ratexpand((p+q+1)^8);

         7       6          5       5          4       4        2  3          3
(d34) 8 q  + 28 q  + 168 p q  + 56 q  + 280 p q  + 70 q  + 560 p  q  + 280 p q

       3        2  2          2       2        3          2
 + 56 q  + 420 p  q  + 168 p q  + 28 q  + 280 p  q + 168 p  q + 56 p q + 8 q

       3       2
 + 56 p  + 28 p  + 8 p + 1

\fP
.eE
The ``rats'' appearing in the command names
here are an indication that the commands use something called
``canonical RATional expression form'',
an efficient form used for dealing with polynomials and ratios of
polynomials. We have also used ``^'' instead of ``**'' (the two notations
are interchangeable
in 
.Ma .)
We will return to representation issue shortly.
.sh 2 Integration
.pp
One of
.Ma 's
flashiest features is its ability to compute symbolic indefinite
integrals:
.eB
\f(CW
(c35) x/(x^3+1);
                                      x
(d35)                               ------
                                     3
                                    x  + 1

(c36) integrate(%,x);
                                        2 x - 1
                      2            atan(-------)
                 log(x  - x + 1)        sqrt(3)    log(x + 1)
(d36)            --------------- + ------------- - ----------
                        6             sqrt(3)          3
\fP
.eE
To check the solution, we can differentiate.
.eB
\f(CW
(c37) diff(%,x);
                        2               2 x - 1           1
(d37)           ------------------ + -------------- - ---------
                            2            2            3 (x + 1)
                   (2 x - 1)         6 (x  - x + 1)
                3 (---------- + 1)
                       3
\fP
.eE
A more satisfactory form would result if the terms were expanded and
the sum put over a common denominator.  By converting this result to
a canonical rational form (the same form used for the previous RAT commands)
the expression is simplified. The \f(CWratsimp\fP command does this:
.eB
\f(CW
(c38) ratsimp(%);
                                      x
(d38)                               ------
                                     3
                                    x  + 1
\fP
.eE
.sh 2 Representation\ and\ Simplification
.pp
The multiplicity of representations illustrated by lines d38 and d37 constitute
an important feature of
.Ma .
It is not always so clear which command will produce the most appealing
form of an expression.  \f(CWRatsimp\fP, which did such a fine job above,
would produce a huge expression if applied to @ (x + 5) sup 100 @, since
it multiplies through all those terms.
.pp
The correct choice of representation is often the key to solving
challenging problems.
.pp
The \f(CWfactor\fP command is another way of changing representation,
illustrated below.
.eB
\f(CW
(c39) factor(x^12+1);
                              4        8    4
(d39)                       (x  + 1) (x  - x  + 1)
\fP
.eE
.pp
\f(CWFactor\fP finds exact integral factors, not approximate zeros, and is
thus qualitatively different from numerical root-finders.  It is generally
much slower than numerical routines, but gives a different type of answer, as
illustrated above.  If your system has a numerical program library for
zero finding, it can probably be connected to
.Ma .
For example,
on VAX systems licensed to use the IMSL library, a routine called \f(CWzrpoly\fP
is available, which finds approximate zeros for real polynomials. 
.pp
\f(CWFactor\fP and \f(CWintegrate\fP are probably two of the more surprising
commands in
.Ma
because most people who understand the problems involved
are not familiar with general algorithms for solving them.
There \f(CWare\fP general algorithms for these problems, although the
algorithm for integration sometimes indicates that the answer does
not exist in terms of elementary functions.
When a general solution to a problem is not available, or even when
it is known but inefficient, it is
sometimes possible to simulate a good
solution method by ``pattern recognition'': that is,
by recognizing those cases that can be solved, and providing the answers,
without dealing with the complete problem.  Many user programs, and
a few built-in
.Ma
facilities use this approach.
.pp
\f(CWFactor\fP, and indeed many of the commands illustrated above, are used
internally by
.Ma
for its own more complicated
algorithms.  For example, \f(CWsolve\fP uses \f(CWfactor\fP  and other routines
on polynomial problems.
.sh 2 Limitations
.pp
You should realize that an algebraic manipulation system like
.Ma
cannot solve all symbolic problems.
.ip
There are times when
\f(CWsolve\fP or \f(CWintegrate\fP or other commands will determine that
there are no closed-form solutions to the problem posed (in which case
they will generally inform you of the situation).
.ip
There are other instances
in which the solution method may be known in principal, but because
the calculations are so onerous, the computer seems unlikely to finish
in a reasonable time.  Algebraic computations are often subject
to ``intermediate expression swell'' where (even though the final answer
may be small -- perhaps 0), the route to the answer is difficult.
.ip
Occasionally you may run out of memory space.  A clever
computer system administrator change the program
and operating system parameters to your benefit, but it is more
likely that you could
try to rearrange your computations.
.pp
Just because it is possible to type a command in a syntactically
satisfactory manner does not mean that the required computation
is easy or even feasible.  Once a computation
has started, you may have second thoughts
about allowing it to finish.  Hence you might be concerned with the
information in
the next section:
.sh 2 Stopping
.pp
You may, from time to time, get your system running on a fool's errand.  How do
you bring it to its senses?
.pp
There are several related notions of running uncontrollably.  If the output is streaming past you
at too high a speed to read, (this is unlikely to happen on a slow
printing terminal, but might happen on a display terminal) you
can make the system pause by typing <control>-S (that's done by holding
the control key down and typing S. We usually write this as ^S),
 which is the default
``X-off'' character.  Normally, no output gets lost, but transmission is
temporarily
halted.  You can resume the display by typing <control>-Q (or ``X-on'').
.pp
Sometimes you want to halt computation, not just
printing. You have an interrupt character,
usually <rubout> or ^C,
which you have chosen as your standard in your UNIX operating system shell.
If you wish to halt a computation,
you can type this interrupt character one, two, or three times.
.LP
The first character will cause an interrupt at the next
available clean place in your
computation. (Technically, this would be
at the interface between some compiled and some interpreted code).
If the interrupt does not happen promptly
enough for you, you may type the interrupt character a second
time. (Technically speaking, this will snap
``transfer links'' which are used when compiled code calls compiled
code, and then cause an
interrupt at the next such function-call.)
It is possible to be caught in a very tight loop in which there are
no function calls, 
in which case the third typing of the interrupt character will stop the computation
\f(CWcold\fP.
Even using this drastic interrupt,
you will generally
be able to avail yourself of any of several alternatives.
.lp
When the system stops, it will type
.eB
\f(CW
 Interrupt (type h for help):
\fP
.eE
.lp
You can then type one of several atoms:
.ip q
Just quit out of the interrupt and continue the computation
(after displaying the time if \f(CW showtime \fP was set to \f(CWtrue \fP or \f(CW all.\fP);
.ip r
Reset the computation to the top-level of 
.Ma ,
.ip exit
Exit from 
.Ma ,
.ip l
Enter a LISP break, (something a LISP expert might want to do: LISP,
an acronym for LISt Processing Language, is the computer language
in which
.Ma
is implemented.),
.ip m
Enter a 
.Ma -break.
This gives you a kind of 
.Ma -subprocess
within your running program, which you can use to inquire about variables,
resetting things, etc.  You exit by typing \f(CWexit;\fP which returns you
to your previous computation.
.ip h
Type a menu of options. Basically what you see above.
.pp
It is also possible to quit temporarily out of your job by typing ^Z.
See your UNIX manual for details on job control, background jobs, and
similar issues.  Some people, in desperation, hang up their telephone.
This might work, assuming you are connected to the computer that way.
Turning the
power off on a hard-wired terminal usually does not work.
.sh 2 Out\ of\ Core?
.pp
In the 4BSD UNIX system, the message 'killed' or 'out of core' immediately
after the starting of a vaxima means that there is currently insufficient free space on
the swapping device to run 
.Ma .
This can happen with any job, but is perhaps more likely to happen
with
.Ma
because of its size.  This situation is
system-load dependent and swap-space dependent: when the load decreases, try again.
.sh 2 Quitting
.pp
If you wish to exit from 
.Ma ,
in an orderly fashion, removing the quiescent job, 
returning control to the shell (or whatever invoked
.Ma ),
you can do this by typing the command \f(CWexit();\fP
.sh 2 Storage\ Allocation\ and\ Timing
.pp
If you run
.Ma 
for long enough, and especially if you set up a
long computation, you will see strange messages like the
two below:
.eB
\f(CW
[*list:634{22%}; fixnum:43{2%}; ut:0%]
[*list:634{23%}; fixnum:43{2%}; ut:69%]
\fP
.eE
This is caused by a phenomenon known as a ``garbage collection''
(really) which is part of the underlying LISP language system.
This is an activity started up when the computation needs more
free storage. The system then stops doing ``useful'' work, and identifies
objects in memory which are no longer needed.  This takes a few
seconds of computer time (maybe 2),
which under heavy load may take a half-minute of real time.
.pp
A message occurs after each garbage collection. You cannot really stop
the garbage collector,
but you can stop
the message from printing out by setting \f(CWgcprint : false \fP.
You may think you don't want to see this information, but it is actually
reassuring to know that your program \f(CWis\fP running sometimes, even
though it is printing nothing but ``gc'' messages.
.pp
Programs which may have run out of storage on other version of
.Ma
may run successfully on the VAX. However, the address space
available to a user is in practice restricted by operating
system constraints, some of which have been incorporated as
parameters in the LISP system.  An error message which declares
``Attempt to allocate beyond static structures'' indicates that
you will have to have a reconfigured LISP system to grow larger.
You should save
your computation and ask your system administration or
manager to make a larger LISP system and 
.Ma .
This
takes about 3 or 4 minutes of computation, but requires
familiarity with the instructions for generating a system.
Since the current allocation is
really fairly large, you should also take this opportunity
to see if you really want to continue with the computation.  Large
jobs in most time-sharing systems,
tend to be more burdensome than small ones, even those running for longer
periods of time.
.pp
It is possible to fiddle with various allocations to attempt to
decrease the number of garbage collections in a system which you
suspect will require large amounts of a particular kind of
space.  The command
\f(CWalloc(<spacetype>,<numberofpages>)\fP allocates
some number of pages.
Spacetypes include  \f(CWlist, bignum, fixnum, flonum, array \fP and
a few others. 
Most
.Ma
computations use
.i list 
cells predominantly.
See the Franz LISP manual for more details.
.pp
The message ``[fasl hole filled up]''  which you may provoke by using
the \f(CWfasl\fP or \f(CWload\fP program, is merely informative, and is not an indication
of trouble.
.pp
If the 
.Ma
variable 
\f(CW gcprint \fP
is set to a non-false value then
after each garbage collection a summary of current memory allocation
will be printed out in this form: [*list:634{87%}; fixnum:23{27%}; ut:87%].
The meaning of this is that after garbage collection and subsequent
allocation of new data space, there are 634 (512 byte) pages of list data and
23 pages of fixnum data. 87% of the list space is used and 27% of the fixnum
space is used.  The * before list indicates that it was list space which ran
out and caused the garbage collection. The ut indicates the percentage
of time utilized in non-garbage collection mode.  The first time the
message is printed, this item will be 0% because 
various counters must be initialized. The allocation of storage is
automatic; you will never be asked to make a decision about which data
space to allocate, although a low utilization measure is an indication
that automatic allocation is not working appropriately for your problem,
and various parameters can be fiddled with via \f(CWalloc\fP.
.pp
You
can also get brief information about the time taken by each command
by setting \f(CW showtime : all\fP. The ``garbage collection'' or ``gc'' time is indicated separately,
because it happens asynchronously and it seems unfair to penalize a
particular (perhaps millisecond) operation for the fact that it
was the unlucky one to trigger a ``gc''.


.ce
\f(CWIntermission. Take a break.\fP

.pp
In the next two sections
of the primer we introduce a number of facilities in 
.Ma
useful in dealing with trigonometric functions. A section on rule-directed
transformations follows, since our favorite examples are
trigonometry simplifications.
.sh 2 Operations\ with\ Trigonometric\ Forms
.pp
Consider the expression @ cos sup 2 x - sin sup 2 x @.
.eB
\f(CW
(c40) cos(x)^2-sin(x)^2;
                               2         2 
(d40)                       cos (x) - sin (x)
\fP
.eE
.pp
To evaluate the last expression at a point, say
@pi / 3 @, you can use the \f(CWev\fP command:
.eB
\f(CW
(c41)ev(%,x=%pi/3)
                                     1
(d41)                              - -
                                     2
\fP
.eE
.pp 
The value of @1 / 2 @ was obtained not by computing @ pi / 3 @
numerically and approximating the value of @sin@ at that point, but
by a routine which provides simplification of special values of
trigonometric functions at points @ n pi / m @, where 
@m@ = 1,2,3,4,6 and @n@ is an integer.
To obtain a 
real approximation, we could use \f(CWnumer, \fP
as illustrated previously.
.pp
Of course
.Ma
is able to differentiate expressions
involving trigonometric functions, also as illustrated previously.
.eB
\f(CW
(c42) diff(d40,x);
(d42)                        - 4 cos(x) sin(x)
\fP
.eE
and knows how to integrate them.
.eB
\f(CW
(c43) integrate(d40,x);

                       sin(2 x)           sin(2 x)
                       -------- + x   x - --------
                          2                  2
(d43)                  ------------ - ------------
                            2              2
\fP
.eE
This result is less than satisfactory. See what we can do:
.eB
\f(CW
(c44) expand(%);
                                 sin(2 x)
(d44)                            --------
                                    2
\fP
.eE
.sh 2 Trigonometric\ Re-representations\ and\ Identities
.pp
There are a number of identity transformations specifically oriented
to trigonometric forms. Whether these produce simpler or more
complex expressions depends on the expressions they are used upon,
and sometimes is a matter of opinion.
.Ma
can convert trigonometric functions with
argument @nx@, @n@ an integer, to trigonometric functions in @x@.
You use \f(CWtrigexpand\fP
for this transformation:
.eB
\f(CW
(c45) trigexpand(%);

(d45)                          cos(x) sin(x)
\fP
.eE
.pp
Another operation named
\f(CWtrigreduce\fP
performs a related, almost ``inverse'' transformation,
that of converting products of
powers of trigonometric functions to functions with multiple
angles. 
.eB
\f(CW
(c46) trigreduce(%);

                                 sin(2 x)
(d46)                            --------
                                    2
\fP
.eE
.pp
Sometimes you wish to convert all trigonometric
functions to exponentials with complex arguments.  With the
flag 
\f(CWexponentialize\fP set to \f(CWtrue \fP you can perform
this transformation:
.eB
\f(CW
(c47) exponentialize:true$

(c48) sin(x);

                                 %i x     - %i x
                           %i (%e     - %e      )
(d48)                    - ----------------------
                                     2
\fP
.eE
.pp
In order to convert back to trigonometric functions you can use
\f(CW realpart.\fP
First we must turn off the exponentialize flag.
.eB
\f(CW
(c49) exponentialize:false$

(c50) realpart(d48);

(d50)                             sin(x)
\fP
.eE
.pp
Exponentials with complex arguments of the form
@n i pi / m , ~~~m = 1,2,3,4,6@, @n@  an integer, will be transformed
to algebraic numbers if the flag\f(CW %emode\fP is set to 
\f(CWtrue.\fP
.eB
\f(CW
(c51) %emode:true$

(c52) d50,x=%pi;
(d52)                                0
\fP
.eE
.pp
Before continuing, let's reset that flag.
.eB
\f(CW
(c53) %emode:false$
\fP
.eE
.pp
A very powerful technique for approximation of analytic functions
is the use of
truncated Taylor series (more generally, Laurent
series).
.Ma
provides a command for the computation of these approximations, as
illustrated below:
.eB
\f(CW
(c54) taylor(sin(x)/x,x,0,4);

                                  2    4
                                 x    x
(d54)/t/                     1 - -- + --- + . . .
                                 6    120
\fP
.eE
This is a Taylor series in @x@ about
@x=0@ up to the 4th power.  Observe that the display
has
some unusual features: the terms are ordered in reverse of
the conventional (non-series) display, there is a \f(CW/t/ \fP mark near the
label, and the ellipsis (. . .) is printed to the right to indicate
truncation of other terms.
Taylor series are a separate representation of expressions in
.Ma .
Recall that we have
encountered the ``rational'' representation
used internally by commands like \f(CWratsimp, factor,\fP and sometimes in
\f(CWintegrate. \fP
This form can also be directly provided in answers from
some commands. All along we have been seeing
a ``usual'' or ``general'' representation in our interactions.
Thus we have already seen evidence of three representations. Many of
.Ma 's
most powerful commands for simplification
are essentially switching between representations.
There are a few more representations in the system directly
accessible by the user such as 
``Poisson'' series, used in celestial mechanics; there are a
number of additional alternative representations used, but
away from the user's sight.
.sh 2 Rules
.pp
It is handy to have a facility 
for applying identities or side relations.
The prototypical one is
@ sin sup 2 x ~+~ cos sup 2 x ~ -> ~ 1 @ .
There are a number of ways of
achieving the effect of such a rule.  The simplest is
substitution.  Let us recall expression d40.
.eB
\f(CW
(c55) d40;
                                2         2
(d55)                        cos (x) - sin (x)

(c56) %,sin(x)^2=1-cos(x)^2;
                                    2
(d56)                          2 cos (x) - 1
\fP
.eE
        The same effect could have been achieved by using
\f(CWsubstitute(1-cos(x)^2,sin(x)^2,%).\fP
.pp
To continue with the same prototypical rule,
often one wishes to recognize that @sin sup 4 x @ can be
transformed using the same rule.  For this one needs the
added power of 
\f(CWratsubst.\fP
.eB
\f(CW
(c57) ratsubst(1-cos(x)^2,sin(x)^2,sin(x)^4);

                             4           2
(d57)                     cos (x) - 2 cos (x) + 1
\fP
.eE
.pp
In general \f(CWratsubst\fP will perform a \f(CWratsimp\fP
(and thus an expansion) as well as apply the substitution.
.pp
When performing calculations repeatedly, you may wish
to apply a substitution rule whenever possible.  You can have an
``automatic'' facility, although not the full power of a
\f(CWratsubst\fP command by using a \f(CWtellsimp\fP rule.
.eB
\f(CW
(c58) tellsimp(sin(x)^2,1-cos(x)^2)$

(c59) (sin(x)+1)^2;
                                           2
(d59)                          (sin(x) + 1)

(c60) expand(%);
                                        2
(d60)                     2 sin(x) - cos (x) + 2

(c61) sin(x)^2;
                                       2
(c61)                           1 - cos (x)
\fP
.eE
.pp
You can ``tell the simplifier''
a more general rule which will convert @ sin sup 2 a @ to
@ 1 - cos sup 2 a @ for any @a@ using a
declaration:
.eB
\f(CW
(c62) matchdeclare(a,true)$

(c63) tellsimp(sin(a)^2,1-cos(a)^2)$

(c64) sin(y)^2;

                                       2
(d64)                           1 - cos (y)
\fP
.eE
.pp
You should understand that the existence of such
rules generally slows down the simplification of expressions with the same
``main operator'' as the 
\f(CWtellsimp\fP
rules.  In this
case the main operator is ``^''.
.pp
Another rule-defining mechanism,
\f(CWlet\fP
has much of the power
of a 
\f(CWratsubst,\fP
although it will be applied only when using
\f(CWletsimp.\fP
First let us remove the
\f(CWtellsimp\fP
rule.
.eB
\f(CW
(c65) kill(rules)$

(c66) let(sin(a)^2,1-cos(a)^2);

                            2                 2
(d66)                   (sin (a)  -->  1 - cos (a))
\fP
.eE
.pp
Note that @a@ is still declared 
\f(CWtrue\fP
for matching
purposes.  To effect a transformation using the
\f(CWlet\fP rules, whatever their number, you use the \f(CWletsimp\fP
command.
.eB
\f(CW
(c67) sin(x)^4;
                                     4
(d67)                             sin (x)

(c68) letsimp(%);
                             4           2
(d68)                     cos (x) - 2 cos (x) + 1
\fP
.eE
.pp
We have not exhausted 
.Ma
facilities for
dealing with trigonometric functions, or for that matter, its
facilities for defining and applying rules.
.pp
Poisson series, mentioned earlier, deals with a special class of
trigonometric expressions frequently used in celestial
mechanics have a special representation. A program called
\f(CWtrigsimp\fP
may provide appropriate simplifications in a goal-driven fashion
(to make the smallest expression). 
Other ways of defining rules and ``advising'' the simplifier are described
in the
.Ma
manual. 
.Lc Introduction\ to\ MACSYMA\'s\ Programming\ Language 2
.sh 2 Introduction 2 1
.pp
This second chapter of the primer on
.Ma
is intended for readers who are familiar with the basic ideas of
algebraic manipulation from chapter 1,
who know at least one programming language, and who wish to use
.Ma 
for more ambitious tasks than can be handled in a few sequential
commands. If you are familiar with Pascal or Algol 60, you will probably
find this adequate as a programming background. Familiarity with Fortran
or Basic is less useful.
.pp
.Ma 's
user-programming language\**
.(f
\** The system-programming language used for implementing
.Ma ,
namely LISP, is quite different. If you wish to see how
.Ma
was constructed, you need to know LISP to understand the source code.
.)f
is designed to allow you
to define program modules or ``functions'' for algebraic manipulation.
Each module uses zero or more arguments, and returns an
algebraic expression.  Since numbers are special cases
of algebraic expressions,
.Ma 's
user-language
can be used as a numeric language too.  Because the language
is implemented as an interpreter it is usually
more general than compiler-based languages, and also
tends to be rather slow in tight inner loops of simple operations,
by comparison.
It has novel linguistic features, some of which are illustrated below.
.sh 2 Some\ Examples
.pp
\f(CWf1\fP
and
\f(CWf2\fP
defined below, are versions of the ``factorial'' function.   Observe the punctuation
carefully.  Assignment is ``:'', function definition is ``:='', statements
are separated from one another by ``,'' [not
.i terminated 
by commas]. The label ``loop'' is set off by a comma as though it
were a statement too.  We have added indentation to make the programs
conform to what you might expect, but extra spaces and tabs are optional.
There is a conditional execution statement (the \f(CWif\fP) which has
an optional \f(CWelse\fP clause.
.eB
\f(CW
(c1) f1(x):=if x<1 then 1 else x*f1(x-1)$

(c2) f1(5);
(d2)                                  120

(c3) f2(x) := block ([temp],
                temp:1,
		while n > 1 do (
			temp:n*temp,
			n:n-1),   /*end while*/
		temp)$

(c4) f2(5);
(d4)                                  120
\fP
.eE
Observe the simplicity of using
.Ma
compared to, say, Pascal.
There is no
need to write a ``driver'' or main program
with input or output commands.  The input is provide through
function application on an argument, and the output is the displayed value.
.pp
Every command or function in
.Ma
has a value, and may, in addition, have some side-effects, such as the
setting of variables, or the printing of messages.
.pp
The \f(CWblock\fP construction illustrated above
is analogous to a procedure declaration.
The first part of it is a list of local variables, and following
that, expressions which are evaluated in order.
Certain expressions or commands make sense only within a block, not
at 
.Ma 's command level:
these are labels, \f(CWreturn\fPs and \f(CWgo\fPs. The semantics of each
of these
commands conforms to the usual intuitive meaning.  If the last statement
in a \f(CWblock\fP does not cause a transfer of control, and ``execution
falls through the bottom'', the value returned from the 
\f(CW block\fP
is the value of the last expression evaluated.
.sh 2 Unconventional\ Conditionals
.pp
The next example shows a function with a side-effect, but the major
point is to illustrate some subtleties which you may not have thought
about in
conditional statements (\f(CWif-then-else\fP).
.pp
If you were asked, ``Is A greater than B'', it would seem you could respond
either ``yes'' or ``no''. In your conventional programming language, certainly,
that would be a reasonable assumption.  But really, wouldn't it
be appropriate in some circumstances for you to answer, ``How should I know?''?
.pp
That option is preserved in
.Ma .
If the flag \f(CWprederror\fP is set to \f(CWtrue\fP, the default, and if
.Ma
is unable to evaluate a predicate, it signals an error, and unless
directed otherwise, returns control to the top-level
.Ma
command monitor.
However, if the \f(CWprederror\fP flag is \f(CWfalse\fP, execution continues
to the next statement, ignoring both 
\f(CWthen\fP and \f(CW else\fP clauses!
.pp
This is illustrated below:
.eB
\f(CW
(c5) test(x,y):=block([],
        if x > y then print(x, '' is greater than '', y)
                 else print(x, '' is not greater than'', y),
        return(alldone))$

(c6) test(4,3);
4  is greater than  3 
(d6)                                alldone

(c7) test(3,4);
3  is not greater than 4 
(d7)                                alldone

(c8) test(y^2+1,-y);

                                                2
MACSYMA was unable to evaluate the predicate: y  + 1 > - y

(c9) prederror:false$

(c10) test(y^2+1,-y);
(d10)                               alldone
\fP
.eE
Note that no message was printed for line 
\f(CWd10,\fP
but the return value, ``alldone''
was displayed.
.sh 2 Assumptions
.pp
What do YOU think? Is @y sup 2 + 1 ~>~ - y@?  For this question to make sense,
both sides of the inequality must be in the same ordered domain.  We
do not know, offhand, whether @y@ can assume values which are matrices,
complex numbers, sets, or even programs!
.pp
If @y@ were known to be real, or more specifically, positive real, a program
could try some deduction.
.Ma 
has some features of this nature, as illustrated below.
.eB
\f(CW
(c11) assume(y>0);
(d11)                               [y > 0]

(c12) test(y^2+1,-y);
 2
y  + 1  is greater than  - y 
(d12)                               alldone
\fP
.eE
If we wish
.Ma
to forget that assumption,
.eB
\f(CW
(c13) forget(y>0);
(d13)                               [y > 0]
.eE
.sh 2 Arbitrary\ Numbers\ of\ Parameters
.pp
Ambitious packages of programs have been written by many
.Ma
users.
Sometimes the requirement that a command has a fixed number of arguments
causes discomfort.\**
.(f
\** The language Pascal does not allow you to define
a function \f(CWf\fP which can
be used with a variable number of actual parameters, although
the Pascal design includes built-in procedures with variable numbers of
arguments (\f(CWwrite\fP for example).
.)f
It is possible to write a 
.Ma
program which counts the
number of arguments it is given, sets default values for others, and
does any number of clever things. A simple example is shown below. Note
the way the ``left-hand-side'' of the ``:='' is set up.
.eB
\f(CW
(c14) prog3([l]) := block( [],
             print (''l is bound to'', l, '' and l[1] is '',l[1]),
             return(length(l)))$

(c15) prog3(a,b,c,d);
l is bound to [a, b, c, d]  and l[1] is  a 
(d15)                                  4

(c16) prog3(a,b);
l is bound to [a, b]  and l[1] is  a 
(d16)                                  2
\fP
.eE
.sh 2 Arrays
.pp
Arrays are a useful data structure, and are provided in most
programming languages. 
.Ma
provides arrays, but does not require that they be declared, or that
they have numeric (integer) index-sets.
Rather than writing a program to fill up an array and then iterating
through all elements, sometimes it is easier to describe a program
to generate elements as they are called for.  Such array-associated
functions are often quite convenient.  The usual
way you set them up is to provide specific values for certain
index values, and then let others be assigned as needed.  Note carefully
the use of ``:='' and ``:''.
.eB
\f(CW
(c17) a[4]:4*u;
(d17)                                 4 u

(c18) a[22/7]:%pi;
(d18)                                 %pi

(c19) a[x]:mystery;
(d19)                               mystery

(c20) a[h]:=cos(h);
(d20)                            a  := cos(h)
                                  h

(c21) a[3];
(d21)                               cos(3)

(c22) a[x+1];
(d22)                             cos(x + 1)
\fP
.eE
You might wonder what the value of @a@ is, after all this.  Most
disappointing:
.eB
\f(CW
(c23) a;
(d23)                                  a
\fP
.eE
The information that you are after is available this way:
.eB
\f(CW
(c24) arrayinfo(a);
                                     22
(d24)              [hashed, 1, [3], [--], [4], [x], [x + 1]]
                                      7
\fP
.eE
The list of information supplied indicates several aspects
of the array.  It is
``hashed'': uses the data-structure of a hash-table for storage
(this is a common encoding trick discussed in data structure texts).
The number of subscripts is 1. The specific indexes for which it has
recorded values are listed.  The array-associated function defined
on line
\f(CWc20\fP
can be displayed
by \f(CWdispfun\fP.
.sh 2 Iteration
.pp
``For'' loops provide the major iteration facility in
.Ma .
Three examples which illustrate variants of this are the factorial
functions below:
.eB
\f(CW
(c25) f3(n) := block([temp],
		temp:1,
		for i:1 thru n do temp : temp*i,
		return(temp))$

(c26) f4(n) := block([temp],
		temp:1,
		for i:n step -1 thru 1 do temp : temp*i,
		return(temp))$

(c27) f5(n) := block([temp],
		temp:1,
		for i:n unless i <= 1 do (temp : temp*i , i:i-2),
		return(temp))$
\fP
.eE
Decrementing @i@ by 2 in the previous program was needed because the default
step size of 1 is added to @i@ each time through. \f(CWF5\fP is certainly
a perverse program.
Incidentally, \f(CWreturn\fPs from within a \f(CWfor\fP exit from the loop, and not from
the enclosing 
\f(CWblock.\fP
It is important to
note that one can group a collection of statement to be ``done'' together
with parentheses, as illustrated in
\f(CWf5.\fP
.sh 2 Serious\ Business
.pp
Most serious users of
.Ma
find that they are repeatedly using the same programs, and need to
save them for another day.  Some users also find they rarely get
the programs or the data quite right the first time, and would rather
type these things in to a text editor, and have
.Ma
gobble the text up from a file rather than the keyboard.
Publication quality programs require comments and other features you
are unlikely to want to type into
.Ma
interactively.
.pp
Some people perfect a function or get an algebraic
expression correct by typing definitions and commands into a file,
say, \f(CWnewstuff\fP, using an editor such as  \f(CWed, ex, vi, \fP or \f(CWemacs\fP
and then within
.Ma
type \f(CWbatch(newstuff);\fP.  If your file-name has funny characters
like periods or slashes, you must use quotes. For example, \f(CWbatch("/usr/mac/demo.begin")\fP.
.pp
.Ma
then reads the statements the file, assigning labels etc., and if there are syntax
or other errors, prompts for help from the keyboard.  If you want it
to continue on to the next line after an error, type \f(CWbatcon(true);\fP .
.pp
Reading very large text files of programs and data can be slow using
\f(CWbatch\fP, and if
you are not changing the text, you might prefer saving your environment
in another way.
You can use \f(CWsave(savedstuff,all);\fP to save every named or labelled
object in a
.Ma
system, on the file 
\f(CWsavedstuff\fP
in your working directory.  (You had
better have write-permission or you'll get an error message.)  Another
time you can start up from where you left off by typing
\f(CWloadfile(savedstuff);\fP
into a fresh
.Ma .
You can load several saved files into a single system. Naturally if the
files contain items with identical names, there is a potential for
conflict. These will be resolved in favor of the last item read in.
.pp
If you want to save only some material you have produced, say only the
functions defined and the values of variables x, y, and z, you can type 
\f(CWsave(savfunxyz,functions,x,y,z);\fP
.pp
A neat way to save a useful section of your environment is
to (carefully) use \f(CWkill\fP to remove useless
items first, and
then save \f(CWall\fP that is left.  Doing \f(CWkill(labels,...)\fP
after first making sure that any useful result also has a name
other than a c or d-label is sometimes a good start.  You generally
should not save every computation, since disk space is not
infinite.
.sh 2 Hardcopy
.pp
If you print out the files produced by \f(CWsave\fP to show to your
colleagues who are as yet unconvinced of the merits of
.Ma ,
you will be disappointed.  While such files are ``ASCII'' character
text, they do not make easy reading for persons uninitiated in various
arcane matters.
.pp
What you might want to do, then, is store human-readable versions of
your output on a file.  This is especially useful if you have a
display terminal, or a slow hardcopy printer.
.Ma
provides a way of opening a file for echoing both input and output of
the system.
The command
\f(CWwritefile(fn);\fP
where fn is a filename, starts the echoing, and
\f(CWclosefile();\fP
stops the echoing.
If you want the output to be human-readable after being run through
a typesetting program (eqn + troff in UNIX), you can experiment with
the output produced by setting \f(CWtypeset : true \fP.
(Suggestion: \f(CWgcprint : false\fP is a good idea.)

.sh 2 Return\ to\ Arrays\ and\ Functions
.pp
.Ma 
provides a fascinating trick: arrays of functions. Imagine an array, each
of whose elements is a function.  For example, Legendre polynomials have
an index, and an argument.  Thus we can refer to @ P sub 4 ( z sup 2 )@.
Just as arrays can
have an associated function, function-arrays can have such an associated
function.
.pp
Because we like to show off occasionally, and typesetting
can be done by the VAX
.Ma
system, we illustrate
this feature here.
This was produced by saving output in a file
and running it through ``troff'' ( \fIT\dE\uX\fP may be an alternative
at some time).

(c28) p[n](x):=ratsimp(1/(2^n*n!)*diff((x^2-1)^n,x,n));

.EQ I (d28) 
 p   sub  n   [ x ] ~:=~ "ratsimp"   ( 1 over  {  2 sup  n  \^   n !
  }   \^  {  d sup  n }  over  {  d   x sup  n }    ( x sup  2  ^-^  1
  ) sup  n )
.EN

(c29) p[4];

.EQ I (d29) 
 lambda   ( [ x ] , {  "35"  \^  x sup  4  ^-^  "30"  \^  x sup  2 
  ^+^  3 }  over  8 )
.EN

(c30) p[4](y+1);

.EQ I (d30) 
 {  "35"  \^  ( y  ^+^  1 ) sup  4  ^-^  "30"  \^  ( y  ^+^  1 ) sup 
  2  ^+^  3 }  over  8
.EN
.EQ
.EN
The ``lambda'' (@lambda@) notation for a raw function of one
variable appears on line c29.  This notation comes from the ``@lambda@-calculus'' 
used to describe the programming language LISP, and illustrates the fact
that
.Ma
can talk about such structures. You can generally ignore this fact, however.
.sh 2 More\ Useful\ Examples
.pp
As has been indicated earlier, procedures in 
.Ma
can be used for almost any classical
programming purposes (e.g. numerical techniques, combinatorial search).
We have already indicated some differences from a purely numerical
language, such as FORTRAN.
We have seen that in
.Ma
there are no required
type declarations, and floating-point numbers, while ``contagious''
in the sense that mixed-mode (floating-point + integer) is converted
to floating-point, do not
necessarily arise from certain calculations.  For example,
\f(CWsin(3)\fP normally results in 
\f(CWsin(3)\fP
in 
.Ma ,
rather than its floating-point equivalent.
\f(CWsin(3.0)\fP
will, however, return a floating-point number.
The numerical subroutine below, a Newton's method zero-finder
sets the flag
\f(CWnumer\fP to \f(CWtrue\fP to force
.Ma 
to convert most expressions free of indeterminates
to numbers.  
.pp
This program uses Newton's method to
find a zero of the expression \f(CWexp\fP
which depends on the variable
\f(CWvar.\fP
The iteration starts with \f(CWvar=x0\fP
and terminates when the expression, evaluated at the trial-point,
has absolute value less than 
\f(CWeps.\fP
The derivative of 
\f(CWexp\fP
is computed algebraically, and its value is computed at various
points as the search is being conducted:
.eB
\f(CW
.lg 0
(c1) newton(exp,var,x0,eps):=                   /* 1 */
                block([xn,s,numer],             /* 2 */
                numer:true,                     /* 3 */
                s:diff(exp,var),                /* 4 */
                xn:x0,                          /* 5 */
          while abs(subst(xn,var,exp))> eps do 
                xn:xn-subst(xn,var,exp)/subst(xn,var,s),
	  return(xn) )                         /* 8 */$
.lg
\fP
.eE
This procedure for Newton's method uses an explicit expression
for the first argument
\f(CWexp\fP
(e.g. 
\f(CWsin(x)*erf(2*x)-%e^x\fP
).
It is not a function name, e.g. 
\f(CWf\fP
as we used before.  The use of such an expression is straightforward and
probably the best way for a beginner.  The resulting program is
somewhat verbose, because, as illustrated in lines 6 and 7 above,
it is necessary to substitute values for variables in the expression
and its derivative, \f(CWs,\fP
to get numbers.
Note the setting
of \f(CWnumer\fP
on line 3 to assure that the \f(CWif\fP statement on line
6 would get numerical values for its test.  The rest of the procedure
is the classical Newton iteration.
The advantage of this procedure 
over a purely numerical one is that it takes advantage
of the ability to compute the derivative 
of \f(CWexp\fP algebraically and automatically, once, before evaluating it at any
point.
.pp
Another item to observe here is the use of comments in the text of
programs which are 
\f(CWbatch\fPed in to the system. \f(CW /* This is a comment */ .\fP
.pp
There are often many different ways of expressing the same computation,
and some of them may be substantially more convenient or efficient
than others.  While it may not make much of a difference in
efficiency in this case, the following revision of the
\f(CWnewton\fP
procedure illustrates some techniques you may find useful
in
.Ma .
.eB
\f(CW
.lg 0
(c2) newton(exp,var,x0,eps):=                   /* 1 */
block([ xn:x0, s:diff(exp,var), numer:true],    /* 2 */
        define(f(var), exp),                    /* 3 */
        define(fprime(var),s),                  /* 4 */
  loop, if abs(f(xn)) < eps then return(xn),    /* 5 */
        xn: xn - f(xn)/fprime(xn),              /* 6 */
        go (loop) )                             /* 7 */ $
\fP
.lg
.eE
Observe the list of local names at the beginning of the 
\f(CWblock,\fP
which are initialized at the same time they are declared on line 2.
Lines 3 and 4 are interesting because they define two new functions,
\f(CWf\fP
and 
\f(CWfprime\fP
each to have as their bodies, the values of
\f(CWexp\fP
and \f(CWs\fP.
The Newton iteration is more easily observed in functional
rather than ``substitution'' notation.
An even smaller version of \f(CWnewton\fP could be defined by
using a single function for \f(CWexp/diff(exp,var)\fP.
.pp
Let us try this last function:
.eB
\f(CW
(c3) h:expand((x-1)*(x-3)*(x-5));
                              3      2
(d3)                         x  - 9 x  + 23 x - 15

(c4) newton(h,x,3.5,1.0e-10);
(d4)                           2.999999999994027
\fP
.eE
You might wonder how many iterations that took.  One way is to use
the very convenient debugging feature provided by
.Ma
which allows you to watch the assignment of values to variables.
You set the variable
\f(CWsetcheck\fP to a list of the variables you wish to watch. (or 
\f(CWall\fP
to watch all the variables.)
.eB
\f(CW
(c5) setcheck:[xn]$

(c6) newton(h,x,3.5,1.0e-10);
xn set to 3.5
xn set to 2.923076923076923
xn set to 3.000228597554006
[*flonum:20{5%}; list:634{17%}; fixnum:43{2%}; ut:0%]
xn set to 2.999999999994027
(d6)                           2.999999999994027
\fP
.eE
(That message ``[*flonum: ...]'' is a message from the
garbage collector, mentioned in the first section of the primer. )
.pp
That tells us that only three iterations were needed in this case.
.pp
We claimed that two functions were defined in running this
program.  To display a function using the same syntax that
you would use to type it in, you use the \f(CWgrind\fP\** command.
.(f
\**  When computers were
slow and programs were large, reformatting programs
took a long time. The name of a program at MIT
to ``grind out'' LISP function definitions was \f(CWgrindef\fP.  The name
was carried over to
.Ma .
Now, most LISP systems call this reformatting ``prettyprinting''.
.)f
.eB
\f(CW
(c7) grind(fprime);
fprime(x):=3*x^2-18*x+23$
(d7)                                 done
\fP
.eE
.sh 2 Part\ Hacking
.pp
An important tool for applications programs in
.Ma
the ability to extract and test parts of expressions.  These are
used for the 
definition or extension of algorithms which do
various conditional manipulation of formulas.
For example, you can write
a symbolic differentiation algorithm for expressions
by applying the rules below:
.EQ I (1)
d over dx~ x ~=~ 1 ~~~~~~~d over dx~ y ~=~ 0 ~~(y != x)
.EN
.EQ I (2)
d over dx~ ( u + v) ~=~ d over dx~ u ~+~ d over dx~ v
.EN
.EQ I (3)
d over dx~ ( u cdot v) ~=~ v d over dx~ u ~+~ u d over dx~ v
.EN
.pp
The technique we shall consider for implementing a version of the
differentiation program is to take the expression apart using the 
\f(CWpart\fP
command, and use the rules above to guide the manipulation.
.pp
First, we check to see if the expression is an
atom (e.g. number, variable).
Thus we begin our differentiation program as follows:
.eB
\f(CW
.lg 0
newdiff(expr,var):=
        if atom(expr)=true then
                (if expr=var then 1
                             else 0)
\fP
.eE
This fragment implements both parts of
rule 1.  If the 
\f(CWif\fP
statement falls through to the 
\f(CWelse \fP
clause,
then we have a composite expression.  We then check what its leading
operator is by selecting its zeroth ``part'' via
\f(CWpart(expr,0).\fP
Based on its value we apply the appropriate rule.
.eB
\f(CW
        else if part(expr,0)=''+'' then
             newdiff(part(expr,1),var)
                     + newdiff(part(expr,2),var)
        else if part(expr,0)=''*'' then
             part(expr,2)*newdiff(part(expr,1),var)
                     + part(expr,1)*newdiff(part(expr,2),var)
        else 'newdiff(expr,var)$
.lg
\fP
.eE
Note the last clause which returns a 'newdiff form, that is, quoted,
as a result when
the program doesn't know how to handle the leading operator.
With some thought, you
should now be able to extend newdiff to accommodate expressions including
\f(CWsin\fP
and
\f(CWcos\fP
as well as
sums and products with more than two terms. (The
.Ma
language does not at the moment have a
\f(CWcase\fP
statement, which would make this particular program look better.)
.sh 2 User\ Representation\ of\ Data
.pp
There is no ``record'' or ``structure'' data-type ``constructor'' in
.Ma ,
but there is a way of doing something similar.  If you have used a
language like Pascal which has such a feature, you may appreciate
its usefulness. Modern dialects of LISP use such structures, but when
.Ma
was first designed and initially implemented (in 1967), this was not
in widespread use.  It also influenced the user-level programming language.
.pp
It
is natural to have to deal with collections of information in writing
programs. For example, you might wish to provide as input or output
data, a pair of expressions representing a lower and an upper bound on
a formula. One way of handling this is by making up a new ``function''
name, say \f(CWbounds\fP and using it as though it were a record designator or
constructor,
but never associating it with an algorithm.  Thus \f(CWbounds(1,x)\fP could
be an expression representing the ordered pair <1,\f(CWx\fP>.
Another example would be the use of \f(CWinteger_vector(1,3,5,7)\fP
to designate a sequence (presumably of arbitrary length, in general),
of integers.  There is a built-in form in
.Ma ,
namely a ``list'', which can be used to deal with such collections.
It is part of the LISP heritage indicated earlier that there was initially
only one type of structure: lists of any length or element type in
.Ma .
A list, when printed, looks like square-brackets
enclosing a sequence of items. Thus you could express the bounds above
as [\f(CW1,x\fP]. However, if you used lists for all collections, you
would not know, on the face of it, whether [1,2] was an instance of
\f(CWbounds\fP
or
\f(CWinteger_vector.\fP
.Ma
allows you to designate functions you intend to treat as lists, although
you can use a different ``header'' like
\f(CWbounds\fP
with each different type.
.Ma
makes available certain built-in
functions which can then be used on such list-like constructions
such as \f(CWinteger_vector\fP.  These are declared by, for example,
\f(CWdeclare(integer_vector,list).\fP
The built-in operations include
\f(CWcons, append, member, endcons, map, rest.\fP
\f(CWlist2:cons(element,list1)\fP
returns a (new) 
\f(CWlist2\fP
which has the given
element inserted at the beginning of 
\f(CWlist1; \fP
\f(CWList1 \fP and \f(CWlist2 \fP
have a common ``shared'' tail.
\f(CWlist3:append(list1,list2)\fP
returns a (new) 
\f(CWlist3\fP which is a
combination of the two lists, sharing a common tail with list2. 
\f(CWMember(element,list)\fP
returns true or false depending on a test
for membership.
\f(CWEndcons(element,list)\fP
returns an (unshared) list where the given element has been
attached to the end of
given list
\f(CWMap(fn,list)\fP
returns a new list where each element
has had the function fn applied to it in turn.
\f(CWRest(list,n) \fP
returns the part of the list beginning n items from
the front. These functions are parts of the fundamental repertoire of
the programming language LISP.
.pp
The use of list-like objects should be considered whenever you are
dealing with a collection of elements: a set of coordinates, a series
of coefficients, a system of equations, a set of solutions, etc.
.pp
Independent of the ``whole list'' operations above,
.Ma
has some selection and alteration operations which are available on
the same collections of data by the use of a numeric index.
If you wish to use these indexing facilities, as we will illustrate for the
notion of 
\f(CWcomplex\fP below, you \f(CWdeclare(complex,list).\fP
Then, if you define a complex
number by \f(CWx:complex(3,4)\fP meaning that 
\f(CWx\fP has real part 3, and imaginary
part 4, the notation \f(CWx[1]:10;\fP
is supported, and changes the value of
\f(CWx\fP
to
\f(CWcomplex(10,4).\fP
The declaration explains to the
.Ma
system that the data structure for
\f(CWcomplex\fP
will be implemented (in effect) as a list of items, and should be decomposable
using the semantics of the
.Ma
list-handling commands.
In fact, both selection and alteration is supported, and if you set the
notation up by
\f(CW(real:1,imag:2)$\fP
you can use the following command:
\f(CWx[imag]:-x[imag]\fP
to change 
\f(CWx\fP
to its complex conjugate.
.pp
An important caution must be observed.  When
.Ma
deals with compound structures, they are usually not recopied, and if
there are two names for the same object and the object is changed, then
both names refer to the changed object.
If
\f(CWx\fP
and
\f(CWy\fP
refer to the same 
\f(CWcomplex\fP
number, then changes to
\f(CWx[real]\fP
are also made to the corresponding component of
\f(CWy\fP.
If these items are to be kept separate, 
\f(CWx:copylist(y);\fP
will give
\f(CWx\fP
a different representation, but whose value is the same as
\f(CWy\fP's.
You can then change their components separately.
.pp
.Ma 's
built-in lists mentioned earlier, which use square-brackets, 
can be altered and selected by indexing.
.pp
There are two other compound structures in
.Ma
which we mention here, which may be useful for
collections of data: arrays and matrices.
The matrix form is useful for two-dimensional rectangular tables of
data.  The matrix data format is supported by a number of special
commands oriented toward the conventional interpretation of
matrices in mathematics: inverses, determinants, etc.
Matrices can be used for other kinds of data, but you should be
cautious about using them in a manner that is too far distant from
the conventional: arithmetic operations in 
.Ma ,
in particular, have already been defined.
.pp
Arrays are unusual in their flexibility in
.Ma .
They are usually treated as global tables, although they can be
declared to be
.i local
to a function; they cannot
be passed around as parameters
as is the case with matrices.  The
names of arrays may be passed from program to program, but the data
itself is not recopied, nor is it convenient to even make a copy
of the data into another array. ``Hashed'' arrays are particularly
ingenious, and have been illustrated earlier. Functions can be associated
with arrays to provide new values for entries as they are required.
.pp
At this point you should be able to make use of the
.Ma
manual to learn more details for representation of
new data types as you develop your application.
.sh 1 More\ learning
.pp
The true programming buff may also be interested in the macro-expansion
capabilities of
.Ma
and its extensible syntax.  At this point we would discourage the use of
these facilities by novices, but encourage their use by persons willing
to experiment in providing the most versatile user-oriented packages within
the
.Ma
framework.
.pp
There is a ``compilation'' facility which allows users to translate
.Ma
code into potentially faster running code.  Since most of the time in
most programs is used by calls to LISP programs, this is usually ineffective.
In general, this should be avoided by novices and most experienced users, since
time spent on this is more wisely spent on mathematical restructuring of
the solution method, or (in the case of primarily numerical computation),
using a numerical library routine written in a suitable language.

.sh 1 Maxims\ for\ the\ MACSYMA\ User 
.pp
Some beginning users of algebraic manipulation systems
find that their
previous experiences with traditional programming systems do
not translate easily into algebraic programming; others find
.Ma
descriptions inadequate because the emphasis is on
the mixture of mathematical notations and algorithms, and not on 
``efficient'' use of machine or human resources (no one likes to wait
longer than necessary for an answer!).
While we cannot provide a complete education in efficient and effective
programming,
we have collected a few
``maxims'' in an attempt to help you with some of these ``start-up'' problems.
.pp
\fIAlgebraic manipulation is a new and different
computational approach for which prior experience with
computational methods may be misleading.
You should attempt to learn the ways in which algebraic
manipulation differs from other approaches.\fP 
.pp
For
example, consider the problem of inverting an @n times n@
matrix.  In numerical analysis we learn that the problem
requires on the order of @n sup 3@ operations.  Theoreticians
will point out that for @n@ sufficiently large, one can
reduce the number of multiplications below @ n sup 3@ to @n sup 2.8@.
This analysis is unfortunately not relevant in dealing with matrices
with symbolic entries.  Consider the number of terms in
the determinant of the general @n times n@ matrix whose elements
are the symbols @ a sub i,j @.  When the inverse is written out
in a fully expanded form, just the
determinant (a necessary part of representing
the inverse) has @n !@
terms. It is impossible to compute this determinant in less than ``time
proportional to @n !@''  In fact,
for large @n@, it is just not feasible
to compute this form explicitly on existing computers.
The combinatorial
or exponential character that some algebraic manipulation
problems have when they are approached with an inefficient algorithm, makes for a vastly
different game from, say, numerical computation, where the size of objects
is generally known at the onset of the calculation, and does not increase.
.pp
\fINeedlessly
generalizing a problem usually results in unnecessary expense\fP.
.pp
For example, if you wish to obtain determinants
for a collection of matrices whose general
pattern of entries is represented by parametric formulas,
you might consider obtaining the determinant
of the general matrix and substituting various values for the parameters
into the 
result.  This may work for matrices of low order, but
is probably a poor plan for dealing with the exponential
growth inherent in computing symbolic determinants. It would probably
be better to substitute the parameters first, since this would
drastically reduce the cost of the determinant calculation.
.pp
Sometimes, when humans are dealing with formulas, it is
preferable to use an indeterminate, say @G@ in a formula 
which is really known to be, say, 3/5.  On the other
hand, it is likely (although not certain!) that the calculation
using 3/5 will take less time than the calculation with @G@.
Since the cost inherent in some computations is usually
a function
of the number of variables in the expression, \fIit pays to reduce the
number of variables in a problem as much as possible.\fR
.PP
\fIYou should be aware of the types of calculations which in the general
case have exponential growth \fR
(e.g. many matrix calculations with symbolic
entries, repeated differentiation of products or quotients, solution of systems
of polynomial equations).
.pp
\fIYour should anticipate a certain amount of trial-and-error in calculations.\fR
Just as in other problem-solving activities,
often the first technique that comes to mind is not the best.  While it
occasionally happens that brute force carries the day, cleverness in computing
can be as important as cleverness in hand calculations.
It is natural, during hand calculations, to apply critical simplificiations
or substitutions in computations. These simplifications include
collecting terms selectively or striking out terms which do not ultimately
contribute to the final answer because of physical interpretations.
Computer algorithms which do not incorporate these same tricks may bog down
surprisingly soon.  Thinking about these shortcuts may be important. In fact,
it is one of the more
rewarding aspects of computer algebra systems that they give the problem solver
an opportunity to organize, encapsulate and distribute
a particularly clever piece of mathematical manipulation.
.pp
\fITry to reduce your problem so that it can be performed in a simpler domain.\fR
For example, if your problem appears to involve trigonometric functions, logs,
exponentials, etc. see if you can reduce it to a rational function (ratio of
polynomials) problem.
If it appears to be a rational function, see if you can, by substitutions,
make it into a polynomial problem, or a truncated power-series problem.
If it appears to be a problem involving rational numbers, consider the use of
floating-point numbers as an alternative, if the growth in the size of numbers
presents difficulties.
.pp
There are other special forms that are especially efficient.  In a number
of areas of investigation \fIit pays to convert all expressions to the internal rational form
(using \fRrat\fI) or into Poisson-series form (using \fRintopois\fI) to
avoid the overhead the the general representation.\fR  The price you may
pay here is thtat the structure of the formulas may be significantly different
from those you began with:  The canonical transformations used by these
representations drastically re-order, expand, and modify the original expressions.
.pp
\fISometimes someone else has already started on your problem.\fR
You should look through the ``share'' directory programs available to see
if there are contributed packages that might be of use either as subroutines or as
models for programming.  You should also consider writing programs that
you develop in solving your problems in a form suitable for sharing with
others.
.pp
\fIPattern matching allows you to ``tune'' the system simplifier to your
.pplication, and develop rule-replacement programs.\fR Learning to use
the pattern-matching facilities effectively is a nontrivial task.  Nevertheless
if you have a fairly complex problem involvilng the recognition and application
of identities, you should consider making an effort to use these facilities.
In recent years, advocates of ``rule-based expert systems'' have claimed
that this type of formalism can or should be used to incorporate varied types of
knowledge.  Algebraic manipulation programs have depended on pattern matching
since at least 1961, for some of their power.




.pp
Finally, we would like to point out that algebraic manipulation systems,
in spite of their pitfalls, can be of major assistance in solving difficult
problems.  If you are willing to invest some time in learning, there may be
enormous benefits in using such a system.  We think it is unfortunate that
some users reserve
.Ma
for difficult problems.  Those of us who have grown up with
.Ma
near at hand find it of great use in routine computations as well.
.pp
We have enjoyed constructing
.Ma ,
and we hope that you will enjoy using it.  We hope you will consider
contributing to program libraries at your local installation and at
other sites.
.pp
Naturally, any comments or additions to this primer are welcome.


.nf
Richard Fateman
University of California, Berkeley
(Last revision 12/85)