**LINEAR** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

An operator can be declared linear in its first argument over powers of
its second argument by the declaration *linear.*

*linear*<operator>{*,*<operator>}*

<operator> must have been declared to be an operator. Be careful not to use a system operator name, because this command may change its definition. The operator being declared must have at least two arguments, and the second one must be a kernel.

operator f; linear f; f(0,x); 0 f(-y,x); - F(1,X)*Y f(y+z,x); F(1,X)*(Y + Z) f(y*z,x); F(1,X)*Y*Z depend z,x; f(y*z,x); F(Z,X)*Y f(y/z,x); 1 F(-,X)*Y Z depend y,x; f(y/z,x); Y F(-,X) Z nodepend z,x; f(y/z,x); F(Y,X) ------ Z f(2*e**sin(x),x); SIN(X) 2*F(E ,X)

Even when the operator has not had its functionality attached, it exhibits linear properties as shown in the examples. Notice the difference when dependencies are added. Dependencies are also in effect when the operator's first argument contains its second, as in the last line above.

For a fully-developed example of the use of linear operators, refer to the article in the <Journal of Computational Physics>, Vol. 14 (1974), pp. 301-317, ``Analytic Computation of Some Integrals in Fourth Order Quantum Electrodynamics," by J.A. Fox and A.C. Hearn. The article includes the complete listing of REDUCE procedures used for this work.

**LINELENGTH** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *linelength* declaration sets the length of the output line. Default
is 80.

*linelength*<expression>

To change the linelength, <expression> must evaluate to a positive integer less than 128 (although this varies from system to system), and should not be less than 20 or so for proper operation.

*linelength*returns the previous linelength. If you want the current
linelength value, but not change it, say *linelength nil*.

**LISP** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *lisp* command changes REDUCE's mode of operation to symbolic. When
*lisp* is followed by an expression, that expression is evaluated in
symbolic mode, but REDUCE's mode is not changed. This command is
equivalent to
symbolic.

lisp; NIL car '(a b c d e); A algebraic; c := (lisp car '(first second))**2; 2 C := FIRST

**LISTARGP** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

If an operator other than those specifically defined for lists is given a
single argument that is a
list, then the result of this
operation will be a list in which that operator is applied to each element
of the list.
This process can be inhibited for a specific operator, or list of operators,
by using the declaration *listargp*.

log {a,b,c}; LOG(A),LOG(B),LOG(C) listargp log; log {a,b,c}; LOG(A,B,C)

It is possible to inhibit such distribution globally by turning on
the
switch
listargs. In addition, if an operator has mor
e than one
argument, no such distribution occurs, so *listargp* has no effect.

**NODEPEND** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *nodepend* declaration removes the dependency declared with
depend.

*nodepend*<dep-kernel>{,<kernel>}+

<dep-kernel> must be a kernel that has had a dependency declared upon the one or more other kernels that are its other arguments.

depend y,x,z; df(sin y,x); COS(Y)*DF(Y,X) df(sin y,x,z); COS(Y)*DF(Y,X,Z) - DF(Y,X)*DF(Y,Z)*SIN(Y) nodepend y,z; df(sin y,x); COS(Y)*DF(Y,X) df(sin y,x,z); 0

A warning message is printed if the dependency had not been declar
ed by
*depend*.

**MATCH** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *match* command is similar to the
let command, except
that it matches only explicit powers in substitution.

*match*<expr> *=* <expression>{,<expr>
*=*<expression>}*

<expr> is generally a term involving powers, and is limited by the rules for the let command. <expression> may be any valid REDUCE scalar expression.

match c**2*a**2 = d; (a+c)**4; 4 3 3 4 A + 4*A *C + 4*A*C + C + 6*D match a+b = c; a + 2*b; B + C (a + b + c)**2; 2 2 2 A - B + 2*B*C + 3*C clear a+b; (a + b + c)**2; 2 2 2 A + 2*A*B + 2*A*C + B + 2*B*C + C let p*r = s; match p*q = ss; (a + p*r)**2; 2 2 A + 2*A*S + S (a + p*q)**2; 2 2 2 A + 2*A*SS + P *Q

Note in the last example that *a + b* has been explicitly m
atched
after the squaring was done, replacing each single power of *a* by
*c - b*. This kind of substitution, although following the rules, is
confusing and could lead to unrecognizable results. It is better to use
*match* with explicit powers or products only. *match* should
not be used inside procedures for the same reasons that *let* should
not be.

