




















				  R E D U C E

			  U S E R ' S   M A N U A L


				  Version 3.0


				   Edited by

			       Anthony C. Hearn

			     The Rand Corporation
			    Santa Monica, CA 90406


				  April  1983




















			 Rand Publication CP78(4/83)



				  ABSTRACT


This document provides the user with a description of the algebraic
programming system REDUCE.  The capabilities of this system include:

    1) expansion and ordering of polynomials and rational functions,
    2) substitutions and pattern matching in a wide variety of forms,
    3) automatic and user controlled simplification of expressions,
    4) calculations with symbolic matrices,
    5) arbitrary precision integer and real arithmetic,
    6) facilities for defining new functions and extending program syntax,
    7) analytic differentiation and integration,
    8) factorization of polynomials,
    9) Dirac matrix calculations of interest to high energy physicists.

























			       ACKNOWLEDGMENT

The production of this version of the manual has been the result of the
contributions of a large number of individuals who have taken the time and
effort to suggest improvements to previous versions, and to draft new
sections.  Particular thanks are due to Gerry Rayna, who provided a draft
rewrite of most of the first half of the manual.  Other people who have
made significant contributions have included John Fitch, Martin Griss, Don
Morrison, Arthur Norman and Larry Seward.






Copyright (c) 1983 The Rand Corporation



                                TABLE OF CONTENTS

1.  AN INTRODUCTION TO REDUCE. . . . . . . . . . . . . . . . . . . . .1-1

2.  STRUCTURE OF PROGRAMS. . . . . . . . . . . . . . . . . . . . . . .2-1
        2.1  The REDUCE Standard Character Set . . . . . . . . . . . .2-1
        2.2  Numbers . . . . . . . . . . . . . . . . . . . . . . . . .2-1
        2.3  Identifiers . . . . . . . . . . . . . . . . . . . . . . .2-2
        2.3.1  Restrictions. . . . . . . . . . . . . . . . . . . . . .2-2
        2.4  Variables . . . . . . . . . . . . . . . . . . . . . . . .2-3
        2.4.1  Reserved Variables. . . . . . . . . . . . . . . . . . .2-3
        2.5  Strings . . . . . . . . . . . . . . . . . . . . . . . . .2-4
        2.6  Comments. . . . . . . . . . . . . . . . . . . . . . . . .2-4
        2.7  Operators . . . . . . . . . . . . . . . . . . . . . . . .2-4
        2.7.1  Built-in Infix Operators. . . . . . . . . . . . . . . .2-6

3.  EXPRESSIONS. . . . . . . . . . . . . . . . . . . . . . . . . . . .3-1
        3.1  Scalar Expressions. . . . . . . . . . . . . . . . . . . .3-1
        3.2  Integer Expressions . . . . . . . . . . . . . . . . . . .3-2
        3.3  Boolean Expressions . . . . . . . . . . . . . . . . . . .3-2
        3.4  Proper Statements as Expressions. . . . . . . . . . . . .3-3

4.  STATEMENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1
        4.1  Assignment Statements . . . . . . . . . . . . . . . . . .4-1
        4.2  Group statements. . . . . . . . . . . . . . . . . . . . .4-2
        4.3  Conditional Statements. . . . . . . . . . . . . . . . . .4-2
        4.4  FOR Statements. . . . . . . . . . . . . . . . . . . . . .4-3
        4.5  WHILE ... DO. . . . . . . . . . . . . . . . . . . . . . .4-4
        4.6  REPEAT ... UNTIL. . . . . . . . . . . . . . . . . . . . .4-5
        4.7  Compound Statements . . . . . . . . . . . . . . . . . . .4-6
        4.7.1  Compound Statements with GO TO. . . . . . . . . . . . .4-7
        4.7.2  Labels and GO TO Statements . . . . . . . . . . . . . .4-8
        4.7.3  RETURN Statements . . . . . . . . . . . . . . . . . . .4-8

5.  COMMANDS AND DECLARATIONS. . . . . . . . . . . . . . . . . . . . .5-1
        5.1  Array Declarations. . . . . . . . . . . . . . . . . . . .5-1
        5.2  Mode Handling Declarations. . . . . . . . . . . . . . . .5-2
        5.3  END . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2
        5.4  BYE . . . . . . . . . . . . . . . . . . . . . . . . . . .5-3
        5.5  QUIT. . . . . . . . . . . . . . . . . . . . . . . . . . .5-3
        5.6  SHOWTIME. . . . . . . . . . . . . . . . . . . . . . . . .5-3
        5.7  DEFINE. . . . . . . . . . . . . . . . . . . . . . . . . .5-3

6.  BUILT-IN PREFIX OPERATORS. . . . . . . . . . . . . . . . . . . . .6-1
        6.1  Numerical Functions . . . . . . . . . . . . . . . . . . .6-1
        6.2  Mathematical Functions. . . . . . . . . . . . . . . . . .6-1
        6.3  DF. . . . . . . . . . . . . . . . . . . . . . . . . . . .6-2
        6.3.1  Adding Differentiation Rules. . . . . . . . . . . . . .6-3
        6.4  INT . . . . . . . . . . . . . . . . . . . . . . . . . . .6-3
        6.4.1  Options . . . . . . . . . . . . . . . . . . . . . . . .6-4
        6.4.2  Advanced Use. . . . . . . . . . . . . . . . . . . . . .6-4
        6.4.3  References. . . . . . . . . . . . . . . . . . . . . . .6-5
        6.5  SOLVE . . . . . . . . . . . . . . . . . . . . . . . . . .6-5
        6.5.1  Options . . . . . . . . . . . . . . . . . . . . . . . .6-5
        6.6  SUB . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7
        6.7  Declaring new Prefix Operators. . . . . . . . . . . . . .6-7



                                ii  

        6.7.1  Declaring new Infix Operators . . . . . . . . . . . . .6-7
        6.8  Linear Operators. . . . . . . . . . . . . . . . . . . . .6-8
        6.9  Non-Commuting Operators . . . . . . . . . . . . . . . . .6-9
        6.10  Creating and Removing Variable Dependency. . . . . . . 6-10

7.  DISPLAY AND STRUCTURING OF EXPRESSIONS . . . . . . . . . . . . . .7-1
        7.1  Kernels . . . . . . . . . . . . . . . . . . . . . . . . .7-1
        7.2  The Expression Workspace. . . . . . . . . . . . . . . . .7-2
        7.3  Output of Expressions . . . . . . . . . . . . . . . . . .7-3
        7.3.1  LINELENGTH. . . . . . . . . . . . . . . . . . . . . . .7-3
        7.3.2  Output Declarations . . . . . . . . . . . . . . . . . .7-3
        7.3.2.1  ORDER . . . . . . . . . . . . . . . . . . . . . . . .7-4
        7.3.2.2  FACTOR. . . . . . . . . . . . . . . . . . . . . . . .7-4
        7.3.3  Output Control Switches . . . . . . . . . . . . . . . .7-4
        7.3.3.1  ALLFAC. . . . . . . . . . . . . . . . . . . . . . . .7-5
        7.3.3.2  DIV . . . . . . . . . . . . . . . . . . . . . . . . .7-5
        7.3.3.3  LIST. . . . . . . . . . . . . . . . . . . . . . . . .7-5
        7.3.3.4  RAT . . . . . . . . . . . . . . . . . . . . . . . . .7-6
        7.3.4  WRITE Command . . . . . . . . . . . . . . . . . . . . .7-6
        7.3.5  Suppression of Zeros. . . . . . . . . . . . . . . . . .7-8
        7.3.6  FORTRAN Style Output of Expressions . . . . . . . . . .7-8
        7.3.6.1  FORTRAN Output Options. . . . . . . . . . . . . . . 7-10
        7.3.7  Saving Expressions for Later Use as Input . . . . . . 7-10
        7.3.8  Displaying Expression Structure . . . . . . . . . . . 7-11
        7.4  Changing the Internal Order of Variables. . . . . . . . 7-12
        7.5  Obtaining Parts of Algebraic Expressions. . . . . . . . 7-12
        7.5.1  COEFF . . . . . . . . . . . . . . . . . . . . . . . . 7-12
        7.5.2  PART. . . . . . . . . . . . . . . . . . . . . . . . . 7-13
        7.5.3  Changing Parts of Expressions . . . . . . . . . . . . 7-14

8.  POLYNOMIAL AND RATIONAL FUNCTION OPERATIONS. . . . . . . . . . . .8-1
        8.1  Controlling the Expansion of Expressions. . . . . . . . .8-1
        8.2  Factorization of Polynomials. . . . . . . . . . . . . . .8-2
        8.3  Cancellation of Common Factors. . . . . . . . . . . . . .8-4
        8.3.1  Determining the GCD of two polynomials. . . . . . . . .8-4
        8.4  Working with Least Common Multiples . . . . . . . . . . .8-5
        8.5  Controlling Use of Common Denominators. . . . . . . . . .8-5
        8.6  REMAINDER . . . . . . . . . . . . . . . . . . . . . . . .8-5
        8.7  RESULTANT . . . . . . . . . . . . . . . . . . . . . . . .8-6
        8.8  Obtaining Parts of Polynomials and Rational Functions . .8-6
        8.8.1  DEG . . . . . . . . . . . . . . . . . . . . . . . . . .8-6
        8.8.2  DEN . . . . . . . . . . . . . . . . . . . . . . . . . .8-6
        8.8.3  LCOF. . . . . . . . . . . . . . . . . . . . . . . . . .8-7
        8.8.4  LTERM . . . . . . . . . . . . . . . . . . . . . . . . .8-7
        8.8.5  MAINVAR . . . . . . . . . . . . . . . . . . . . . . . .8-7
        8.8.6  NUM . . . . . . . . . . . . . . . . . . . . . . . . . .8-8
        8.8.7  REDUCT. . . . . . . . . . . . . . . . . . . . . . . . .8-8
        8.9  Polynomial Coefficient Arithmetic . . . . . . . . . . . .8-8
        8.9.1  Rational Coefficients in Polynomials. . . . . . . . . .8-8
        8.9.2  Real coefficients in Polynomials. . . . . . . . . . . .8-9
        8.9.3  Arbitrary Precision Real Coefficients . . . . . . . . .8-9
        8.9.4  Modular Number Coefficients in Polynomials. . . . . . .8-9



                                iii 

9.  SUBSTITUTION COMMANDS. . . . . . . . . . . . . . . . . . . . . . .9-1
        9.1  Simple LET Rules. . . . . . . . . . . . . . . . . . . . .9-1
        9.2  FOR ALL ... LET . . . . . . . . . . . . . . . . . . . . .9-2
        9.3  FOR ALL ... SUCH THAT ... LET . . . . . . . . . . . . . .9-3
        9.4  Removing Assignments and Substitution Rules . . . . . . .9-3
        9.5  Overlapping LET Rules . . . . . . . . . . . . . . . . . .9-4
        9.5.1  Substitutions for General Expressions . . . . . . . . .9-4
        9.6  Asymptotic Commands . . . . . . . . . . . . . . . . . . .9-6

10.  FILE HANDLING COMMANDS. . . . . . . . . . . . . . . . . . . . . 10-1
        10.1  IN . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1
        10.2  OUT. . . . . . . . . . . . . . . . . . . . . . . . . . 10-1
        10.3  SHUT . . . . . . . . . . . . . . . . . . . . . . . . . 10-2

11.  COMMANDS FOR INTERACTIVE USE OF REDUCE. . . . . . . . . . . . . 11-1
        11.1  Referencing Previous Results . . . . . . . . . . . . . 11-1
        11.2  Interactive Editing. . . . . . . . . . . . . . . . . . 11-1
        11.3  Interactive File Control . . . . . . . . . . . . . . . 11-2

12.  MATRIX CALCULATIONS . . . . . . . . . . . . . . . . . . . . . . 12-1
        12.1  MAT. . . . . . . . . . . . . . . . . . . . . . . . . . 12-1
        12.2  Matrix Variables . . . . . . . . . . . . . . . . . . . 12-1
        12.3  Matrix Expressions . . . . . . . . . . . . . . . . . . 12-2
        12.4  Operators With Matrix Arguments. . . . . . . . . . . . 12-2
        12.4.1  DET. . . . . . . . . . . . . . . . . . . . . . . . . 12-2
        12.4.2  TP . . . . . . . . . . . . . . . . . . . . . . . . . 12-3
        12.4.3  TRACE. . . . . . . . . . . . . . . . . . . . . . . . 12-3
        12.5  Matrix Assignments . . . . . . . . . . . . . . . . . . 12-3
        12.6  Evaluating Matrix Elements . . . . . . . . . . . . . . 12-3

13.  PROCEDURES. . . . . . . . . . . . . . . . . . . . . . . . . . . 13-1
        13.1  Procedure Heading. . . . . . . . . . . . . . . . . . . 13-1
        13.2  The Procedure Body . . . . . . . . . . . . . . . . . . 13-2
        13.3  Using LET Inside Procedures. . . . . . . . . . . . . . 13-4
        13.4  Let Rules as Procedures. . . . . . . . . . . . . . . . 13-4

14.  SYMBOLIC MODE . . . . . . . . . . . . . . . . . . . . . . . . . 14-1
        14.1  Symbolic Infix Operators . . . . . . . . . . . . . . . 14-2
        14.2  Symbolic Expressions . . . . . . . . . . . . . . . . . 14-2
        14.3  Quoted Expressions . . . . . . . . . . . . . . . . . . 14-2
        14.4  LAMBDA Expressions . . . . . . . . . . . . . . . . . . 14-3
        14.5  Symbolic Assignment Statements . . . . . . . . . . . . 14-3
        14.6  FOR EACH Statement . . . . . . . . . . . . . . . . . . 14-3
        14.7  Symbolic Procedures. . . . . . . . . . . . . . . . . . 14-4
        14.8  Obtaining the Standard LISP Equivalent of REDUCE Input 14-4
        14.9  Communicating with Algebraic Mode. . . . . . . . . . . 14-5
        14.9.1   Passing Algebraic Mode Values to Symbolic Mode. . . 14-5
        14.9.2  Passing Symbolic Mode Values back to Algebraic Mode. 14-7
        14.9.3  Complete Example . . . . . . . . . . . . . . . . . . 14-8
        14.9.4  Defining Procedures which Communicate between Modes. 14-9
        14.10  References: . . . . . . . . . . . . . . . . . . . . . 14-9



                                iv  

15.  CALCULATIONS IN HIGH ENERGY PHYSICS . . . . . . . . . . . . . . 15-1
        15.1  Notation . . . . . . . . . . . . . . . . . . . . . . . 15-1
        15.2  Operators used in High Energy Physics Calculations . . 15-1
        15.2.1  . (DOT). . . . . . . . . . . . . . . . . . . . . . . 15-1
        15.2.2  G. . . . . . . . . . . . . . . . . . . . . . . . . . 15-2
        15.2.3  EPS. . . . . . . . . . . . . . . . . . . . . . . . . 15-2
        15.3  Vector variables . . . . . . . . . . . . . . . . . . . 15-3
        15.4  Additional Expression Types. . . . . . . . . . . . . . 15-3
        15.4.1  Vector Expressions . . . . . . . . . . . . . . . . . 15-3
        15.4.2  Dirac Expressions. . . . . . . . . . . . . . . . . . 15-4
        15.5  Trace Calculations . . . . . . . . . . . . . . . . . . 15-4
        15.6  Mass Declarations. . . . . . . . . . . . . . . . . . . 15-4
        15.7  Example. . . . . . . . . . . . . . . . . . . . . . . . 15-5
        15.8  Extensions to More than Four Dimensions. . . . . . . . 15-6

16.  REDUCE AND RLISP UTILITIES. . . . . . . . . . . . . . . . . . . 16-1
        16.1  The Standard LISP Compiler . . . . . . . . . . . . . . 16-1
        16.2  Fast Loading Code Generation Program . . . . . . . . . 16-1
        16.3  The Standard LISP Cross-Reference Program. . . . . . . 16-2
        16.3.1  Restrictions:. . . . . . . . . . . . . . . . . . . . 16-3
        16.3.2  Usage: . . . . . . . . . . . . . . . . . . . . . . . 16-3
        16.3.3  Options: . . . . . . . . . . . . . . . . . . . . . . 16-3
        16.4  Prettyprinting Reduce Expressions. . . . . . . . . . . 16-4
        16.5  Prettyprinting Standard LISP S-expressions . . . . . . 16-4

A.  RESERVED IDENTIFIERS . . . . . . . . . . . . . . . . . . . . . . .A-1

B.  OPERATORS NORMALLY AVAILABLE IN REDUCE . . . . . . . . . . . . . .B-1

C.  COMMANDS AND DECLARATIONS. . . . . . . . . . . . . . . . . . . . .C-1

D.  MODE SWITCHES IN REDUCE. . . . . . . . . . . . . . . . . . . . . .D-1

E.  DIAGNOSTIC AND ERROR MESSAGES IN REDUCE. . . . . . . . . . . . . .E-1

F.  VARIABLES IN REDUCE. . . . . . . . . . . . . . . . . . . . . . . .F-1

G.  KEYWORD INDEX. . . . . . . . . . . . . . . . . . . . . . . . . . .G-1



                                1-1


1. AN INTRODUCTION TO REDUCE
   __ ____________ __ ______

REDUCE is a system for carrying out algebraic operations accurately, no
matter how complicated the expressions become. It can manipulate
polynomials in a variety of forms, both expanding and factoring them, and
extracting various parts of them as required. REDUCE can also do
differentiation and integration, but we shall only show trivial examples of
this in this introduction. Other topics which are not considered include
the use of arrays, the definition of procedures and operators, the specific
routines for high energy physics calculations, the use of files to
eliminate repetitious typing and for saving results, and the editing of the
input text.

Also not considered in any detail in this introduction are the many options
that are available for varying computational procedures, output forms,
number systems used, and so on.

REDUCE is designed to be an interactive system, so that the user can input
an algebraic expression and see its value before moving on to the next
calculation. Not all computer systems support interactive use, of course.
However, REDUCE can also be used in batch mode by inputting a sequence of
calculations and getting results without any possibility of interaction
during the calculations.

In this introduction, we shall limit ourselves to the interactive use of
REDUCE, since this illustrates most completely the capabilities of the
system. When REDUCE is called, it begins by printing a banner message
like:

     REDUCE 3.0, 15-Apr-83 ...

where the version number (3.0) and the system release date will change from
time to time. It then prompts the user for input by:

     1:

The user can now type a valid REDUCE statement, terminated by a semicolon
to indicate the end of the expression, for example:

     (x+y+z)**2;

This expression would normally be followed by another character (a Return
on an Ascii keyboard) to "wake up" the system, which would then input the
expression, evaluate it, and return the result. in a form like:

       2                    2            2
      X  + 2*X*Y + 2*X*Z + Y  + 2*Y*Z + Z

Let us review this simple example to learn a little more about the way
that REDUCE works. First, we note that REDUCE deals with variables, and
constants like other computer languages, but that in evaluating the
former, a variable can stand for itself. Expression evaluation normally



                                1-2

follows the rules of high school algebra, so the only surprise in the
above might be that the expression was expanded. The normal mode of REDUCE
does in fact expand all expressions where possible, collecting like terms
and ordering the variables in a specific manner. However, the expansion
option, ordering of variables, the format of output and so on is under the
control of the user, and various declarations are available to control
these.

Another characteristic of the above example is the use of lower case on
input and upper case on output. In fact, input may be in either mode, but
lower case is converted to upper case by the system.

Finally, the numerical prompt can be used to reference the result in a
later computation.

As a further illustration of the system characteristics, the user should
try:

     for i:= 1:50 product i;

The result in this case is the number

     30414093201713378043612608166064768844377641568960512000000000000

Since we want exact results in algebraic calculations, it is essential that
integer arithmetic be performed to arbitrary precision, as in the above
example. Furthermore, the FOR statement in the above is illustrative of a
whole range of combining forms which REDUCE supports for the convenience of
the user.

Among the many options in REDUCE is the use of other number systems, such
as multiple precision floating point with any specified number of digits --
of use if roundoff in, say, the 100th digit is all that can be tolerated.

In many cases, it is necessary to use the results of one calculation in
succeeding calculations. One way to do this is via an assignment for a
variable, such as

     u := (x+y+z)**2;

If we now use u in later calculations, the value of the right hand side of
the above will be used.

The results of a given calculation are in fact saved in the variable WS
(for workspace), so this can be used in the next calculation for further
processing.

For example, the expression

     df(ws,x);

following the previous evaluation will calculate the derivative of
(x+y+z)**2 with respect to x.



                                1-3

 Alternatively,

     int(ws,y);

would calculate the integral of the same expression with respect to y.

One nice feature of REDUCE is its handling of symbolic matrices. For
example,

     matrix m(2,2);

declares m to be a two by two matrix, and

     m := mat((a,b),(c,d));

gives it specific element values. Expressions which include m and make
algebraic sense may now be evaluated, such as 1/m to give the inverse, 2*m
- u*m**2 to give us another matrix and det(m) to give us the determinant
of m.

REDUCE also has a wide range of substitution capabilities. The system
knows about elementary functions, but does not automatically invoke many
of their well-known properties. For example, products of trigonometrical
functions are not converted automatically into multiple angle expressions,
but if the user wants this, he can say:

     for all x,y let cos(x)*cos(y) = (cos(x+y)+cos(x-y))/2,
                     cos(x)*sin(y) = (sin(x+y)-sin(x-y))/2,
                     sin(x)*sin(y) = (cos(x-y)-cos(x+y))/2;

An expression such as sin(a+b)*cos(a-b) would now convert into the
equivalent expression

      (SIN(2*A) + SIN(2*B))/2.

Another very commonly used capability of the system, and an illustration
of one of the many output modes of Reduce, is the ability to output
results in a Fortran compatible form. Such results can then be used later
in a Fortran-based numerical calculation. This is particularly useful as a
way of generating algebraic formulas to be used as the basis of extensive
numerical calculations.

For example, the statements

     on fort;
     df(log(x)*(sin(x)+cos(x))/sqrt(x),x,2);

will result in the output

      ANS=(-4.*LOG(X)*COS(X)*X**2-4.*LOG(X)*COS(X)*X+3.*LOG(X)*
     . COS(X)-4.*LOG(X)*SIN(X)*X**2+4.*LOG(X)*SIN(X)*X+3.*LOG(X)
     . *SIN(X)+8.*COS(X)*X-8.*COS(X)-8.*SIN(X)*X-8.*SIN(X))/(4.*
     . SQRT(X)*X**2)



                                1-4

 These algebraic manipulations illustrate the algebraic mode of REDUCE.
REDUCE is based on Standard LISP. A symbolic mode is also available for
executing LISP statements. These statements follow the syntax of LISP,
e.g.

  symbolic car '(a);

Communication between the two modes is possible.

With this simple introduction, the user is now in a position to study the
material in the full REDUCE manual in order to learn just how extensive the
range of facilities really is. If further tutorial material is considered
necessary, the seven REDUCE Interactive Lessons by David R. Stoutemyer are
recommended. These are normally available online at most installations.




                                2-1


2. STRUCTURE OF PROGRAMS
   _________ __ ________

A REDUCE program consists of a set of functional commands which are
evaluated sequentially by the computer. These commands are built up from
declarations, statements and expressions. Such entities are composed of
sequences of numbers, variables, operators, strings, reserved words and
delimiters (such as commas and parentheses), which in turn are sequences of
basic characters.


2.1 The REDUCE Standard Character Set
    ___ ______ ________ _________ ___

The basic characters which are used to build up REDUCE symbols are the
following:

 i)   The 26 upper case letters A through Z
 ii)  The 10 decimal digits 0 through 9
 iii) The special characters ! " $ % ' ( ) * + , - . / : ; < > =

Programs composed from this standard set of characters will run in any
available REDUCE system. Most implementations permit lower case on input.
With the exception of strings and characters preceded by an exclamation
mark (qv), such lower case characters will be converted internally into
upper case. If you do not wish this conversion to occur, the command OFF
RAISE; achieves this. However, now case IS distinguished internally, so
that df for example is not the same as DF (the derivative operator).
Several implementations also allow some special characters to represent
operators in the system. The operating instructions for the particular
implementation should be consulted on these points. For generality, we
shall limit ourselves to the standard character set in this exposition.


2.2 Numbers
    _______

There are several different types of numbers available in REDUCE. Integers
consist of a signed or unsigned sequence of decimal digits written without
a decimal point.

        e.g.  -2, 5396, +32

In principle, there is no practical limit on the number of digits
permitted as arbitrary precision arithmetic is used in most
implementations. (You should however check the specific instructions for
your particular system implementation to make sure that this is true.) For
example, if you ask for the value of 2**2000 (2 to the 2000th power) you
get it displayed as a number of 603 decimal digits, taking up nine lines
of output on an interactive display.

Numbers that aren't integers are usually represented as the quotient of
two integers, in lowest terms: that is, as rational numbers.

In most versions of REDUCE it is also possible (but not always desirable!)



                                2-2

to ask REDUCE to work with floating point approximations to numbers,
either single precision or -- in some versions -- multiple precision with
any specified number of digits. Such numbers are called REAL. They can be
input in two ways:

   i) as a signed or unsigned sequence of decimal digits with an embedded
      or trailing decimal point.  Up to 8 such digits are allowed in most
      implementations, although this can vary.  Again, you should check the
      specific instructions for a given implementation for the maximum size
      permitted.

  ii) as in i) followed by a decimal exponent which is written as the
      letter E followed by a signed or unsigned integer.

e.g. 32. +32.0 0.32E2 and 320.E-1 are all representations of 32.

CAUTION: The unsigned part of any number may NOT begin with a decimal
point, as this causes confusion with the CONS (.) operator in symbolic
mode (qv),

        i.e. NOT ALLOWED: .5  -.23  +.12; use: 0.5 -0.23 +0.12 instead.


2.3 Identifiers
    ___________

Identifiers in REDUCE consist of one or more alphanumeric characters (i.e.
upper case alphabetic letters or decimal digits) the first of which must
be alphabetic. The maximum number of characters allowed is implementation
dependent, although twenty-four is permitted in most implementations:

        e.g.  A AZ P1 Q23P  AVERYLONGVARIABLE

Special characters, such as -, *, and blank, may be used in identifiers
too, even as the first character, but each must be preceded by an
exclamation mark in input:

        e.g.   LIGHT!-YEARS    D!*!*N   GOOD! MORNING
                !$SIGN         !5GOLDRINGS

CAUTION: Many system identifiers have such special characters in their
names (especially * and =). If the user accidentally picks the name of one
of them for his own purposes it may have catastrophic consequences for his
REDUCE run.

Identifiers are used as variables, labels and to name arrays, operators
and procedures.


2.3.1 Restrictions
      ____________

The reserved words listed in another section may not be used as
identifiers. No spaces may appear within an identifier, and an identifier
may not extend over a line of text. (Hyphenation of an identifier, by using



                                2-3

a reserved character as a hyphen before an end-of-line character is
possible in some versions of REDUCE).


2.4 Variables
    _________

Every variable is named by an identifier, and is given a specific type.
The type is of no concern to the ordinary user. Most variables are allowed
to have the default type, called SCALAR. These can receive, as values, the
representation of any ordinary algebraic expression. In the absence of
such a value, they stand for themselves.


