One of the principal motivations for a user of the algebraic facilities of REDUCE to learn about symbolic mode is that it gives one access to a wider range of techniques than is possible in algebraic mode alone. For example, if a user wishes to use parts of the system defined in the basic system source code, or refine their algebraic code definitions to make them more efficient, then it is necessary to understand the source language in fairly complete detail. Moreover, it is also necessary to know a little more about the way REDUCE operates internally. Basically, REDUCE considers expressions in two forms: prefix form, which follow the normal Lisp rules of function composition, and so-called canonical form, which uses a completely different syntax.
Once these details are understood, the most critical problem faced by a user is how to make expressions and procedures communicate between symbolic and algebraic mode. The purpose of this section is to teach a user the basic principles for this.
If one wants to evaluate an expression in algebraic mode, and then use that expression in symbolic mode calculations, or vice versa, the easiest way to do this is to assign a variable to that expression whose value is easily obtainable in both modes. To facilitate this, a declaration SHARE is available. SHARE takes a list of identifiers as argument, and marks these variables as having recognizable values in both modes. The declaration may be used in either mode.
says that X and Y will receive values to be used in both modes.
If a SHARE declaration is made for a variable with a previously assigned algebraic value, that value is also made available in symbolic mode.
If one wishes to work with parts of an algebraic mode expression in symbolic mode, one simply makes an assignment of a shared variable to the relevant expression in algebraic mode. For example, if one wishes to work with (a+b)^2, one would say, in algebraic mode:
assuming that X was declared shared as above. If we now change to symbolic mode and say
its value will be printed as a prefix form with the syntax:
This particular format reflects the fact that the algebraic mode processor currently likes to transfer prefix forms from command to command, but doesn’t like to reconvert standard forms (which represent polynomials) and standard quotients back to a true Lisp prefix form for the expression (which would result in excessive computation). So *SQ is used to tell the algebraic processor that it is dealing with a prefix form which is really a standard quotient and the second argument (T or NIL) tells it whether it needs further processing (essentially, an already simplified flag).
So to get the true standard quotient form in symbolic mode, one needs CADR of the variable. E.g.,
would store in Z the standard quotient form for (a+b)^2.
Once you have this expression, you can now manipulate it as you wish. To facilitate this, a standard set of selectors and constructors are available for getting at parts of the form. Those presently defined are as follows:
denominator of standard quotient
leading coefficient of polynomial
leading degree of polynomial
leading power of polynomial
leading term of polynomial
main variable of polynomial
numerator (of standard quotient)
degree of a power
reductum of polynomial
coefficient of a term
degree of a term
power of a term
add a term to a polynomial
divide (two polynomials to get quotient)
multiply power by coefficient to produce term
raise a variable to a power
For example, to find the numerator of the standard quotient above, one could say:
or to find the leading term of the numerator:
Conversion between various data structures is facilitated by the use of a set of functions defined for this purpose. Those currently implemented include:
convert an algebraic expression to a standard form. If result is rational, an error results;
converts an algebraic expression to a kernel. If this is not possible, an error results;
converts a standard form to an algebraic expression;
convert a standard form to a standard quotient;
convert a kernel to a standard form;
convert a kernel to a standard quotient;
convert a standard power to a standard form;
convert a standard power to a standard quotient;
convert a standard quotient to a standard form. If the quotient denominator is not 1, an error results;
convert a standard quotient to a kernel. If this is not possible, an error results;
convert a standard term to a standard form
convert a standard term to a standard quotient.
In order to pass the value of a shared variable from symbolic mode to algebraic mode, the only thing to do is make sure that the value in symbolic mode is a prefix expression. E.g., one uses (expt (plus a b) 2) for (a+b)^2, or the format (*sq ⟨standard quotient⟩ t) as described above. However, if you have been working with parts of a standard form they will probably not be in this form. In that case, you can do the following:
For example, to pass the leading term of (a+b)^2 back to algebraic mode, one could say:
where Y has been declared shared as above. If you now go back to algebraic mode, you can work with Y in the usual way.
The following is the complete code for doing the above steps. The end result will be that the square of the leading term of (a + b)2 is calculated.
If one wishes to define a procedure in symbolic mode for use as an operator in algebraic mode, it is necessary to declare this fact to the system by using the declaration OPERATOR in symbolic mode. Thus
would declare the procedure LEADTERM as an algebraic operator. This declaration must be made in symbolic mode as the effect in algebraic mode is different. The value of such a procedure must be a prefix form.
The algebraic processor will pass arguments to such procedures in prefix form. Therefore if you want to work with the arguments as standard quotients you must first convert them to that form by using the function SIMP!*. This function takes a prefix form as argument and returns the evaluated standard quotient.
For example, if you want to define a procedure LEADTERM which gives the leading term of an algebraic expression, one could do this as follows:
Note that this operator has a different effect than the operator LTERM. In the latter case, the calculation is done with respect to the second argument of the operator. In the example here, we simply extract the leading term with respect to the system’s choice of main variable.
Finally, if you wish to use the algebraic evaluator on an argument in a symbolic mode definition, the function REVAL can be used. The one argument of REVAL must be the prefix form of an expression. REVAL returns the evaluated expression as a true Lisp prefix form.