Unlike
let substitutions, *match* substitutio
ns are executed
after all other operations are complete. The last example shows the
difference. *match* commands can be cleared by using
clear,
with exactly the expression that the original *match* took.
*match* commands can also be done more generally with *for all*
or
forall...*such that* commands.

**NONCOM** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

*noncom*declares that already-declared operators are noncommutative
under multiplication.

*noncom*<operator>{,<operator>}*

<operator> must have been declared an operator, or a warning message is given.

operator f,h; noncom f; f(a)*f(b) - f(b)*f(a); F(A)*F(B) - F(B)*F(A) h(a)*h(b) - h(b)*h(a); 0 operator comm; for all x,y such that x neq y and ordp(x,y) let f(x)*f(y) = f(y)*f(x) + comm(x,y); f(1)*f(2); F(1)*F(2) f(2)*f(1); COMM(2,1) + F(1)*F(2)

The last example introduces the commutator of f(x) and f(y) for all x and y. The equality check is to prevent an infinite loop. The operator f can have other functionality attached to it if desired, or it can remain an indeterminate operator.

**NONZERO** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

If an
operator *f* is declared
odd, then *f(0)*
is replaced by zero unless *f* is also declared non zero by the
declaration *nonzero*.

odd f; f(0) 0 nonzero f; f(0) F(0)

**ODD** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

This declaration is used to declare an operator odd in its first argument. Expressions involving an operator declared in this manner are transformed if the first argument contains a minus sign. Any other arguments are not affected.

odd f; f(-a) -F(A) f(-a,-b) -F(A,-B) f(a,-b) F(A,-B)

If say *f* is declared odd, then *f(0)* is replaced by zero
unless *f* is also declared non zero by the declaration
nonzero.

**OFF** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *off* command is used to turn switches off.

*off*<switch>{,<switch>}*

<switch> can be any *switch* name. There is no problem if the
switch is already off. If the switch name is mistyped, an error message is
given.

**ON** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *on* command is used to turn switches on.

*on*<switch>{,<switch>}*

<switch> can be any *switch* name. There is no problem if the
switch is already on. If the switch name is mistyped, an error message is
given.

**OPERATOR** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

Use the *operator* declaration to declare your own operators.

*operator*<identifier>{,<identifier>}*

<identifier> can be any valid REDUCE identifier, which is not the name of a matrix, array, scalar variable or previously-defined operator.

operator dis,fac; let dis(~x,~y) = sqrt(x^2 + y^2); dis(1,2); SQRT(5) dis(a,10); 2 SQRT(A + 100) on rounded; dis(1.5,7.2); 7.35459040329 let fac(~n) = if n=0 then 1 else if not(fixp n and n>0) then rederr "choose non-negative integer" else for i := 1:n product i; fac(5); 120 fac(-2); ***** choose non-negative integer

The first operator is the Euclidean distance metric, the distance of point (x,y) from the origin. The second operator is the factorial.

Operators can have various properties assigned to them; they can be
declared
infix,
linear,
symmetric,
antisymmetric, or
noncom*mutative*.
The default operator is prefix, nonlinear, and commutative.
Precedence can also be assigned to operators using the declaration
precedence.

Functionality is assigned to an operator by a
let statement or
a
forall...*let* statement,
(or possibly by a procedure with the name
of the operator). Be careful not to redefine a system operator by
accident. REDUCE permits you to redefine system operators, giving you a
warning message that the operator was already defined. This flexibility
allows you to add mathematical rules that do what you want them to do, but
can produce odd or erroneous behavior if you are not careful.

You can declare operators from inside procedures, as long as they are not local variables. Operators defined inside procedures are global. A formal parameter may be declared as an operator, and has the effect of declaring the calling variable as the operator.

**ORDER** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *order* declaration changes the order of precedence of kernels for
display purposes only.

*order*<identifier>{,<identifier>}*

<kernel> must be a valid kernel or operator name complete with argument or a list of such objects.

x + y + z + cos(a); COS(A) + X + Y + Z order z,y,x,cos(a); x + y + z + cos(a); Z + Y + X + COS(A) (x + y)**2; 2 2 Y + 2*Y*X + X order nil; (z + cos(z))**2; 2 2 COS(Z) + 2*COS(Z)*Z + Z