2.4.1 Reserved Variables
      ________ _________

Several variables in REDUCE have particular properties which should not be
changed by the user. These variables are as follows:

        E               Intended to represent the base of the natural
                        logarithms. LOG(E), if it occurs in an expression,
                        is automatically replaced by 1. In the ON NUMVAL
                        mode (qv), E is replaced by the value of E to the
                        current degree of floating point precision.

        I               Intended to represent the square root of -1.  I**2
                        is replaced by -1, and appropriately for higher
                        powers of I.  (This applies only to the symbol I
                        used on the top level, not as a formal parameter
                        in a procedure, a local variable, nor in the
                        context  FOR I:= ... .)

        NIL             In REDUCE (algebraic mode only) taken as a synonym
                        for zero.  Therefore NIL can not be used as a
                        variable.

        PI              Intended to represent the circular constant. In the
                        ON NUMVAL mode, it is replaced by the value of PI
                        to the current degree of floating point precision.

        T               Can not be used as a formal parameter or local
                        variable in procedures, since conflict arises with
                        the symbolic mode meaning of T as "true".

Use of these reserved variables inappropriately will lead to an error.

Certain words are reserved in REDUCE. They may only be used in the manner
intended. A partial list follows:

 ALGEBRAIC     EDITDEF      HELP         MATCH        REMFAC       SYMMETRIC
 ANTISYMMETRIC EMB          IF           MATRIX       REPEAT       TR
 ARRAY         END          IN           MSHELL       RETRY        TRST
 BEGIN         EXEC         INDEX        NODEPEND     RETURN       UP
 CLEAR         EXPR         INFIX        OFF          RLISP        VARNAME



                                2-4

 CMD           FACTOR       INPUT        ON           SAVEAS       VECTOR
 CONT          FEXPR        INTEGER      OPERATOR     SCALAR       WEIGHT
 CORE          FLAGOP       KORDER       ORDER        SHARE        WHILE
 CREATE        FLOAD        LAMBDA       OUT          SHOWTIME     WRITE
 DCL           FOR          LET          PAUSE        SHUT         WS
 DEFINE        FORALL       LINEAR       PRECEDENCE   SLISP        WTLEVEL
 DEPEND        FOREACH      LISP         PROCEDURE    SMACRO
 DOWN          FSLOUT       MACRO        QUIT         STRUCTR
 EDIT          GO           MASS         REAL         SYMBOLIC

This is, of course, an impossibly long list to keep in mind. The reader
may want to make himself a copy of it, deleting the names he doesn't think
he is likely to use by mistake.


2.5 Strings
    _______

Strings are used only in WRITE statements (qv). A string consists of any
number of characters enclosed in double quotes.

        e.g. "A STRING".

Lower case characters within a string are not converted to upper case.

The string "" represents the empty string. It is not possible to include a
double quote itself in a string.


2.6 Comments
    ________

Text can be included in program listings for the convenience of human
readers, in such a way that REDUCE pays no attention to it. There are two
ways to do this:

1) Everything from the word COMMENT to the next statement terminator (qv)
is ignored. Such comments can be placed anywhere a blank could properly
appear. (Note that END and >> are NOT treated as COMMENT delimiters!)

2) Everything from the symbol % to the end of the line on which it appears
is ignored. Such comments can be placed as the last part of any line.
Statement terminators have no special meaning in such comments. Remember
to put a semicolon before the % if the earlier part of the line is
intended to be so terminated. Remember also to begin EACH line of a
multi-line "%" comment with a % sign.


2.7 Operators
    _________

Operators in REDUCE are specified by name and type. There are two types,
infix and prefix. Operators can be purely abstract, just symbols with no
properties; they can have values assigned (using := or simple LET
declarations) for specific arguments; they can have properties declared for
some collection of arguments (using more general LET declarations); or they



                                2-5

can be fully defined (usually by a procedure declaration).

Infix operators occur between their arguments.

        e.g. A + B - C          (spaces optional)

             X<Y AND Y>Z       (spaces required where shown)

Spaces can be freely inserted between operators and variables or operators
and operators. They are required only where operator names are spelled out
with letters (such as the AND in the example) and must be unambiguously
separated from another such or from a variable (like Y). Wherever one
space can be used, so can any larger number.

Prefix operators occur to the left of their arguments, which are written as
a list enclosed in parentheses and separated by commas, as with normal
mathematical functions.

        e.g. COS(U)
             DF(X**2,X)
             Q(V+W)

Unmatched parentheses, incorrect groupings of infix operators and the like,
naturally lead to syntax errors. The parentheses can be omitted (replaced
by a space following the operator name) if the operator is unary and the
argument is a single symbol or begins with a prefix operator name:


        COS Y           means COS(Y)
        COS (-Y)        -- parentheses necessary
        LOG COS Y       means LOG(COS(Y))
        LOG COS (A+B)   means LOG(COS(A+B))
but
        COS A*B         means (COS A)*B
        COS -Y          is erroneous (treated as a variable
                           "COS" minus the variable Y)

A unary prefix operator has a precedence higher than any infix operator.
In other words, REDUCE will always interpret COS Y + 3 as (COS Y) + 3
rather than as COS(Y + 3).

Infix operators may also be used in a prefix format on input, e.g.,
+(A,B,C).  On output, however, such expressions will always be printed in
infix form (i.e., A + B + C for this example).

A number of prefix operators are built into the system with predefined
properties. Users may also add new operators and define their rules for
simplification. The built in operators are described in another section.



                                2-6


2.7.1 Built-in Infix Operators
      ________ _____ _________

The following infix operators are built into the system. They are all
defined internally as procedures.

<infix operator>::= :=|OR|AND|NOT|MEMBER|MEMQ|=|NEQ|EQ|>=|
                    >|<=|<|+|-|*|/|**|.

These operators may be further divided into the following subclasses:

   <assignment operator> ::= :=
   <logical operator>    ::= OR|AND|NOT|MEMBER|MEMQ
   <relational operator> ::= =|NEQ|EQ|>=|>|<=|<
   <arithmetic operator> ::= +|-|*|/|**
   <symbolic operator>   ::= .

(MEMBER, MEMQ, and EQ are not used in the algebraic mode of REDUCE. They
are explained in the section on symbolic mode (qv).)

For compatibility with the intermediate language used by REDUCE, each
special character infix operator has an alternative alphanumeric identifier
associated with it. These identifiers may be used interchangeably with the
corresponding special character names on input. This correspondence is as
follows:

        :=      SETQ  (the assignment operator)
        =       EQUAL
        >=      GEQ
        >       GREATERP
        <=      LEQ
        <       LESSP
        +       PLUS
        -       DIFFERENCE (if unary, MINUS)
        *       TIMES
        /       QUOTIENT (if unary, RECIP)
        **      EXPT (raising to a power)
        .       CONS

Note: NEQ is used to mean NOT EQUAL. There is no special symbol provided
for it.

The above operators are binary, except NOT which is unary and + and * which
are n-ary (i.e., taking an arbitrary number of arguments). In addition, -
and / may be used in a unary position, e.g., /2 means the same as 1/2. Any
other operator is parsed as a binary operator using a left association
rule. Thus A/B/C is interpreted as (A/B)/C. There are two exceptions to
this rule: := and . are right associative. Example: A:=B:=C is interpreted
as A:=(B:=C).

The operators <, <=, >, >= can only be used for making comparisons between
numbers. No meaning is currently assigned to this kind of comparison
between general expressions.



                                2-7

 Parentheses may be used to specify the order of combination. If
parentheses are omitted then this order is by the ordering of the
precedence list defined by the right hand side of the BNF definition of
<infix operator> above, from lowest to highest. In other words, := has the
lowest precedence, and . (the dot operator) the highest.



                                3-1


3. EXPRESSIONS
   ___________

REDUCE expressions may be of several types and consist of syntactically
allowed sequences of numbers, variables, operators, left and right
parentheses and commas. The most common types are as follows:


3.1 Scalar Expressions
    ______ ___________

Scalar expressions are composed, using the arithmetic operations + - * /
** (power) and parentheses, from

   numbers,
   ordinary ("SCALAR") variables (or identifiers),
   array names with appropriate subscripts given,
   operator or procedure names with suitable arguments,
   statement expressions.

Examples:

        X
        X**3 - 2*Y/(2*Z**2 - DF(X,Z))
        (P**2 + M**2)**(1/2)*LOG (Y/M)
        A(5) + B(I,Q)

Statement expressions (qv), usually in parentheses, can also form part of a
scalar expression, as in the example

        W + (C:=X+Y) + Z

When the (algebraic) value of an expression is needed, REDUCE determines
it, starting with the (algebraic) values of the parts, roughly as follows:

Variables and operator symbols with an argument list have the algebraic
values they were last assigned, or if never assigned stand for themselves.

Array symbols with appropriate subscripts have the algebraic values they
were last assigned, or, if never assigned, are taken to be 0.

Procedures are evaluated with the values of the given arguments.

In evaluating expressions, the standard rules of algebra are applied.
Unfortunately, this algebraic evaluation of an expression is not as
unambiguous as is numerical evaluation. This process is generally referred
to as 'simplification' in the sense that the evaluation usually but not
always produces a simplified form for the expression.

There are many options available to the user for carrying out such
simplification. If the user doesn't specify any method, the default method
is used. The default evaluation of an expression involves expansion of the
expression and collection of like terms, ordering of the terms, evaluation
of derivatives and other functions and substitution for any expressions



                                3-2

which have values assigned or declared (qv assignments and LET statements).
In many cases, this is all that the user needs.

The declarations by which the user can exercise some control over the way
in which the evaluation is performed are explained in another section. For
example, if a real (floating point) number is encountered during
evaluation, the system will normally convert it into a ratio of two
integers, and print a message informing the user of the conversion. If the
user wants to use real arithmetic, he can affect this by the command ON
FLOAT;. Other modes for coefficient arithmetic are described elsewhere.

If an illegal expression occurs during evaluation (such as division by zero)
or functions are called with the wrong number of arguments, an appropriate
error message is generated.


3.2 Integer Expressions
    _______ ___________

These are expressions which, because of the values of the constants and
variables in them, evaluate to whole numbers.

Examples:

        2,      37 * 999,       (X + 3)**2 - X**2 - 6*X

are obviously integer expressions.

        J + K - 2 * J**2

is an integer expression when J and K have values that are integers, or if
not integers are such that "the variables and fractions cancel out", as in

        K = 7/3 - J + 2/3 + 2*J**2.


3.3 Boolean Expressions
    _______ ___________

A boolean expression returns a truth value. In the algebraic mode of
REDUCE, boolean expressions have the syntactical form:

        <expression> <relational operator> <expression>
or
        <boolean function> (<arguments>)
or
        <boolean expression> <logical operator> <boolean expression>.

In addition to the logical and relational operators defined earlier as
infix operators (qv), the following boolean functions are also defined:

        FIXP(U)         determines if the expression U is integer or not.
        FREEOF(U,V)     determines if the expression U does not contain
                        the kernel (qv) V anywhere in its structure.
        NUMBERP(U)      determines if U is a number or not.



                                3-3

        ORDP(U,V)       determines if U is ordered ahead of V by
                        some canonical ordering (based on the
                        expression structure and an internal ordering
                        of identifiers).

In the algebraic mode of REDUCE the result, True or False, of such an
expression cannot be assigned to a variable. Boolean expressions can only
appear directly within IF, FOR, WHILE, and UNTIL statements, as described
in other sections.

Examples:

        J<1
        X>0  OR  X=-2
        NUMBERP X
        NUMBERP X AND X NEQ 0

When two or more boolean expressions are combined with AND, they are
evaluated one by one until a False expression is found. The rest are not
evaluated. Thus

        NUMBERP X AND NUMBERP Y AND X>Y

does not attempt to make the X>Y comparison unless X and Y are both
verified to be numbers.

Similarly, evaluation of a string of boolean expressions connected by OR
stops as soon as a True expression is found.

If an algebraic (non-boolean) expression is used in place where a boolean
expression is expected, then True is assumed (i.e., no error occurs) as in

        IF (X := A+B) THEN Y := C+D.


3.4 Proper Statements as Expressions
    ______ __________ __ ___________

Several kinds of proper statements (qv) deliver an algebraic or numeric
result of some kind, which can in turn be used as an expression or part of
an expression. For example, the assignment statement (placed in
parentheses) itself has a value, namely the value assigned: so

        2 * (X:=A+B)

is equal to 2*(A+B), as well as having the "side-effect" of assigning the
value A+B to X. In context,

        Y := 2 * (X:=A+B);

sets X to A+B and Y to 2*(A+B).

The sections on the various proper statement types indicate which can be
used usefully as expressions as well.



                                4-1


4. STATEMENTS
   __________

A statement is any allowed combination of reserved words and expressions,
and has the syntax

<statement> ::= <expression>|<proper statement>

A REDUCE program consists of a series of commands (qv), which are statements
each followed by a terminator:

<terminator> ::= ;|$

The division of the program into lines is arbitrary. Several statements
can be on one line, or one statement can be freely broken into several
lines. If the program is run interactively, statements ending with ; or $
are not processed until an end-of-line character is hit. This character
can vary from system to system, but is normally the RETURN key on an Ascii
terminal. Specific systems can also use additional keys as statement
terminators. For example, on the DECSystem 20, the ESCAPE key can be used.
This also terminates the line. Thus ESCAPE in this case is equivalent to
typing $ and hitting return: in fact in many contexts a dollar sign is
printed automatically when ESCAPE is hit.

If the statement is a proper statement, the appropriate action takes place.

Depending on the nature of the proper statement some appropriate result or
response may or may not print out, and the response may or may not depend
on the terminator used.

If the statement is an expression, it is evaluated. If the terminator was
a semicolon, the result is automatically printed. Because it is not
usually possible to know in advance how large an expression will be, no
explicit format statements are offered to the user. However, a variety of
output declarations are available so that the output can be produced in a
variety of forms. These output declarations are explained elsewhere.

If the statement is an expression and the terminator is a dollar sign or
an ESCAPE keystroke, the result of the evaluation is not automatically
printed out. The following sub-sections describe some proper statements
types in REDUCE.


4.1 Assignment Statements
    __________ __________

These statements have the syntax

<assignment statement> ::= <expression> := <expression>

The <expression> on the left side is normally the name of a variable, an
operator symbol with its list of arguments filled in, or an array name with
the proper number of integer subscript values within the array bounds.
(More general assignments such as A+B := C are in fact also allowed. The



                                4-2

effect of these is explained in the section "Substitutions for General
Expressions".)

        e.g.  A1 := B+C
              H(L,M) := X-2*Y     (where H is an operator)
              K(3,5) := X-2*Y     (where K is a 2-dim. array)

An assignment statement causes the expression on the right side to be
evaluated, and the resulting value is assigned to the variable or array
position or operator "position" indicated on the left.

If a semicolon is used as terminator when an assignment is issued as a
command (i.e. not as a part of a group statement or procedure or other
similar construct), the left-hand side symbol of the assignment statement
is printed out, followed by a ":=" , followed by the value of the
expression on the right.

It is also possible to write a multiple assignment statement:

    <expression> := <expression> := ... := <expression> := <expression>

In this form, each <expression> is set to the value of the rightmost
<expression>.


4.2 Group statements
    _____ __________

The group statement is a construct used where REDUCE expects a single
statement, but a series of actions needs to be performed. It is formed by
enclosing one or more statements (of any kind) between the symbols << and
>>, separated by semicolons or dollar signs -- it doesn't matter which.
The statements are executed one after another.

Examples will be given in the sections on IF and other types of statements
in which the << ... >> construct is useful.

If the last statement in the enclosed group has a value, then that is also
the value of the group statement. Care must be taken not to have a
semicolon or dollar sign after the last grouped statement, if the value of
the group is relevant: such an extra terminator causes the group to have
the value NIL or zero.


4.3 Conditional Statements
    ___________ __________

The conditional statement has the following syntax:

<conditional statement> ::= IF <boolean expression> THEN <statement>
                                 ELSE <statement>

The boolean expression is evaluated. If the result is True, the first
<statement> is executed. If it is False, the second is. In either case the
statement after the entire conditional statement is executed next.



                                4-3

 Examples:

        IF X=5 THEN A:=B+C ELSE D:=E+F

        IF X=5 AND NUMBERP Y
           THEN <<FF:=Q1; A:=B+C>>
           ELSE <<FF:=Q2; D:=E+F>>

Note the use of the group statement.

If it is the value of the conditional statement which is of primary
interest, it is often called a conditional expression instead. Its value
is the value of whichever statement was executed. (If the executed
statement has no value, the conditional expression has no value or the
value 0, depending on how it is used.)

Examples:

        A:=IF X<5 THEN 123 ELSE 456;

        B:=U + V**(IF NUMBERP Z THEN 10*Z  ELSE 1) + W;

If the value is of no concern, the ELSE clause may be omitted if no action
is required in the "False" case.

        IF X=5 THEN A:=B+C;

Note: If by mistake a scalar or numeric expression is used in place of the
boolean expression in forming a conditional -- for example, a variable is
written there -- the True alternative is always followed.


4.4 FOR Statements
    ___ __________

The FOR statement is used to define a variety of program loops. Its
general syntax is as follows:

    FOR <variable> := <number> STEP <number> UNTIL <number>

                        (DO <statement>
                        (SUM <algebraic expression>
                        (PRODUCT <algebraic expression>

If expressions that do not evaluate to numbers are used in the designated
places, an error will result.

The DO version of the FOR statement is like the FOR statement of ALGOL and
the DO statement of FORTRAN. The <statement> is executed repeatedly with
the <variable> running through the prescribed range of values. If the
limit is less than the starting value (in the case of negative steps:
greater), the <statement> is not executed at all.

Example:



                                4-4


        FOR I := 5 STEP 1 UNTIL 10 DO
                <<A(I):=I**2; B(I):=I**3>>

If A, B have been declared to be arrays, this stores 5**2 through 10**2 in
A(5) through A(10), and at the same time stores the cubes in the B array.

As a convenience, the common construction

                STEP 1 UNTIL

may be abbreviated to a colon. Thus we could write, instead of the above,

        FOR I := 5:10 DO <<A(I):=I**2; B(I):=I**3>>

The FOR ... DO statement is not intended to be used as an expression. If
it is, its value is 0.

The SUM and PRODUCT versions respectively form the sum and product of the
specified algebraic expression over the defined range. They are intended
to be used as expressions, and return the value of the computed sum or
product.

Examples:

        C := FOR J:=1 STEP 2 UNTIL 9 SUM J**2;
        D := FOR K:=0 STEP 1 UNTIL 4 PRODUCT (X+K);

This sets C to the sum of the squares of 1,3,5,7,9; and D is set to the
expression

        X * (X+1) * (X+2) * (X+3) * (X+4).

The control variable used in the FOR statement is actually a new variable,
not related to the variable of the same name outside the FOR statement. In
other words, executing a statement FOR I:= ... doesn't change the value
(if any) the user may have given I, or the system's assumption that I**2 =
-1.


4.5 WHILE ... DO
    _____ ___ __

The FOR ... DO feature allows easy coding of a repeated operation in which
the number of repetitions is known in advance. If the criterion for
repetition is more complicated, WHILE ... DO can often be used. Its syntax
is:

        WHILE <boolean expression> DO <statement>

For the meaning of boolean expression, see the appropriate section.

The WHILE ... DO controls the single statement following DO. If several
statements are to be repeated, as is almost always the case, they must be



                                4-5

grouped using the << ... >> as in the example below.

The WHILE condition is tested each time BEFORE the action following the DO
is attempted. If the condition is false to begin with, the action is not
performed at all. Make sure that what is to be tested has an appropriate
value initially.

Example:

Suppose we want to add up a series of terms, generated one by one, until
we reach a term which is less than 1/1000 in value.  For our simple
example, let us suppose the first term equals 1 and each term is gotten
from the one before by taking one third of it and adding one third its
square. We would write:

        EX:=0; TERM:=1;
        WHILE NUM(TERM - 1/1000) >= 0  DO
                <<EX := EX+TERM; TERM:=(TERM + TERM**2)/3>>;
        EX;

As long as TERM is greater than or equal ( >= ) to 1/1000 it will be added
to EX and the next TERM calculated. As soon as TERM becomes less than
1/1000 the WHILE test fails and the TERM will not be added.


4.6 REPEAT ... UNTIL
    ______ ___ _____

REPEAT ... UNTIL is very similar in purpose to WHILE ... DO. Its syntax
is:

        REPEAT <statement> UNTIL <boolean expression>

(PASCAL users note: Only a single statement -- usually a group statement
-- is allowed between the REPEAT and the UNTIL.)

There are two essential differences:

1) The test is performed after the controlled statement (or group of
statements) is executed, so the controlled statement is always executed at
least once.

2) The test is a test for when to stop rather than when to continue, so its
"polarity" is the opposite of that in WHILE ... DO.

Example:

We rewrite the example from the WHILE ... DO section:

        EX:=0; TERM:=1;
        REPEAT <<EX := EX+TERM; TERM:=(TERM + TERM**2)/3>>
           UNTIL NUM(TERM - 1/1000) < 0;
        EX;




                                4-6

The answer here will not be exactly the same as before, because the first
term which is less than 1/1000 WILL be added to EX this time.


4.7 Compound Statements
    ________ __________

Often the desired process can best (or only) be described as a series of
steps to be carried out one after the other. In many cases, this can be
achieved by use of the group statement (qv). However, each step often
provides some intermediate result, until at the end we have the final
result wanted. Alternatively, iterations on the steps are needed that are
not possible with constructs such as WHILE or REPEAT statements (qv). In
such cases the steps of the process must be enclosed between the words
BEGIN and END forming what is technically called a block or compound
statement. Such a compound statement can in fact be used wherever a group
statement appears. The converse is not true: BEGIN ... END can be used in
ways that << ... >> can not.

If intermediate results must be formed, local variables must be provided in
which to store them. "Local" means that their values are deleted as soon as
the block's operations are complete, and there is no conflict with
variables outside the block that happen to have the same name. Local
variables are created by a SCALAR declaration immediately after the BEGIN:

        SCALAR A,B,C,Z;

If more convenient, several SCALAR declarations can be given one after
another:

        SCALAR A,B,C;
        SCALAR Z;

In place of SCALAR one can also use the declarations INTEGER or REAL. In
the present version of REDUCE variables declared INTEGER are expected to
have only integer values, and are initialized to 0. REAL variables on the
other hand are currently treated as SCALAR.


CAUTION: INTEGER, REAL and SCALAR declarations can only be given
immediately after a BEGIN. An error will result if they are used after
other statements in a block (including ARRAY and OPERATOR declarations,
which are global in scope), or outside the top-most block (e.g., at the
top level). All variables declared SCALAR are automatically initialized to
zero in algebraic mode (NIL in symbolic mode).

Any symbols not declared as local variables in a block are global, in the
sense that they refer to the variables of the same name outside the block.
In particular, if they are not so declared at a higher level (e.g., in
another block or as parameters in a procedure (qv)), their values can be
permanently changed.

Following the SCALAR declaration(s), if any, write the statements to be
executed, one after the other, separated by delimiters (e.g., ; or $) (it



                                4-7

doesn't matter which).

The last statement in the body, just before END, need not have a terminator
(since the BEGIN ... END are in a sense brackets confining the block
statements). The last statement must also be the command RETURN followed by
the variable or expression whose value is to be the value returned by the
procedure. If the RETURN is omitted (or nothing is written after the word
RETURN) the value returned by the procedure will be zero (or NIL in
symbolic mode).

Remember to put a terminator after the END.

Example:

Given a previously assigned integer value for N, the following block will
compute the Legendre polynomial of degree N in the variable X:

     BEGIN SCALAR SEED,DERIV,TOP,FACT;
        SEED:=1/(Y**2 - 2*X*Y +1)**(1/2);
        DERIV:=DF(SEED,Y,N);
        TOP:=SUB(Y=0,DERIV);
        FACT:=FOR I:=1:N PRODUCT I;
        RETURN TOP/FACT
     END;


4.7.1 Compound Statements with GO TO
      ________ __________ ____ __ __

It is possible to have more complicated structures inside the BEGIN ...
END brackets than indicated in the previous example. That the individual
lines of the program need not be assignment statements, but could be
almost any other kind of statement or command, needs no explanation. For
example, conditional statements, and WHILE and REPEAT constructions, have
an obvious role in defining more intricate blocks.

If these structured constructs don't suffice, it is possible to use labels
and GO TOs within a compound statement, and also to use RETURN in places
within the block other than just before the END. The following subsections
discuss these matters in detail. For many readers the following example,
presenting one possible definition of a process to calculate the factorial
of N for preassigned N (there are far simpler ones!) will suffice:

Example:

     BEGIN SCALAR M;
         M:=1;
      L: IF N=0 THEN RETURN M;
         M:=M*N;
         N:=N-1;
         GO TO L
     END;



                                4-8


4.7.2 Labels and GO TO Statements
      ______ ___ __ __ __________

Within a BEGIN ... END compound statement it is possible to label
statements, and transfer to them out of sequence using GO TO statements.
Only statements on the top level inside compound statements can be
labeled, not ones inside subsidiary constructions like << ... >>, IF ...
THEN ..., WHILE ... DO ... , etc.

Labels and GO TO statements have the syntax:

<go to statement> ::= GO TO <label> | GOTO <label> <label> ::=
<identifier> <labeled statement> ::= <label>:<statement>

While GO TO is an unconditional transfer, it is frequently used in
conditional statements such as

        IF X>5 THEN GO TO ABCD;

giving the effect of a conditional transfer.


4.7.3 RETURN Statements
      ______ __________

The value corresponding to a BEGIN ... END compound statement, such as a
procedure body, is normally 0 (NIL in symbolic mode). By executing a
RETURN statement in the compound statement a different value can be
returned. After a RETURN statement is executed no further statements
within the compound statement are.

Examples:

                RETURN X+Y;
                RETURN M;
                RETURN;

Note that parentheses are not required around the X+Y, although they are
permitted. The last example is equivalent to RETURN 0; .

Since RETURN actually moves up only one block level, in a sense the casual
user is not expected to understand, we tabulate some cautions concerning
its use.

RETURN can be used on the top level inside the compound statement, i.e. as
one of the statements bracketed together by the BEGIN ... END.

RETURN can be used within a top level << ... >> construction within the
compound statement.

RETURN can be used within an IF ... THEN ... ELSE ... on the top level
within the compound statement.

If RETURN is used in a FOR, WHILE, or REPEAT statement within the compound



                                4-9

statement, presumably to force early termination in some circumstance, the
RETURN only exits from the FOR, WHILE, or REPEAT, not from the compound
statement (and procedure).

Example:

Suppose that as a step within a process you want to search a 100-place
array A(0) through A(99), and if X is found in some A(I) you want to set Y
to B(I), B being a similar array. Write

    Y := FOR I:=0:99 DO IF A(I)=X THEN RETURN B(I);

If X is found, Y will be set to B(I). If not found, the Y will be set to 0
(the normal "value" of a FOR ... DO).

If instead of setting Y to B(I) we want the result to be the B(I) (or zero
if not found), we could use

    RETURN FOR I:=0:99 DO IF A(I)=X THEN RETURN B(I);

Note the two RETURNs!



                                5-1


5. COMMANDS AND DECLARATIONS
   ________ ___ ____________

A command is an order to the system to do something. Some commands cause
visible results (such as calling for input or output); others, usually
called declarations, set options, define properties of variables, or define
procedures. Commands are formally defined as a statement followed by a
terminator

        <command> ::= <statement> <terminator>

        <terminator> ::= ;|$

Some REDUCE commands and declarations are described in the following
sub-sections.


5.1 Array Declarations
    _____ ____________

Array declarations in REDUCE are similar to FORTRAN dimension statements.

        e.g. ARRAY  A(10),B(2,3,4);

Array indices each range from 0 to the value declared. An element of an
array is referred to in standard FORTRAN notation,

        e.g. A(2)

We can also use an expression for defining an array bound, provided the
value of the expression is a positive integer. For example, if X has the
value 10 and Y the value 7 then

        ARRAY C(5*X+Y)   is the same as ARRAY C(57).

If an array is referenced by an index outside its range, an error occurs.
If the array is to be one-dimensional, and the bound a number or a
variable (not a more general expression) the parentheses may be omitted:

        ARRAY A 10, C 57;

All array elements are initialized to 0 at declaration time. In other words,
an array element cannot stand for itself. If this is required, then an
operator (qv) should be used instead.

Array declarations can appear anywhere in a program. Once a symbol is
declared to name an array, it can not also be used to name an operator or
a procedure. It can however be re-declared to be an array, and its size
may be changed at that time. An array name can also continue to be used as
an ordinary variable.



                                5-2


5.2 Mode Handling Declarations
    ____ ________ ____________

Two declarations are offered to the user for controlling various system
options. Each option is represented by a so-called "switch" being ON or
OFF. The declarations ON and OFF take a list of switch names as argument
and turn them on and off respectively.

        e.g.    ON TIME;

causes the system to print a message after each command giving the elapsed
cpu time since the last command, or since TIME was last turned off, or the
session began. Another useful switch with interactive use is DEMO, which
causes the system to pause after each command in a file until a Return is
typed on the terminal. This enables a user to set up a demonstration file
and step through it command by command.

As with most declarations, arguments to ON and OFF may be strung together
separated by commas. For example,

                OFF TIME,DEMO;

will turn off both the time messages and the demonstration switch.

We note here that while most ON and OFF commands are obeyed almost
instantaneously, some trigger time-consuming actions such as reading in
necessary modules from secondary storage.

Caution: No error message is generated if the name of a switch is
mistyped. If mistyped, the intended option change simply doesn't take
place.


5.3 END
    ___

The identifier END has three separate uses.

1) Its use in a BEGIN ... END bracket has been discussed in connection
with compound statements (qv).

2) Files to be read using IN should end with an extra END; command. The
reason for this is explained in the section on the IN command (qv). This
use of END does not allow an immediately preceding END (such as the END of
a procedure definition), so we advise using ;END; there.

3) A command END; entered at the top level transfers control to the
Standard LISP system which is the host of the REDUCE system. All files
opened by IN or OUT statements are closed in the process. END; does not
stop REDUCE. Those familiar with LISP can experiment with typing
identifiers and (<function name><argument list>) lists to see the value
returned by LISP. (No terminators, other than RETURN, should be used.) The
data structures created during the REDUCE run are accessible.




                                5-3

