File r38/lisp/csl/r38.doc/structr.tex artifact ddd34fbddb part of check-in fe6b5d0560


\chapter{Display and Structuring of Expressions}\index{Display}
\index{Structuring}
In this section, we consider a variety of commands and operators that
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.

\section{Kernels}\index{Kernel}
{\REDUCE} is designed so that each operator in the system has an
evaluation (or simplification)\index{Simplification} function associated
with it that transforms the expression into an internal canonical form.
\index{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 the 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 {\tt +}, {\tt *} and {\tt /} , for example,
because the canonical form\index{Canonical form} does not include these
operators explicitly.  It is also true of an operator such as the
determinant operator {\tt DET}\ttindex{DET} because the relevant
evaluation function calculates the appropriate determinant, and the
operator {\tt 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 {\tt COS}, a residual expression like {\tt
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 {\em kernels\/}\index{Kernel} 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 those cases where the evaluation process leaves an operator expression
with non-trivial arguments, the form of the argument can vary depending on
the state of the system at the point of evaluation.  Such arguments are
normally produced in expanded form with no terms factored or grouped in
any way.  For example, the expression {\tt cos(2*x+2*y)} will normally be
returned in the same form.  If the argument {\tt 2*x+2*y} were evaluated
at the top level, however, it would be printed as {\tt 2*(X+Y)}.  If it is
desirable to have the arguments themselves in a similar form, the switch
{\tt INTSTR}\ttindex{INTSTR} (for ``internal structure''), if on, will
cause this to happen.

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 {\em kernel form\/}\index{kernel form} as an
expression that transforms to a kernel on evaluation.

Examples of kernel forms are:
\begin{verbatim}
        a
        cos(x*y)
        log(sin(x))
\end{verbatim}
whereas
\begin{verbatim}
        a*b
        (a+b)^4
\end{verbatim}
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.

\section{The Expression Workspace}\index{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 {\tt WS} that we shall refer to as the
workspace. (More precisely, the expression is assigned to the variable
{\tt WS} that is then available for further manipulation.)

{\it Example:}

If we evaluate the expression {\tt (x+y)\verb|^|2} at the top level and next
wish to differentiate it with respect to {\tt Y}, we can simply say
\begin{verbatim}
        df(ws,y);
\end{verbatim}
to get the desired answer.

If the user wishes to assign the workspace to a variable or expression for
later use, the {\tt SAVEAS}\ttindex{SAVEAS} statement can be used.  It
has the syntax
\begin{verbatim}
        SAVEAS <expression>
\end{verbatim}
For example, after the differentiation in the last example, the workspace
holds the expression {\tt 2*x+2*y}.  If we wish to assign this to the
variable {\tt Z} we can now say
\begin{verbatim}
        saveas z;
\end{verbatim}
If the user wishes to save the expression in a form that allows him to use
some of its variables as arbitrary parameters, the {\tt FOR ALL}
command can be used.

{\it Example:}
\begin{verbatim}
        for all x saveas h(x);
\end{verbatim}

with the above expression would mean that {\tt h(z)} evaluates to {\tt
2*Y+2*Z}.

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


\section{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 are in most cases 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 that 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
{\tt OUTPUT}\ttindex{OUTPUT} which is normally on.  It is useful for
limiting output when loading large files or producing ``clean'' output from
the prettyprint programs.

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,\index{Output
declaration} however, can be used to affect this format.  To begin with,
we look at an operator for changing the length of the output line.

\subsection{LINELENGTH Operator}\ttindex{LINELENGTH}

This operator is used with the syntax
\begin{verbatim}
        LINELENGTH(NUM:integer):integer
\end{verbatim}
and sets the output line length to the integer {\tt NUM}. It returns the
previous output line length (so that it can be stored for later resetting
of the output line if needed).

\subsection{Output Declarations}

We now describe a number of switches and declarations that 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 the output in such cases, he can turn off the switch {\tt
PRI}.\ttindex{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. {\tt PRI} is normally on.

With {\tt PRI} on, the output declarations\index{Output declaration}
and switches available are as follows:

\subsubsection{ORDER Declaration}

The declaration {\tt ORDER}\ttindex{ORDER} may be used to order variables
on output.  The syntax is:
\begin{verbatim}
        order v1,...vn;
\end{verbatim}
where the {\tt vi} are kernels.  Thus,
\begin{verbatim}
        order x,y,z;
\end{verbatim}
orders {\tt X} ahead of {\tt Y}, {\tt Y} ahead of {\tt Z} and all three
ahead of other variables not given an order. {\tt order nil;} resets the
output order to the system default.  The order of variables may be changed
by further calls of {\tt ORDER}, but then the reordered variables would
have an order lower than those in earlier {\tt ORDER}\ttindex{ORDER} calls.
Thus,
\begin{verbatim}
        order x,y,z;
        order y,x;
\end{verbatim}
would order {\tt Z} ahead of {\tt Y} and {\tt X}.  The default ordering is
usually alphabetic.

\subsubsection{FACTOR Declaration}

This declaration takes a list of identifiers or kernels\index{Kernel}
as argument. {\tt FACTOR}\ttindex{FACTOR} is not a factoring command
(use {\tt FACTORIZE} or the {\tt FACTOR} switch 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. For example:
\begin{verbatim}
        factor x,cos,sin(x);
\end{verbatim}
causes all powers of {\tt X} and {\tt SIN(X)} and all functions of
{\tt COS} to be factored.

Note that {\tt FACTOR} does not affect the order of its arguments.  You
should also use {\tt ORDER} if this is important.

The declaration {\tt remfac v1,...,vn;}\ttindex{REMFAC} removes the
factoring flag from the expressions {\tt v1} through {\tt vn}.

\subsection{Output Control Switches}
\label{sec-output}
In addition to these declarations, the form of the output can be modified
by switching various output control switches using the declarations
{\tt ON} and {\tt OFF}.  We shall illustrate the use of these switches by an
example, namely the printing of the expression
\begin{verbatim}
        x^2*(y^2+2*y)+x*(y^2+z)/(2*a) .
\end{verbatim}
The relevant switches are as follows:

\subsubsection{ALLFAC Switch}

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 {\tt ALLFAC}
\ttindex{ALLFAC}
off will print as
\begin{verbatim}
            2  2        2          2
        (2*X *Y *A + 4*X *Y*A + X*Y  + X*Z)/(2*A)
\end{verbatim}
and with {\tt ALLFAC} on as
\begin{verbatim}
                2                2
        X*(2*X*Y *A + 4*X*Y*A + Y  + Z)/(2*A) .
\end{verbatim}
{\tt ALLFAC} is normally on, and is on in the following examples, except
where otherwise stated.

\subsubsection{DIV Switch}\ttindex{DIV}

This switch makes the system search the denominator of an expression for
simple factors that it divides into the numerator, so that rational
fractions and negative powers appear in the output. With {\tt DIV} on, our
expression would print as
\begin{verbatim}
              2                2  (-1)        (-1)
        X*(X*Y  + 2*X*Y + 1/2*Y *A     + 1/2*A    *Z) .
\end{verbatim}
{\tt DIV} is normally off.

\subsubsection{LIST Switch}\ttindex{LIST}

This switch causes the system to print each term in any sum on a separate
line. With {\tt LIST} on, our expression prints as
\begin{verbatim}
                2
        X*(2*X*Y *A

            + 4*X*Y*A

               2
            + Y

            + Z)/(2*A) .
\end{verbatim}
{\tt LIST} is normally off.

\subsubsection{NOSPLIT Switch}\ttindex{NOSPLIT}

Under normal circumstances, the printing routines try to break an expression
across lines at a natural point.  This is a fairly expensive process.  If
you are not overly concerned about where the end-of-line breaks come, you
can speed up the printing of expressions by turning off the switch
{\tt NOSPLIT}.  This switch is normally on.

\subsubsection{RAT Switch}\ttindex{RAT}

This switch is only useful with expressions in which variables are
factored with {\tt FACTOR}. With this mode, the overall denominator of the
expression is printed with each factored sub-expression. We assume a prior
declaration {\tt factor x;} in the following output. We first print the
expression with {\tt RAT off}:
\begin{verbatim}
            2                   2
        (2*X *Y*A*(Y + 2) + X*(Y  + Z))/(2*A) .
\end{verbatim}
With {\tt RAT} on the output becomes:
\extendedmanual{\newpage}
\begin{verbatim}
         2                 2
        X *Y*(Y + 2) + X*(Y  + Z)/(2*A) .
\end{verbatim}
{\tt RAT} is normally off.

Next, if we leave {\tt X} factored, and turn on both {\tt DIV} and
{\tt RAT}, the result becomes
\begin{verbatim}
         2                    (-1)   2
        X *Y*(Y + 2) + 1/2*X*A    *(Y  + Z) .
\end{verbatim}
Finally, with {\tt X} factored, {\tt RAT} on and {\tt ALLFAC}\ttindex{ALLFAC}
off we retrieve the original structure
\begin{verbatim}
         2   2              2
        X *(Y  + 2*Y) + X*(Y  + Z)/(2*A) .
\end{verbatim}

\subsubsection{RATPRI Switch}\ttindex{RATPRI}

If the numerator and denominator of an expression can each be printed in
one line, the output routines will print them in a two dimensional
notation, with numerator and denominator on separate lines and a line of
dashes in between. For example, {\tt (a+b)/2} will print as
\begin{verbatim}
        A + B
        -----
          2
\end{verbatim}
Turning this switch off causes such expressions to be output in a linear
form.

\subsubsection{REVPRI Switch}\ttindex{REVPRI}

The normal ordering of terms in output is from highest to lowest power.
In some situations (e.g., when a power series is output), the opposite
ordering is more convenient.  The switch {\tt REVPRI} if on causes such a
reverse ordering of terms.  For example, the expression
{\tt y*(x+1)\verb|^|2+(y+3)\verb|^|2} will normally print as
\begin{verbatim}
         2              2
        X *Y + 2*X*Y + Y  + 7*Y + 9
\end{verbatim}
whereas with {\tt REVPRI} on, it will print as
\begin{verbatim}
                   2            2
        9 + 7*Y + Y  + 2*X*Y + X *Y.
\end{verbatim}

\subsection{WRITE Command}\ttindex{WRITE}

In simple cases no explicit output\index{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 {\tt FOR}, {\tt WHILE}, or {\tt 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 {\tt WRITE} command consists of the word {\tt WRITE} followed by one
or more items separated by commas, and followed by a terminator.  There
are three kinds of items that can be used:
\begin{enumerate}
\item Expressions (including variables and constants).  The expression is
evaluated, and the result is printed out.

\item Assignments.  The expression on the right side of the {\tt :=}
operator is evaluated, and is assigned to the variable on the left; then
the symbol on the left is printed, followed by a ``{\tt :=}'', 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 {\tt WRITE} is in a {\tt FOR} statement and the left-hand side
of the assignment is an array position or something similar containing the
variable of the {\tt FOR} iteration, then the value of that variable is
inserted in the printout.)

\item Arbitrary strings of characters, preceded and followed by double-quote
marks (e.g., {\tt "string"}).
\end{enumerate}
The items specified by a single {\tt 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 {\tt WRITE} command itself however does not
return a value.

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

{\it Examples:}
\begin{enumerate}
\item If {\tt A} is {\tt X+5}, {\tt B} is itself, {\tt C} is 123, {\tt M} is
an array, and {\tt Q}=3, then
\begin{verbatim}
        write m(q):=a," ",b/c," THANK YOU";
\end{verbatim}
will set {\tt M(3)} to {\tt x+5} and print
\begin{verbatim}
        M(Q) := X + 5 B/123 THANK YOU
\end{verbatim}
The blanks between the {\tt 5} and {\tt B}, and the
{\tt 3} and {\tt T}, come from the blanks in the quoted strings.

\item To print a table of the squares of the integers from 1 to 20:
\begin{verbatim}
        for i:=1:20 do write i," ",i^2;
\end{verbatim}

\item 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 {\tt A:}
\begin{verbatim}
        for i:=1:20 do <<a(i):=i^2; write i," ",a(i)>>;
\end{verbatim}
This will give us two columns of numbers. If we had used
\begin{verbatim}
        for i:=1:20 do write i," ",a(i):=i^2;
\end{verbatim}
we would also get {\tt A(}i{\tt ) := } repeated on each line.

\item 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).
\begin{verbatim}
 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;
\end{verbatim}
 A portion of the output, to illustrate the printout from the {\tt WRITE}
command, is as follows:
\begin{verbatim}
                ... <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> ...

\end{verbatim}
\end{enumerate}
\subsection{Suppression of Zeros}

It is sometimes annoying to have zero assignments (i.e. assignments of the
form {\tt <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 {\tt NERO}.\ttindex{NERO}

\subsection{{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 switch {\tt ROUNDED}\ttindex{ROUNDED}.  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\index{FORTRAN} or similar system.  For
this purpose, {\REDUCE} offers facilities for users to produce FORTRAN
compatible files for numerical processing.

First, when the switch {\tt FORT}\ttindex{FORT} is on, the system will
print expressions in a FORTRAN notation.  Expressions begin in column
seven.  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 {\tt
CARD\_NO}),\ttindex{CARD\_NO} 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 {\tt ANS}.  An error occurs if identifiers or
numbers are outside the bounds permitted by FORTRAN.

A second option is to use the {\tt WRITE} command to produce other programs.

{\it Example:}

The following {\REDUCE} statements
\begin{verbatim}
 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     it was foolish to expand this expression";
 write "      print 1,x";
 write "      end";
 shut "forfil";
 off fort;
\end{verbatim}
will generate a file {\tt forfil} that contains:

{\small
\begin{verbatim}
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.
     . *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     it was foolish to expand this expression
      print 1,x
      end
\end{verbatim}
}
If the arguments of a {\tt WRITE} statement include an expression that
requires continuation records, the output will need editing, since the
output routine prints the arguments of {\tt WRITE} sequentially, and the
continuation mechanism therefore generates its auxiliary variables after
the preceding expression has been printed.

Finally, since there is no direct analog of {\em list\/} in FORTRAN,
a comment line of the form
\begin{verbatim}
	c ***** invalid fortran construct (list) not printed
\end{verbatim}
will be printed if you try to print a list with {\tt FORT} on.

\subsubsection{{FORTRAN} Output Options}\index{Output}\index{FORTRAN}

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
\begin{verbatim}
	card_no := <number>;
\end{verbatim}
where {\tt <number>} is the {\em total\/} number of cards allowed in a
statement. The default value of {\tt CARD\_NO} is 20.

The width of the output expression is also adjustable by the assignment
\begin{verbatim}
	fort_width := <integer>;
\end{verbatim}
\ttindex{FORT\_WIDTH} which sets the total width of a given line to
{\tt <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
{\tt 4.} ). To prevent this, set the {\tt PERIOD}\ttindex{PERIOD}
mode switch to {\tt OFF}.

FORTRAN output is normally produced in lower case.  If upper case is desired,
the switch {\tt FORTUPPER}\ttindex{FORTUPPER} should be turned on.

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

Further facilities for the production of FORTRAN and other language output
are provided by the SCOPE and GENTRAN
packages\extendedmanual{described in chapters~\ref{GENTRAN} and \ref{SCOPE}}.

\subsection{Saving Expressions for Later Use as Input}
\index{Saving an expression}

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 is not compatible with the input syntax. So to print the
expression in an input compatible form we must inhibit this natural style
by turning off the switch {\tt NAT}.\ttindex{NAT} If this is done, a
dollar sign will also be printed at the end of the expression.

{\it Example:}

The following sequence of commands
\begin{verbatim}
        off nat; out "out"; x := (y+z)^2; write "end";
        shut "out"; on nat;
\end{verbatim}
will generate a file {\tt out} that contains
\begin{verbatim}
        X := Y**2 + 2*Y*Z + Z**2$
        END$
\end{verbatim}

\subsection{Displaying Expression Structure}\index{Displaying 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
{\tt STRUCTR},\ttindex{STRUCTR} that takes a single expression as argument,
will do this for you.  Its syntax is:
\begin{verbatim}
   STRUCTR(EXPRN:algebraic[,ID1:identifier[,ID2:identifier]]);
\end{verbatim}
The structure is printed effectively as a tree, in which the subparts are
laid out with auxiliary names.  If the optional {\tt ID1} is absent, the
auxiliary names are prefixed by the root {\tt ANS}.  This root may be
changed by the operator {\tt VARNAME}\ttindex{VARNAME}.  If the
optional {\tt ID1} is present, and is an array name, the subparts are
named as elements of that array, otherwise {\tt ID1} is used as the root
prefix. (The second optional argument {\tt ID2} is explained later.)

The {\tt EXPRN} can be either a scalar or a matrix expression.  Use of any
other will result in an error.

{\it Example:}

Let us suppose that the workspace contains
{\tt ((A+B)\verb|^|2+C)\verb|^|3+D}.
Then the input {\tt STRUCTR WS;} will (with {\tt EXP} off) result in the
output:\newpage
\begin{verbatim}
        ANS3

           where

                          3
              ANS3 := ANS2  + D

                          2
              ANS2 := ANS1  + C

              ANS1 := A + B
\end{verbatim}
The workspace remains unchanged after this operation, since {\tt STRUCTR}
\ttindex{STRUCTR} in the default situation returns
no value (if {\tt STRUCTR} is used as a sub-expression, its value is taken
to be 0).  In addition, the sub-expressions are normally only displayed
and not retained. If you wish to access the sub-expressions with their
displayed names, the switch {\tt SAVESTRUCTR}\ttindex{SAVESTRUCTR} should be
turned on.  In this case, {\tt STRUCTR} returns a list whose first element
is a representation for the expression, and subsequent elements are the
sub-expression relations.  Thus, with {\tt SAVESTRUCTR} on, {\tt STRUCTR WS}
in the above example would return
\vspace{-11pt}
\begin{verbatim}
                       3              2
        {ANS3,ANS3=ANS2  + D,ANS2=ANS1  + C,ANS1=A + B}
\end{verbatim}
The {\tt PART}\ttindex{PART} operator can
be used to retrieve the required parts of the expression.  For example, to
get the value of {\tt ANS2} in the above, one could say:
\begin{verbatim}
	part(ws,3,2);
\end{verbatim}
If {\tt 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.  The second optional argument {\tt ID2} may also be
used in this case to name the actual expression (or expressions in the
case of a matrix argument).

{\it Example:}

Let us suppose that {\tt M}, a 2 by 1 matrix, contains the elements {\tt
((a+b)\verb|^|2 + c)\verb|^|3 + d} and {\tt (a + b)*(c + d)} respectively,
and that {\tt V} has been declared to be an array.  With {\tt EXP} off and
{\tt FORT} on, the statement {\tt structr(2*m,v,k);} will result in the output

\begin{verbatim}
      V(1)=A+B
      V(2)=V(1)**2+C
      V(3)=V(2)**3+D
      V(4)=C+D
      K(1,1)=2.*V(3)
      K(2,1)=2.*V(1)*V(4)
\end{verbatim}

\section{Changing the Internal Order of Variables}

The internal ordering of variables (more specifically kernels) can have
a significant effect on the space and time associated with a calculation.
In its default state, {\REDUCE} uses a specific order for this which may
vary between sessions.  However, it is possible for the user to change
this internal order by means of the declaration
{\tt KORDER}\ttindex{KORDER}.  The syntax for this is:
\begin{verbatim}
        korder v1,...,vn;
\end{verbatim}
where the {\tt Vi} are kernels\index{Kernel}.  With this declaration, the
{\tt Vi} are ordered internally ahead of any other kernels in the system.
{\tt V1} has the highest order, {\tt V2} the next highest, and so on.  A
further call of {\tt KORDER} replaces a previous one. {\tt KORDER NIL;}
resets the internal order to the system default.

Unlike the {\tt ORDER}\ttindex{ORDER} declaration, that has a purely
cosmetic effect on the way results are printed, the use of {\tt KORDER}
can have a significant effect on computation time.  In critical cases
then, the user can experiment with the ordering of the variables used to
determine the optimum set for a given problem.

\section{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.

\subsection{COEFF Operator}\ttindex{COEFF}
Syntax:
\begin{verbatim}
        COEFF(EXPRN:polynomial,VAR:kernel)
\end{verbatim}
{\tt COEFF} is an operator that partitions {\tt EXPRN} into its various
coefficients with respect to {\tt VAR} and returns them as a list, with
the coefficient independent of {\tt VAR} first.

Under normal circumstances, an error results if {\tt EXPRN} is not a
polynomial in {\tt VAR}, although the coefficients themselves can be
rational as long as they do not depend on {\tt VAR}.  However, if the
switch {\tt RATARG}\ttindex{RATARG} is on, denominators are not checked for
dependence on {\tt VAR}, and are taken to be part of the coefficients.

{\it Example:}
\begin{verbatim}
        coeff((y^2+z)^3/z,y);
\end{verbatim}
returns the result
\begin{verbatim}
          2
        {Z ,0,3*Z,0,3,0,1/Z}.
\end{verbatim}
whereas
\begin{verbatim}
        coeff((y^2+z)^3/y,y);
\end{verbatim}
gives an error if {\tt RATARG} is off, and the result
\begin{verbatim}
          3        2
        {Z /Y,0,3*Z /Y,0,3*Z/Y,0,1/Y}
\end{verbatim}
if {\tt RATARG} is on.

The length of the result of {\tt COEFF} is the highest power of {\tt VAR}
encountered plus 1.  In the above examples it is 7.  In addition, the
variable {\tt HIGH\_POW}\ttindex{HIGH\_POW} is set to the highest non-zero
power found in {\tt EXPRN} during the evaluation, and {\tt LOW\_POW}
\ttindex{LOW\_POW} to the lowest non-zero power, or zero if there is a
constant term.  If {\tt EXPRN} is a constant, then {\tt HIGH\_POW} and
{\tt LOW\_POW} are both set to zero.

\subsection{COEFFN Operator}\ttindex{COEFFN}

The {\tt COEFFN} operator is designed to give the user a particular
coefficient of a variable in a polynomial, as opposed to {\tt COEFF} that
returns all coefficients. {\tt COEFFN} is used with the syntax
\begin{verbatim}
        COEFFN(EXPRN:polynomial,VAR:kernel,N:integer)
\end{verbatim}
It returns the $n^{th}$ coefficient of {\tt VAR} in the polynomial
{\tt EXPRN}.

\subsection{PART Operator}\ttindex{PART}
Syntax:
\begin{verbatim}
        PART(EXPRN:algebraic[,INTEXP:integer])
\end{verbatim}

This operator works on the form of the expression as printed {\em 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 {\tt PRI} is {\tt ON} at that point in the calculation.
The reason for this is that with {\tt PRI} off, an expression is printed
by walking the tree representing the expression internally.  To save
space, it is never actually transformed into the equivalent prefix
expression as occurs when {\tt 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,
\begin{verbatim}
     PART(<expression>,<integer1>,<integer2>)
         ->  PART(PART(<expression>,<integer1>),<integer2>)
\end{verbatim}
 and so on, and
\begin{verbatim}
        PART(<expression>) ->  <expression>.
\end{verbatim}
{\tt 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 {\tt a+b} is printed as {\tt A+B} (i.e.,
the ordering of the variables is alphabetical), then
\begin{verbatim}
        part(a+b,2)  ->   B
        part(a+b,-1) ->   B
and
        part(a+b,0)  ->  PLUS
\end{verbatim}
An operator {\tt ARGLENGTH}\ttindex{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,
\begin{verbatim}
        arglength(a+b+c) ->  3
        arglength(f())   ->  0
        arglength(a)     ->  -1
\end{verbatim}

\subsection{Substituting for Parts of Expressions}

{\tt PART} may also be used to substitute for a given part of an
expression.  In this case, the {\tt 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 the {\REDUCE} switches:
\begin{verbatim}
        xx := a+b;
        part(xx,2) := c;   ->  A+C
        part(c+d,0) := -;   -> C-D
\end{verbatim}

Note that {\tt xx} in the above is not changed by this substitution.  In
addition, unlike expressions such as array and matrix elements that have
an {\em instant evaluation\/}\index{Instant evaluation} property, the values
of {\tt part(xx,2)} and {\tt part(c+d,0)} are also not changed.


REDUCE Historical
REDUCE Sourceforge Project | Historical SVN Repository | GitHub Mirror | SourceHut Mirror | NotABug Mirror | Chisel Mirror | Chisel RSS ]