*order*affects the printing order of the identifiers only;
internal
order is unchanged. Change internal order of evaluation with the
declaration
korder. You can use *order* to feature
variables
or functions you are particularly interested in.

Declarations made with *order* are cumulative: kernels in new order
declarations are ordered behind those in previous declarations, and
previous declarations retain their relative order. Of course, specific
kernels named in new declarations are removed from previous ones and given
the new priority. Return to the standard canonical printing order with the
statement *order nil*.

The print order specified by *order* commands is not in effect if the
switch
pri is off.

**PRECEDENCE** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *precedence* declaration attaches a precedence to an infix operator.

*precedence*<operator>,<known\_operator>

<operator> should have been declared an operator but may be a REDUCE identifier that is not already an operator, array, or matrix. <known\_operator> must be a system infix operator or have had its precedence already declared.

operator f,h; precedence f,+; precedence h,*; a + f(1,2)*c; (1 F 2)*C + A a + h(1,2)*c; 1 H 2*C + A a*1 f 2*c; A F 2*C a*1 h 2*c; 1 H 2*A*C

The operator whose precedence is being declared is inserted into t he infix operator precedence list at the next higher place than <known\_operator>.

Attaching a precedence to an operator has the side effect of declaring the
operator to be infix. If the identifier argument for *precedence* has
not been declared to be an operator, an attempt to use it causes an error
message. After declaring it to be an operator, it becomes an infix operator
with the precedence previously given. Infix operators may be used in prefix
form; if they are used in infix form, a space must be left on each side of
the operator to avoid ambiguity. Declared infix operators are always binary.

To see the infix operator precedence list, enter symbolic mode and type
*preclis!*;*. The lowest precedence operator is listed first.

All prefix operators have precedence higher than infix operators.

**PRECISION** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *precision* declaration sets the number of decimal places used when
rounded is on. Default is system dependent, a
nd normally about 12.

*precision*(<integer>) or *precision* <integer>

<integer> must be a positive integer. When <integer> is 0, the current precision is displayed, but not changed. There is no upper limit, but precision of greater than several hundred causes unpleasantly slow operation on numeric calculations.

on rounded; 7/9; 0.777777777778 precision 20; 20 7/9; 0.77777777777777777778 sin(pi/4); 0.7071067811865475244

Trailing zeroes are dropped, so sometimes fewer than 20 decimal pl
aces are
printed as in the last example. Turn on the switch
fullprec if
you want to print all significant digits. The
rounded mode
carries calculations to two more places than given by *precision*, and
rounds off.

**PRINT\_PRECISION** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

In
rounded mode, numbers are normally printed to
the specified
precision. If the user wishes to print such numbers with less precision,
the printing precision can be set by the declaration *print_precision*.

on rounded; 1/3; 0.333333333333 print_precision 5; 1/3 0.33333

**REAL** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *real* declaration must be made immediately after a
begin (or other variable declaration such as
integer
and
scalar) and declares local integer variables.
They are
initialized to zero.

*real*<identifier>{,<identifier>}*

<identifier> may be any valid REDUCE identifier, except
*t* or *nil*.

Real variables remain local, and do not share values with variables of the
same name outside the
begin...*end* block. When the
block is finished, the variables are removed. You may use the words
integer or
scalar in the place of *real*.
*real* does not indicate typechecking by the current REDUCE; it is
only for your own information. Declaration statements must immediately
follow the *begin*, without a semicolon between *begin* and the
first variable declaration.

Any variables used inside a *begin*...*end*
block
that were not declared *scalar*, *real* or *integer* are
global, and any change made to them inside the block affects their global
value. Any
array or
matrix declared inside a block is always
global.

**REMFAC** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *remfac* declaration removes the special factoring treatment of its
arguments that was declared with
factor.

*remfac*<kernel>{,<kernel>}+

<kernel> must be a kernel or operator name that was declared as special with the factor declaration.

**SCALAR** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *scalar* declaration must be made immediately after a
begin (or other variable declaration such as
integer
and
real) and declares local scalar variables. Th
ey are
initialized to 0.

*scalar*<identifier>{,<identifier>}*

<identifier> may be any valid REDUCE identifier, except *t* or
*nil*.

Scalar variables remain local, and do not share values with variables of
the same name outside the
begin...*end*
block.
When the block is finished, the variables are removed. You may use the
words
real or
integer in the place of *scalar*.
*real* and *integer* do not indicate typechecking by the current
REDUCE; they are only for your own information. Declaration statements
must immediately follow the *begin*, without a semicolon between
*begin* and the first variable declaration.