You remain in this LISP mode until you make a LISP error, or explicitly
re-enter REDUCE by saying (BEGIN) at the LISP top level. Any error
automatically returns you to REDUCE (always the algebraic mode, even if
you were in symbolic mode before the END;). If you are in LISP mode by
mistake -- which is usually the case, the result of typing more ENDs than
BEGINs -- type some identifier you haven't used, perhaps BYE, and hit
RETURN. If you prefer, type (BEGIN) in parentheses as shown and hit
RETURN.


5.4 BYE
    ___

The command BYE; stops the execution of REDUCE and returns you to the
computer system monitor program. Where the implementation permits it, your
REDUCE session is destroyed. If you wish to return later to that session,
use QUIT; instead.


5.5 QUIT
    ____

The command QUIT; stops the execution of REDUCE and returns you to the
computer system monitor program. Where the implementation permits it, your
REDUCE session is retained so that you can use it again later. If you do
not wish to reenter the REDUCE session, use BYE; instead.


5.6 SHOWTIME
    ________

SHOWTIME; prints the elapsed time since the last call of this command or,
on its first call, since the current REDUCE session began. The time is
normally given in milliseconds and gives the time as measured by a system
clock. The operations covered by this measure are system dependent.


5.7 DEFINE
    ______

The command DEFINE allows a user to supply a new name for any identifier
or replace it by any well-formed expression. Its argument is a list of
expressions of the form

        <identifier> = <number>|<identifier>|<operator>|
                        <reserved word>|<expression>

Example:

        DEFINE BE==,X=Y+Z;

means that 'BE' will be interpreted as an equal sign, and 'X' as the
expression Y+Z from then on. This renaming is done at the input level and
therefore takes precedence over any other replacement declared for the
same identifier. It stays in effect until the end of the REDUCE run.

The identifiers ALGEBRAIC and SYMBOLIC have properties which prevent



                                5-4

DEFINE from being used on them. To define ALG to be a synonym for
ALGEBRAIC, the more complicated construction

        PUT('ALG,'NEWNAM,'ALGEBRAIC);

must be used.



                                6-1


6. BUILT-IN PREFIX OPERATORS
   ________ ______ _________

In the following subsections are descriptions of the most useful prefix
operators built into REDUCE. Some are fully defined internally as
procedures; others are more nearly abstract operators, with only some of
their properties known to the system.

In many cases, an operator is described by a prototypical header line as
follows. Each formal parameter is given a name and followed by its allowed
type. The names of classes referred to in the definition are printed in
lower case, and parameter names in upper case. If a parameter type is not
commonly used, it may be a specific set enclosed in brackets {...}.
Operators which accept formal parameter lists of arbitrary length have the
parameter and type class enclosed in square brackets indicating that zero
or more occurrences of that argument are permitted. Optional parameters
and their type classes are enclosed in angle brackets.


6.1 Numerical Functions
    _________ _________

REDUCE knows that the following represent functions that can take an
arbitrary number of numerical expressions as their arguments:

        MAX MIN.

For example,

        MAX(2,-3,4,5) ==> 5

        MIN(2,-2)     ==> 2.

In addition, the function ABS will return the absolute value of its single
numerical argument.

An error occurs if a non-numeric argument is supplied to any of these
functions.


6.2 Mathematical Functions
    ____________ _________

REDUCE knows that the following represent mathematical functions that can
take arbitrary scalar expressions as their single argument:

        SIN COS TAN COT ASIN ACOS ATAN SQRT EXP LOG SINH COSH TANH
        ASINH ACOSH ATANH ERF DILOG EXPINT.

It only knows the most elementary identities and properties of these
functions, however (except in ON NUMVAL mode (qv)). For example:

     COS (-X) = COS (X)                 SIN (-X) = - SIN (X)
     COS (n*PI) = (-1)**n               SIN (n*PI) = 0
     LOG (E)  = 1                       E**(I*PI/2) = I



                                6-2

     LOG (1)  = 0                       E**(I*PI) = -1
     LOG (E**X) = X                     E**(3*I*PI/2) = -I
     SQRT (-X) = I * SQRT(X)            SQRT (A**2) = A
     SQRT (A*B) = SQRT(A) * SQRT(B)     SQRT (100) = 10
     SQRT (200) = 10 * SQRT(2), etc.

REDUCE replaces SQRT(A**2) by A, which is usually reasonable but can cause
trouble if A eventually is given a value which is a negative number.

The square root function can be input using the name SQRT, or the power
operation **(1/2). On output, unsimplified square roots are represented by
the operator SQRT rather than a fractional power.

The derivatives of these functions are also known to the system.

The user can add further rules for the reduction of expressions involving
these operators by using the LET command (qv).

The statement that REDUCE knows very little about these functions applies
only in the mathematically exact OFF NUMVAL mode. If the mode ON NUMVAL is
set, any of the functions

        SIN COS TAN ASIN ACOS ATAN SQRT EXP LOG

which is given a numeric argument has its value calculated to the current
degree of floating point precision.


6.3 DF
    __

The operator DF is used to represent partial differentiation with respect
to one or more variables. It is used with the syntax:

     DF(EXPRN:algebraic,[VAR:kernel<,NUM:integer>]):algebraic.

The first argument is the expression to be differentiated. The remaining
arguments specify the differentiation variables and the number of times
they are applied.

The number NUM may be omitted if it is 1.

        e.g.    DF(Y,X) = dY/dX
                             2    2
                DF(Y,X,2) = d Y/dX
                                     5     2       2
                DF(Y,X1,2,X2,X3,2)= d Y/dX1 dX2 dX3

The evaluation of DF(Y,X) proceeds as follows: first, the values of Y and
X are found. Let us assume that X has no assigned value, so its value is
X. Each term or other part of the value of Y which contains the variable X
is differentiated by the standard rules. If Z is another variable, not X
itself, then its derivative with respect to X is taken to be 0, unless Z
has previously been declared to DEPEND (qv) on X, in which case the



                                6-3

derivative is reported as the symbol DF(Z,X).


6.3.1 Adding Differentiation Rules
      ______ _______________ _____

The LET statement (qv) can be used for the introduction of rules for
differentiation of user-defined operators. Its general form is

        FOR ALL <var1>,...,<varn>
             LET DF(<operator><varlist>,<vari>)=<expression>

where <varlist> ::= (<var1>,...,<varn>), and <var1>,...,<varn> are the
dummy variable arguments of <operator>.

An analogous form applies to infix operators.

Examples:

        FOR ALL X LET DF(TAN X,X)= SEC(X)**2;
           (This is how the Tan differentiation rule appears in the
            REDUCE source.)
        FOR ALL X,Y LET DF(F(X,Y),X)=2*F(X,Y), DF(F(X,Y),Y)=X*F(X,Y);

Notice that all dummy arguments of the relevant operator must be declared
arbitrary by the FOR ALL command, and that rules may be supplied for
operators with any number of arguments. If no differentiation rule appears
for any argument in an operator, the differentiation routines will return
as result an expression in terms of DF. For example, if the rule for the
differentiation with respect to the second argument of F is not supplied,
the evaluation of DF(F(X,Z),Z) would leave this expression unchanged. (No
DEPEND declaration (qv) is needed here, since F(X,Z) obviously "depends
on" Z.


6.4 INT
    ___

INT is an operator in REDUCE for analytic integration using a combination
of the Risch-Norman algorithm and pattern matching. It is used with the
syntax:

   INT(EXPRN1:algebraic,VAR:kernel):algebraic.

It will return correctly the indefinite integral for expressions
comprising polynomials, log functions, exponential functions and tan and
atan. The arbitrary constant is not represented. If the integral cannot be
done in closed terms, it returns a formal integral for the answer in one
of two ways:

        1) It returns the input, INT( ... , ... ) unchanged.
        2) It returns an expression involving INT's of some
           other functions (sometimes more complicated than
           the original one, unfortunately).




                                6-4

Rational functions can be integrated when the denominator is factorizable
by the program.

In addition it will attempt to integrate expressions involving error
functions, dilogarithms and other trigonometric expressions. In these
cases it might not always succeed in finding the solution, even if one
exists.

Examples:

        INT(LOG(X),X) ==> X*(LOG(X) - 1),
        INT(E**X,X)   ==> E**X.

The program checks that the variable supplied is a variable and gives an
error if it is not.


6.4.1 Options
      _______

The switch TRINT when on will trace the operation of the algorithm. It
produces a great deal of output in a somewhat illegible form, and is not
of much interest to the general user.

If the switch FAILHARD is on the algorithm will terminate with an error if
the integral cannot be done in closed terms, rather than return a formal
integration form.

The switch NOLNR suppresses the use of the linear properties of
integration in cases when then integral cannot be found in closed terms.


6.4.2 Advanced Use
      ________ ___

If a function appears in the integrand which is not one of the functions
EXP, ERF, TAN, ATAN, LOG, DILOG then the algorithm will make an attempt to
integrate the argument if it can, differentiate it and reach a known
function. However the answer cannot be guaranteed in this case. If a
function is known to be algebraically independent of this set it can be
flagged transcendental by

FLAG('TRILOG,'TRANSCENDENTAL);

in which case this function will be added to the permitted field
descriptors for an genuine decision procedure. If this is done the user is
responsible for the mathematical correctness of his actions.

The current version does not deal with algebraic extensions. Thus
integration of expressions involving square roots and other like things
will lead to trouble. If however the answer is known to involve certain
logarithms they can be added as a 'hint' by providing a third argument
which is a list of the hints. This must only be done if the hints are the
correct ones, and strange results will occur if they are not.



                                6-5


6.4.3 References
      __________

        A. C. Norman & P. M. A. Moore, "Implementing the New Risch
                Algorithm", Proc. 4th International Symposium on Advanced
                Comp. Methods in Theor. Phys., CNRS, Marseilles, 1977.
        S. J. Harrington, "A New Symbolic Integration System in Reduce",
                Comp. Journ. 22 (1979) 2.
        A. C. Norman & J. H. Davenport, "Symbolic Integration - The Dust
                Settles?", Proc. EUROSAM 79, Lecture Notes in Computer
                Science 72, Springer-Verlag, Berlin Heidelberg New York
                (1979) 398-407.

Comments and complaints should be sent to;

        Professor John P. Fitch,   or   Dr. Arthur C. Norman
        Dept of Computing Studies,      Computer Laboratory,
        Bath University,                University of Cambridge
        Bath, Somerset                  Cambridge, CB2 3QG,
        England                         England.


6.5 SOLVE
    _____

SOLVE is an EXPERIMENTAL operator for solving one or more simultaneous
algebraic equations. It is used with the syntax:

     SOLVE(EXPRN:algebraic[,VAR:kernel]):integer.

EXPRN is of the form <expression> or LST(<expression1>, <expression2>,
...). Each expression is the difference in the two sides of an algebraic
equation. The second argument may be omitted if the number of distinct
top-level kernels equals the number of unknowns, in which case these
kernels are presumed to be the unknowns. Simultaneous equations must
currently be linear in the kernels in terms of which the solutions are
sought.


6.5.1 Options
      _______

If SOLVESINGULAR is on, degenerate systems such as x+y=0,2x+2y=0 will be
solved by introducing appropriate arbitrary constants.

For example:
            SOLVE(LOG(SIN(X+3))**5 - 8);
or
            SOLVE(A*LOG(SIN(X+3))**5 - B, SIN(X+3));
or
            SOLVE(LST(A*X+Y-3, Y+2), X, Y);

If SOLVEINTERVAL is on, real roots which cannot be determined exactly, are
isolated using Vincent's method, if possible. (CAUTION: This loses if the
roots are very large.) SOLVEINTERVAL is initially off. At most 10 real



                                6-6

roots are isolated. If more are needed, define an N by 2 array, where N is
greater than or equal to the number of roots to be isolated, and put its
name in the (symbolic) global variable !!INTERVALARRAY. Isolated solutions
are returned in the form: INTERVL(lowlim, highlim), where lowlim and
highlim are rational numbers.

SOLVE returns the number of rows in the global matrix SOLN, after storing
one solution per row with the components in the order of the kernels in the
second argument of SOLVE. When there is only one equation, the
corresponding multiplicities are stored in the global one-column matrix
MULTIPLICITY. A negative multiplicity indicates that the corresponding row
of SOLN is an unsolved factor with the absolute value of that multiplicity.
This situation is also revealed by the appearance of the unknown in that
row of SOLN.

SOLN is automatically printed if SOLVEWRITE is ON, which is the default.

For one equation, SOLVE recursively uses square-free factorization together
with the known inverses of LOG, SIN, COS, **, ACOS, ASIN, and linear,
quadratic, cubic, quartic, or binomial factors. For simultaneous linear
equations, the built-in Bareiss matrix equation solver is used, SOLVE
merely providing a convenient form of input for small or sparse systems.

The consistent singular equation 0=0 or equations involving functions with
multiple inverses may introduce unique new indeterminant kernels
ARBCOMPLEX(j), ARBREAL(j), or ARBINT(j), (j=1,2,...), representing
arbitrary complex, real or integer numbers respectively. To automatically
select the principal branches, do OFF ALLBRANCH. To suppress solutions of
consistent singular equations do OFF SOLVESINGULAR.

To incorporate additional inverse functions do, for example:

     PUT('SINH,'INVERSE,'ASINH);
     PUT('ASINH,'INVERSE,'SINH);

together with any desired simplification rules such as

     FOR ALL X LET SINH(ASINH(X))=X, ASINH(SINH(X))=X;

For completeness, functions with non-unique inverses should be treated as
**, SIN, and COS are in the SOLVE module source.

Arguments of ASIN and ACOS are not checked to insure that the absolute
value of the real part does not exceed 1; and arguments of LOG are not
checked to insure that the absolute value of the imaginary part does not
exceed PI; but checks (perhaps involving user response for non-numerical
arguments) could be introduced using LET statements for these operators.



                                6-7


6.6 SUB
    ___

Syntax: SUB([VAR:kernel = EXPRN:algebraic,]EXPRN1:algebraic):algebraic.

The SUB operator gives the algebraic result of replacing every occurrence
of the variable VAR in the expression EXPRN1 by the expression EXPRN.
Specifically, EXPRN1 is first evaluated using all available rules. Next
the substitutions are made, and finally the substituted expression is
reevaluated. When more than one variable occurs in the substitution list,
the substitution is performed by recursively walking down the tree
representing EXPRN1, and replacing every VAR found by the appropriate
EXPRN. The EXPRN are not themselves searched for any occurrences of the
various VARs. The trivial case SUB(EXPRN1) returns the algebraic value of
EXPRN1.

Example:

        SUB(X=A+Y,Y=Y+1,X**2+Y**2) ==>
             (A+Y)**2+(Y+1)**2   (normally multiplied out).

Note that the assignments X:=A+Y, etc, do not take place.


6.7 Declaring new Prefix Operators
    _________ ___ ______ _________

The user may add new prefix operators to the system by the using the
declaration OPERATOR.

        e.g.  OPERATOR  H,G1,ARCTAN;

adds the prefix operators H, G1 and ARCTAN to the system.

This allows symbols like H(W), H(X,Y,Z), G1(P+Q), ARCTAN(U/V) to be used
in expressions, but no meaning or properties of the operator are implied.
The same operator symbol can be used equally well as a 1-, 2-, 3-, etc.-
place operator.

To give a meaning to an operator symbol, or express some of its
properties, LET statements can be used, or the operator can be given a
definition as a procedure (qv).

If the user forgets to declare an identifier as an operator, the system
will prompt the user to do so in interactive mode, or do it automatically
in non-interactive mode. A diagnostic message will also be printed if an
identifier is declared operator more than once.


6.7.1 Declaring new Infix Operators
      _________ ___ _____ _________

The advanced user can add new infix operators by using the declarations
INFIX and PRECEDENCE.




                                6-8

        e.g.    INFIX MM;
                PRECEDENCE MM,-;

The declaration INFIX MM would allow one to use the symbol MM as an infix
operator:

        A MM B   instead of   MM(A,B).
        
The declaration PRECEDENCE MM,- says that MM should be inserted into the
infix operator precedence list (qv) just AFTER the - operator. This gives
it higher precedence than - and lower precedence than * . Thus

        A - B MM C - D   means   A - (B MM C) - D,
while   A * B MM C * D means (A * B) MM (C * D).

Both infix and prefix operators have no transformation properties unless
LET statements or procedure declarations are used to assign a meaning.

We should note here that infix operators so defined are always binary:

        A MM B MM C means (A MM B) MM C.


6.8 Linear Operators
    ______ _________

An operator can be declared to be linear in its first argument over powers
of its second argument. If an operator F is so declared, F of any sum is
broken up into sums of F's, and any factors which are not powers of the
variable are taken outside. This means that F must have (at least) two
arguments. In addition, the second argument must be an identifier (or more
generally a kernel), not an expression.

Example:

If F were declared linear, then

    F(A*X**5 + B*X + C,X) ==> A*F(X**5,X) + B*F(X,X) + C*F(1,X).

More precisely, not only will the variable and its powers remain within the
scope of the F operator, but so will any variable and its powers which had
been declared to DEPEND (qv) on the prescribed variable; and so would any
expression which contains that variable or a dependent variable on any
level : e.g. COS(SIN(X)).

To declare F and G to be linear operators, use:

        LINEAR F,G;

(If F or G were previously declared OPERATOR, there is a warning message,
but the LINEAR declaration is accepted.)

The analysis is done of the first argument with respect to the second; any
other arguments are ignored. It uses the following rules of evaluation:



                                6-9


        F(0) => 0
        F(-Y,X) => -F(Y,X)
        F(Y+Z,X) => F(Y,X)+F(Z,X)
        F(Y*Z,X) => Z*F(Y,X) if Z does not depend on X.
        F(Y/Z,X) => F(Y,X)/Z if Z does not depend on X.

To summarize, Y "depends" on the indeterminate X in the above if either of
the following hold:

1)  Y is an expression which contains X at any level as a variable,
    e.g.: COS(SIN(X))

2) Any variable in the expression Y has been declared dependent on
    X by use of the declaration DEPEND (qv).

The use of such linear operators can be seen in the paper Fox, J.A. and A.
C. Hearn, "Analytic Computation of Some Integrals in Fourth Order Quantum
Electrodynamics" Journ. Comp. Phys. 14 (1974) 301-317, which contains a
complete listing of a program for definite integration of some expressions
which arise in fourth order quantum electrodynamics.


6.9 Non-Commuting Operators
    _____________ _________

An operator can be declared to be non-commutative under multiplication by
the declaration NONCOM.

Example: If the declaration NONCOM U,V; is given, then the expressions
U(X)*U(Y)-U(Y)*U(X) and U(X)*V(Y)-V(Y)*U(X) will remain unchanged on
simplification, and in particular will not simplify to zero.

Note that it is the operator (U and V in the above example) and not the
variable that has the non-commutative property.

The LET statement may be used to introduce rules of evaluation for such
operators. In particular, the boolean operator ORDP is useful for
introducing an ordering on such expressions.

Example: The rule

     FOR ALL X,Y SUCH THAT X NEQ Y AND ORDP(X,Y)
         LET U(X)*U(Y)= U(Y)*U(X)+COMM(X,Y);

would introduce the commutator of U(X) and U(Y) for all X and Y. Note that
since ORDP(X,X) is True, the equality check is necessary in the degenerate
case to avoid a circular loop in the rule.



                                6-10


6.10 Creating and Removing Variable Dependency
     ________ ___ ________ ________ __________

There are several facilities in REDUCE, such as the differentiation
operator and the linear operator facility, which can utilize knowledge of
the dependency between various variables, or kernels (qv). Such dependency
may be expressed by the command DEPEND. DEPEND takes an arbitrary number
of arguments and sets up a dependency of the first argument on the
remaining arguments.

     e.g.: DEPEND X, Y, Z;

says that X is dependent on both Y and Z.

     DEPEND Z,COS(X),Y;

says that Z is dependent on COS(X) and Y.

Dependencies introduced by DEPEND can be removed by the command NODEPEND.
The arguments of this are the same as for DEPEND.

e.g., given the above dependencies,

     NODEPEND Z,COS(X);

says that Z is no longer dependent on COS(X), although it remains
dependent on Y.



                                7-1


7. DISPLAY AND STRUCTURING OF EXPRESSIONS
   _______ ___ ___________ __ ___________

In this section, we consider a variety of commands and operators which
permit the user to obtain various parts of algebraic expressions and also
display their structure in a variety of forms. Also presented are some
additional concepts in the REDUCE design that help the user gain a better
understanding of the structure of the system.


7.1 Kernels
    _______

REDUCE is designed so that each operator in the system has an evaluation
(or simplification) function associated with it which transforms the
expression into an internal canonical form. This form, which bears little
resemblance to the original expression, is described in detail in Hearn, A.
C., "REDUCE 2, A System and Language for Algebraic Manipulation," Proc. of
Second Symposium on Symbolic and Algebraic Manipulation, ACM, New York
(1971) 128-133.

The evaluation function may transform its arguments in one of two
alternative ways. First, it may convert the expression into other
operators in the system, leaving no functions of the original operator for
further manipulation. This is in a sense true of the evaluation functions
associated with the operators +, * and / , for example, because the
canonical form does not include these operators explicitly. It is also
true of an operator such as the determinant operator DET (qv) because the
relevant evaluation function calculates the appropriate determinant, and
the operator DET no longer appears. On the other hand, the evaluation
process may leave some residual functions of the relevant operator. For
example, with the operator COS, a residual expression like COS(X) may
remain after evaluation unless a rule for the reduction of cosines into
exponentials, for example, were introduced. These residual functions of an
operator are termed kernels and are stored uniquely like variables.
Subsequently, the kernel is carried through the calculation as a variable
unless transformations are introduced for the operator at a later stage.

In cases where the arguments of the kernel operators may be reordered, the
system puts them in a canonical order, based on an internal intrinsic
ordering of the variables. However, some commands allow arguments in the
form of kernels, and the user has no way of telling what internal order the
system will assign to these arguments. To resolve this difficulty, we
introduce the notion of a kernel form as an expression which transforms to
a kernel on evaluation.

Examples of kernel forms are:

        A
        COS (X*Y)
        LOG (SIN (X))

whereas




                                7-2

        A*B
        (A+B)**4

are not.

We see that kernel forms can usually be used as generalized variables, and
most algebraic properties associated with variables may also be associated
with kernels.


7.2 The Expression Workspace
    ___ __________ _________

Several mechanisms are available for saving and retrieving previously
evaluated expressions. The simplest of these refers to the last algebraic
expression simplified. When an assignment of an algebraic expression is
made, or an expression is evaluated at the top level, (i.e., not inside a
compound statement or procedure) the results of the evaluation are
automatically saved in a variable WS which we shall refer to as the
workspace. (More precisely, the expression is assigned to the variable WS
which is then available for further manipulation.)

Example:

If we evaluate the expression (X+Y)**2 at the top level and next wish to
differentiate it with respect to Y, we can simply say

        DF(WS,Y);

to get the desired answer.

If the user wishes to assign the workspace to a variable or expression for
later use, the SAVEAS statement can be used. It has the syntax

        SAVEAS <expression>

e.g. after the differentiation in the last example, the workspace holds
the expression 2*X+2*Y. If we wish to assign this to the variable Z we can
now say

        SAVEAS Z;

If the user wishes to save the expression in a form that allows him to use
some of its variables as arbitrary parameters, the FOR ALL (qv) command
can be used.

Example:

        FOR ALL X SAVEAS H(X);

with the above expression would mean that H(Z) evaluates to 2*Y+2*Z.

A further method for referencing more than the last expression is described
in the section on interactive use of REDUCE.



                                7-3


7.3 Output of Expressions
    ______ __ ___________

A considerable degree of flexibility is available in REDUCE in the printing
of expressions generated during calculations. No explicit format
statements are supplied, as these prove to be of little use in algebraic
calculations, where the size of output or its composition is not generally
known in advance. Instead, REDUCE provides a series of mode options to the
user which should enable him to produce his output in a comprehensible and
possibly pleasing form.

