R E D U C E U S E R ' S M A N U A L Version 3.3 Anthony C. Hearn The Rand Corporation Santa Monica, CA 90406-2138 July 1987 Rand Publication CP78 (Rev. 7/87) Copyright (c) 1987 The Rand Corporation. All rights reserved. Registered system holders may reproduce all or any part of this publication for internal purposes, provided that the source of the material is clearly acknowledged, and the copyright notice is retained. 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, Jed Marti, Don Morrison, Arthur Norman and Larry Seward. TABLE OF CONTENTS 1. Introductory information about 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-3 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-5 3. Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . .3-1 3.1 Scalar expressions. . . . . . . . . . . . . . . . . . . .3-1 3.2 Integer expressions . . . . . . . . . . . . . . . . . . .3-2 3.3 Boolean expressions . . . . . . . . . . . . . . . . . . .3-2 3.4 Equations . . . . . . . . . . . . . . . . . . . . . . . .3-3 3.5 Proper statements as expressions. . . . . . . . . . . . .3-4 4. Lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4-1 4.1 Operations on lists . . . . . . . . . . . . . . . . . . .4-1 4.1.1 First . . . . . . . . . . . . . . . . . . . . . . . . .4-1 4.1.2 Second. . . . . . . . . . . . . . . . . . . . . . . . .4-1 4.1.3 Third . . . . . . . . . . . . . . . . . . . . . . . . .4-1 4.1.4 Rest. . . . . . . . . . . . . . . . . . . . . . . . . .4-1 4.1.5 . (Cons) operator . . . . . . . . . . . . . . . . . . .4-2 4.1.6 Append. . . . . . . . . . . . . . . . . . . . . . . . .4-2 4.1.7 Reverse . . . . . . . . . . . . . . . . . . . . . . . .4-2 5. Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-1 5.1 Assignment statements . . . . . . . . . . . . . . . . . .5-1 5.1.1 SET statement . . . . . . . . . . . . . . . . . . . . .5-2 5.2 Group statements. . . . . . . . . . . . . . . . . . . . .5-2 5.3 Conditional statements. . . . . . . . . . . . . . . . . .5-3 5.4 FOR statements. . . . . . . . . . . . . . . . . . . . . .5-4 5.5 WHILE...DO. . . . . . . . . . . . . . . . . . . . . . . .5-5 5.6 REPEAT...UNTIL. . . . . . . . . . . . . . . . . . . . . .5-6 5.7 Compound statements . . . . . . . . . . . . . . . . . . .5-7 5.7.1 Compound statements with GO TO. . . . . . . . . . . . .5-8 5.7.2 Labels and GO TO statements . . . . . . . . . . . . . .5-9 5.7.3 RETURN statements . . . . . . . . . . . . . . . . . . .5-9 6. Commands and declarations. . . . . . . . . . . . . . . . . . . . .6-1 6.1 Array declarations. . . . . . . . . . . . . . . . . . . .6-1 6.2 Mode handling declarations. . . . . . . . . . . . . . . .6-2 6.3 END identifier. . . . . . . . . . . . . . . . . . . . . .6-2 6.4 BYE command . . . . . . . . . . . . . . . . . . . . . . .6-3 6.5 QUIT command. . . . . . . . . . . . . . . . . . . . . . .6-3 6.6 SHOWTIME command. . . . . . . . . . . . . . . . . . . . .6-3 6.7 DEFINE command. . . . . . . . . . . . . . . . . . . . . .6-3 ii 7. Built-in prefix operators. . . . . . . . . . . . . . . . . . . . .7-1 7.1 Numerical functions . . . . . . . . . . . . . . . . . . .7-1 7.2 Mathematical functions. . . . . . . . . . . . . . . . . .7-1 7.3 DF operator . . . . . . . . . . . . . . . . . . . . . . .7-3 7.3.1 Adding differentiation rules. . . . . . . . . . . . . .7-3 7.4 INT operator. . . . . . . . . . . . . . . . . . . . . . .7-4 7.4.1 Options . . . . . . . . . . . . . . . . . . . . . . . .7-5 7.4.2 Advanced use. . . . . . . . . . . . . . . . . . . . . .7-5 7.4.3 References. . . . . . . . . . . . . . . . . . . . . . .7-5 7.5 Length operator . . . . . . . . . . . . . . . . . . . . .7-6 7.6 MKID operator . . . . . . . . . . . . . . . . . . . . . .7-6 7.7 SOLVE operator. . . . . . . . . . . . . . . . . . . . . .7-6 7.7.1 Options . . . . . . . . . . . . . . . . . . . . . . . .7-7 7.8 Linear operators. . . . . . . . . . . . . . . . . . . . .7-8 7.9 Non-commuting operators . . . . . . . . . . . . . . . . .7-9 7.10 Symmetric and antisymmetric operators. . . . . . . . . .7-9 7.11 Declaring new prefix operators . . . . . . . . . . . . 7-10 7.12 Declaring new infix operators. . . . . . . . . . . . . 7-11 7.13 Creating and removing variable dependency. . . . . . . 7-11 8. Display and structuring of expressions . . . . . . . . . . . . . .8-1 8.1 Kernels . . . . . . . . . . . . . . . . . . . . . . . . .8-1 8.2 The expression workspace. . . . . . . . . . . . . . . . .8-2 8.3 Output of expressions . . . . . . . . . . . . . . . . . .8-3 8.3.1 LINELENGTH operator . . . . . . . . . . . . . . . . . .8-3 8.3.2 Output declarations . . . . . . . . . . . . . . . . . .8-3 8.3.2.1 ORDER declaration . . . . . . . . . . . . . . . . . .8-4 8.3.2.2 FACTOR declaration. . . . . . . . . . . . . . . . . .8-4 8.3.3 Output control switches . . . . . . . . . . . . . . . .8-5 8.3.3.1 ALLFAC switch . . . . . . . . . . . . . . . . . . . .8-5 8.3.3.2 DIV switch. . . . . . . . . . . . . . . . . . . . . .8-5 8.3.3.3 LIST switch . . . . . . . . . . . . . . . . . . . . .8-5 8.3.3.4 RAT switch. . . . . . . . . . . . . . . . . . . . . .8-6 8.3.3.5 RATPRI switch . . . . . . . . . . . . . . . . . . . .8-6 8.3.3.6 REVPRI switch . . . . . . . . . . . . . . . . . . . .8-7 8.3.4 WRITE command . . . . . . . . . . . . . . . . . . . . .8-7 8.3.5 Suppression of zeros. . . . . . . . . . . . . . . . . .8-9 8.3.6 FORTRAN style output of expressions . . . . . . . . . .8-9 8.3.6.1 FORTRAN output options. . . . . . . . . . . . . . . 8-11 8.3.7 Saving expressions for later use as input . . . . . . 8-11 8.3.8 Displaying expression structure . . . . . . . . . . . 8-12 8.4 Changing the internal order of variables. . . . . . . . 8-13 8.5 Obtaining parts of algebraic expressions. . . . . . . . 8-13 8.5.1 COEFF operator. . . . . . . . . . . . . . . . . . . . 8-13 8.5.2 COEFFN operator . . . . . . . . . . . . . . . . . . . 8-14 8.5.3 PART operator . . . . . . . . . . . . . . . . . . . . 8-14 8.5.4 Changing parts of expressions . . . . . . . . . . . . 8-15 9. Operations on polynomials and rationals. . . . . . . . . . . . . .9-1 9.1 Controlling the expansion of expressions. . . . . . . . .9-1 9.2 Factorization of polynomials. . . . . . . . . . . . . . .9-2 9.3 Cancellation of common factors. . . . . . . . . . . . . .9-4 9.3.1 Determining the GCD of two polynomials. . . . . . . . .9-5 iii 9.4 Working with least common multiples . . . . . . . . . . .9-5 9.5 Controlling use of common denominators. . . . . . . . . .9-5 9.6 REMAINDER operator. . . . . . . . . . . . . . . . . . . .9-6 9.7 RESULTANT operator. . . . . . . . . . . . . . . . . . . .9-6 9.8 Obtaining parts of polynomials and rational functions . .9-6 9.8.1 DEG operator. . . . . . . . . . . . . . . . . . . . . .9-7 9.8.2 DEN operator. . . . . . . . . . . . . . . . . . . . . .9-7 9.8.3 LCOF operator . . . . . . . . . . . . . . . . . . . . .9-7 9.8.4 LTERM operator. . . . . . . . . . . . . . . . . . . . .9-8 9.8.5 MAINVAR operator. . . . . . . . . . . . . . . . . . . .9-8 9.8.6 NUM operator. . . . . . . . . . . . . . . . . . . . . .9-8 9.8.7 REDUCT operator . . . . . . . . . . . . . . . . . . . .9-8 9.9 Polynomial coefficient arithmetic . . . . . . . . . . . .9-9 9.9.1 Rational coefficients in polynomials. . . . . . . . . .9-9 9.9.2 Real coefficients in polynomials. . . . . . . . . . . .9-9 9.9.3 Arbitrary precision real coefficients . . . . . . . . 9-10 9.9.4 Modular number coefficients in polynomials. . . . . . 9-10 9.9.5 Complex number coefficients in polynomials. . . . . . 9-10 10. Substitution commands . . . . . . . . . . . . . . . . . . . . . 10-1 10.1 SUB operator . . . . . . . . . . . . . . . . . . . . . 10-1 10.2 WHERE operator . . . . . . . . . . . . . . . . . . . . 10-1 10.3 LET rules. . . . . . . . . . . . . . . . . . . . . . . 10-2 10.3.1 FOR ALL...LET. . . . . . . . . . . . . . . . . . . . 10-4 10.3.2 FOR ALL...SUCH THAT...LET. . . . . . . . . . . . . . 10-5 10.3.3 Removing assignments and substitution rules. . . . . 10-5 10.3.4 Overlapping LET Rules. . . . . . . . . . . . . . . . 10-6 10.3.5 Substitutions for general expressions. . . . . . . . 10-6 10.4 Asymptotic commands. . . . . . . . . . . . . . . . . . 10-9 11. File handling commands. . . . . . . . . . . . . . . . . . . . . 11-1 11.1 IN command . . . . . . . . . . . . . . . . . . . . . . 11-1 11.2 OUT command. . . . . . . . . . . . . . . . . . . . . . 11-1 11.3 SHUT command . . . . . . . . . . . . . . . . . . . . . 11-2 12. Commands for interactive use of REDUCE. . . . . . . . . . . . . 12-1 12.1 Referencing previous results . . . . . . . . . . . . . 12-1 12.2 Interactive editing. . . . . . . . . . . . . . . . . . 12-2 12.3 Interactive file control . . . . . . . . . . . . . . . 12-3 13. Matrix calculations . . . . . . . . . . . . . . . . . . . . . . 13-1 13.1 MAT operator . . . . . . . . . . . . . . . . . . . . . 13-1 13.2 Matrix variables . . . . . . . . . . . . . . . . . . . 13-1 13.3 Matrix expressions . . . . . . . . . . . . . . . . . . 13-2 13.4 Operators with matrix arguments. . . . . . . . . . . . 13-2 13.4.1 DET operator . . . . . . . . . . . . . . . . . . . . 13-3 13.4.2 TP operator. . . . . . . . . . . . . . . . . . . . . 13-3 13.4.3 TRACE operator . . . . . . . . . . . . . . . . . . . 13-3 13.5 Matrix assignments . . . . . . . . . . . . . . . . . . 13-3 13.6 Evaluating matrix elements . . . . . . . . . . . . . . 13-4 iv 14. Procedures. . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1 14.1 Procedure heading. . . . . . . . . . . . . . . . . . . 14-1 14.2 Procedure body . . . . . . . . . . . . . . . . . . . . 14-2 14.3 Using LET inside procedures. . . . . . . . . . . . . . 14-4 14.4 Let Rules as procedures. . . . . . . . . . . . . . . . 14-4 15. User contributed packages . . . . . . . . . . . . . . . . . . . 15-1 15.1 ALGINT: indefinite integration of square roots . . . . 15-1 15.2 ANUM: an algebraic number package. . . . . . . . . . . 15-1 15.3 EXCALC: a differential geometry package. . . . . . . . 15-1 15.4 GENTRAN: a code generation package . . . . . . . . . . 15-2 15.5 GROEBNER: Groebner Basis computation . . . . . . . . . 15-2 15.6 SPDE: a package for finding symmetry groups of PDE's . 15-2 16. Symbolic mode . . . . . . . . . . . . . . . . . . . . . . . . . 16-1 16.1 Symbolic infix operators . . . . . . . . . . . . . . . 16-2 16.2 Symbolic expressions . . . . . . . . . . . . . . . . . 16-2 16.3 Quoted expressions . . . . . . . . . . . . . . . . . . 16-3 16.4 LAMBDA expressions . . . . . . . . . . . . . . . . . . 16-3 16.5 Symbolic assignment statements . . . . . . . . . . . . 16-4 16.6 FOR EACH statement . . . . . . . . . . . . . . . . . . 16-4 16.7 Symbolic procedures. . . . . . . . . . . . . . . . . . 16-4 16.8 Standard LISP equivalent of REDUCE input . . . . . . . 16-5 16.9 Communicating with algebraic mode. . . . . . . . . . . 16-5 16.9.1 Passing algebraic mode values to symbolic mode . . . 16-6 16.9.2 Passing Symbolic mode values back to algebraic mode. 16-8 16.9.3 Complete example . . . . . . . . . . . . . . . . . . 16-9 16.9.4 Defining procedures which communicate between modes. 16-9 16.10 References. . . . . . . . . . . . . . . . . . . . . .16-10 17. Calculations in high energy physics . . . . . . . . . . . . . . 17-1 17.1 Notation . . . . . . . . . . . . . . . . . . . . . . . 17-1 17.2 Operators used in high energy physics calculations . . 17-1 17.2.1 . (Cons) operator. . . . . . . . . . . . . . . . . . 17-1 17.2.2 G operator for gamma matrices. . . . . . . . . . . . 17-2 17.2.3 EPS operator . . . . . . . . . . . . . . . . . . . . 17-3 17.3 Vector variables . . . . . . . . . . . . . . . . . . . 17-3 17.4 Additional expression types. . . . . . . . . . . . . . 17-3 17.4.1 Vector expressions . . . . . . . . . . . . . . . . . 17-3 17.4.2 Dirac expressions. . . . . . . . . . . . . . . . . . 17-4 17.5 Trace calculations . . . . . . . . . . . . . . . . . . 17-4 17.6 Mass declarations. . . . . . . . . . . . . . . . . . . 17-5 17.7 Example. . . . . . . . . . . . . . . . . . . . . . . . 17-5 17.8 Extensions to more than four dimensions. . . . . . . . 17-6 18. REDUCE and RLISP utilities. . . . . . . . . . . . . . . . . . . 18-1 18.1 The Standard LISP compiler . . . . . . . . . . . . . . 18-1 18.2 Fast loading code generation program . . . . . . . . . 18-1 18.3 The Standard LISP cross reference program. . . . . . . 18-2 18.3.1 Restrictions:. . . . . . . . . . . . . . . . . . . . 18-3 18.3.2 Usage: . . . . . . . . . . . . . . . . . . . . . . . 18-3 18.3.3 Options: . . . . . . . . . . . . . . . . . . . . . . 18-3 18.4 Prettyprinting REDUCE expressions. . . . . . . . . . . 18-4 v 18.5 Prettyprinting Standard LISP S-expressions . . . . . . 18-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. INTRODUCTORY INFORMATION ABOUT 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 extract 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, so REDUCE can also be used in batch mode by inputting a sequence of calculations and getting results without the necessity 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.3, 15-Jul-87 ... where the version number and the system release date will change from time to time. It then prompts the user for input by: 1: You can now type a 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: 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 follows 1-2 the rules of high school algebra, so the only surprise in the above example might be that the expression was expanded. REDUCE normally expands expressions where possible, collecting like terms and ordering the variables in a specific manner. However, expansion, ordering of variables, format of output and so on is under control of the user, and various declarations are available to manipulate 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 features, the user should try: for i:= 1:50 product i; The result in this case is the value of 50!, 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 also 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. Alternatively, 1-3 int(ws,y); would calculate the integral of the same expression with respect to y. REDUCE is also capable of handling 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 its elements 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 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 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) These algebraic manipulations illustrate the algebraic mode of REDUCE. REDUCE is based on Standard LISP. A symbolic mode is also available for 1-4 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, you are 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 desired, 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 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 (q.v.), 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 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 a 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 exact 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. It should be borne in mind of course that computations with such long numbers can be quite slow. Numbers that aren't integers are usually represented as the quotient of two integers, in lowest terms: that is, as rational numbers. 2-2 In most versions of REDUCE it is also possible (but not always desirable!) 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 (q.v.), 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 A sequence of alphanumeric characters in which the first is a digit is interpreted as a product. For example, 2AB3C is interpreted as 2*AB3C. There is one exception to this: If the first letter after a digit is E, the system will try to interpret that part of the sequence as a real number, which may fail in some cases. For example, 2E12 is the real number 2.0*10**12, 2E3C is 2000.0*C, and 2EBC gives an error. 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 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 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. If NUMVAL (q.v.) is on in an appropriate real arithmetic mode, 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. With NUMVAL on in an appropriate real arithmetic 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. 2-4 There are also internal variables used by REDUCE that have similar restrictions. These usually have an asterisk in their names, so it is unlikely a casual user would use one. An example of such a variable is K!* used in the asymptotic command package. Certain words are reserved in REDUCE. They may only be used in the manner intended. A list of these is given in the section "Reserved Identifiers". There are, of course, an impossibly large number of such names to keep in mind. The reader may therefore want to make himself a copy of the list, deleting the names he doesn't think he is likely to use by mistake. 2.5 Strings _______ Strings are used only in WRITE statements (q.v.). 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 (q.v.), normally ; or $, 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 can be fully defined (usually by a procedure declaration). 2-5 Infix operators occur between their arguments. e.g. A + B - C (spaces optional) XZ (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.7.1 Built-In Infix Operators ________ _____ _________ The following infix operators are built into the system. They are all defined internally as procedures. 2-6 ::= WHERE|:=|OR|AND|NOT|MEMBER|MEMQ|=|NEQ|EQ|>=| >|<=|<|+|-|*|/|**|. These operators may be further divided into the following subclasses: ::= := ::= OR|AND|NOT|MEMBER|MEMQ ::= =|NEQ|EQ|>=|>|<=|< ::= WHERE ::= +|-|*|/|** ::= . MEMBER, MEMQ, and EQ are not used in the algebraic mode of REDUCE. They are explained in the section on symbolic mode (q.v.). WHERE is described in the section on substitutions. 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 as unary operators, 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). Unlike ALGOL and PASCAL, ** is left associative. The operators <, <=, >, >= can only be used for making comparisons between numbers. No meaning is currently assigned to this kind of comparison between general expressions. 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 2-7 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 sequences of numbers, variables, operators, left and right parentheses and commas. The most common types are as follows: 3.1 Scalar Expressions ______ ___________ Using the arithmetic operations + - * / ** (power) and parentheses, scalar expressions are composed from numbers, ordinary "scalar" variables (identifiers), array names with subscripts, operator or procedure names with 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) In most systems, the carat symbol (^) may be used as an alternative to ** for forming powers. The particular system instructions should be consulted to determine if this is not supported. Statement expressions (q.v.), 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. However, array elements have the algebraic values they were last assigned, or, if never assigned, are taken to be 0. Procedures are evaluated with the values of their actual parameters. 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 3-2 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 which have values assigned or declared (see 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 other sections. 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 action occurs during evaluation (such as division by zero) or functions are called with the wrong number of arguments, and so on, an appropriate error message is generated. A list of such error messages is given in an appendix. 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: or () or . In addition to the logical and relational operators defined earlier as infix operators, the following boolean functions are also defined: 3-3 EVENP(U) determines if the number U is even or not. FIXP(U) determines if the expression U is integer or not. FREEOF(U,V) determines if the expression U does not contain the kernel (q.v.) V anywhere in its structure. NUMBERP(U) determines if U is a number or not. 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 FIXP X AND EVENP 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 sequence of boolean expressions connected by OR stops as soon as a True expression is found. NB: It is not possible to define in algebraic mode a procedure (q.v.) which returns a boolean value; symbolic mode (q.v.) must be used instead. An algebraic mode procedure can however be written to return say 1 or 0 as its value, which can then be tested for in a boolean expression. Finally, if an algebraic (non-boolean) expression is used in a 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 Equations _________ Equations are a particular type of expression with the syntax = . In addition to their role as boolean expressions, they can also be used as 3-4 arguments to several operators (e.g., SOLVE (q.v.)), and can be returned as values. To facilitate the handling of equations, two selectors, LHS and RHS, which return the left- and right-hand sides of a equation respectively, are provided. For example, LHS(A+B=C) ==> A+B and RHS(A+B=C) ==> C. 3.5 Proper Statements As Expressions ______ __________ __ ___________ Several kinds of proper statements (q.v.) 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, an assignment statement 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 of these statements are also useful as expressions. 4-1 4. LISTS _____ A list is an object consisting of a sequence of other objects (including lists themselves), separated by commas and surrounded by braces. Examples of lists are: {A,B,C} {1,A-B,C=D} {{A},{{B,C},D},E}. 4.1 Operations On Lists __________ __ _____ Several operators in the system return their results as lists, and a user can create new lists using braces and commas. To facilitate the use of such lists, a number of operators are also available for manipulating them. PART(,n) for example will return the nth element of a list. LENGTH will return the length of a list. Several operators are also defined uniquely for lists. For those familiar with them, these operators in fact mirror the operations defined for LISP lists. These operators are as follows: 4.1.1 First _____ This operator returns the first member of a list. An error occurs if the argument is not a list, or the list is empty. 4.1.2 Second ______ SECOND returns the second member of a list. An error occurs if the argument is not a list or has no second element. 4.1.3 Third _____ This operator returns the third member of a list. An error occurs if the argument is not a list or has no third element. 4.1.4 Rest ____ REST returns its argument with the first element removed. An error occurs if the argument is not a list, or is empty. 4-2 4.1.5 . (Cons) Operator _ ______ ________ This operator adds ("conses") an expression to the front of a list. For example: A . {B,C} ==> {A,B,C}. 4.1.6 Append ______ This operator appends its first argument to its second to form a new list. Examples: APPEND({A,B},{C,D}) ==> {A,B,C,D} APPEND({{A,B}},{C,D}) ==> {{A,B},C,D}. 4.1.7 Reverse _______ The operator REVERSE returns its argument with the elements in the reverse order. It only applies to the top level list, not any lower level lists that may occur. Examples are: REVERSE({A,B,C}) ==> {C,B,A} REVERSE({{A,B,C},D}) ==> {D,{A,B,C}}. 5-1 5. STATEMENTS __________ A statement is any combination of reserved words and expressions, and has the syntax ::= | A REDUCE program consists of a series of commands which are statements followed by a terminator: ::= ;|$ The division of the program into lines is arbitrary. Several statements can be on one line, or one statement can be freely broken onto several lines. If the program is run interactively, statements ending with ; or $ are not processed until an end-of-line character is encountered. This character can vary from system to system, but is normally the RETURN key on an ASCII terminal. Specific systems may also use additional keys as statement terminators. If a statement is a proper statement, the appropriate action takes place. Depending on the nature of the proper statement some result or response may or may not be printed out, and the response may or may not depend on the terminator used. If a statement is an expression, it is evaluated. If the terminator is a semicolon, the result is printed. If the terminator is a dollar sign, the result is not 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 different forms. These output declarations are explained elsewhere. The following sub-sections describe the proper statements types in REDUCE. 5.1 Assignment Statements __________ __________ These statements have the syntax ::= := The 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. For example: 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) 5-2 More general assignments such as A+B := C are also allowed. The effect of these is explained in the section "Substitutions for General Expressions". 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 the 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: := := ... := := In this form, each but the last is set to the value of the last . If a semicolon is used as a terminator, each expression except the last is printed followed by a ":=" ending with the value of the last expression. 5.1.1 Set Statement ___ _________ In some cases, it is desirable to perform an assignment in which BOTH the left- and right-hand sides of an assignment are evaluated. In this case, the SET statement can be used with the syntax: SET(,); For example, the statements A := B+C; SET(A-C,X); will set the value of A-C, namely B, to X. 5.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 5-3 the group is relevant: such an extra terminator causes the group to have the value NIL or zero. 5.3 Conditional Statements ___________ __________ The conditional statement has the following syntax: ::= IF THEN [ELSE ] The boolean expression is evaluated. If the result is True, the first is executed. If it is False, the second is. In either case the statement after the entire conditional statement is executed next. Examples: IF X=5 THEN A:=B+C ELSE D:=E+F IF X=5 AND NUMBERP Y THEN <> ELSE <> Note the use of the group statement. Conditional statements associate to the right; i.e., IF THEN ELSE IF THEN ELSE is equivalent to: IF THEN ELSE (IF THEN ELSE ) In addition, the construction IF THEN IF THEN ELSE parses as IF THEN (IF THEN ELSE ). 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; 5-4 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 -- for example, a variable is written there -- the True alternative is always followed. 5.4 For Statements ___ __________ The FOR statement is used to define a variety of program loops. Its general syntax is as follows: {STEP UNTIL} { := { } } FOR { { : } } { } { EACH IN } where ::= DO|PRODUCT|SUM|COLLECT|JOIN. The assignment form of the FOR statement defines an iteration over the indicated numerical range. If expressions that do not evaluate to numbers are used in the designated places, an error will result. The FOR EACH form of the FOR statement is designed to iterate down a list. Again, an error will occur if a list is not used. The action DO means that is simply evaluated and no value kept; the statement returning 0 in this case (or no value at the top level). COLLECT means that the results of evaluating each time are linked together to make a list, and JOIN means that the values of are themselves lists that are joined to make one list (similar to CONC in LISP). Finally, PRODUCT and SUM form the respective combined value out of the values of . In all cases, is evaluated algebraically within the scope of the current value of . If is DO, then nothing else happens. In other cases, is a binary operator that causes a result to be built up and returned by FOR. In those cases, the loop is initialized to a default value (zero for SUM, 1 for PRODUCT, and an empty list for the other actions). The test for the end condition is made before any action is taken. If the variable is out of range in the assignment case, or the is empty in the FOR EACH case, is not evaluated at all, unlike FORTRAN which executes each DO loop at least once. Examples: 1) If A, B have been declared to be arrays, the following stores 5**2 through 10**2 in A(5) through A(10), and at the same time stores the cubes in the B array: 5-5 FOR I := 5 STEP 1 UNTIL 10 DO <> 2) As a convenience, the common construction STEP 1 UNTIL may be abbreviated to a colon. Thus, instead of the above we could write: FOR I := 5:10 DO <> 3) The following sets C to the sum of the squares of 1,3,5,7,9; and D to the expression X * (X+1) * (X+2) * (X+3) * (X+4): C := FOR J:=1 STEP 2 UNTIL 9 SUM J**2; D := FOR K:=0 STEP 1 UNTIL 4 PRODUCT (X+K); 4) The following forms a list of the squares of the elements of the list {A,B,C}: FOR EACH X IN {A,B,C} COLLECT X**2; 5) The following forms a list of the listed squares of the elements of the list {A,B,C} (i.e., {{A**2},{B**2}<{C**2}}): FOR EACH X IN {A,B,C} COLLECT {X**2}; 6) The following also forms a list of the squares of the elements of the list {A,B,C}, since the JOIN operation joins the individual lists into one list: FOR EACH X IN {A,B,C} JOIN {X**2}; 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 system's assumption that I**2 = -1. Furthermore, in algebraic mode, the value of the control variable is substituted in only if it occurs explicitly in that expression. It will not replace a variable of the same name in the value of that expression. For example: B := A; FOR A := 1:2 DO WRITE B; prints A twice, not 1 followed by 2. 5.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: 5-6 WHILE DO 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 grouped using the << ... >> or BEGIN ... END 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 obtained 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; 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. 5.6 Repeat...Until ______________ REPEAT ... UNTIL is very similar in purpose to WHILE ... DO. Its syntax is: REPEAT UNTIL (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: 5-7 EX:=0; TERM:=1; REPEAT <> UNTIL NUM(TERM - 1/1000) < 0; EX; 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. 5.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 (q.v.). 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 (q.v.). 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 algebraic mode SCALARs. 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 refer to the variables of the same name in the current calling environment. In particular, if they are not so declared at a higher level (e.g., in a surrounding block or as parameters in a calling procedure, their values can 5-8 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 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; 5.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; 5-9 GO TO L END; 5.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