Any variables used inside *begin*...*end* blocks that were not
declared *scalar*, *real* or *integer* are global, and any
change made to them inside the block affects their global value. Arrays
declared inside a block are always global.

**SCIENTIFIC\_NOTATION** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

<m> and <n> are positive integers.
*scientific_notation* controls the output format of floating point
numbers. At the default settings, any number with five or less digits
before the decimal point is printed in a fixed-point notation, e.g.,
12345.6. Numbers with more than five digits are printed in scientific
notation, e.g., 1.234567E+5. Similarly, by default, any number with
eleven or more zeros after the decimal point is printed in scientific
notation.

When *scientific_notation* is called with the numerical argument
m a number with more than m digits before the decimal point,
or m or more zeros after the decimal point, is printed in scientific
notation. When *scientific_notation* is called with a list
{<m>,<n>}, a number with more than m digits before the
decimal point, or n or more zeros after the decimal point is
printed in scientific notation.

on rounded; 12345.6; 12345.6 123456.5; 1.234565e+5 0.00000000000000012; 1.2e-16 scientific_notation 20; 5,11 5: 123456.7; 123456.7 0.00000000000000012; 0.00000000000000012

**SHARE** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *share* declaration allows access to its arguments by both
algebraic and symbolic modes.

*share*<identifier>{,<identifier>}*

<identifier> can be any valid REDUCE identifier.

Programming in
symbolic as well as algebraic mode allows
you a wider range
of techniques than just algebraic mode alone. Expressions do not cross the
boundary since they have different representations, unless the *share*
declaration is used. For more information on using symbolic mode, see
the <REDUCE User's Manual>, and the <Standard Lisp Report>.

You should be aware that a previously-declared array is destroyed by the
*share* declaration. Scalar variables retain their values. You can
share a declared
matrix that has not yet
been dimensioned so that it can be
used by both modes. Values that are later put into the matrix are
accessible from symbolic mode too, but not by the usual matrix reference
mechanism. In symbolic mode, a matrix is stored as a list whose first
element is
MAT, and whose next elements are the rows of
the matrix
stored as lists of the individual elements. Access in symbolic mode is by
the operators
first,
second,
third and
rest.

**SYMBOLIC** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *symbolic* command changes REDUCE's mode of operation to symbolic.
When *symbolic* is followed by an expression, that expression is
evaluated in symbolic mode, but REDUCE's mode is not changed. It is
equivalent to the
lisp command.

symbolic; NIL cdr '(a b c); (B C) algebraic; x + symbolic car '(y z); X + Y

**SYMMETRIC** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

When an operator is declared *symmetric*, its arguments are reordered
to conform to the internal ordering of the system.

*symmetric*<identifier>{,<identifier>}*

<identifier> is an identifier that has been declared an operator.

operator m,n; symmetric m,n; m(y,a,sin(x)); M(SIN(X),A,Y) n(z,m(b,a,q)); N(M(A,B,Q),Z)

If <identifier> has not been declared to be an operator, the
flag
*symmetric* is still attached to it. When <identifier> is
subsequently used as an operator, the message *Declare*<identifier>
*operator ? (Y or N)* is printed. If the user replies *y*, the
symmetric property of the operator is used.

**TR** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *tr* declaration is used to trace system or user-written procedures.
It is only useful to those with a good knowledge of both Lisp and the
internal formats used by REDUCE.

<name> is the name of a REDUCE system procedure or one of your own procedures.

The system procedure *prepsq* is traced,
which prepares REDUCE standard
forms for printing by converting them to a Lisp prefix form.