The most extreme option offered is to suppress the output entirely from
any top level evaluation. This is accomplished by turning off the switch
OUTPUT which is normally on. It is useful for limiting output when loading
large files or producing "clean" output from the prettyprint programs (qv).

In most circumstances, however, we wish to view the output, so we need to
know how to format it appropriately. As we mentioned earlier, an algebraic
expression is normally printed in an expanded form, filling the whole
output line with terms. Certain output declarations, however, can be used
to affect this format. To begin with, we look at an operator for changing
the length of the output line.


7.3.1 LINELENGTH
      __________

This operator is used with the syntax

     LINELENGTH(NUM:integer):integer,

and sets the output line length to the integer NUM. It returns the
previous output line length (so that it can be stored for later resetting
of the output line if needed).


7.3.2 Output Declarations
      ______ ____________

We now describe a number of switches and declarations which are available
for controlling output formats. It should be noted, however, that the
transformation of large expressions to produce these varied output formats
can take a lot of computing time and space. If a user wishes to speed up
the printing of his output in such cases, he can turn off the switch PRI.
If this is done, then output is produced in one fixed format, which
basically reflects the internal form of the expression, and none of the
options below apply. PRI is normally on.

With PRI on, the output declarations and switches available are as
follows:



                                7-4


7.3.2.1 ORDER
        _____

The declaration ORDER may be used to order variables on output. The syntax
is:

        ORDER V1,...VN;

where the Vi are kernels (qv). Thus,

                ORDER X,Y,Z;

orders X ahead of Y, Y ahead of Z and all three ahead of other variables
not given an order. ORDER NIL; resets the output order to the system
default. The order of variables may be changed by further calls of ORDER,
but then the reordered variables would have an order lower than those in
earlier ORDER calls. Thus,

                ORDER X,Y,Z;

                ORDER Y,X;

would order Z ahead of Y and X. The default ordering is implementation
dependent, but is usually alphabetic.


7.3.2.2 FACTOR
        ______

This declaration takes a list of identifiers or kernels (qv) as argument.
FACTOR is not a factoring command (use FACTORIZE or the FACTOR switch (qv)
for this purpose); rather it is a separation command. All terms involving
fixed powers of the declared expressions are printed as a product of the
fixed powers and a sum of the rest of the terms.

All expressions involving a given prefix operator may also be factored by
putting the operator name in the list of factored identifiers.

        e.g. FACTOR X,COS,SIN(X);

causes all powers of X and SIN(X) and all functions of COS to be factored.

The declaration REMFAC V1,...,Vn; removes the factoring flag from the
expressions V1 through Vn.


7.3.3 Output Control Switches
      ______ _______ ________

In addition to these declarations, the form of the output can be modified
by switching various output control switches using the declarations ON and
OFF. We shall illustrate the use of these switches by an example, namely
the printing of the expression

                X**2*(Y**2+2*Y)+X*(Y**2+Z)/(2*A).



                                7-5

 The relevant switches are as follows:


7.3.3.1 ALLFAC
        ______

This switch will cause the system to search the whole expression, or any
sub-expression enclosed in parentheses, for simple multiplicative factors
and print them outside the parentheses. Thus our expression with ALLFAC
off will print as

            2  2        2          2
        (2*X *Y *A + 4*X *Y*A + X*Y  + X*Z)/(2*A)

and with ALLFAC on as

                2                2
        X*(2*X*Y *A + 4*X*Y*A + Y  + Z)/(2*A)

ALLFAC is normally on, and is on in the following examples, except where
otherwise stated.


7.3.3.2 DIV
        ___

This switch makes the system search the denominator of an expression for
simple factors which it divides into the numerator, so that rational
fractions and negative powers appear in the output. With DIV on, our
expression would print as

              2                2  (-1)        (-1)
        X*(X*Y  + 2*X*Y + 1/2*Y *A     + 1/2*A    *Z)

DIV is normally off.


7.3.3.3 LIST
        ____

This switch causes the system to print each term in any sum on a separate
line. With LIST on, our expression prints as

                2
        X*(2*X*Y *A

            + 4*X*Y*A

               2
            + Y

            + Z)/(2*A)

LIST is normally off.



                                7-6


7.3.3.4 RAT
        ___

This switch is only useful with expressions in which variables are
factored with FACTOR. With this mode, the overall denominator of the
expression is printed with each factored sub-expression. We assume a prior
declaration FACTOR X; in the following output. We first print the
expression with RAT off:

            2                   2
        (2*X *Y*A*(Y + 2) + X*(Y  + Z))/(2*A)

With RAT on the output becomes:

         2                 2
        X *Y*(Y + 2) + X*(Y  + Z)/(2*A)

RAT is normally off.

Next, if we leave X factored, and turn on both DIV and RAT, the result
becomes

         2                    (-1)   2
        X *Y*(Y + 2) + 1/2*X*A    *(Y  + Z)

Finally, with X factored, RAT on and ALLFAC off we retrieve the original
structure

         2   2              2
        X *(Y  + 2*Y) + X*(Y  + Z)/(2*A)


7.3.4 WRITE Command 
      _____ _______ 

In simple cases no explicit output command is necessary in REDUCE, since
the value of any expression is automatically printed if a semicolon is
used as a delimiter. There are, however, several situations in which such
a command is useful.

In a FOR, WHILE, or REPEAT statement it may be desired to output something
each time the statement within the loop construct is repeated.

It may be desired for a procedure to output intermediate results or other
information while it is running. It may be desired to have results labeled
in special ways, especially if the output is directed to a file or device
other than the terminal.

The WRITE command consists of the word WRITE followed by one or more items
separated by commas, and followed by a terminator. There are three kinds
of items which can be used:

1) Expressions (including variables and constants).  The expression is
evaluated, and the result is printed out.



                                7-7

 2) Assignments. The expression on the right side of the := operator is
evaluated, and is assigned to the variable on the left; then the symbol on
the left is printed, followed by a ":=", followed by the value of the
expression on the right -- almost exactly the way an assignment followed
by a semicolon prints out normally. (The difference is that if the WRITE
is in a FOR statement and the left-hand side of the assignment is an array
position or something similar containing the variable of the FOR
iteration, then the value of that variable is inserted in the printout.)

3) Arbitrary strings of characters, preceded and followed by double-quote
(") marks.

The items specified by a single WRITE statement print side by side on one
line. (The line is broken automatically if it is too long.) Strings print
exactly as quoted.

The print line is closed at the end of a WRITE command evaluation.
Therefore the command WRITE ""; (specifying nothing to be printed except
the empty string) causes a line to be skipped.

Examples:

 (1)    If A is X+5, B is itself, C is 123, M is an array, and Q=3, then

        WRITE M(Q):=A," ",B/C," THANK YOU"

will set M(3) to X+5 and prints

        M(Q) := X + 5 B/123 THANK YOU

The only reason there are blanks between the 5 and B, and the 3 and T, are
the blanks in the quoted strings.

(2)     To print a table of the squares of the integers from 1 to 20:

        FOR I:=1:20 DO WRITE I," ",I**2;

(3)     To print a table of the squares of the integers from 1 to 20, and at
the same time store them in positions 1 to 20 of an array A:

        FOR I:=1:20 DO <<A(I):=I**2; WRITE I," ",A(I)>>;

This will give us two columns of numbers. If we had used

        FOR I:=1:20 DO WRITE I," ",A(I):=I**2;

we would also get "A(i) := " repeated on each line.

(4)     The following more complete example calculates the famous f and g
series, first reported in Sconzo, P., LeSchack, A. R., and Tobey, R.,
"Symbolic Computation of f and g Series by Computer", Astronomical Journal
70 (May 1965).




                                7-8

     X1:= -SIG*(MU+2*EPS)$
     X2:= EPS-2*SIG**2$
     X3:= -3*MU*SIG$
     F:= 1$
     G:= 0$
     FOR I:= 1 STEP 1 UNTIL 10 DO BEGIN
        F1:= -MU*G + X1*DF(F,EPS) + X2*DF(F,SIG) + X3*DF(F,MU);
        WRITE "F(",I,") := ",F1;
        G1:= F + X1*DF(G,EPS) + X2*DF(G,SIG) + X3*DF(G,MU);
        WRITE "G(",I,") := ",G1;
        F:=F1$
        G:=G1$
       END;

A portion of the output, to illustrate the printout from the WRITE
command, is as follows:

                ... <prior output> ...

                           2
 F(4) := MU*(3*EPS - 15*SIG  + MU)

 G(4) := 6*SIG*MU

                                    2
 F(5) := 15*SIG*MU*( - 3*EPS + 7*SIG  - MU)

                           2
 G(5) := MU*(9*EPS - 45*SIG  + MU)

                ... <more output> ...


7.3.5 Suppression of Zeros
      ___________ __ _____

It is sometimes annoying to have zero assignments (i.e. assignments of the
form <expression> := 0) printed, especially in printing large arrays with
many zero elements. The output from such assignments can be suppressed by
turning on the switch NERO.


7.3.6 FORTRAN Style Output of Expressions
      _______ _____ ______ __ ___________

It is naturally possible to evaluate expressions numerically in REDUCE by
giving all variables and sub-expressions numerical values. However, as we
pointed out elsewhere the user must declare real arithmetical operation by
turning on the switches FLOAT or BIGFLOAT. However, it should be
remembered that arithmetic in REDUCE is not particularly fast, since
results are interpreted rather than evaluated in a compiled form. The user
with a large amount of numerical computation after all necessary algebraic
manipulations have been performed is therefore well advised to perform
these calculations in a FORTRAN or similar system. For this purpose,
REDUCE offers facilities for users to produce FORTRAN compatible files for



                                7-9

numerical processing.

First, when the switch FORT is on, the system will print expressions in a
FORTRAN notation. Expressions begin in column 7. If an expression extends
over one line, a continuation mark (.) followed by a blank appears on
subsequent cards. After a certain number of lines have been produced
(according to the value of the variable *CARDNO (qv)), a new expression is
started. If the expression printed arises from an assignment to a
variable, the variable is printed as the name of the expression. Otherwise
the expression is given the default name ANS. An error occurs if
identifiers or numbers are outside the bounds permitted by FORTRAN.

A second option is to use the WRITE command to produce other programs.

Example:

The following REDUCE statements

 ON FORT;
 OUT FORFIL;
 WRITE "C     THIS IS A FORTRAN PROGRAM";
 WRITE " 1    FORMAT(E13.5)";
 WRITE "      U=1.23";
 WRITE "      V=2.17";
 WRITE "      W=5.2";
 X:=(U+V+W)**11;
 WRITE "C     OF COURSE IT WAS FOOLISH TO EXPAND THIS EXPRESSION";
 WRITE "      PRINT 1,X";
 WRITE "      END";
 SHUT FORFIL;
 OFF FORT;

will generate a file FORFIL which contains:

C THIS IS A FORTRAN PROGRAM
 1    FORMAT(E13.5)
      U=1.23
      V=2.17
      W=5.2
      ANS1=1320.*U**3*V*W**7+165.*U**3*W**8+55.*U**2*V**9+495.*U
     . **2*V**8*W+1980.*U**2*V**7*W**2+4620.*U**2*V**6*W**3+
     . 6930.*U**2*V**5*W**4+6930.*U**2*V**4*W**5+4620.*U**2*V**3*
     . W**6+1980.*U**2*V**2*W**7+495.*U**2*V*W**8+55.*U**2*W**9+
     . 11.*U*V**10+110.*U*V**9*W+495.*U*V**8*W**2+1320.*U*V**7*W
     . **3+2310.*U*V**6*W**4+2772.*U*V**5*W**5+2310.*U*V**4*W**6
     . +1320.*U*V**3*W**7+495.*U*V**2*W**8+110.*U*V*W**9+11.*U*W
     . **10+V**11+11.*V**10*W+55.*V**9*W**2+165.*V**8*W**3+330.*
     . V**7*W**4+462.*V**6*W**5+462.*V**5*W**6+330.*V**4*W**7+
     . 165.*V**3*W**8+55.*V**2*W**9+11.*V*W**10+W**11
      X=U**11+11.*U**10*V+11.*U**10*W+55.*U**9*V**2+110.*U**9*V*
     . W+55.*U**9*W**2+165.*U**8*V**3+495.*U**8*V**2*W+495.*U**8
     . *V*W**2+165.*U**8*W**3+330.*U**7*V**4+1320.*U**7*V**3*W+
     . 1980.*U**7*V**2*W**2+1320.*U**7*V*W**3+330.*U**7*W**4+462.



                                7-10

     . *U**6*V**5+2310.*U**6*V**4*W+4620.*U**6*V**3*W**2+4620.*U
     . **6*V**2*W**3+2310.*U**6*V*W**4+462.*U**6*W**5+462.*U**5*
     . V**6+2772.*U**5*V**5*W+6930.*U**5*V**4*W**2+9240.*U**5*V
     . **3*W**3+6930.*U**5*V**2*W**4+2772.*U**5*V*W**5+462.*U**5
     . *W**6+330.*U**4*V**7+2310.*U**4*V**6*W+6930.*U**4*V**5*W
     . **2+11550.*U**4*V**4*W**3+11550.*U**4*V**3*W**4+6930.*U**
     . 4*V**2*W**5+2310.*U**4*V*W**6+330.*U**4*W**7+165.*U**3*V
     . **8+1320.*U**3*V**7*W+4620.*U**3*V**6*W**2+9240.*U**3*V**
     . 5*W**3+11550.*U**3*V**4*W**4+9240.*U**3*V**3*W**5+4620.*U
     . **3*V**2*W**6+ANS1
C OF COURSE IT WAS FOOLISH TO EXPAND THIS EXPRESSION
      PRINT 1,X
      END


7.3.6.1 FORTRAN Output Options
        _______ ______ _______

There are a number of methods available to change the default format of the
FORTRAN output.

The breakup of the expression into subparts is such that the number of
continuation lines produced is less than a given number. This number can
be modified by the assignment

        CARDNO!* := <number>;

where <number> is the TOTAL number of cards allowed in a statement.
CARDNO!* is initially set to 20.

The width of the output expression is also adjustable by the assignment

        FORTWIDTH!* := <integer>;

which sets the total width of a given line to <integer>. The initial
FORTRAN output width is 70.

REDUCE automatically inserts a decimal point after each isolated integer
coefficient in a FORTRAN expression (so that, for example, 4 becomes 4.).
To prevent this, set the PERIOD mode switch to OFF.

Finally, the default name ANS assigned to an unnamed expression and its
subparts can be changed by the operator VARNAME. This takes a single
identifier as argument, which then replaces ANS as the expression name.
The value of VARNAME is its argument.


7.3.7 Saving Expressions for Later Use as Input
      ______ ___________ ___ _____ ___ __ _____

It is often useful to save an expression on an external file for use later
as input in further calculations. The commands for opening and closing
output files are explained elsewhere. However, we see in the examples on
output of expressions that the standard 'natural' method of printing
expressions in not compatible with the input syntax. So to print the



                                7-11

expression in an input compatible form we must inhibit this natural style
by turning off the switch NAT. If this is done, a dollar sign will also be
printed at the end of the expression.

Example:

The following sequence of commands

 OFF NAT; OUT OUT; X := (Y+Z)**2; WRITE "END"; SHUT OUT; ON NAT;

will generate a file OUT which contains

 X := Y**2 + 2*Y*Z + Z**2$
 END$


7.3.8 Displaying Expression Structure
      __________ __________ _________

In those cases where the final result has a complicated form, it is often
convenient to display the skeletal structure of the answer. The operator
STRUCTR, which takes a single expression as argument, will do this for
you. Its syntax is:

     STRUCTR(EXPRN:algebraic):EXPRN;

The answer is printed effectively as a tree, in which the subparts are
laid out with auxiliary names prefixed by the root ANS. This root may be
changed by the operator VARNAME (qv).

Example:

Let us suppose that the workspace contains ((A+B)**2+C)**3+D. Then the
input STRUCTR WS; will (with EXP off) result in the output:

     ANS3

        WHERE

                       3
           ANS3 := ANS2  + D

                       2
           ANS2 := ANS1  + C

           ANS1 := A + B

The workspace remains unchanged after this operation, since the
expressions are only displayed and not stored in this form. However, the
PART operator (qv) can be used to retrieve the appropriate parts of the
expression. For example, to get the term corresponding to ANS2 in the
above, one could say:

     PART(WS,1,1);



                                7-12

 If FORT is on, then the results are printed in the reverse order; the
algorithm in fact guaranteeing that no sub-expression will be referenced
before it is defined.


7.4 Changing the Internal Order of Variables
    ________ ___ ________ _____ __ _________

In its default state, REDUCE uses a specific order for variables (more
precisely kernels) in expressions during simplification, However, it is
possible for the user to change this internal order by means of the
declaration KORDER. The syntax for this is:

        KORDER V1,...,Vn;

where the Vi are kernels. With this declaration, the Vi are ordered
internally ahead of any other kernels in the system. V1 has the highest
order, V2 the next highest, and so on. A further call of KORDER replaces a
previous one. KORDER NIL; resets the internal order to that used by the
system.

Unlike the ORDER declaration (qv), which has a purely cosmetic effect on
the way results are printed, the use of KORDER can have potentially
significant effects on the space and time associated with a calculation.
In critical cases then, the user can experiment with the ordering of the
variables used to determine the optimum set for a given problem.


7.5 Obtaining Parts of Algebraic Expressions
    _________ _____ __ _________ ___________

There are many occasions where it is desirable to obtain a specific part
of an expression, or even change such a part to another expression. A
number of operators are available in REDUCE for this purpose, and will be
described in this section. In addition, operators for obtaining specific
parts of polynomials and rational functions (such as a denominator) are
described in another section.


7.5.1 COEFF
      _____

Syntax: COEFF(EXPRN:polynomial,VAR:kernel,ID:identifier).

COEFF is an operator which partitions EXPRN into its various coefficients
with respect to VAR and stores them in ID. If ID has been previously
declared a single dimensioned array, the size of the array is redefined to
match the highest power in EXPRN and the ith array element is assigned to
the coefficient (zero or non zero) of the ith power of VAR in EXPRN, up to
the highest power. An error results if EXPRN is not a polynomial.

If ID is not an array name, a variable with name ID<power> is assigned to
the coefficient of that power. Only NON ZERO powers are set in this
manner, and a message is printed to inform the user of the variables set.

Example:



                                7-13


        ARRAY X(2);
        COEFF((Y**2+Z)**3,Y,X);

will cause X to be redefined as a seven-dimensioned array (i.e., equivalent
to saying ARRAY X(6)) and then X(6) set to 1, X(5) to 0, X(4) to 3*Z and so
on until X(0), which would be set to Z**3.

On the other hand, if we said

        COEFF((Y**2+Z)**3,Y,W);

we would get a message

        W6 W4 W2 W0 are non zero

and W6 would be set to 1, W4 to 3*Z and so on.

It is also possible to place the various coefficients generated by COEFF in
a particular column of a multi-dimensional array. To do this, ID in the
above symbols should be replaced by an array expression in which the
relevant array column is indicated by an asterisk. In this case, the array
size is not changed so an error occurs if the array is too small to take
all powers, and elements corresponding to missing powers are set to zero up
to the maximum size of the array column.

For example,

        ARRAY XX(7,7,7);
        COEFF((Y**2+Z)**3,Y,XX(5,*,7));

will cause XX(5,7,7) to be set to 0, XX(5,6,7) to 1, XX(5,5,7) to 0 and so
on.

The value of COEFF is the highest non-zero power encountered in the
expression. Thus in the above examples it would be 6. In addition, the
variables HIPOW!* and LOWPOW!* are set to the highest and lowest non-zero
power found in EXPRN during the evaluation. If EXPRN is zero, then HIPOW!*
and LOWPOW!* are both set to zero.


7.5.2 PART
      ____

Syntax: PART(EXPRN:algebraic[,INTEXP:integer]).

This operator works on the form of the expression as printed OR AS IT WOULD
HAVE BEEN PRINTED AT THAT POINT IN THE CALCULATION bearing in mind all the
relevant switch settings at that point. The reader therefore needs some
familiarity with the way that expressions are represented in prefix form in
REDUCE to use these operators effectively. Furthermore, it is assumed that
PRI is ON at that point in the calculation. The reason for this is that
with PRI off, an expression is printed by walking the tree representing the
expression internally. To save space, it is never actually transformed



                                7-14

into the equivalent prefix expression as occurs when PRI is on. However,
the operations on polynomials described elsewhere can be equally well used
in this case to obtain the relevant parts.

The evaluation proceeds recursively down the integer expression list. In
other words,

     PART(<expression>,<integer1>,<integer2>)
         ==> PART(PART(<expression>,<integer1>),<integer2>)

 and so on, and

     PART(<expression>) ==> <expression>.

INTEXP can be any expression that evaluates to an integer. If the integer
is positive, then that term of the expression is found. If the integer is
0, the operator is returned.  Finally, if the integer is negative, the
counting is from the tail of the expression rather than the head.

For example, if the expression A+B is printed as A+B (i.e., the ordering of
the variables is alphabetical), then

      PART(A+B,2)  ==>  B
      PART(A+B,-1) ==>  B
and
      PART(A+B,0) ==> PLUS.

An operator ARGLENGTH is available to determine the number of arguments of
the top level operator in an expression. If the expression does not
contain a top level operator, then -1 is returned. For example,

      ARGLENGTH(A+B+C) ==> 3
      ARGLENGTH(F()) ==> 0
      ARGLENGTH(A) ==> -1.



7.5.3 Changing Parts of Expressions
      ________ _____ __ ___________

PART may also be used to change a given part of an expression. In this case,
the PART construct appears on the left-hand-side of an assignment statement,
and the expression to replace the given part on the right-hand-side.

For example, with the normal settings of REDUCE's switches:

      PART(A+B,2) := C; ==> A+C
      PART(A+B,0) := -; ==> A-B.



                                8-1


8. POLYNOMIAL AND RATIONAL FUNCTION OPERATIONS
   __________ ___ ________ ________ __________

Many operations in computer algebra are concerned with polynomials and
rational functions. In this section, we review some of the switches and
operators available for this purpose. These are in addition to those that
work on general expressions (such as DF and INT) described elsewhere. In
the case of operators, the arguments are first simplified before the
operations are applied. In addition, they operate only on arguments of
prescribed types, and produce a type mismatch error if given arguments which
cannot be interpreted in the required mode with the current switch settings.
For example, if an argument is required to be a kernel and A/2 is used (with
no other rules for A), an error

        A/2 invalid as kernel

will result.

With the exception of those that select various parts of a polynomial or
rational function, these operations have potentially significant effects on
the space and time associated with a given calculation. The user should
therefore experiment with their use in a given calculation in order to
determine the optimum set for a given problem.

One such operation provided by the system is an operator TERMS that returns
the number of top level terms in the numerator of its argument. For example,

        TERMS ((A+B+C)**3/(C+D));

has the value 10. To get the number of terms in the denominator, one would
first select the denominator by the operator DEN (qv) and then call terms,
as in

        TERMS DEN ((A+B+C)**3/(C+D));

Other operations currently supported, the relevant switches and operators,
and the required argument and value modes of the latter, follow.


8.1 Controlling the Expansion of Expressions
    ___________ ___ _________ __ ___________

The switch EXP controls the expansion of expressions. If it is off, no
expansion of powers or products of expressions occurs. Users should note
however that in this case results come out in a normal but not necessarily
canonical form. This means that zero expressions simplify to zero, but
that two equivalent expressions need not necessarily simplify to the same
form.

Example:

With EXP on, the two expressions (A+B)*(A+2*B) and A**2+3*A*B+2*B**2 will
both simplify to the latter form. With EXP off, they would remain
unchanged (unless the complete factoring option were in force).



                                8-2

 EXP is normally on.

Several operators that expect a polynomial as an argument behave
differently when EXP is off, since there is often only one term at the top
level. For example, with EXP off

        TERMS ((A+B+C)**3/(C+D));

returns the value 1.


8.2 Factorization of Polynomials
    _____________ __ ___________

REDUCE is capable of factorizing univariate and multivariate polynomials
that have integer coefficients, finding all factors that also have integer
coefficients. The easiest way to use this facility is to turn on the
switch FACTOR, which causes all expressions to be output in a factored
form. For example, with FACTOR on, the expression A**2-B**2 is returned as
(A+B)*(A-B).

It is also possible to factorize a given expression explicitly. The
operator FACTORIZE that invokes this facility generally leaves its results
in an array, returning an indication of how many factors it found. Thus to
find and display all factors of the cyclotomic polynomial x**105-1, one
could write:

      ARRAY W(20);                % Place for results to be put;
      N := FACTORIZE(X**105-1,W); % N gets set to number of factors found;
      FOR I:=0:N DO WRITE W(I);   % Display results;

In the above example W(1) through W(N) get set to the proper factors of
the input polynomial and W(0) receives any purely numeric content. No
attempt is made by FACTORIZE to split this integer, but it will always be
normalized to be positive. The order in which the factors are put into the
result array is system dependent and should not be relied on. Similarly it
should be noted that any pair of individual factors can be negated without
altering their product, and that REDUCE may sometimes do that.

If the name used as a second argument to FACTORIZE has not been declared as
an array, results are left in variables. A call

      FACTORIZE(X**2-A**2,ZZZ);

where ZZZ has not been mentioned before will lead to a message of the form

      *** ZZZ0 ZZZ1 ZZZ2 ARE NOW NON-ZERO

and ZZZ0 will be numeric, with ZZZ0*ZZZ1*ZZZ2 = X**2-A**2. If FACTORIZE is
called without a second argument it deposits its results in variables called
FACTOR0, FACTOR1 and so on.

The factorizer works by first reducing multivariate problems to univariate
ones and then solving the univariate ones modulo small primes. It normally



                                8-3

selects both evaluation points and primes using a random number generator
that should lead to different detailed behavior each time any particular
problem is tackled. If, for some reason, it is known that a certain
(probably univariate) factorization can be performed effectively with a
known prime, P say, this value of P can be handed to FACTORIZE as a third
argument. It is an error to provide a non-prime to FACTORIZE in this way,
and it is also an error to specify a prime that divides the discriminant
of the polynomial to be worked with.

When factorization of a univariate polynomial is required modulo some
prime, the form

      N := PFACTORIZE(polynomial,identifier,prime);

may be used. Its behavior is analogous to FACTORIZE except that it works
modulo the given odd prime, and none of the arguments are optional.
Finally, the polynomial must be univariate, otherwise an error occurs. The
modular factors that are returned are all normalized to be monic.

The factorization module is provided with a trace facility that may be useful
as a way of monitoring progress on large problems, and of satisfying
curiosity about the internal workings of the package. The most simple use
of this is enabled by issuing the REDUCE command

      ON TRFAC;

Following this, all calls to the factorizer will generate informative messages
reporting on such things as the reduction of multivariate to univariate cases,
the choice of a prime and the reconstruction of full factors from their
images. Further levels of detail in the trace are intended mainly for
system tuners and for the investigation of suspected bugs. The switch that
can be set by "ON TIMINGS;" makes it possible for one who is familiar with
the algorithms used to determine what part of the factorization code is
consuming the most resources. "ON OVERVIEW;" modifies the level of detail
presented in other forms of trace. Other forms of trace output are enabled
by directives of the form

      SYMBOLIC SET!-TRACE!-FACTOR(number,filename);

where useful numbers are 1,2,3 and 100,101,... . This facility is intended to
make it possible to discover in fairly great detail what just some small
part of the code has been doing - the numbers refer mainly to depths of
recursion when the factorizer calls itself, and to the split between its
work forming and factorizing images and reconstructing full factors from
these. If NIL is used in place of a filename the trace output requested is
directed to the standard output stream. After use of this trace facility the
generated trace files should be closed by calling

      SYMBOLIC CLOSE!-TRACE!-FILES();

CAUTION: The code for performing multivariate factorization is very large,
and therefore takes considerable time to load. As a result, there is some
delay when the factorizer is first used while the code is being loaded.



                                8-4


8.3 Cancellation of Common Factors
    ____________ __ ______ _______

Facilities are available in REDUCE for cancelling common factors in the
numerators and denominators of expressions, at the option of the user. The
system will perform this greatest common divisor computation if the switch
GCD is on.

A check is automatically made, however, for common variable and numerical
products in the numerators and denominators of expressions, and the
appropriate cancellations made.

When GCD is on, and EXP is off, a check is made for square free factors in
an expression. This includes separating out and independently checking the
content of a given polynomial where appropriate. (For an explanation of
these terms, see Anthony C. Hearn, "Non-Modular Computation of Polynomial
GCDS Using Trial Division", Proc. EUROSAM 79, published as Lecture Notes
on Comp. Science, Springer-Verlag, Berlin, No 72 (1979) 227-239.)

Example:

With EXP off and GCD on, the polynomial A*C+A*D+B*C+B*D would be returned
as (A+B)*(C+D).

Under normal circumstances, gcd's are computed using an algorithm described
in the above paper. It is also possible in REDUCE to compute gcd's using
an alternative algorithm, called the ezgcd algorithm, that uses modular
arithmetic. The switch EZGCD, if on in addition to GCD, makes this happen.
For a description of the ezgcd algorithm, see J. Moses and D. Y. Y. Yun,
"The EZ GCD Algorithm", Proc. ACM 1973, ACM, New York (1973) 159-166.

CAUTION: The code for the ezgcd algorithm is included in the factorization
module. Consequently, there is usually a delay when it is first used while
that module is loaded. Note also that a certain amount of trace
information can be produced using the same switches as are used to control
the factorizer.

GCD is normally off.


8.3.1 Determining the GCD of two polynomials
      ___________ ___ ___ __ ___ ___________

This operator, used with the syntax

GCD(EXPRN1:polynomial,EXPRN2:polynomial):polynomial,

returns the greatest common divisor of the two polynomials EXPRN1 and
EXPRN2.

Examples:

        GCD(X**2+2*X+1,X**2+3*X+2) ==> X+1
        GCD(2*X**2-2*Y**2,4*X+4*Y) ==> 2*X+2*Y



                                8-5

        GCD(X**2+Y**2,X-Y)         ==> 1.


8.4 Working with Least Common Multiples
    _______ ____ _____ ______ _________

Greatest common divisor calculations can often become expensive if
extensive work with large rational expressions is required. However, in
many cases, the only significant cancellations arise from the fact that
there are often common factors in the various denominators which are
combined when two rationals are added. Since these denominators tend to be
smaller and more regular in structure than the numerators, considerable
savings in both time and space can occur if a full gcd check is made when
the denominators are combined and only a partial check when numerators are
constructed. In other words, the true least common multiple of the
denominators is computed at each step. The switch LCM is available for
this purpose, and is normally on.


8.5 Controlling Use of Common Denominators
    ___________ ___ __ ______ ____________

When two rational functions are added, REDUCE normally produces an
expression over a common denominator. However, if the user does not want
denominators combined, he can turn off the switch MCD which controls this
process. The latter switch is particularly useful if no greatest common
divisor calculations are desired, or excessive differentiation of rational
functions is required.

CAUTION: With MCD off, results are not guaranteed to come out in either
normal or canonical form. In other words, an expression equivalent to zero
may in fact not be simplified to zero. This option is therefore most
useful for avoiding expression swell during intermediate parts of a
calculation.

MCD is normally on.


8.6 REMAINDER
    _________

Syntax: REMAINDER(EXPRN1:polynomial,EXPRN2:polynomial):polynomial.

Returns the remainder when EXPRN1 is divided by EXPRN2. This is the true
remainder based on the internal ordering of the variables, and not the
pseudo-remainder.

Examples:

        REMAINDER((X+Y)*(X+2*Y),X+3*Y) ==> 2*Y**2
        REMAINDER(2*X+Y,2)             ==> Y.



                                8-6


8.7 RESULTANT
    _________

This is used with the syntax

RESULTANT(EXPRN1:polynomial,EXPRN2:polynomial,VAR:kernel):polynomial.

It computes the resultant of the two given polynomials with respect to the
given variable. The result can be identified as the determinant of a
Sylvester matrix, but can often also be thought of informally as the
result obtained when the given variable is eliminated between the two input
polynomials. If the two input polynomials have a non-trivial gcd their
resultant vanishes.

CAUTION: Since the code for resultant computations is contained in the
factorization module, there is usually a delay when it is first used while
that module is loaded.


8.8 Obtaining Parts of Polynomials and Rational Functions
    _________ _____ __ ___________ ___ ________ _________

These operators select various parts of a polynomial or rational function
structure. Except for the cost of rearrangement of the structure, these
operations take very little time to perform.


8.8.1 DEG
      ___

This operator is used with the syntax

DEG(EXPRN:polynomial,VAR:kernel):integer.

It returns the leading degree of the polynomial EXPRN in the variable VAR.
If VAR does not occur as a variable in EXPRN, 0 is returned.

Examples:

        DEG((A+B)*(C+2*D)**2,A) ==> 1
        DEG((A+B)*(C+2*D)**2,D) ==> 2
        DEG((A+B)*(C+2*D)**2,E) ==> 0.


8.8.2 DEN
      ___

This is used with the syntax:

     DEN(EXPRN:rational):polynomial.

It returns the denominator of the rational expression EXPRN. If EXPRN is a
polynomial, 1 is returned.

Examples:




                                8-7

        DEN(X/Y**2) ==> Y**2
        DEN(100/6) ==> 3
             [since 100/6 is first simplified to 50/3]
        DEN(A/4+B/6) ==> 12
        DEN(A+B) ==> 1


8.8.3 LCOF
      ____

LCOF is used with the syntax

LCOF(EXPRN:polynomial,VAR:kernel):polynomial.

It returns the leading coefficient of the polynomial EXPRN in the variable
VAR. If VAR does not occur as a variable in EXPRN, 0 is returned.

Examples:

        LCOF((A+B)*(C+2*D)**2,A) ==> C**2+4*C*D+4*D**2
        LCOF((A+B)*(C+2*D)**2,D) ==> 4*(A+B)
        LCOF((A+B)*(C+2*D)**2,E) ==> 0.


8.8.4 LTERM
      _____

Syntax: LTERM(EXPRN:polynomial,VAR:kernel):polynomial.

LTERM is used with the syntax

LTERM(EXPRN:polynomial,VAR:kernel):polynomial.

It returns the leading term of EXPRN with respect to VAR. If EXPRN does
not depend on VAR, 0 is returned.

Examples:

        LTERM((A+B)*(C+2*D)**2,A) ==> A*(C**2+4*C*D+4*D**2)
        LTERM((A+B)*(C+2*D)**2,D) ==> 4*D**2*(A+B)
        LTERM((A+B)*(C+2*D)**2,E) ==> 0.


8.8.5 MAINVAR
      _______

Syntax: MAINVAR(EXPRN:polynomial):expression.

Returns the main variable (based on the internal polynomial representation)
of EXPRN. If EXPRN is a domain element, 0 is returned.

Examples:

        MAINVAR((A+B)*(C+2*D)**2) ==> A (normally)
        MAINVAR(2) ==> 0



                                8-8


8.8.6 NUM
      ___

Syntax: NUM(EXPRN:rational):polynomial.

Returns the numerator of the rational expression EXPRN. If EXPRN is a
polynomial, that polynomial is returned.

Examples:

        NUM(X/Y**2) ==> X
        NUM(100/6) ==> 50
        NUM(A/4+B/6) ==> 2*A+3*B
        NUM(A+B) ==> A+B


8.8.7 REDUCT
      ______

Syntax: REDUCT(EXPRN:polynomial,VAR:kernel):polynomial.

Returns the reductum of EXPRN with respect to VAR (i.e., the part of EXPRN
left after the leading term is removed). If EXPRN does not depend on the
variable VAR, 0 is returned.

Examples:

        REDUCT((A+B)*(C+2*D)**2,A) ==> B*(C**2+4*C*D+4*D**2)
        REDUCT((A+B)*(C+2*D)**2,D) ==> C*(A+B)
        REDUCT((A+B)*(C+2*D)**2,E) ==> 0.


8.9 Polynomial Coefficient Arithmetic
    __________ ___________ __________

REDUCE allows for a variety of numerical modes for the numerical coefficients
of polynomials used in calculations. The default mode is integer arithmetic,
although the possibility of using real coefficients has been discussed
elsewhere. Rational coefficients have also been available by using integer
coefficients in both the numerator and denominator of an expression, using
the ON DIV option (qv) to print the coefficients as rationals. However,
REDUCE includes several other coefficient options in its basic version which
we shall describe in this section. All such coefficient modes are actually
supported in a table-driven manner so that it is straightforward to extend
the range of possibilities. A description of how to do this is given in
another publication.


8.9.1 Rational Coefficients in Polynomials
      ________ ____________ __ ___________

Instead of treating rational numbers as the numerator and denominator of a
rational expression, it is also possible to use them as polynomial
coefficients directly. This is accomplished by turning on the switch RATIONAL.

Example: With RATIONAL off, the input expression A/2 would be converted into



                                8-9

a rational expression, whose numerator was A and denominator 2. With RATIONAL
on, the same input would become a rational expression with numerator 1/2*A
and denominator 1. Thus the latter can be used in operations that require
polynomial input whereas the former could not.


8.9.2 Real coefficients in Polynomials
      ____ ____________ __ ___________

The switch FLOAT permits the use of fixed-sized real coefficients in polynomial
expressions. The actual precision of these coefficients is system dependent.
In this mode, denominators are automatically made monic, and an appropriate
adjustment made to the numerator.

Example: With FLOAT on, the input expression A/2 would be converted into a
rational expression whose numerator is 0.5*A and denominator 1.


8.9.3 Arbitrary Precision Real Coefficients
      _________ _________ ____ ____________

REDUCE includes a module for those calculations that require greater real
number precision than the FLOAT mode supports. To use this mode, the command
ON BIGFLOAT; is used. The default precision in this case is ten decimal
digits. This precision can however be changed by the command PRECISION. For
example, PRECISION 50; sets the precision to fifty decimal digits.

Further information on this module may be found in T. Sasaki, "Manual for
Arbitrary Precision Real Arithmetic System in REDUCE", Department of Computer
Science, University of Utah, Technical Note No. TR-8 (1979).


8.9.4 Modular Number Coefficients in Polynomials
      _______ ______ ____________ __ ___________

REDUCE includes facilities for manipulating polynomials whose coefficients
are computed modulo a given base. To use this option, two commands must be
used; SETMOD <integer>, to set the prime modulus, and ON MODULAR to cause the
actual modular calculations to occur.

For example, with SETMOD 3; and ON MODULAR, the polynomial (A+2*B)**3 would
become A**3 + B**3. Note that the modular calculations are on the
polynomial coefficients only. It is not currently possible to reduce the
exponents since no check for a prime modulus is made (which would allow
x**(p-1) to be reduced to 1 mod p).

Users should also note that since the argument of SETMOD is evaluated by
the algebraic processor in algebraic mode, it is usually necessary to
change it with the modular switch off. In addition, any division by a
number not co-prime with the modulus will result in the error "Invalid
modular division".



                                9-1


9. SUBSTITUTION COMMANDS
   ____________ ________

An important class of commands in REDUCE is that which defines
substitutions for variables and expressions to be made during the
evaluation of expressions. Such substitutions use forms of the command
LET.

LET rules stay in effect until replaced or CLEARed. Temporary substitution
rules, for the evaluation of a single statement, are created using the SUB
operator (qv).


9.1 Simple LET Rules
    ______ ___ _____

The simplest use of the LET statement is in the form

          LET <substitution list>

where <substitution list> is a list of rules, each of the form:

        <variable> = <expression>

 or     <prefix operator> (<argument>,...,<argument>) = <expression>

 or     <argument> <infix operator>,..., <argument> = <expression>

        e.g. LET X = Y**2,
                 H(U,V) = U - V,
                 COS(PI/3) = 1/2,
                 A*B = C,
                 L+M = N,
                 W**3 = 2*Z - 3,
                 Z**10 = 0

(These could have been entered as seven separate LET statements.)

After such LET rules have been input, X will always be evaluated as the
square of Y, and so on. This is so even if at the time the LET rule was
input, the variable Y had a value other than Y. (In contrast, the
assignment X:=Y**2 will set X equal to the square of the current value of
Y, which could be quite different.)

The rule LET A*B=C means that whenever A and B are both factors in an
expression their product will be replaced by C. For example, A**5 * B**7 *
W would be replaced by C**5 * B**2 * W.

The rule pertaining to W**3 will apply to any power of W greater than or
equal to the third.

Note especially the last example, LET Z**10=0. This declaration means, in
effect: ignore the tenth or any higher power of Z. Such declarations, when
appropriate, often speed up a computation to a considerable degree. (qv



                                9-2

Asymptotic Commands for more details.)

Any new operators occurring in such LET rules will be automatically
declared OPERATOR by the system, if the rules are being read from a file.
If they are being entered interactively, the system will ask DECLARE ...
OPERATOR? . Answer Y or N and hit RETURN.

In each of these examples, substitutions are only made for the explicit
expressions given; i.e., none of the variables may be considered arbitrary
in any sense. For example, the command

        LET H(U,V) = U - V;

will cause H(U,V) to evaluate to U - V, but will not affect H(U,Z) or H
with any arguments other than precisely the symbols U,V.

These simple LET rules are on the same logical level as assignments made
with the := operator. An assignment X := P+Q cancels a rule LET X = Y**2
made earlier, and vice versa.

CAUTION: A rule such as

        LET X = X + 1;

is erroneous, since any subsequent evaluation of X will lead to a
non-terminating chain of substitutions (and finally a stack overflow
error):

        X ==> X + 1 ==> (X + 1) + 1 ==> ((X + 1) + 1) + 1 ==> ...

Similarly, coupled substitutions such as

        LET L = M + N, N = L + R;

will lead to the same error.


9.2 FOR ALL ... LET
    ___ ___ ___ ___

If a substitution for all possible values of a given argument of an
operator is required, the declaration FOR ALL (or FORALL) may be used. The
syntax of such a command is

        FOR ALL <variable>,...,<variable> <LET statement> <terminator>

        e.g.    FOR ALL X,Y LET H(X,Y) = X-Y;
                FOR ALL X LET K(X,Y) = X**Y;

The first of these declarations would cause H(A,B) to be evaluated as A-B,
H(U+V,U+W) to be V-W, etc. If the operator symbol H is used with more or
fewer argument places, not two, the LET would have no effect, and no error
would result.




                                9-3

The second declaration would cause K(A,Y) to be evaluated as A**Y, but
would have no effect on K(A,Z) since the rule didn't say FOR ALL Y ... .

Where we used X and Y in the examples, any variables could have been used.
This use of a variable doesn't affect the value it may have outside the
LET statement. However, you should remember what variables you actually
used. If you want to delete the rule subsequently, you must use the same
variables in the CLEAR command (qv).

It is possible to use more complicated expressions as a template for a LET
statement, as explained in the section on substitutions for general
expressions. However, there is a limit to the complexity of the expression
which can appear after the LET. This limit will change with successive
versions of REDUCE. If the expression is too complicated, the error
message

        SUBSTITUTION FOR ... NOT ALLOWED

will be issued, with the ... a copy of the left-hand side of the equal
sign, possibly slightly rearranged. Any variable listed in the FOR ALL
part will have its symbol preceded by an equal sign: X, for example will
appear as =X . An error will also occur if a variable in the FOR ALL part
is not properly matched on both sides of the LET equation.


9.3 FOR ALL ... SUCH THAT ... LET
    ___ ___ ___ ____ ____ ___ ___

If a substitution is desired for more than a single value of a variable in
an operator or other expression, but not all values, a conditional form of
the FOR ALL ... LET declaration can be used.

Example:

        FOR ALL X SUCH THAT NUMBERP X AND X<0 LET H(X)=0;

will cause H(-5) to be evaluated as 0, but H of a positive integer, or of
an argument which is not an integer at all, would not be affected. Any
boolean expression can follow the SUCH THAT keywords.


9.4 Removing Assignments and Substitution Rules
    ________ ___________ ___ ____________ _____

The user may remove all assignments and substitution rules from any
expression by the command CLEAR, in the form

                CLEAR <expression>,...,<expression><terminator>

        e.g.    CLEAR  X, H(X,Y);

An individual element of an array A can be reset to 0 by a command such as
CLEAR A(3);.

A whole array A can be cleared by the command CLEAR A; . This means much



                                9-4

more than resetting to 0 all the elements of A. The fact that A is an
array, and what its dimensions are, are forgotten, so A can be redefined
as another type of object -- say, operator.

The more general types of LET declarations can also be deleted by using
CLEAR. Simply repeat the LET rule to be deleted, using CLEAR in place of
LET, and omitting the equal sign and right-hand part. The same dummy
variables must be used in the FOR ALL part, and the boolean expression in
the SUCH THAT part must be written the same way. (The placing of blanks
doesn't have to be identical.)

Example:

The LET rule

        FOR ALL X SUCH THAT NUMBERP X AND X<0 LET H(X)=0;

can be erased by the command

        FOR ALL X SUCH THAT NUMBERP X AND X<0 CLEAR H(X);


9.5 Overlapping LET Rules
    ___________ ___ _____

CLEAR is not the only way to delete a LET rule. A new LET rule identical
to the first, but with a different expression after the equal sign,
replaces the first. The user should however be cautioned against having
several LET rules in effect which relate to the same expression. No
guarantee can be given as to which rules will be applied by REDUCE or in
what order. It is best to CLEAR an old rule before entering a new related
LET rule.


9.5.1 Substitutions for General Expressions
      _____________ ___ _______ ___________

All substitutions discussed so far have been very limited in scope, because
they involve only replacements for variables and kernels. These
substitutions are very efficient to implement because variables and kernels
are stored uniquely in the system. However, there are many situations
where more general substitutions are required, most of which require
extensive pattern matching within the expression being evaluated.
Consequently, such substitutions cannot be as efficiently implemented as
those discussed so far.

The general substitution mechanism used in REDUCE is discussed in Hearn, A.
C., "REDUCE, A User-Oriented Interactive System for Algebraic
Simplification," Interactive Systems for Experimental Applied Mathematics,
(edited by M. Klerer and J. Reinfelds), Academic Press, New York (1968),
79-90, and Hearn. A. C., "The Problem of Substitution," Proc. 1968 Summer
Institute on Symbolic Mathematical Computation, IBM Programming Laboratory
Report FSC 69-0312 (1969).

For the reasons given in these references, REDUCE does not attempt to



                                9-5

implement a general pattern matching algorithm. However, the present
system uses more sophisticated techniques than those discussed in the above
papers. It is now possible for the equations appearing in arguments of LET
to have the form

        <substitution expression> = <expression>

where <substitution expression> is ANY expression, subject to the
following restrictions:

(i) The operators - and / cannot appear at the top level in a
     substitution expression.

        e.g.  LET A - B = 1; is NOT allowed.

(ii) The operators + and * can only be used in binary form within
     substitution expressions.

        e.g.  LET SIN (X + Y) = SIN(X)*COS(Y) + COS(X)*SIN(Y);

     is allowed but a substitution for FN(X+Y+Z) would not be.  The
     system will of course substitute for any expression containing +
     or * as an n-ary operator by making the appropriate expansion of
     the binary rule.

(iii) The operator - can only be specified as a unary operator within
     substitution expressions.

        e.g.    LET COS(-X)  = COS(X) is allowed
         but    LET COS(X-Y) = <expression> is not.

     It should be noted, however, that a rule for COS(X+Y) and one
     for COS(-X) is sufficient to specify the expansion of COS(X-Y).

After a substitution has been made, the expression being evaluated is
reexamined in case a new allowed substitution has been generated. This
process is continued until no more substitutions can be made. However,
this is sometimes undesirable. For example, if one wishes to integrate a
polynomial with respect to X by a rule of the form

        FOR ALL N LET X**N = X**(N+1)/(N+1);

one only wants the substitution to be made once. (Otherwise X**2 would
become X**3/3 which would then become X**4/12 and so on). This
resubstitution can be inhibited by turning off the switch RESUBS (which is
normally on).

When a substitution expression appears in a product, the substitution is
made if that expression divides the product. For example, the rule

        LET A**2*C = 3*Z;

would cause A**2*C*X to be replaced by 3*Z*X and A**2*C**2 by 3*Z*C. If



                                9-6

the substitution is desired only when the substitution expression appears
in a product with the explicit powers supplied in the rule, the command
MATCH should be used instead.

For example,

        MATCH A**2*C = 3*Z;

would cause A**2*C*X to be replaced by 3*Z*X, but A**2*C**2 would not be
replaced. MATCH can also be used with the FOR ALL constructions described
above.

To remove substitution rules of the type discussed in this section, the
CLEAR command can be used, combined, if necessary, with a FOR ALL clause.

        e.g.  FOR ALL X CLEAR LOG(E**X),E**LOG(X),COS(W*T+THETA(X));

Note, however, that the arbitrary variable names in this case MUST be the
same as those used in defining the substitution.


9.6 Asymptotic Commands
    __________ ________

In expansions of polynomials involving variables which are known to be
small, it is often desirable to throw away all powers of these variables
beyond a certain point to avoid unnecessary computation. The command LET
may be used to do this. For example, if only powers of X up to X**7 are
needed, the command

        LET X**8 = 0;

will cause the system to delete all powers of X higher than 7.

CAUTION: This particular simplification works differently from most
substitution mechanisms in REDUCE in that it is applied during polynomial
manipulation rather than to the whole evaluated expression. Thus, with the
above rule in effect, x**10/x**5 would give the result zero, since the
numerator would simplify to zero. Similarly x**20/x**10 would give a ZERO
DENOMINATOR error message, since both numerator and denominator would
first simplify to zero.

The method just described is not adequate when expressions involve several
variables having different degrees of smallness. In this case, it is
necessary to supply an asymptotic weight to each variable and count up the
total weight of each product in an expanded expression before deciding
whether to keep the term or not. There are two associated commands in the
system to permit this type of asymptotic constraint. The command WEIGHT
takes a list of equations of the form

        <kernel form> = <number>,

where <number> must be a positive integer (not just evaluate to a positive
integer). This command assigns the weight <number> to the relevant kernel



                                9-7

form. A check is then made in all algebraic evaluations to see if the
total weight of the term is greater than the weight level assigned to the
calculation. If it is, the term is deleted. To compute the total weight of
a product, the individual weights of each kernel form are multiplied by
their corresponding powers and then added.

The weight level of the system is initially set to 2. The user may change
this setting by the command

        WTLEVEL <number>;

which sets <number> as the new weight level of the system. Again, <number>
must be a positive integer.



                                10-1


10. FILE HANDLING COMMANDS
    ____ ________ ________

In many applications, it is desirable to load previously prepared REDUCE
files into the system, or to write output on other files. REDUCE offers
four commands for this purpose, namely, IN, OUT, SHUT and LOAD. The first
three operators are described here; LOAD is discussed in another section.


10.1 IN
     __

This command takes a list of file names as argument and directs the system
to input each file (which should contain REDUCE statements and commands)
into the system. File names can either be an identifier or a string. The
explicit format of these will be system dependent and, in many cases, site
dependent. The explicit instructions for the implementation being used
should therefore be consulted for further details.

        e.g.  IN F1,"GGG.RR.S"; will first load file F1, then GGG.RR.S.

When a semicolon is used as the terminator of the IN statement, the
statements in the file are echoed on the terminal or written on the
current output file. If $ or ESCAPE is used as the terminator, the input
is not shown. Echoing of all or part of the input file can be prevented,
even if a semicolon was used, by placing an OFF ECHO; command in the input
file.

Files to be read using IN should end with ;END; . (Note the two
semicolons!) First of all, this is protection against obscure difficulties
the user will have if there are, by mistake, more BEGINs than ENDs on the
file. Secondly, it triggers some file control book-keeping which may
improve system efficiency. If END is omitted, an error message "EOF read"
will occur.


10.2 OUT
     ___

This command takes a single file name as argument, and directs output to
that file from then on, until another OUT changes the output file, or SHUT
closes it. Output can go to only one file at a time, although many can be
open. If the file has previously been used for output during the current
job, and not SHUT, the new output is appended to the end of the file. Any
existing file is erased before its first use for output in a job, or if
had been SHUT before the new OUT.

To output on the terminal without closing the output file, the reserved
file name T (for terminal) may be used.

        e.g.    OUT OFILE; will direct output to the file OFILE and
                OUT T; will direct output to the user's terminal.

The output sent to the file will be in the same form that it would have on
the terminal. In particular X**2 would appear on two lines, an X on the



                                10-2

lower line and a 2 on the line above. If the purpose of the output file is
to save results to be read in later, this is not an appropriate form. We
first must turn off the NAT switch which specifies that output should be
in standard mathematical notation.

Example: To create a file ABCD from which it will be possible to read --
using IN -- the value of the expression XYZ:

 OFF NAT$       % output in IN-readable form. Each expression
                % printed will end with a $ .
 OUT ABCD$      % output to new file
 XYZ:=XYZ;      % will output "XYZ := " followed by the value
                % of XYZ
 WRITE ";END;"$ % standard for ending files for IN
 SHUT ABCD$     % save ABCD, return to terminal output
 ON NAT$                % restore usual output form


10.3 SHUT
     ____

This command takes a list of names of files which have been previously
opened via an "OUT" statement and closes them. Most systems require this
action by the user before he ends the REDUCE job (if not sooner),
otherwise the output may be lost. If a file is shut and a further OUT
command issued for the same file, the file is erased before the new output
is written.

If it is the current output file which is shut, output will switch to the
terminal. Attempts to shut files that have not been opened by "OUT", or an
input file will lead to errors.



                                11-1


11. COMMANDS FOR INTERACTIVE USE OF REDUCE
    ________ ___ ___________ ___ __ ______

REDUCE is designed as an interactive system, but naturally it can also
operate in a batch processing or background mode by taking its input
command by command from the relevant input stream. There is a basic
difference, however, between interactive and batch use of the system. In
the former case, whenever the system discovers an ambiguity at some point
in a calculation, such as a forgotten type assignment for instance, it asks
the user for the correct interpretation. In batch operation, it is not
practical to terminate the calculation at such points and require
resubmission of the job, so the system makes the most obvious guess of the
user's intentions and continues the calculation.

There is also a difference in the handling of errors. In the former case,
the computation can continue since the user has the opportunity to correct
the mistake. In batch mode, the error may lead to consequent erroneous (and
possibly time consuming) computations. So no further evaluation occurs,
although the remainder of the input is checked for syntax errors. A message
"Continuing with parsing only" informs the user that this is happening.


11.1 Referencing Previous Results
     ___________ ________ _______

It is often useful to be able to reference results of previous computations
during a REDUCE session. For this purpose, REDUCE maintains a history of
all interactive inputs and the results of all interactive computations during
a given session. These results are referenced by the command number that
REDUCE prints automatically in interactive mode. To use an input expression
in a new computation, one writes INPUT(n), where n is the command number.
To use an output expression, one writes WS(n). WS references the previous
command. E.g., if command number 1 was int(x-1,x); and the result of
command number 7 was X-1, then

     2*input(1)-ws(7)**2;

would give the result -1, whereas

     2*ws(1)-ws(7)**2;

would yield the same result, but WITHOUT a recomputation of the integral.

The operator DISPLAY is available to display previous inputs. If its
argument is a positive integer, n say, then the previous n inputs are
displayed. If its argument is ALL (or in fact any non-numerical expression),
then all previous inputs are displayed.


11.2 Interactive Editing
     ___________ _______

It is possible when working interactively to edit any REDUCE input that
comes from the user's terminal, and also some user-defined procedure
definitions. At the top level, one can access any previous command string



                                11-2

by the command ED(n), where n is the desired command number as prompted by
the system in interactive mode. ED; (i.e. no argument) accesses the
previous command.

After ED has been called, you can now edit the displayed string using a
string editor with the following commands:

        B                   move pointer to beginning
        C<character>        replace next character by <character>
        D                   delete next character
        E                   end editing and reread text
        F<character>        move pointer to next occurrence of <character>
        I<string><escape>   insert <string> in front of pointer
        K<character>        delete all chars until <character>
        P                   print string from current pointer
        Q                   give up with error exit
        S<string><escape>   search for first occurrence of <string>
                            positioning pointer just before it
        <space> or X        move pointer right one char.

The above table can be displayed online by typing a question mark followed
by a carriage return to the editor. The editor prompts with an angle
bracket. Commands can be combined on a single line, and all command
sequences must be followed by a carriage return to become effective.

Thus, to change the command X := A+1; to X := A+2;, and cause it to be
executed, the following edit command sequence could be used:

        F1C2E<return>.

The interactive editor may also be used to edit a user-defined procedure that
has not been compiled (qv). To do this, one says:

        EDITDEF <id>;

where <id> is the name of the procedure. The procedure definition will then
be displayed in editing mode, and may then be edited and redefined on exiting
from the editor.


11.3 Interactive File Control
     ___________ ____ _______

If input is coming from an external file, the system treats it as a batch
processed calculation. If the user desires interactive response in this
case, he can include the command ON INT; in the file. Likewise, he can
issue the command OFF INT; in the main program if he does not desire
continual questioning from the system. Regardless of the setting of INT,
input commands from a file are not kept in the system, and so can not be
edited using ED. However, many implementations of REDUCE provide a link to
an external system editor that can be used for such editing. The specific
instructions for the particular implementation should be consulted for
information on this.




                                11-3

Two commands are available in REDUCE for interactive use of files. PAUSE;
may be inserted at any point in an input file. When this command is
encountered on input, the system prints the message CONT? on the user's
terminal and halts. If the user responds Y (for yes), the calculation
continues from that point in the file. If the user responds N (for no),
control is returned to the terminal, and the user can input further
statements and commands. Later on he can use the command CONT; to transfer
control back to the point in the file following the last PAUSE encountered.
A top-level PAUSE; from the user's terminal has no effect.



                                12-1


12. MATRIX CALCULATIONS
    ______ ____________

A very powerful feature of the REDUCE system is the ease with which matrix
calculations can be performed. To extend our syntax to this class of
calculations we need to add another prefix operator, MAT, and a further
variable and expression type as follows:


12.1 MAT
     ___

This prefix operator is used to represent n x m matrices. MAT has n
arguments interpreted as rows of the matrix, each of which is a list of m
expressions representing elements in that row. For example, the matrix

                (A B C)
                (     )
                (D E F)

would be written as MAT ((A,B,C),(D,E,F)).

Note that the single column matrix

                (X)
                (Y)

becomes MAT((X),(Y)). The inside parentheses are required to distinguish
it from the single row matrix

                (X Y)

which would be written as MAT((X,Y)).


12.2 Matrix Variables
     ______ _________

An identifier may be declared a matrix variable by the declaration MATRIX.
The size of the matrix may be declared explicitly in the matrix
declaration, or by default in assigning such a variable to a matrix
expression.

        e.g. MATRIX X(2,1),Y(3,4),Z;

declares X to be a 2 x 1 (column) matrix, Y to be a 3 x 4 matrix and Z a
matrix whose size is declared later by default.

An element of a matrix is referred to in the expected manner; thus X(1,1)
gives the first element of the matrix X defined above. References to elements
of a matrix whose size has not yet been declared leads to an error. All
elements of a matrix whose size is declared are initialized to 0. As a
result, a matrix element cannot stand for itself. If this is required,
then an operator (qv) should be used to name the matrix elements.



                                12-2


12.3 Matrix Expressions
     ______ ___________

These follow the normal rules of matrix algebra as defined by the
following syntax:

  <matrix expression> ::= MAT<matrix description>|<matrix variable>|
                          <scalar expression>*<matrix expression>|
                          <matrix expression>*<matrix expression>
                          <matrix expression>+<matrix expression>|
                          <matrix expression>**<integer>|
                          <matrix expression>/<matrix expression>

Sums and products of matrix expressions must be of compatible size
otherwise an error will result during their evaluation. Similarly, only
square matrices may be raised to a power. A negative power is computed as
the inverse of the matrix raised to the corresponding positive power. A/B
is interpreted as A*B**(-1).

Examples:

Assuming X and Y have been declared as matrices, the following are matrix
expressions

        Y
        Y**2*X-3*Y**(-2)*X
        Y+ MAT((1,A),(B,C))/2


12.4 Operators With Matrix Arguments
     _________ ____ ______ _________

Three additional operators are useful in matrix calculations, namely DET,
TP and TRACE defined as follows


12.4.1 DET
       ___

Syntax: DET(EXPRN:matrix_expression):algebraic.

The operator DET is used to represent the determinant of a square matrix
expression.

        e.g. DET(Y**2)

is a scalar expression whose value is the determinant of the square of the
matrix Y, and

        DET MAT((A,B,C),(D,E,F),(G,H,J));

is a scalar expression whose value is the determinant of the matrix

                ( A B C )
                (       )



                                12-3

                ( D E F )
                (       )
                ( G H J ).


12.4.2 TP
       __

Syntax: TP(EXPRN:matrix_expression):matrix.

This operator takes a single matrix argument and returns its transpose.


12.4.3 TRACE
       _____

Syntax: TRACE(EXPRN:matrix_expression):algebraic. The operator TRACE is
used to represent the trace of a square matrix.


12.5 Matrix Assignments
     ______ ___________

Matrix expressions may appear in the right hand side of assignment
statements. If the left hand side of the assignment, which must be a
variable, has not already been declared a matrix, it is declared by default
to the size of the right hand side. The variable is then set to the value
of the right hand side.

Such an assignment may be used very conveniently to find the solution of a
set of linear equations. For example, to find the solution of the
following set of equations

        A11*X(1) + A12*X(2) = Y1
        A21*X(1) + A22*X(2) = Y2

we simply write

        X := 1/MAT((A11,A12),(A21,A22))*MAT((Y1),(Y2));


12.6 Evaluating Matrix Elements
     __________ ______ ________

Once an element of a matrix has been assigned, it may be referred to in
standard array element notation. Thus Y(2,1) refers to the element in the
second row and first column of the matrix Y.



                                13-1


13. PROCEDURES
    __________

It is often useful to name a statement for repeated use in calculations
with varying parameters, or to define a complete evaluation procedure for
an operator. REDUCE offers a procedural declaration for this purpose. Its
general syntax is:

        <procedural type> PROCEDURE <name><varlist>;<statement>;
and
        <varlist> ::= (<variable>,...,<variable>)

This will be explained more fully in the following sections.

In the algebraic mode of REDUCE the <procedure type> can be omitted, since
the default is ALGEBRAIC. Procedures of type INTEGER or REAL may also be
used. In the former case, the system checks to ensure that the input
parameters and value of the procedure are integers. At present, such
checking is not done for a real procedure, although this will change in the
future when a more complete type checking mechanism is installed. Users
should therefore only use these types when appropriate.

All procedures are automatically declared to be operators on definition.

In order to allow users relatively easy access to the whole REDUCE source
program, system procedures are not protected against user redefinition. If
a procedure is redefined, a message

        *** <procedure name> REDEFINED

is printed. If this occurs, and the user is not redefining his own
procedure, he is well advised to rename it, and possibly start over
(because he has ALREADY redefined some internal procedure whose correct
functioning may be required for his job!)

All required procedures should be defined at the top level, since they
have global scope throughout a program. In particular, an attempt to
define a procedure within a procedure will cause an error to occur.


13.1 Procedure Heading
     _________ _______

Each procedure has a heading consisting of the word PROCEDURE (optionally
preceded by the word ALGEBRAIC), followed by the name of the procedure to
be defined, and followed by its formal parameters -- the symbols which
will be used in the body of the definition to illustrate what is to be
done. There are three cases:

1) No parameters. Simply follow the procedure name with a terminator
(semicolon or dollar sign or ESCAPE).

        PROCEDURE ABC;




                                13-2

When such a procedure is used in an expression or command, ABC(), with
empty parentheses, must be written.

2) One parameter. Enclose it in parentheses OR just leave at least one
space, then follow with a terminator.

        PROCEDURE ABC(X);