tr prepsq; (PREPSQ) x**2 + y; PREPSQ entry: Arg 1: (((((X . 2) . 1) ((Y . 1) . 1)) . 1) PREPSQ return value = (PLUS (EXPT X 2) Y) PREPSQ entry: Arg 1: (1 . 1) PREPSQ return value = 1 2 X + Y untr prepsq; (PREPSQ)

This example is for a PSL-based system; the above format will vary if other Lisp systems are used.

When a procedure is traced, the first lines show entry to the procedure and
the arguments it is given. The value returned by the procedure is printed
upon exit. If you are tracing several procedures, with a call to one of
them inside the other, the inner trace will be indented showing procedure
nesting. There are no trace options. However, the format of the trace
depends on the underlying Lisp system used. The trace can be removed with
the command
untr. Note that *trace*, below, is a m
atrix
operator, while *tr* does procedure tracing.

**UNTR** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The *untr* declaration is used to remove a trace from system or
user-written procedures declared with
tr. It is only useful to
those with a good knowledge of both Lisp and the internal formats used by
REDUCE.

<name> is the name of a REDUCE system procedure or one of your own
procedures that has previously been the argument of a *tr*
declaration.

**VARNAME** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

The declaration *varname* instructs REDUCE to use its argument as the
default Fortran (when
fort is on) or
structr identifier
and identifier stem, rather than using *ANS*.

*varname*<identifier>

<identifier> can be any combination of one or more alphanumeric characters. Try to avoid REDUCE reserved words.

varname ident; IDENT on fort; x**2 + 1; IDENT=X**2+1. off fort,exp; structr(((x+y)**2 + z)**3); 3 IDENT2 where 2 IDENT2 := IDENT1 + Z IDENT1 := X + Y

expwas turned off so that
structr could show the
structure. If *exp* had been on, the expression would have been
expanded into a polynomial.

**WEIGHT** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *weight* command is used to attach weights to kernels for asymptotic
constraints.

*weight*<kernel> *=*<number>

<kernel> must be a REDUCE kernel, <number> must be a positive integer, not 0.

a := (x+y)**4; 4 3 2 2 3 4 A := X + 4*X *Y + 6*X *Y + 4*X*Y + Y weight x=2,y=3; wtlevel 8; a; 4 X wtlevel 10; a; 2 2 2 X *(6*Y + 4*X*Y + X ) int(x**2,x); ***** X invalid as KERNEL

Weights and wtlevel are used for asymptotic constraints, where higher-order terms are considered insignificant.

Weights are originally equivalent to 0 until set by a *weight*
command. To remove a weight from a kernel, use the
clear
command. Weights once assigned cannot be changed without clearing the
identifier. Once a weight is assigned to a kernel, it is no longer a
kernel and cannot be used in any REDUCE commands or operators that require
kernels, until the weight is cleared. Note that terms are ordered by
greatest weight.

The weight level of the system is set by
wtlevel, initially at
2. Since no kernels have weights, no effect from *wtlevel* can be
seen. Once you assign weights to kernels, you must set *wtlevel*
correctly for the desired operation. When weighted variables appear in a
term, their weights are summed for the total weight of the term (powers of
variables multiply their weights). When a term exceeds the weight level
of the system, it is discarded from the result expression.

**WHERE** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *where* operator provides an infix notation for one-time
substitutions for kernels in expressions.

<expression> *where* <kernel>
*=*<expression>
{,<kernel> *=*<expression>}*

<expression> can be any REDUCE scalar expression, <kernel> must
be a
kernel. Alternatively a
rule or a *rule list*
can be a member of the right-hand part of a *where* expression.

x**2 + 17*x*y + 4*y**2 where x=1,y=2; 51 for i := 1:5 collect x**i*q where q= for j := 1:i product j; 2 3 4 5 {X,2*X ,6*X ,24*X ,120*X } x**2 + y + z where z=y**3,y=3; 2 3 X + Y + 3

Substitution inside a *where* expression has no effect upon
the values
of the kernels outside the expression. The *where* operator has the
lowest precedence of all the infix operators, which are lower than prefix
operators, so that the substitutions apply to the entire expression
preceding the *where* operator. However, *where* is applied
before command keywords such as *then*, *repeat*, or *do*.

A
rule or a *rule set* in the right-hand
part of the
*where* expression act as if the rules were activated by
let
immediately before the evaluation of the expression and deactivated
by
clearrules immediately afterwards.

*where*gives you a natural notation for auxiliary variables in
expressions. As the second example shows, the substitute expression can be
a command to be evaluated. The substitute assignments are made in
parallel, rather than sequentially, as the last example shows. The
expression resulting from the first round of substitutions is not
reexamined to see if any further such substitutions can be made.
*where* can also be used to define auxiliary variables in
procedure definitions.

**WHILE** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *while* command causes a statement to be repeatedly executed until a
given condition is true. If the condition is initially false, the statement
is not executed at all.

*while*<condition> *do* <statement>

<condition> is given by a logical operator, <statement> must be a
single REDUCE statement, or a
group (*<<*...*>>*)
or
begin...*end*
block.

a := 10; A := 10 while a <= 12 do <<write a; a := a + 1>>; 10 11 12 while a < 5 do <<write a; a := a + 1>>; nothing is printed

**WTLEVEL** _ _ _ _ _ _ _ _ _ _ _ _ **command**

In conjunction with
weight, *wtlevel* is used to implement
asymptotic constraints. Its default value is 2.

*wtlevel*<expression>

To change the weight level, <expression> must evaluate to a positive
integer that is the greatest weight term to be retained in expressions
involving kernels with weight assignments. *wtlevel* returns the
new weight level. If you want the current weight level, but not
change it, say *wtlevel nil*.

(x+y)**4; 4 3 2 2 3 4 X + 4*X *Y + 6*X *Y + 4*X*Y + Y weight x=2,y=3; wtlevel 8; (x+y)**4; 4 X wtlevel 10; (x+y)**4; 2 2 2 X *(6*Y + 4*X*Y + X ) int(x**2,x); ***** X invalid as KERNEL

*wtlevel*is used in conjunction with the command
weight to
enable asymptotic constraints. Weight of a term is computed by multiplying
the weights of each variable in it by the power to which it has been
raised, and adding the resulting weights for each variable. If the weight
of the term is greater than *wtlevel*, the term is dropped from the
expression, and not used in any further computation involving the
expression.

Once a weight has been attached to a
kernel, it is no longer
recognized by the system as a kernel, though still a variable. It cannot
be used in REDUCE commands and operators that need kernels. The weight
attachment can be undone with a
clear command. *wtlevel* can
be changed as desired.

**Declarations**

**IN** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *in* command takes a list of file names and inputs each file into
the system.

*in*<filename>{,<filename>}*

<filename> must be in the current directory, or be a valid pathname.
If the file name is not an identifier, double quote marks (*"*) are
needed around the file name.

A message is given if the file cannot be found, or has a mistake in it.

Ending the command with a semicolon causes the file to be echoed to the screen; ending it with a dollar sign does not echo the file. If you want some but not all of a file echoed, turn the switch echo on or off in the file.

An efficient way to develop procedures in REDUCE is to write them into a file using a system editor of your choice, and then input the files into an active REDUCE session. REDUCE reparses the procedure as it takes information from the file, overwriting the previous procedure definition. When it accepts the procedure, it echoes its name to the screen. Data can also be input to the system from files.

Files to be read in should always end in
end*;* to avoid
end-of-file problems. Note that this is an additional *end;* to any
ending procedures in the file.

**INPUT** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *input* command returns the input expression to the REDUCE numbered
prompt that is its argument.

*input*(<number>) or *input* <number>

<number> must be between 1 and the current REDUCE prompt number.

An expression brought back by *input* can be reexecuted with new
values or switch settings, or used as an argument in another expression.
The command
ws brings back the results of a numbered REDU
CE
statement. Two lists contain every input and every output statement since
the beginning of the session. If your session is very long, storage space
begins to fill up with these expressions, so it is a good idea to end the
session once in a while, saving needed expressions to files with the
saveas and
out commands.

Switch settings and
let statements can also be reexecuted by usin
g
*input*.

An error message is given if a number is called for that has not yet been used.

**OUT** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *out* command directs output to the filename that is its argument,
until another *out* changes the output file, or
shut closes it.

*out*<filename> or *out "*<pathname> *"
* or *out t*

<filename> must be in the current directory, or be a valid complete file description for your system. If the file name is not in the current directory, quote marks are needed around the file name. If the file already exists, a message is printed allowing you to decide whether to supersede the contents of the file with new material.

To restore output to the terminal, type *out t*, or
shut the
file. When you use *out t*, the file remains available, and if you
open it again (with another *out*), new material is appended rather
than overwriting.

To write a file using *out* that can be input at a later time, the
switch
nat must be turned off, so that the standard
linear form
is saved that can be read in by
in. If *nat* is on, exponents
are printed on the line above the expression, which causes trouble
when REDUCE tries to read the file.

There is a slight complication if you are using the *out* command from
inside a file to create another file. The
echo switch is normally
off at the top-level and on while reading files (so you can see what is
being read in). If you create a file using *out* at the top-level,
the result lines are printed into the file as you want them. But if you
create such a file from inside a file, the *echo* switch is on, and
every line is echoed, first as you typed it, then as REDUCE parsed it, and
then once more for the file. Therefore, when you create a file from
a file, you need to turn *echo* off explicitly before the *out*
command, and turn it back on when you *shut* the created file, so your
executing file echoes as it should. This behavior also means that as you
watch the file execute, you cannot see the lines that are being put into
the *out* file. As soon as you turn *echo* on, you can see
output again.

**SHUT** _ _ _ _ _ _ _ _ _ _ _ _ **command**

The *shut* command closes output files.

*shut*<filename>{,<filename>}*

<filename> must have been a file opened by out.

A file that has been opened by
out must be *shut* before it is
brought in by
in. Files that have been opened by *out
* should
always be *shut* before the end of the REDUCE session, to avoid either
loss of information or the printing of extraneous information into the file.
In most systems, terminating a session by
bye closes all open
output files.

**Input and Output**

**ACOS** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *acos* operator returns the arccosine of its argument.

<expression> may be any scalar REDUCE expression, not an array, matrix or vector expression. <simple\_expression> must be a single identifier or begin with a prefix operator name.

acos(ab); ACOS(AB) acos 15; ACOS(15) df(acos(x*y),x); 2 2 SQRT( - X *Y + 1)*Y -------------------- 2 2 X *Y - 1 on rounded; res := acos(sqrt(2)/2); RES := 0.785398163397 res-pi/4; 0

An explicit numeric value is not given unless the switch rounded is on and the argument has an absolute numeric value less than or equal to 1.

**ACOSH** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

*acosh*represents the hyperbolic arccosine of its argument. It takes
an arbitrary scalar expression as its argument. The derivative of
*acosh* is known to the system. Numerical values may also be found by
turning on the switch
rounded.

<expression> may be any scalar REDUCE expression, not an array, matrix or vector expression. <simple\_expression> must be a single identifier or begin with a prefix operator name.

acosh a; ACOSH(A) acosh(0); ACOSH(0) df(acosh(a**2),a); 4 2*SQRT(A - 1)*A ---------------- 4 A - 1 int(acosh(x),x); INT(ACOSH(X),X)

You may attach functionality by defining *acosh* to be the
inverse of
*cosh*. This is done by the commands

put('cosh,'inverse,'acosh); put('acosh,'inverse,'cosh);

You can write a procedure to attach integrals or other
functions to *acosh*. You may wish to add a check to see that its
argument is properly restricted.

**ACOT** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

*acot*represents the arccotangent of its argument. It takes
an arbitrary scalar expression as its argument. The derivative of
*acot* is known to the system. Numerical values may also be found by
turning on the switch
rounded.

<expression> may be any scalar REDUCE expression, not an array, matrix or
vector expression. <simple\_expression> must be a single identifier or
begin with a prefix operator name.
You can add functionality yourself with *let* and procedures.

**ACOTH** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

*acoth*represents the inverse hyperbolic cotangent of its argument.
It takes an arbitrary scalar expression as its argument. The derivative
of *acoth* is known to the system. Numerical values may also be found
by turning on the switch
rounded.

<expression> may be any scalar REDUCE expression, not an array,
matrix or vector expression. <simple\_expression> must be a single
identifier or begin with a prefix operator name. You can add
functionality yourself with *let* and procedures.

**ACSC** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *acsc* operator returns the arccosecant of its argument.

<expression> may be any scalar REDUCE expression, not an array, matrix or vector expression. <simple\_expression> must be a single identifier or begin with a prefix operator name.

acsc(ab); ACSC(AB) acsc 15; ACSC(15) df(acsc(x*y),x); 2 2 -SQRT(X *Y - 1) ---------------- 2 2 X*(X *Y - 1) on rounded; res := acsc(2/sqrt(3)); RES := 1.0471975512 res-pi/3; 0

An explicit numeric value is not given unless the switch *round
ed* is
on and the argument has an absolute numeric value less than or equal to 1.

**ACSCH** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *acsch* operator returns the hyperbolic arccosecant of its argument.

acsch(ab); ACSCH(AB) acsch 15; ACSCH(15) df(acsch(x*y),x); 2 2 -SQRT(X *Y + 1) ---------------- 2 2 X*(X *Y + 1) on rounded; res := acsch(3); RES := 0.327450150237

An explicit numeric value is not given unless the switch *round
ed* is
on and the argument has an absolute numeric value less than or equal to 1.

**ASEC** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *asec* operator returns the arccosecant of its argument.

asec(ab); ASEC(AB) asec 15; ASEC(15) df(asec(x*y),x); 2 2 SQRT(X *Y - 1) --------------- 2 2 X*(X *Y - 1) on rounded; res := asec sqrt(2); RES := 0.785398163397 res-pi/4; 0

An explicit numeric value is not given unless the switch *round
ed* is
on and the argument has an absolute numeric value greater or equal to 1.

**ASECH** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

*asech*represents the hyperbolic arccosecant of its argument. It takes
an arbitrary scalar expression as its argument. The derivative of
*asech* is known to the system. Numerical values may also be found by
turning on the switch
rounded.

asech a; ASECH(A) asech(1); 0 df(acosh(a**2),a); 4 2*SQRT(- A + 1) ---------------- 4 A*(A - 1) int(asech(x),x); INT(ASECH(X),X)

You may attach functionality by defining *asech* to be the
inverse of
*sech*. This is done by the commands

put('sech,'inverse,'asech); put('asech,'inverse,'sech);

You can write a procedure to attach integrals or other
functions to *asech*. You may wish to add a check to see that its
argument is properly restricted.

**ASIN** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *asin* operator returns the arcsine of its argument.

asin(givenangle); ASIN(GIVENANGLE) asin(5); ASIN(5) df(asin(2*x),x); 2 2*SQRT( - 4*X + 1)) - -------------------- 2 4*X - 1 on rounded; asin .5; 0.523598775598 asin(sqrt(3)); ASIN(1.73205080757) asin(sqrt(3)/2); 1.04719755120

A numeric value is not returned by *asin* unless the switch
*rounded* is on and its argument has an absolute value less than or
equal to 1.

**ASINH** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *asinh* operator returns the hyperbolic arcsine of its argument.
The derivative of *asinh* and some simple transformations are known
to the system.

asinh d; ASINH(D) asinh(1); ASINH(1) df(asinh(2*x),x); 2 2*SQRT(4*X + 1)) ----------------- 2 4*X + 1