or      PROCEDURE ABC X;

3) More than one parameter. Enclose them in parentheses, separated by
commas, then follow with a terminator.

        PROCEDURE ABC(X,Y,Z);

Referring to the last example, if later in some expression being evaluated
the symbols ABC(U,P*Q,123) appear, the operations of the procedure body
will be carried out as if X had the same value as U does, Y the same value
as P*Q does, and Z the value 123. The values of X, Y, Z, after the
procedure body operations are completed are unchanged. So, normally, are
the values of U, P, Q, and (of course) 123. (This is technically referred
to as call by value.)

The reader will have noted the word "normally" a few lines earlier. The
call by value protections can be bypassed if necessary, as described
elsewhere.


13.2 The Procedure Body
     ___ _________ ____

Following the delimiter which ends the procedure heading must be a SINGLE
statement defining the action to be performed or the value to be
delivered. A terminator must follow the statement. If it is a semicolon,
the name of the procedure just defined is printed. It is not printed if
dollar sign or ESCAPE is used.

If the result wanted is given by a formula of some kind, the body is just
that formula, using the variables in the procedure heading.

Simple Example:

If F(X) is to mean (X+5)*(X+6)/(X+7), the entire procedure definition
could read

        PROCEDURE F X; (X+5)*(X+6)/(X+7);

Then F(10) would evaluate to 240/17, F(A-6) to A*(A-1)/(A+1), and so on.

More Complicated Example:

Suppose we need a function P(N,X) which, for any positive integer N, is
the Legendre polynomial of order N. We can define this operator using the
textbook formula defining these functions:




                                13-3

                               n                  |
                         1    d          1        |
          p (x)   =     ---   ---  ---------------|
           n             n!     n    2         1/2|
                              dy   (y -2*x*y+1)   | y=0

Put into words, the Legendre polynomial P(N,X) is the result of
substituting Y=0 in the Nth partial derivative with respect to Y of a
certain fraction involving X and Y, then dividing that by N factorial.

This verbal formula can easily be written in REDUCE:

     PROCEDURE P(N,X);
        SUB(Y=0,DF(1/(Y**2-2*X*Y+1)**(1/2),Y,N))
            /(FOR I:=1:N PRODUCT I);

Having input this definition, the expression evaluation

        2*P(2,W);

would result in the output

           2
        3*W  - 1

If the desired process is best described as a series of steps, then a group
or compound statement can be used.

Example:

The above Legendre polynomial example can be rewritten as a series of steps
instead of a single formula as follows:

     PROCEDURE P(N,X);
       BEGIN SCALAR SEED,DERIV,TOP,FACT;
            SEED:=1/(Y**2 - 2*X*Y +1)**(1/2);
            DERIV:=DF(SEED,Y,N);
            TOP:=SUB(Y=0,DERIV);
            FACT:=FOR I:=1:N PRODUCT I;
            RETURN TOP/FACT
       END;

Procedures may also be defined recursively. In other words, the procedure
body can include references to the procedure name itself, or to other
procedures which themselves reference the given procedure. As an example,
we can define the Legendre polynomial through its standard recurrence
relation:

     PROCEDURE P(N,X);
        IF N<0 THEN REDERR "Invalid argument to P(N,X)"
         ELSE IF N=0 THEN 1
         ELSE IF N=1 THEN X
         ELSE ((2*N-1)*X*P(N-1,X)-(N-1)*P(N-2,X))/N;



                                13-4

 The operator REDERR in the above example provides for a simple error exit
from an algebraic procedure. It takes a string as argument.

It should be noted however that all the above definitions of P(N,X) are
quite inefficient if extensive use is to be made of such polynomials, since
each call effectively recomputes all lower order polynomials. It would be
better to store these expressions in an array, and then use say the
recurrence relation to compute only those polynomials that have not already
been derived. We leave it as an exercise for the reader to write such a
definition.


13.3 Using LET Inside Procedures
     _____ ___ ______ __________

By using LET instead of an assignment in the procedure body it is possible
to bypass the call-by-value protection. If X is a formal parameter or
local variable of the procedure (i.e. is in the heading or in a SCALAR
declaration), and LET is used instead of := to make an assignment to X,
e.g.

        LET X = 123;

then it is the variable which is the value of X that is changed. (If the
value of X is not a variable, but say P*Q, it is as if LET P*Q = 123 has
been executed. With P*Q this is a meaningful LET statement; with more
complicated expressions it may not be, and an error message will result.)


13.4 Let Rules as Procedures
     ___ _____ __ __________

The LET statement offers an alternative syntax and semantics for procedure
definition.

In place of

        PROCEDURE ABC (X,Y,Z);
           <procedure body>;

one can write

        FOR ALL X,Y,Z LET ABC(X,Y,Z) = <procedure body>;

There are several differences to note.

If the procedure body contains an assignment to one of the formal
parameters, e.g.

           X:=123;

in the PROCEDURE case it is a variable holding a copy of the first actual
argument which is changed. The actual argument is not changed.

In the LET case, the actual argument is changed. Thus, if ABC is defined



                                13-5

using LET, and ABC(U,V,W) is evaluated, the value of U changes to 123.

That is, the LET form of definition allows the user to bypass the
protections which are enforced by the call by value conventions of
standard PROCEDURE definitions.

Example: We take our earlier FACTORIAL procedure and write it as a LET
statement.

FOR ALL N LET FACTORIAL N =
            BEGIN SCALAR M,S;
            M:=1; S:=N;
        L1: IF S=0 THEN RETURN M;
            M:=M*S;
            S:=S-1;
            GO TO L1
        END;

The reader will notice that we introduced a new local variable, S, and set
it equal to N. The original form of the procedure contained the statement
N:=N-1;. If the user asked for the value of FACTORIAL (5) then N would
correspond to -- not just have the value of -- 5, and REDUCE would object
to trying to execute the statement 5:=5-1.

If PQR is a procedure with no parameters,

        PROCEDURE PQR;
           <procedure body>;

it can be written as a LET statement quite simply:

        LET PQR = <procedure body>;

To call "procedure" PQR if defined in the latter form, the empty
parentheses would not be used: use PQR not PQR() where a call on the
procedure is needed.

The two notations for a procedure with no arguments can be combined. PQR
can be defined in the standard PROCEDURE form. Then a LET statement

        LET PQR = PQR();

would allow a user to use PQR instead of PQR() in calling the procedure.

A feature available with LET-defined procedures and not with procedures
defined in the standard way is the possibility of defining partial
functions.

    FOR ALL X SUCH THAT NUMBERP X LET UVW(X) = <procedure body);

Now UVW of an integer would be calculated as prescribed by the procedure
body, while UVW of a general argument, such as Z or P+Q (assuming these
evaluate to themselves) would simply stay UVW(Z) or UVW(P+Q) as the case
may be.



                                14-1


14. SYMBOLIC MODE
    ________ ____

At the system level, REDUCE is based on a version of the programming
language LISP known as Standard LISP which is described in J. Marti,
Hearn, A. C., Griss, M. L. and Griss, C., "Standard LISP Report" SIGPLAN
Notices, ACM, New York, 14, No 10 (1979) 48-68. We shall assume in this
section that the reader is familiar with the material in that paper. This
also assumes implicitly that the reader has a reasonable knowledge about
LISP in general, say at the level of the LISP 1.5 Programmer's Manual
(McCarthy, J., Abrahams, P. W., Edwards, D. J., Hart, T. P. and Levin, M.
I., "LISP 1.5 Programmer's Manual", M.I.T. Press, 1965) or any of the
books mentioned at the end of this section. Persons unfamiliar with this
material will have some difficulty understanding this section.

Although REDUCE is designed primarily for algebraic calculations, its
source language is general enough to allow for a full range of LISP-like
symbolic calculations. To achieve this generality, however, it is
necessary to provide the user with two modes of evaluation, namely an
algebraic mode and a symbolic mode. To enter symbolic mode, the user types
SYMBOLIC; (or LISP;) and to return to algebraic mode he types ALGEBRAIC;.
Evaluations proceed differently in each mode so the user is advised to
check what mode he is in if a puzzling error arises. He can find his mode
by typing

        !*MODE;

The current mode will then be printed as ALGEBRAIC or SYMBOLIC.

Expression evaluation may proceed in either mode at any level of a
calculation, provided the results are passed from mode to mode in a
compatible manner. One simply prefixes the relevant expression by the
appropriate mode. If the mode name prefixes an expression at the top
level, it will then be handled as if the global system mode had been
changed for the scope of that particular calculation.

For example, if the current mode is ALGEBRAIC, then the commands

        SYMBOLIC CAR '(A);
        X+Y;

will cause the first expression to be evaluated and printed in symbolic
mode and the second in algebraic mode. Only the second evaluation will
thus affect the expression workspace. On the other hand, the statement

        X + SYMBOLIC CAR '(12);

will result in the algebraic value X+12.

For convenience, it is assumed that any operator whose FIRST argument is
quoted is being evaluated in symbolic mode, regardless of the mode in
effect at that time. Thus, the first example above could be equally well
written:



                                14-2


        CAR '(A);

Except where explicit limitations have been made, most REDUCE algebraic
constructions carry over into symbolic mode. However, there are some
differences. First, expression evaluation now becomes LISP evaluation.
Secondly, assignment statements are handled differently, as we discuss
shortly. Thirdly, local variables and array elements are initialized to
NIL rather than 0. (In fact, any variables not explicitly declared INTEGER
and all array elements are also initialized to NIL in algebraic mode, but
the algebraic evaluator recognizes NIL as 0.) Fourthly, the delimiters SUM
and PRODUCT in the FOR statement (qv) are not defined in symbolic mode.
Finally, function definitions follow the conventions of Standard LISP.

To begin with, we mention a few extensions to our basic syntax which are
designed primarily if not exclusively for symbolic mode.


14.1 Symbolic Infix Operators
     ________ _____ _________

There are four binary infix operators in REDUCE intended for use in
symbolic mode, namely . (CONS), EQ, MEMBER and MEMQ. The precedence of
these operators was given in another section.


14.2 Symbolic Expressions
     ________ ___________

These consist of scalar variables and operators and follow the normal
rules of the LISP meta language.

Examples:
        X
        CAR U . REVERSE V
        SIMP (U+V**2)


14.3 Quoted Expressions
     ______ ___________

Because LISP evaluation requires that each variable or expression has a
value, it is necessary to add to REDUCE the concept of a quoted expression
by analogy with the LISP QUOTE function. This is provided by the single
quote mark '.

        e.g. 'A       represents the LISP S-expression (QUOTE A)
             '(A B C) represents the LISP S-expression (QUOTE (A B C))

Note, however, that strings are constants and therefore evaluate to
themselves in symbolic mode. Thus, to print the string "A string", one
would write

        PRIN2 "A string";

Within a quoted expression, identifier syntax rules are those of REDUCE.



                                14-3

Thus ( A !. B) is the list consisting of the three elements A, . and B,
whereas (A . B) is the dotted pair of A and B.


14.4 LAMBDA Expressions
     ______ ___________

LAMBDA expressions provide the means for constructing LISP LAMBDA
expressions in symbolic mode. They may not be used in algebraic mode.

Syntax:

<LAMBDA expression> ::= LAMBDA <varlist><terminator><statement>
 where <varlist> ::= (<variable>,...,<variable>)

        e.g. LAMBDA (X,Y); CAR X . CDR Y

is equivalent to the LISP LAMBDA expression

        (LAMBDA (X Y) (CONS (CAR X) (CDR Y)))

The parentheses may be omitted in specifying the variable list if desired.

LAMBDA expressions may be used in symbolic mode in place of prefix
operators, or as an argument of the reserved word FUNCTION.


14.5 Symbolic Assignment Statements
     ________ __________ __________

In symbolic mode, if the left side of an assignment statement is a
variable, a SETQ of the right hand side to that variable occurs. If the
left hand side is an expression, it must be of the form of an array
element, otherwise an error will result.

        e.g.  X:=Y  translates into  (SETQ X Y)

        whereas

        A(3) := 3

will be valid if A has been previously declared a single dimensioned array
of at least four elements.


14.6 FOR EACH Statement
     ___ ____ _________

The FOR EACH (or FOREACH) statement is designed for iteration down a list
in symbolic mode. Its syntax is:

  FOR EACH ID:identifier {IN|ON} LST:list {DO|COLLECT|CONC} EXPRN:S-expr

If the keyword IN is used, iteration is on each element of the list, with
ON, on the whole list remaining at each point in the iteration. The
keyword DO means that EXPRN is simply evaluated and no value kept; the



                                14-4

statement returning NIL in this case. COLLECT means that the results of
evaluating EXPRN each time are consed together, and CONC means they are
CONCed together. In other words, we have the following equivalence between
each form of FOR EACH and the various mapping functions in LISP:

           |    DO    COLLECT   CONC
       ----|--------------------------
        IN |   MAPC   MAPCAR   MAPCAN
        ON |   MAP    MAPLIST  MAPCON

Example:

To list each element of the list (A B C):

        FOR EACH X IN '(A B C) COLLECT LIST X;


14.7 Symbolic Procedures
     ________ __________

All the functions described in the Standard LISP Report are available to
users in symbolic mode. Additional functions may also be defined as
symbolic procedures. For example, to define the LISP function ASSOC, the
following could be used:

     SYMBOLIC PROCEDURE ASSOC(U,V);
        IF NULL V THEN NIL
         ELSE IF U = CAAR V THEN CAR V
         ELSE ASSOC(U, CDR V);

If the default mode were symbolic, then SYMBOLIC could be omitted in the
above definition. MACROs and FEXPRs may be defined by prefixing the
keyword PROCEDURE by the word MACRO or FEXPR. (In fact, ordinary functions
may be defined with the keyword EXPR prefixing PROCEDURE as was used in
the Standard LISP Report.)

e.g. we could define a MACRO CONSCONS by

        SYMBOLIC MACRO PROCEDURE CONSCONS L;
           EXPAND(CDR L, 'CONS);


14.8 Obtaining the Standard LISP Equivalent of REDUCE Input
     _________ ___ ________ ____ __________ __ ______ _____

A user can obtain the Standard LISP equivalent of his REDUCE input by
turning on the switch DEFN (for definition). The system then prints the
LISP translation of his input but does not evaluate it. Normal operation
is resumed when DEFN is turned off.



                                14-5


14.9 Communicating with Algebraic Mode
     _____________ ____ _________ ____

One of the principal motivations for a user of the algebraic facilities of
REDUCE to learn about symbolic mode is that it gives one access to a wider
range of techniques than is possible in algebraic mode alone. For example,
if a user wishes to use parts of the system defined in the basic system
source code, or refine their algebraic code definitions to make them more
efficient, then it is necessary to understand the source language in
fairly complete detail. Moreover, it is also necessary to know a little
more about the way REDUCE operates internally. Basically, REDUCE considers
expressions in two forms; prefix form, which follow the normal LISP rules
of function composition, and so called canonical form, which uses a
different syntax.

Once these details are understood, the most critical problem faced by a
user is how to make expressions and procedures communicate between symbolic
and algebraic mode. The purpose of this section is to teach a user the
basic principles for this.

If one wants to evaluate an expression in algebraic mode, and then use
that expression in symbolic mode calculations, or vice versa, the easiest
way to do this is to assign a variable to that expression whose value is
easily obtainable in both modes. To facilitate this, a declaration SHARE
is available. SHARE takes a list of identifiers as argument, and marks
these variables as having recognizable values in both modes. The
declaration may be used in either mode.

E.g.,

        SHARE X,Y;

says that X and Y will receive values to be used in both modes.


14.9.1  Passing Algebraic Mode Values to Symbolic Mode
        _______ _________ ____ ______ __ ________ ____

If one wishes to work with parts of an algebraic mode expression in
symbolic mode, one simply makes an assignment of a shared variable to the
relevant expression in algebraic mode. For example, if one wishes to work
with (A+B)**2, one would say, in algebraic mode:

        X := (A+B)**2;

assuming that X was declared shared as above. If we now change to symbolic
mode and say

        X;

its value will be printed as a prefix form with the syntax:

        (*SQ <standard quotient> T)




                                14-6

This particular format reflects the fact that the algebraic mode processor
currently likes to transfer prefix forms from command to command, but
doesn't like to reconvert standard forms (which represent polynomials) and
standard quotients back to a true LISP prefix form for the expression
(which would result in excessive computation). So *SQ is used to tell the
algebraic processor that it is dealing with a prefix form which is really a
standard quotient and the second argument (T or NIL) tells it whether it
needs further processing (essentially, an 'already simplified' flag).

So to get the true standard quotient form in symbolic mode, one needs CADR
of the variable. E.g.,

        Z := CADR X;

would store in Z the standard quotient form for (A+B)**2.

Once you have this expression, you can now manipulate it as you wish. To
facilitate this, a standard set of selectors and constructors are available
for getting at parts of the form. Those presently defined are as follows:

REDUCE Selectors

 DENR           denominator of standard quotient

 LC             leading coefficient of polynomial

 LDEG           leading degree of polynomial

 LPOW           leading power of polynomial

 LT             leading term of polynomial

 MVAR           main variable of polynomial

 NUMR           numerator (of standard quotient)

 PDEG           degree of a power

 RED            reductum of polynomial

 TC             coefficient of a term

 TDEG           degree of a term

 TPOW           power of a term


REDUCE Constructors

 .+             add a term to a polynomial

 ./             divide (two polynomials to get quotient)




                                14-7

 .*             multiply a power by a coefficient to produce a term

 .**            raise a variable to a power     


For example, to find the numerator of the standard quotient above, one
could say:

        NUMR Z;

or to find the leading term of the numerator:

        LT NUMR Z;

Conversion between various data structures is facilitated by the use of a
set of functions defined for this purpose. Those currently implemented
include:

 !*A2F          convert an algebraic expression to a standard form.
                If result is rational, an error results.

 !*A2K          converts an algebraic expression to a kernel. If this
                is not possible, an error results.

 !*F2A          converts a standard form to an algebraic expression

 !*F2Q          convert a standard form to a standard quotient

 !*K2F          convert a kernel to a standard form

 !*K2Q          convert a kernel to a standard quotient

 !*P2F          convert a standard power to a standard form

 !*P2Q          convert a standard power to a standard quotient

 !*Q2F          convert a standard quotient to a standard form.
                If the quotient denominator is not 1, an error results

 !*Q2K          convert a standard quotient to a kernel. If this
                is not possible, an error results.

 !*T2F          convert a standard term to a standard form

 !*T2Q          convert a standard term to a standard quotient


14.9.2 Passing Symbolic Mode Values back to Algebraic Mode
       _______ ________ ____ ______ ____ __ _________ ____

In order to pass the value of a shared variable from symbolic mode to
algebraic mode, the only thing to do is make sure that the value in
symbolic mode is a prefix expression. E.g.,




                                14-8

        (EXPT (PLUS A B) 2)

for (A+B)**2, or in the format (*SQ <standard quotient> T) as described
above. However, if you have been working with parts of a standard form
they will probably not be in this form. In that case, you can do the
following:

1) If it is a standard quotient, call PREPSQ on it.  This takes a standard
quotient as argument, and returns a prefix expression. Alternatively, you
can call MK!*SQ on it, which returns a prefix form like (*SQ <standard
quotient> T) and avoids translation of the expression into a true prefix
form.

2) If it is a standard form, call PREPF on it. This takes a standard form
as argument, and returns the equivalent prefix expression. Alternatively,
you can convert it to a standard quotient and then call MK!*SQ.

3) If it is a part of a standard form, you must usually first build up a
standard form out of it, and then go to step 2. The conversion functions
described earlier may be used for this purpose. For example,
   a) If Z is an expression which is a term, !*T2F Z is a standard form.
   b) If Z is a standard power, !*P2F Z is a standard form.
   c) If Z is a variable, you can pass it direct to algebraic mode.

For example, to pass the leading term of (A+B)**2 back to algebraic mode,
one could say:

        Y:= MK!*SQ !*T2Q LT NUMR Z;

where Y has been declared shared as above. If you now go back to algebraic
mode, you can work with Y in the usual way.


14.9.3 Complete Example
       ________ _______

The following is the complete code for doing the above steps. The end
result will be that the square of the leading term of (A+B)**2 is
calculated.

 SHARE X,Y;     %declare X and Y as shared variables;
 X := (A+B)**2; %store (A+B)**2 in X;
 SYMBOLIC;      %transfer to symbolic mode;
 Z := CADR X;   %store true standard quotient in Z;
 LT NUMR Z;     %print the leading term of the numerator of Z;
 Y := MK!*SQ !*T2Q NUMR Z;
                %store a valid prefix form of this leading term in Y;
 ALGEBRAIC;     %return to algebraic mode;
 Y**2;          %evaluate the square of the leading term of (A+B)**2;



                                14-9


14.9.4 Defining Procedures which Communicate between Modes
       ________ __________ _____ ___________ _______ _____

If one wishes to define a procedure in symbolic mode for use as an
operator in algebraic mode, it is necessary to declare this fact to the
system by using the declaration OPERATOR in SYMBOLIC MODE. Thus

        SYMBOLIC OPERATOR LEADTERM;

would declare the procedure LEADTERM as an algebraic operator. This
declaration MUST be made in symbolic mode as the effect in algebraic mode
is different. The value of such a procedure must be a prefix form.

The algebraic processor will pass arguments to such procedures in prefix
form. Therefore if you want to work with the arguments as standard
quotients you must first convert them to that form by using the function
SIMP!*. This function takes a prefix form as argument and returns the
evaluated standard quotient.

For example, if you want to define a procedure LEADTERM which gives the
leading term of an algebraic expression, one could do this as follows:

 SYMBOLIC OPERATOR LEADTERM;    %declare LEADTERM as a symbolic mode
                                %procedure to be used in algebraic mode;

 SYMBOLIC PROCEDURE LEADTERM U; %define LEADTERM;
   MK!*SQ !*T2Q LT NUMR SIMP!* U;

Note that this operator has a different effect than the operator LTERM
(qv). In the latter case, the calculation is done with respect to the
second argument of the operator. In the example here, we simply extract
the leading term with respect to the system's choice of main variable.

Finally, if you wish to use the algebraic evaluator on an argument in a
symbolic mode definition, the function REVAL can be used. The one argument
of REVAL must be the prefix form of an expression. REVAL returns the
evaluated expression as a true LISP prefix form.


14.10 References:
      ___________

There are a number of useful books which can give you further information
about LISP. Here is a selection:

Allen, J. R., "The Anatomy of LISP", McGraw Hill, New York, 1978.

McCarthy J., P. W. Abrahams, J. Edwards, T. P. Hart and
     M. I. Levin, "LISP 1.5 Programmer's Manual", M.I.T. Press, 1965.

Weissman, C., "LISP 1.5 Primer", Dickenson, 1967.

Winston, P. H. and Horn, B. K. P., "LISP", Addison-Wesley, 1981.



                                15-1


15. CALCULATIONS IN HIGH ENERGY PHYSICS
    ____________ __ ____ ______ _______

A set of REDUCE commands is provided for users interested in symbolic
calculations in high energy physics. Several extensions to our basic
syntax are necessary, however, to allow for the different data structures
encountered.


15.1 Notation
     ________

In order to allow for the printing of this text on printers with limited
character sets, we represent Greek characters in this section by their
(upper case) English names.


15.2 Operators used in High Energy Physics Calculations
     _________ ____ __ ____ ______ _______ ____________

We begin by introducing three new operators required in these
calculations.


15.2.1 . (DOT)
       _ _____

Syntax: (EXPRN1:vector_expression)
                 . (EXPRN2:vector_expression):algebraic.

The . operator is a binary operator used in algebraic mode to denote the
scalar product of two Lorentz four-vectors. In the present system, the
index handling routines all assume that Lorentz four-vectors are used, but
these routines could be rewritten to handle other cases.

Components of vectors can be represented by including representations of
unit vectors in the system. Thus if EO represents the unit vector
(1,0,0,0), (P.EO) represents the zeroth component of the four-vector P.
Our metric and notation follows Bjorken and Drell "Relativistic Quantum
Mechanics" (McGraw-Hill, New York, 1965). Similarly, an arbitrary
component P may be represented by (P.U). If contraction over components of
vectors is required, then the declaration INDEX must be used.

Thus

                INDEX U;

declares U as an index, and the simplification of

                (P.U) * (Q.U)

would result in

                (P.Q)

The metric tensor g(u,v) may be represented by (U.V). If contraction over



                                15-2

u and v is required, then U and V should be declared as indices.

The declaration REMIND V1...VN; removes the index flags from the variables
V1 through Vn. However, these variables remain vectors in the system.


15.2.2 G
       _

Syntax: G(ID:identifier[,EXPRN:vector_expression])
                :gamma_matrix_expression.

G is an n-ary operator used to denote a product of gamma matrices
contracted with Lorentz four-vectors. Gamma matrices are associated with
fermion lines in a Feynman diagram. If more than one such line occurs,
then a different set of gamma matrices (operating in independent spin
spaces) is required to represent each line. To facilitate this, the first
argument of G is a line identification identifier (not a number) used to
distinguish different lines.

Thus
                G(L1,P) * G(L2,Q)

denotes the product of P associated with a fermion line identified as L1,
and Q associated with another line identified as L2 and where P and Q are
Lorentz four-vectors. A product of gamma matrices associated with the same
line may be written in a contracted form.

Thus

                G(L1,P1,P2,...,P3) = G(L1,P1)*G(L1,P2)*,...,*G(L1,P3)

The vector A is reserved in arguments of G to denote the special gamma
matrix GAMMA5. Thus

                G(L,A)   =   GAMMA5 associated with line L.

                G(L,P,A) =   GAMMA.P*GAMMA5 associated with line L.

GAMMA (associated with line L) may be written as G(L,U), with U flagged
     U
as an index if contraction over U is required.

The notation of Bjorken and Drell is assumed in all operations involving
gamma matrices.


15.2.3 EPS
       ___

Syntax: EPS(EXPRN1:vector_expression,...,EXPRN4:vector_exp):vector_exp.