You may attach further functionality by defining *asinh* to
be the
inverse of *sinh*. This is done by the commands

put('sinh,'inverse,'asinh); put('asinh,'inverse,'sinh);

A numeric value is not returned by *asinh* unless the switch
*rounded* is on and its argument evaluates to a number.

**ATAN** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *atan* operator returns the arctangent of its argument.

atan(middle); ATAN(MIDDLE) on rounded; atan 45; 1.54857776147 off rounded; int(atan(x),x); 2 2*ATAN(X)*X - LOG(X + 1) ------------------------- 2 df(atan(y**2),y); 2*Y ------- 4 Y + 1

A numeric value is not returned by *atan* unless the switch
rounded is on and its argument evaluates to a
number.

**ATANH** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *atanh* operator returns the hyperbolic arctangent of its argument.
The derivative of *asinh* and some simple transformations are known
to the system.

atanh aa; ATANH(AA) atanh(1); ATANH(1) df(atanh(x*y),y); - X ---------- 2 2 X *Y - 1

A numeric value is not returned by *asinh* unless the switc
h
*rounded* is on and its argument evaluates to a number.
You may attach additional functionality by defining *atanh* to be the
inverse of *tanh*. This is done by the commands

put('tanh,'inverse,'atanh); put('atanh,'inverse,'tanh);

**ATAN2** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

<expression> is any valid scalar REDUCE expression. In
rounded mode, if a numerical value exists,
*atan2* returns
the principal value of the arc tangent of the second argument divided by
the first in the range [-pi,+pi] radians, using the signs of both
arguments to determine the quadrant of the return value. An expression in
terms of *atan2* is returned in other cases.

atan2(3,2); ATAN2(3,2); on rounded; atan2(3,2); 0.982793723247 atan2(a,b); ATAN2(A,B); atan2(1,0); 1.57079632679

*atan2*returns a numeric value only if
rounded is on. Then
*atan2* is calculated to the current degree of floating point precision.

**COS** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *cos* operator returns the cosine of its argument.

<expression> is any valid scalar REDUCE expression, <simple\_expression> is a single identifier or begins with a prefix operator name.

cos abc; COS(ABC) cos(pi); -1 cos 4; COS(4) on rounded; cos(4); - 0.653643620864 cos log 5; - 0.0386319699339

*cos*returns a numeric value only if
rounded is on. Then the
cosine is calculated to the current degree of floating point precision.