The operator EPS has four arguments, and is used only to denote the
completely antisymmetric tensor of order 4 and its contraction with Lorentz
four-vectors.



                                15-3

 Thus

        EPS     = ( +1 if I,J,K,L is an even permutation of 0,1,2,3
           IJKL   ( -1 if an odd permutation
                  ( 0 otherwise

 A contraction of the form EPS    p q  may be written as EPS(I,J,P,Q),
                              IJuv u v

with I and J flagged as indices, and so on.


15.3 Vector variables
     ______ _________

Apart from the line identification identifier in the G operator, all other
arguments of the operators in this section are vectors. Variables used as
such must be declared so by the type declaration VECTOR.

        e.g.    VECTOR  P1,P2;

declares P1 and P2 to be vectors. Variables declared as indices or given a
mass (qv) are automatically declared vector by these declarations.


15.4 Additional Expression Types
     __________ __________ _____

Two additional expression types are necessary for high energy
calculations, namely


15.4.1 Vector Expressions
       ______ ___________

These follow the normal rules of vector combination. Thus the product of a
scalar or numerical expression and a vector expression is a vector, as are
the sum and difference of vector expressions. If these rules are not
followed, error messages are printed. Furthermore, if the system finds an
undeclared variable where it expects a vector variable, it will ask the
user in interactive mode whether to make that variable a vector or not. In
batch mode, the declaration will be made automatically and the user
informed of this by a message.

Examples:

Assuming P and Q have been declared vectors, the following are vector
expressions

        P
        P-2*Q/3
        2*X*Y*P - P.Q*Q/(3*Q.Q)

whereas P*Q and P/Q are not.



                                15-4


15.4.2 Dirac Expressions
       _____ ___________

These denote those expressions which involve gamma matrices. A gamma
matrix is implicitly a 4 x 4 matrix, and so the product, sum and difference
of such expressions, or the product of a scalar and Dirac expression is
again a Dirac expression. There are no Dirac variables in the system, so
whenever a scalar variable appears in a Dirac expression without an
associated gamma matrix expression, an implicit unit 4 x 4 matrix is
assumed.

        e.g. G(L,P) + M denotes G(L,P) + M*<unit 4 x 4 matrix>

Multiplication of Dirac expressions, as for matrix expressions, is of
course non-commutative.


15.5 Trace Calculations
     _____ ____________

When a Dirac expression is evaluated, the system computes one quarter of
the trace of each gamma matrix product in the expansion of the expression.
One quarter of each trace is taken in order to avoid confusion between the
trace of the scalar M, say, and M representing M * <unit 4 x 4 matrix>.
Contraction over indices occurring in such expressions is also performed.
If an unmatched index is found in such an expression, an error occurs.

The algorithms used for trace calculations are the best available at the
time this system was produced. For example, in addition to the algorithm
developed by Chisholm for contracting indices in products of traces, REDUCE
uses the elegant algorithm of Kahane for contracting indices in gamma
matrix products. These algorithms are described in Chisholm, J. S. R., Il
Nuovo Cimento X, 30, 426 (1963) and Kahane, J., Journal Math. Phys. 9,
1732 (1968).

It is possible to prevent the trace calculation over any line identifier
by the declaration NOSPUR.

        E.g. NOSPUR L1,L2;

will mean that no traces are taken of gamma matrix terms involving the line
numbers L1 and L2. However, in some calculations involving more than one
line, a catastrophic error "This NOSPUR option not implemented" can occur
(for the reason stated!) If you encounter this error, please let us know!

A trace of a gamma matrix expression involving a line identifier which has
been declared NOSPUR may be later taken by making the declaration SPUR.


15.6 Mass Declarations
     ____ ____________

It is often necessary to put a particle 'on the mass shell' in a
calculation. This can, of course, be accomplished with a LET command such
as



                                15-5


        LET P.P= M**2;

but an alternative method is provided by two commands MASS and MSHELL.
MASS takes a list of equations of the form:

        <vector variable> = <scalar variable>

        e.g. MASS P1=M, Q1=MU;

The only effect of this command is to associate the relevant scalar
variable as a mass with the corresponding vector. If we now say

        MSHELL <vector variable>,...,<vector variable>;

and a mass has been associated with these arguments, a substitution of the
form

     <vector variable>.<vector variable> = <mass>**2

is set up. An error results if the variable has no preassigned mass.


15.7 Example
     _______

We give here as an example of a simple calculation in high energy physics
the computation of the Compton scattering cross-section as given in
Bjorken and Drell Eqs. (7.72) through (7.74).

We wish to compute

        2         2        PF+m  E'EKI   EE'KF   PI+m  KIEE'   KFE'E
   ALPHA /2 (k'/k) trace ((----)(----- + ------)(----)(----- + ------)).
                            2m   2k.PI   2k'.PI   2m   2k.PI   2k'.PI

where ki and kf are the four-momenta of incoming and outgoing photons
(with polarization vectors e and e' and laboratory energies k and k'
respectively) and pi,pf are incident and final electron four-momenta.
Upper case momenta in the above formula are used to indicate contractions
of the momenta with gamma matrices. For example, PF = GAMMA . pf.

      Omitting the factor ALPHA**2/(2*m**2)*(k'/k)**2 we need to find
                
                          E'EKI   EE'KF         KIEE'   KFE'E
        1/4 trace ((PF+m)(----- + ------)(PI+m)(----- + ------))
                          2k.pi   2k'.pi        2k.pi   2k'.pi

A straightforward REDUCE program for this, with appropriate substitutions
would be:

 ON DIV; COMMENT THIS GIVES US OUTPUT IN SAME FORM AS BJORKEN AND DRELL;
 MASS KI= 0, KF= 0, PI= M, PF= M; VECTOR E;
 COMMENT IF E IS USED AS A VECTOR, IT LOSES ITS SCALAR IDENTITY AS THE



                                15-6

        BASE OF NATURAL LOGARITHMS;
 MSHELL KI,KF,PI,PF;
 LET PI.E= 0, PI.EP= 0, PI.PF= M**2+KI.KF, PI.KI= M*K,PI.KF=
     M*KP, PF.E= -KF.E, PF.EP= KI.EP, PF.KI= M*KP, PF.KF=
     M*K, KI.E= 0, KI.KF= M*(K-KP), KF.EP= 0, E.E= -1, EP.EP=-1;
 FOR ALL P LET GP(P)= G(L,P)+M;
 COMMENT THIS IS JUST TO SAVE US A LOT OF WRITING;
 GP(PF)*(G(L,EP,E,KI)/(2*KI.PI) + G(L,E,EP,KF)/(2*KF.PI))
   * GP(PI)*(G(L,KI,E,EP)/(2*KI.PI) + G(L,KF,EP,E)/(2*KF.PI)) $
 WRITE "THE COMPTON CROSS-SECTION IS ",WS;

This program will print the following result

                            (-1)        (-1)            2
 THE COMPTON CXN IS 1/2*K*KP     + 1/2*K    *KP + 2*E.EP  - 1


15.8 Extensions to More than Four Dimensions
     __________ __ ____ ____ ____ __________

In our discussion so far, we have assumed that we are working in the
normal four dimensions of QED calculations. However, in most cases, the
programs will also work in an arbitrary number of dimensions. The command

     VECDIM <expression>;

sets the appropriate dimension. The dimension can be symbolic as well as
numeric. Users should note however, that the EPS operator and the gamma 5
symbol (A) are not properly defined in other than four dimensions and will
lead to an error if used.



                                16-1


16. REDUCE AND RLISP UTILITIES
    ______ ___ _____ _________

REDUCE and its associated support language system RLISP include a number
of utilities which have proved useful for program development over the
years. The following are supported in most of the implementations of
REDUCE currently available.


16.1 The Standard LISP Compiler
     ___ ________ ____ ________

REDUCE includes a Standard LISP compiler that is automatically loaded on
demand. To make the compiler active, the switch COMP should be turned on.
Any further definitions input after this will be compiled automatically.
Furthermore, if the switch PWRDS is on (the default), a statistics message
of the form

<function-name> COMPILED, <words> WORDS, <words> LEFT

is printed. The first number is the number of words of binary program
space the compiled function took, and the second number the number of words
left unused in binary program space.

Other switches of interest which may be used with the compiler are as follows:

 PLAP   If ON, causes the printing of the portable macros produced
        by the compiler.

 PGWD   If ON, causes the printing of the actual assembly language
        instructions generated from the macros.

A complete description of the compiler may be found in M. L. Griss and A.
C. Hearn, "A Portable LISP Compiler", SOFTWARE - Practice and Experience
11 (1981) 541-605.


16.2 Fast Loading Code Generation Program
     ____ _______ ____ __________ _______

It is possible to take any set of LISP, RLISP or REDUCE commands and build
a fast loading version of them. In RLISP or REDUCE, one does the
following:

 FASLOUT <filename>;
 <commands or IN statements>
 FASLEND;

To load such a file, one uses the command LOAD, e.g. LOAD FOO; or LOAD
FOO,BAH;

Fast-loading files produced by this process may have an implementation
dependent extension added by this process. For example, on the DEC-10 an
extension FAP is added, and on the VAX, b (for binary). Such extensions are
required by the LOAD program; if they are missing, an error occurs.



                                16-2

 In doing this build, as with the production of a Standard LISP form of
such statements, it is important to remember that some of the commands
must be instantiated during the building process. For example, macros must
be expanded, and some property list operations must happen. To facilitate
this, the EVAL and IGNORE flags (qv) may be used. Note also that there can
be no LOAD command within the input statements.

To avoid excessive printout, input statements should be followed by a $
instead of the semicolon. With LOAD however, the input doesn't print out
regardless of which terminator is used with the command.

If you subsequently change the source files used in producing a fast
loading file, don't forget to repeat the above process in order to update
the fast loading file correspondingly. Remember also that the text which
is read in during the creation of the fast load file, in the compiling
process described above, is NOT stored in your REDUCE environment, but only
translated and output. If you want to use the file just created, you must
then use LOAD to load the output of the fast-loading file generation program.


16.3 The Standard LISP Cross-Reference Program
     ___ ________ ____ _______________ _______

CREF is a Standard LISP program for processing a set of Standard LISP
function definitions to produce:

1) A "summary" showing:

     i. A list of files processed.
    ii. A list of "entry points" (functions which are not called or
        are only called by themselves).
   iii. A list of undefined functions (functions called but not
        defined in this set of functions).
    iv. A list of variables that were used non-locally but not
        declared GLOBAL or FLUID before their use.
     v. A list of variables that were declared GLOBAL but not used
        as FLUIDs, i.e., bound in a function.
    vi. A list of FLUID variables that were not bound in a function
        so that one might consider declaring them GLOBALs.
   vii. A list of all GLOBAL variables present.
  viii. A list of all FLUID variables present.
    ix. A list of all functions present.

2) A "global variable usage" table, showing for each non-local
   variable:

    i. Functions in which it is used as a declared FLUID or GLOBAL.
   ii. Functions in which it is used but not declared.
  iii. Functions in which it is bound.
   iv. Functions in which it is changed by SETQ.

3) A "function usage" table showing for each function:

    i. Where it is defined.



                                16-3

   ii. Functions which call this function.
  iii. Functions called by it.
   iv. Non-local variables used.

The program will also check that functions are called with the correct
number of arguments, and print a diagnostic message otherwise.

The output is alphabetized on the first seven characters of each function
name.


16.3.1 Restrictions:
       _____________

Algebraic procedures in REDUCE are treated as if they were symbolic, so
that algebraic constructs will actually appear as calls to symbolic
functions, such as AEVAL.


16.3.2 Usage:
       ______

To invoke the cross reference program, the switch CREF is used. ON CREF
causes the cref program to load and the cross-referencing process to
begin. After all the required definitions are loaded, OFF CREF will cause
the cross-reference listing to be produced. For example, if you wish to
cross-reference all functions in the file TST.RED, and produce the
cross-reference listing in the file TST.CRF, the following sequence can be
used:

     OUT TST.CRF;
     ON CREF;
     IN TST.RED$
     OFF CREF;
     END;

To process more than one file, more IN statements may be added before the
call of OFF CREF, or the IN statement changed to include a list of files.


16.3.3 Options:
       ________

Functions with the flag NOLIST will not be examined or output. Initially,
all Standard LISP functions are so flagged. (In fact, they are kept on a
list NOLIST!*, so if you wish to see references to ALL functions, then CREF
should be first loaded with the command LOAD CREF, and this variable then
set to NIL).

It should also be remembered that any macros with the property list flag
EXPAND, or, if the switch FORCE is on, without the property list flag
NOEXPAND, will be expanded before the definition is seen by the cross-
reference program, so this flag can also be used to select those macros you
require expanded and those you do not.



                                16-4


16.4 Prettyprinting Reduce Expressions
     ______________ ______ ___________

REDUCE includes a module for printing REDUCE syntax in a standard format.
This module is activated by the switch PRET, which is normally off.

Since the system converts algebraic input into an equivalent symbolic form,
the printing program tries to interpret this as an algebraic expression
before printing it. In most cases, this can be done successfully. However,
there will be occasional instances where results are printed in symbolic
mode form that bears little resemblance to the original input, even though
it is formally equivalent.

If you want to prettyprint a whole file, say OFF OUTPUT,MSG; and
(hopefully) only clean output will result. Unlike DEFN (qv), input is also
evaluated with PRET on.


16.5 Prettyprinting Standard LISP S-expressions
     ______________ ________ ____ _____________

Standard LISP includes a module for printing S-expressions in a standard
format. The Standard LISP function for this purpose is PRETTYPRINT which
takes a LISP expression and prints the formatted equivalent.

Users can also have their REDUCE input printed in this form by use of the
switch DEFN. This is in fact a convenient way to convert REDUCE (or RLISP)
syntax into LISP. OFF MSG; will prevent warning messages from being printed.

NOTE: When DEFN is on, input is not evaluated.



                                A-1


A. RESERVED IDENTIFIERS
   ________ ___________

We list here all identifiers which are normally reserved in REDUCE. We
include in this list all reserved identifiers described in the text plus
all command names and operators initially in the system.

Commands                ALGEBRAIC ARRAY CLEAR COMMENT END FACTOR  FOR
                        FORALL  GO  GOTO  IF IN INTEGER LET LISP MASS
                        MATCH MATRIX MSHELL NOSPUR  OFF  ON  OPERATOR
                        ORDER OUT PROCEDURE REAL RETURN SAVEAS SCALAR
                        SHUT  SPUR  SYMBOLIC  VECTOR   WEIGHT   WRITE
                        WTLEVEL (Page 5-1)

Infix Operators         := = >= > <= < + * / ** . SETQ OR AND NOT MEMBER
                        MEMQ EQUAL NEQ EQ GEQ GREATERP LEQ LESSP PLUS
                        DIFFERENCE MINUS TIMES QUOTIENT EXPT CONS (Page 2-6)

Prefix Operators        COEFF COS DEN DET DF EPS G LOG MAT INT NUM SIN
                        SUB TRACE (Page 6-1)

Reserved Variables      E I NIL PI T (Page 2-3)

Reserved Words          ALGEBRAIC ANTISYMMETRIC ARRAY BEGIN CLEAR CMD CONT
                        CORE CREATE DCL DEFINE DEPEND DOWN EDIT EDITDEF
                        EMB END EXEC EXPR FACTOR FEXPR FLAGOP FLOAD FOR
                        FORALL FOREACH FSLOUT GO HELP IF IN INDEX INFIX
                        INPUT INTEGER KORDER LAMBDA LET LINEAR LISP MACRO
                        MASS MATCH MATRIX MSHELL NODEPEND OFF ON OPERATOR
                        ORDER OUT PAUSE PRECEDENCE PROCEDURE QUIT REAL
                        REMFAC REPEAT RETRY RETURN RLISP SAVEAS SCALAR
                        SHARE SHOWTIME SHUT SLISP SMACRO STRUCTR SYMBOLIC
                        SYMMETRIC TR TRST UP VARNAME VECTOR WEIGHT WHILE
                        WRITE WS WTLEVEL (Page 2-4)



                                B-1


B. OPERATORS NORMALLY AVAILABLE IN REDUCE
   _________ ________ _________ __ ______

Notation: Each operator is provided with a prototypical header line given
here. Each formal parameter is given a name and followed by its allowed
type. The names of classes referred to in the definition are printed in
lower case, and parameter names in upper case. If a parameter type is not
commonly used, it may be a specific set enclosed in brackets {...}.
Operators which accept formal parameter lists of arbitrary length have the
parameter and type class enclosed in square brackets indicating that zero
or more occurrences of that argument are permitted. Optional parameters
and their type classes are enclosed in angle brackets.

ARGLENGTH(EXPRN:algebraic)
                        Returns the number of arguments of the top level
                        operator in EXPRN (Page 7-14)

COEFF(EXPRN:polynomial,VAR:kernel,ID:identifier)
                        Partitions polynomial EXPRN into its coefficients
                        with respect to VAR and stores them in ID
                         (Page 7-12)

DEG(EXPRN:polynomial,VAR:kernel):integer
                        Returns the leading degree of the polynomial EXPRN
                        in the variable VAR (Page 8-6)

DEN(EXPRN:rational):polynomial
                        Returns the denominator of the rational expression
                        EXPRN (Page 8-6)

DET(EXPRN:matrix_expression):algebraic
                        Returns the determinant of the matrix EXPRN
                         (Page 12-2)

DF(EXPRN:algebraic,[VAR:kernel<,NUM:integer>]):algebraic
                        Returns the derivative of EXPRN wrt VAR, repeated
                        NUM times (Page 6-2)

EPS(EXPRN1:vector_expression,...,EXPRN4:vector_exp):vector_exp
                        Represents the antisymmetric tensor of order 4 in
                        high energy physics calculations (Page 15-2)

FACTORIZE(EXPRN:polynomial[,ID:identifier[,INTEXP:prime integer]])
                        Factorizes polynomial EXPRN, leaving factors in ID,
                        and using optional prime INTEXP for internal
                        computation (Page 8-2)

GCD(EXPRN1:polynomial,EXPRN2:polynomial):polynomial
                        Returns the greatest common divisor of the two
                        polynomials EXPRN1 and EXPRN2 (Page 8-4)

G(ID:identifier[,EXPRN:vector_expression]):gamma_matrix_expression
                        Represents a Dirac gamma matrix expression in high



                                B-2

                        energy physics calculations (Page 15-2)

LCOF(EXPRN:polynomial,VAR:kernel):polynomial
                        Returns the leading coefficient of the polynomial
                        EXPRN in the variable VAR (Page 8-7)

LINELENGTH(NUM:integer):integer
                        Sets the output line length to NUM and returns
                        previous line length (Page 7-3)

LTERM(EXPRN:polynomial,VAR:kernel):polynomial
                        Returns the leading term of EXPRN with respect to
                        VAR (Page 8-7)

MAINVAR(EXPRN:polynomial):expression
                        Returns the main variable of EXPRN (Page 8-7)

MAT                     Used to represent matrices (Page 12-1)

NUM(EXPRN:rational):polynomial
                        Returns the numerator of the rational expression
                        EXPRN (Page 8-8)

PART(EXPRN:algebraic[,INTEXP:integer])
                        Returns the appropriate part of EXPRN as defined
                        by INTEXP (Page 7-13)

PFACTORIZE(EXPRN:polynomial,ID:identifier,INTEXP:prime integer)
                        Factorizes the univariate polynomial EXPRN modulo
                        the prime INTEXP, storing the resultant factors in
                        ID (Page 8-3)

REDUCT(EXPRN:polynomial,VAR:kernel):polynomial
                        Returns the reductum of EXPRN with respect to'
                        VAR (Page 8-8)

REMAINDER(EXPRN1:polynomial,EXPRN2:polynomial):polynomial
                        Returns the remainder when EXPRN1 is divided by
                        EXPRN2 (Page 8-5)

RESULTANT(EXPRN1:polynomial,EXPRN2:polynomial,VAR:kernel):polynomial
                        Returns the resultant of EXPRN1 and EXPRN2 with
                        respect to the variable VAR (Page 8-6)

SOLVE(EXPRN:algebraic[,VAR:kernel]):integer
                        Solves a set of linear equations in terms of the
                        kernel VAR (Page 6-5)

STRUCTR(EXPRN:algebraic):EXPRN
                        Displays the structure of EXPRN (Page 7-11)

SUB([VAR1:kernel = EXPRN1:algebraic],EXPRN:algebraic):algebraic
                        Replaces every occurrence of VAR1 in EXPRN by



                                B-3

                        EXPRN1 (Page 6-7)

TP(EXPRN:matrix_expression):matrix
                        Returns the transpose of the matrix EXPRN
                         (Page 12-3)

TRACE(EXPRN:matrix_expression):algebraic
                        Returns the trace of the matrix EXPRN (Page 12-3)

VARNAME(ID:identifier)  Sets the expression naming variable to ID
                         (Page 7-10)



                                C-1


C. COMMANDS AND DECLARATIONS
   ________ ___ ____________

This index summarizes the commands and declarations normally available in
REDUCE.

 Notation:      E, E1,...,En    denote expressions
                V, V1,...,Vn    denote variables (or more generally kernels)


ALGEBRAIC E;            If E is empty, the system mode is set to algebraic.
                        Otherwise, E is evaluated in algebraic mode and the
                        system mode is not changed (Page 14-1)

ARRAY V1<size>,...,Vn<size>
                        Declares V1 through Vn as array names. <size>
                        describes the maximum size of the array (Page 5-1)

BYE;                    Stops the execution of REDUCE and returns you to
                        the system monitor. The REDUCE job is destroyed
                         (Page 5-3)

CLEAR E1,...En;         Removes any substitutions declared for E1 through
                        En from system (Page 9-3)

COMMENT <any>;          Used for including comments in text. <any> is any
                        sequence of characters not including a
                        terminator (Page 2-4)

CONT;                   An interactive command which causes the system to
                        continue the calculation from the point in the input
                        file where the last PAUSE was encountered (Page 11-2)

DEFINE E1,...,En;       Allows for the replacement of the left-hand-side of
                        the equations E1 through En by the corresponding
                        right-hand-side (Page 5-3)

DEPEND V1,...,Vn;       Sets up a dependency of variable V1 on kernels V2
                        through Vn (Page 6-10)

DISPLAY E;              Causes previous inputs to be displayed. If E is a
                        non-negative integer, then that many expressions
                        will be displayed (Page 11-1)

EDITDEF <name>          Causes the uncompiled procedure <name> to be
                        displayed in interactive editing mode (Page 11-2)

ED <null or number>     Invokes an interactive string editor for previous
                        command or command <number> (Page 11-2)

END;                    Used to terminate a program block, end a file, or
                        transfer control to LISP (Page 5-2)



                                C-2

FACTOR E1,...En;        Declares expressions as factors in output (Page 7-4)

FOR                     Command used to define a variety of program loops
                         (Page 4-3)

FORALL V1,...,Vn <command>
                        Declares variables V1 through Vn as arbitrary in
                        the substitution rule given by <command> (Page 9-2)

FOR EACH                Used for defining a variety of iterations on lists
                        in symbolic mode (Page 14-3)

GO (TO) V;              Performs an unconditional transfer to label V
                        Can only be used in compound statements (Page 4-8)

IF                      Used to define conditional statements (Page 4-2)

INDEX V1,...,Vn;        Declares high energy vectors V1 through Vn as
                        indices (Page 15-1)

INFIX ID1,...,IDn;      Declares ID1 through IDn to be infix operators
                         (Page 6-7)

INTEGER V1,...,Vn;      Declares V1 through Vn as local integer variables in
                        a block statement (Page 4-6)

IN V1,...,Vn;           Inputs the external REDUCE files V1 through
                        Vn (Page 10-1)

KORDER V1,...,Vn;       Declares an internal ordering for variables V1
                        through Vn (Page 7-12)

LET E1,...,En;          Declares substitutions for the left hand sides of
                        expressions E1 through En. In addition, LET can be
                        used to input differentiation rules (Page 9-1)

LISP E;                 A synonym for SYMBOLIC E; (Page 14-1)

MASS V1=M1,...,VN=MN;   Assigns a mass Mi to each vector Vi in high energy
                        physics calculations (Page 15-5)

MATCH E1,..., En;       Declares substitutions for the left hand sides
                        of E1 through En when matching of explicit
                        powers is required (Page 9-6)

MATRIX E1,...,En;       Declares matrix variables to the system.  The
                        Ei  may be matrix variable  names, or include
                        details of the size of the matrix (Page 12-1)

MSHELL V1,...,Vn;       Puts each Vi "on the mass shell" in high energy
                        physics calculations (Page 15-5)



                                C-3

NODEPEND V1,...,Vn;     Removes dependency of variable V1 on V2 through
                        Vn (Page 6-10)

NONCOM ID1,...,IDn;     Declares operators ID1 through IDn to be non-
                        commutative under multiplication (Page 6-9)

NOSPUR V1,...,Vn;       Declares that line identification symbols V1 through
                        Vn do not have traces taken over them in high energy
                        physics calculations (Page 15-4)

OFF V1,...,Vn;          Turns off the switches V1 through Vn (Page 5-2)

ON V1,...,Vn;           Turns on the switches V1 through Vn (Page 5-2)

OPERATOR V1,...,Vn;     Declares identifiers V1 through Vn as algebraic
                        operators (Page 6-7)

ORDER V1,...,Vn;        Declares an ordering for variables V1 through Vn on
                        output (Page 7-4)

OUT V;                  Declares V as an output file (Page 10-1)

PAUSE;                  An interactive command for use in an input file.
                        When it is evaluated, control is transferred to
                        the user's terminal (Page 11-2)

PRECEDENCE ID1,ID2;     Give infix operator ID1 a precedence higher than
                        ID2 (Page 6-7)

PRECISION E;            Sets the real number precision to E decimal digits
                        when arbitrary precision real arithmetic (BIGFLOAT)
                        is used (Page 8-9)

PROCEDURE               Names a statement for repeated use in calculations.
                        Type specification of procedure precedes the
                        command name (Page 13-1)

QUIT;                   Stops the execution of REDUCE and returns you to
                        the system monitor. The REDUCE job is retained
                         (Page 5-3)

REAL V1,...,Vn;         Declares V1 through Vn as local real variables in a
                        block statement (Page 4-6)

REMFAC E1,...,En;       Removes expressions as factors in output (Page 7-4)

REMIND V1,...,Vn;       Declares that V1 through Vn are no longer high
                        energy physics indices (Page 15-2)

RETURN E;               Causes a transfer out of a compound statement
                        to the next highest program level. Value of E
                        is returned from compound statement. E may be
                        empty (Page 4-8)



                                C-4

SAVEAS E;               Assigns E to the current expression in the
                        workspace (Page 7-2)

SCALAR V1,...,Vn;       Declares V1 through Vn as local scalar variables in
                        a block statement (Page 4-6)

SETMOD E;               Sets the modular base to E (used with the switch
                        MODULAR) (Page 8-9)

SHARE V1,...,Vn;        Permits variables V1 through Vn to be accessed
                        in both symbolic and algebraic modes (Page 14-5)

SHOWTIME;               Prints the elapsed time since the last call of this
                        command or the beginning of the session (Page 5-3)

SHUT V1,...,Vn;         Closes the output files V1 through Vn (Page 10-2)

SPUR V1,...,Vn;         Declares that line identification symbols V1 through
                        Vn now have traces taken over them in high energy
                        physics calculations (Page 15-4)

SYMBOLIC E;             If E is empty, the system evaluation mode is set to
                        symbolic. Otherwise, E is evaluated in symbolic mode
                        and the system mode not changed (Page 14-1)

VECDIM E;               Sets the dimension of the vector and Dirac matrix
                        algebra to the expression E in high energy physics
                        calculations (Page 15-6)

VECTOR V1,...,Vn;       Declares V1 through Vn to be high energy physics
                        vectors (Page 15-3)

WEIGHT E1,...En;        Assigns an asymptotic weight to the left hand sides
                        of E1 through En (Page 9-6)

WRITE E1,...,En;        Causes the values of E1 through En to be written on
                        the current output channel (Page 7-6)

WTLEVEL E;              Sets the asymptotic weight level of the system to E
                         (Page 9-6)



                                D-1


D. MODE SWITCHES IN REDUCE
   ____ ________ __ ______

This section lists the switches that may appear as arguments of ON and OFF.
The action of the switch when it is ON is described here, unless stated
otherwise. Unless otherwise indicated the default value of the switch is
OFF.

ALLBRANCH               Used by the SOLVE module to select all or only
                        principal branches of solutions. Default ON
                         (Page 6-6)

ALLFAC                  Causes the system to factor out common products on
                        output of expressions. Default ON (Page 7-5)

BIGFLOAT                Provides for the use of arbitrary precision real
                        coefficients in polynomials (Page 8-9)

COMP                    If ON, causes succeeding function definitions to be
                        compiled (Page 16-1)

CREF                    If ON, causes a cross-reference analysis of subse-
                        quent inputs to occur. The actual table is printed
                        following a later OFF CREF (Page 16-3)

DEFN                    Causes the system to output the LISP equivalent of
                        REDUCE input without evaluation (Page 14-4)

DEMO                    Causes the system to pause after each command in a
                        file until a Return is typed on the terminal (Page 5-2)

DIV                     Causes the system to divide out simple factors on
                        output, so that negative powers or rational fractions
                        can be produced (Page 7-5)

ECHO                    Causes echoing of input (Page 10-1)

EXP                     Causes expressions to be expanded during their
                        evaluation. Default ON (Page 8-1)

FACTOR                  If on, causes the system to factor expressions into
                        factors with integer coefficients (Page 8-2)

FAILHARD                If on, causes integration algorithm to terminate
                        with an error if integral not possible in closed
                        terms (Page 6-4)

FLOAT                   Allows for the use of floating point numbers during
                        evaluation (Page 3-2)

FORT                    Declares output in a FORTRAN notation (Page 7-9)



                                D-2

GCD                     Causes the system to cancel greatest common divisors
                        in rational expressions (Page 8-4)

INT                     Specifies an interactive mode of operation. Default
                        is system dependent (Page 11-2)

LCM                     When on, uses least common multiple of denominators
                        when combining rational expressions (Page 8-5)

LIST                    Causes output to be listed one term to each line
                         (Page 7-5)

MCD                     Causes denominators to be combined when expressions
                        are added. Default ON (Page 8-5)

MODULAR                 Provides for the use of modular integer coefficients.
                        Base used is set by SETMOD (Page 8-9)

MSG                     When off, suppresses the printing of warning
                        messages. Error messages are still printed.
                        Default ON (Page 16-4)

NAT                     Specifies 'natural' style of output. Default ON
                         (Page 7-11)

NERO                    Inhibits printing of zero assignments (Page 7-8)

NOLNR                   Suppresses the use of the linear properties in the
                        integration algorithm (Page 6-4)

OUTPUT                  If OFF, suppresses printing the value of any top
                        level expression. Default ON (Page 7-3)

PERIOD                  Causes a period to be printed after each integer
                        coefficient in FORTRAN output. Default ON
                         (Page 7-10)

PGWD                    Causes the printing of the assembly language
                        instructions generated from the macros (Page 16-1)

PLAP                    Causes the printing of the portable macros produced
                        by the compiler (Page 16-1)

PRET                    Causes input commands to be printed in REDUCE syntax
                        in a standard format (Page 16-4)

PRI                     Specifies formatted printing for output. Default
                        ON (Page 7-3)

PWRDS                   Causes a statistics message to be printed after a
                        function is compiled. Default ON (Page 16-1)



                                D-3

RAISE                   Causes input lower case characters to be converted
                        into upper case. Characters in strings and those
                        preceded by ! are excluded. Default ON (Page 2-1)

RAT                     Output switch used in conjunction with FACTOR. Causes
                        the overall denominator in an expression to be
                        printed with each factored sub-expression (Page 7-6)

RATIONAL                Provides for the use of rational number coefficients
                        in polynomials (Page 8-8)

RESUBS                  When RESUBS is off, the system does not re-examine
                        an expression for further substitutions after one
                        has been made. Default ON (Page 9-5)

SOLVEINTERVAL           Used by the SOLVE module to represent inexact roots
                        by intervals (Page 6-5)

SOLVESINGULAR           Used by the SOLVE module to solve degenerate systems
                        by introducing arbitrary constants. Default ON
                         (Page 6-5)

SOLVEWRITE              Used by the SOLVE module to control printing of
                        solutions. Default ON (Page 6-6)

TIME                    Causes the system to print a message after each
                        command giving the elapsed cpu time since the last
                        command, or since TIME was last turned OFF or the
                        session began (Page 5-2)

TRFAC                   Traces the operation of the factorization algorithm
                         (Page 8-3)

TRINT                   Traces the operation of the integration algorithm
                         (Page 6-4)



                                E-1


E. DIAGNOSTIC AND ERROR MESSAGES IN REDUCE
   __________ ___ _____ ________ __ ______

Diagnostic messages in the REDUCE system are of two types; error messages
and warning messages. The former usually cause the termination of the
current calculation whereas the latter warn the user of an ambiguity
encountered or some action taken which may indicate an error. If the
system is in an interactive state, it can ask the user when it encounters
an ambiguity for the correct interpretation. Otherwise it will make the
most plausible guess, print a message informing the user of the choice
made, and continue.

If an error is found during the parsing of the input, the current phrase
is reprinted with the place marked where the error was encountered. In
interactive systems, the expression can then be edited with the command
ED.

A list of the current diagnostic messages is given below. Those that
indicate a warning (as opposed to an error) are so marked.

 Notation:       E, E1,...,En    denote expressions
                 ID, ID1...,IDn  denote identifiers

A represents only gamma5 in vector expressions
                        An attempt to use A as other than gamma5 in a high
                        energy physics expression has been found (Page 15-2)

CATASTROPHIC ERROR      This error should not occur normally. If it does,
                        please send a copy of the relevant input and output
                        to the author (Page 3-2)

Cannot shut current input file ID
                        An attempt has been made to shut the current input
                        file (Page 10-2)

Continuing with parsing only
                        An error has been found in a session being run in
                        batch mode, so no further computation is done
                         (Page 11-1)

Domain mode ID1 changed to ID2
                        An automatic change of domain mode has occurred. This
                        is usually the result of a user's change in a switch
                        value. WARNING (Page 8-8)

Domain mode error: <reason>
                        A check of the tables that control polynomial coeff-
                        icient arithmetic has revealed an error. This should
                        only occur if a user has introduced a new coefficient
                        mode (Page 8-8)

EOF read [in file ID]   There was a missing END in a file, or an end-of-file
                        character had been typed on a terminal (Page 10-1)



                                E-2

E invalid [in ID statement]
                        The expression E is not permitted at this point in
                        the (optionally) named statement (Page 4-1)

E invalid as ID         The expression E has been used in a context where
                        ID was required (Page 8-1)

Gamma5 not allowed unless vecdim is 4
                        Gamma5 has been used in a computation involving a
                        vector dimension other than 4 (Page 15-6)

ID invalid outside block
                        An INTEGER, REAL or SCALAR declaration has been
                        used outside a block. Such declarations should be
                        deleted (Page 4-6)

ID is a reserved identifier
                        The reserved variable ID has not been used
                        correctly (Page 2-3)

ID not found            ID was expected but could not be found (Page 6-7)

ID not open             An attempt has been made to shut a file that has
                        not been opened for output (Page 10-2)

ID redefined            ID has been defined of a particular type more than
                        once. WARNING (Page 6-7)

ID too long for FORTRAN An identifier exceeds the size allowed for FORTRAN
                        identifiers (Page 7-9)

ID1 ID2 not set         An object of type ID1 and name ID2 whose size is not
                        yet known has been referenced (Page 12-1)

ID1 declared ID2        ID1 has been declared of type ID2. Posed as a
                        question in interactive mode. WARNING (Page 6-7)

Improper delimiter      An unexpected delimiter has been found at or near
                        the marked position (Page 2-5)

Index out of range      A reference has been made to an array element or
                        other structure outside the defined index range
                         (Page 5-1)

Invalid S-expression    An ill-formed S-expression has been found on input
                        at or near the marked point (Page 14-3)

Invalid modular division
                        A modular division in which the argument is not
                        co-prime with the modulus has occurred (Page 8-9)

MACRO ID used as function
                        A MACRO has been used as a functional argument



                                E-3

                         (Page 14-4)

Matrix mismatch         Two matrix expressions are not correctly matched for
                        addition or multiplication (Page 12-2)

Missing ID              A symbol of type ID (e.g., matrix or vector) was
                        expected and not found (Page 15-3)

Missing arguments for G operator
                        A line symbol is missing in a gamma matrix
                        expression (Page 15-2)

Missing operator        An operator was expected at or near the marked
                        position (Page 2-5)

Non square matrix       An invalid operation on a non square matrix has been
                        requested (e.g., a trace) (Page 12-2)

No file open            CONT has been improperly called with no files open
                         (Page 11-3)

Redundant operator      An unexpected operator was found at or near the
                        marked position (Page 2-5)

Redundant vector        A redundant vector has been found in a vector
                        expression (Page 15-3)

Singular matrix         A request has been made to invert a singular
                        matrix (Page 12-2)

Substitution for <expression> not allowed
                        Indicates that <expression> is an invalid form in a
                        LET or CLEAR statement (Page 9-3)

Syntax error: <reason>  A syntax error has been encountered in the input
                        for the reason given (Page 2-5)

Too few right parentheses
                        Input syntax error (Page 2-5)

Too many right parentheses
                        Input syntax error (Page 2-5)

Unmatched free variables <list>
                        The variables in <list> have not been properly
                        matched in a LET statement (Page 9-3)

Unmatched index <list>  Unmatched indices have been encountered during the
                        evaluation of a gamma matrix expression (Page 15-4)

V has no mass           A variable encountered in an MSHELL declaration has
                        no mass assigned to it (Page 15-5)



                                E-4

Wrong number of arguments to ID
                        ID has been called with the wrong number of
                        arguments (Page 3-2)

Zero denominator        REDUCE cannot handle a zero denominator (Page 3-2)

0**0 formed             REDUCE cannot handle 0**0 (Page 3-2)

0/0 formed              REDUCE cannot handle 0/0 (Page 3-2)

<number1> represented by <number2>
                        Real <number1> has been converted to rational
                        <number2>. WARNING (Page 3-2)



                                F-1


F. VARIABLES IN REDUCE
   _________ __ ______

The following variables are defined in the basic REDUCE system. Variables
prefixed or suffixed with an asterisk are changeable, either by the user or
the system as appropriate. In particular, the mode switches (qv) are based
on a corresponding variable prefixed by an asterisk that is either true or
false depending on whether the switch is on or off. E.g., the switch COMP
corresponds to the internal variable !*COMP. Such switch variables are not
listed in this section.

A                       Reserved only in arguments of the G operator in the
                        high energy physics package to denote gamma5. May be
                        used freely elsewhere (Page 15-2)

CARDNO!*                Value is the total number of lines produced
                        in a given FORTRAN output expression (Page 7-10)

FORTWIDTH!*             Value is the current line width for FORTRAN output
                         (Page 7-10)

HIPOW!*                 Set by COEFF to highest power encountered (Page 7-13)

LOWPOW!*                Set by COEFF to lowest power encountered (Page 7-13)

!*MODE                  Value is the current top level mode of the system.
                        May be accessed in either algebraic or symbolic
                        mode (Page 14-1)



                                G-1


G. KEYWORD INDEX
   _______ _____


Abs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-1

Algebraic_Mode. . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1

Allfac. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-5

Arbitrary_Precision_Real. . . . . . . . . . . . . . . . . . . . . . .8-9

Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-1

Assignment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-3

Asymptotic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-6

Bigfloat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8

Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-6

Body. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-2

Boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-2

Bye . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-3

Call_By_Value . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4

Call_by_value . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-2

Canonical_Form. . . . . . . . . . . . . . . . . . . . . . . . . . . .7-1

Cardno!*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8

Character_Set . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1

Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-3
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-4

Coeff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12

Coefficient . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-8

Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-1
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .C-1

Comment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4

Comp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1



                                G-2

Compiler. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

Compound_Statement. . . . . . . . . . . . . . . . . . . . . . . . . .4-2
                  . . . . . . . . . . . . . . . . . . . . . . . . . .4-6

Conditional_Statement . . . . . . . . . . . . . . . . . . . . . . . .4-2

Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-5

Cont. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2

Cref. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-2

Cross_Reference . . . . . . . . . . . . . . . . . . . . . . . . . . 16-2

Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-1

Define. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-3

Defn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-4

Deg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-6

Degree. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-6

Den . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-6

Denominator . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-6

Depend. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10

Det . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-1
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2

Df. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-2
  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-3

Differentiation . . . . . . . . . . . . . . . . . . . . . . . . . . .6-2

Dirac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-4

Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-1

Div . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-5

Do. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-3
  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-4

Dollar_Sign . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1

Dot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-1



                                G-3

Ed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

Editdef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

End . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2

Eps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-2

Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .E-1

Exclamation_Point . . . . . . . . . . . . . . . . . . . . . . . . . .2-2

Exp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-1

Expression. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-1
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-3

FORTRAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8

Factor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-3
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4

Factorization . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-2

Factorize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-2

Fap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

Fasl. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

Faslout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

Fast_Loading. . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

File_Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1

Fixp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-2

Float . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-2
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-9

For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-3

For_Each. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-3

For_all . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-1
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-2
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-3

Fort. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8

Freeof. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-2



                                G-4

Function. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-1

G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-2

Gamma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-2

Gamma_matrix. . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-1

Gcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-4

Go. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-7
  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-8

Goto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-8

Group_Statement . . . . . . . . . . . . . . . . . . . . . . . . . . .4-2

HIPOW!* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13

High_Energy_Physics . . . . . . . . . . . . . . . . . . . . . . . . 15-1

History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

Identifier. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-2

If. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-2

In. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1

Infix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-6
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7

Infix_Operator. . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4

Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

Int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-3

Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-2
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-6

Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-3

Interactive . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-1

I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1

Kernel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-1



                                G-5

Keyword_Index . . . . . . . . . . . . . . . . . . . . . . . . . . . .G-1

Korder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12

LISP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-4

LOWPOW!*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13

Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-7
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-8

Lambda. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-3

Lcm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-5

Lcof. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-7

Leading_Coefficient . . . . . . . . . . . . . . . . . . . . . . . . .8-7

Leading_Term. . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-7

Let . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-3
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-1
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-2
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-3
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-4
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4

Line_length . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-3

Linear. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-8

Linear_Operator . . . . . . . . . . . . . . . . . . . . . . . . . . .6-8

List. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-5

Load. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

Loop. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-3

Lterm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-7

Main_Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-7

Mainvar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-7

Mass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-4

Mat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1



                                G-6

Match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-4

Mathematical_Function . . . . . . . . . . . . . . . . . . . . . . . .6-1

Matrix. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1

Max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-1

Mcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-5

Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .E-1

Min . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-1

Mode. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1

Mode_Communication. . . . . . . . . . . . . . . . . . . . . . . . . 14-5

Modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-9

Mshell. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-4

Multiple_assignment_statement . . . . . . . . . . . . . . . . . . . .4-2

Nero. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8

Nodepend. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10

Noncom. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-9

Noncommuting_Operator . . . . . . . . . . . . . . . . . . . . . . . .6-9

Nospur. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-4

Num . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-8

Number. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1

Numberp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-2

Numerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-8

Numerical_Function. . . . . . . . . . . . . . . . . . . . . . . . . .6-1

Numval. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-2

Off . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2

On. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2

Operator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7



                                G-7

        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .B-1

Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-3
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4

Ordp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-3
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-9

Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1

Output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-3
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-6
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2

Output_Declaration. . . . . . . . . . . . . . . . . . . . . . . . . .7-3

Part. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-13
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-14

Pause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2

Polynomial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-1

Precedence. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7

Precedence_List . . . . . . . . . . . . . . . . . . . . . . . . . . .2-7

Prefix. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-1
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7

Prefix_Operator . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4

Pret. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-4

Prettyprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-4

Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-1
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-9

Procedure_Heading . . . . . . . . . . . . . . . . . . . . . . . . . 13-1

Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-3

Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1

Proper_Statement. . . . . . . . . . . . . . . . . . . . . . . . . . .4-1

Quit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-3

Quote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2



                                G-8

REDUCE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1

RLISP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1

Rat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-6

Rational_Coefficient. . . . . . . . . . . . . . . . . . . . . . . . .8-8

Rational_Function . . . . . . . . . . . . . . . . . . . . . . . . . .8-1

Real. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-6

Real_Coefficient. . . . . . . . . . . . . . . . . . . . . . . . . . .8-9

Reduct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-8

Reductum. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-8

Remainder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-5

Remfac. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-4

Rename. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-3

Repeat. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-5

Reserved. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .A-1

Reserved_Variable . . . . . . . . . . . . . . . . . . . . . . . . . .2-3

Resultant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-6

Return. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-7
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-8

Save. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10

Scalar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-1
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-6

Selector. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-5

Semicolon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1

Series. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-6

Share . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-5

Showtime. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-3



                                G-9

Shut. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2

Side_effect . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-3

Simplification. . . . . . . . . . . . . . . . . . . . . . . . . . . .3-1
              . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-1

Solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-5

Spur. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-4

Standard_form . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-6

Standard_quotient . . . . . . . . . . . . . . . . . . . . . . . . . 14-5

Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-3
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1

String. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4

Structr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-11

Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-1
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-11

Structuring . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-1

Sub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7

Subroutine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-1

Substitution. . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-4

Such_that . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-1
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-3

Sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-3

Switch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .D-1

Symbolic_Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1

Terminator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1

Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-1

Time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-2

Tp. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-3

Trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-3
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-4



                                G-10

Truncation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-6

Until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-5

Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-1

Variable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-3
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .F-1

Varname . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10
        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-11

Vector. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-3

WS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-2

Weight. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-6

While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-4

Workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-2

Write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-6
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7-8

Ws. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1

Wtlevel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-6

% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4
