Up | Next | Prev | PrevTail | Tail |
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.
E.g.,
share x,y;
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:
x := (a+b)^2;
assuming that x was declared shared as above. If we now change to symbolic mode and say
x;
its value will be printed as a prefix form with the syntax:
This particular format reflects the fact that the algebraic mode processor currently likes to transfer prefix forms from command to command, but doesn’t like to reconvert standard forms (which represent polynomials) and standard quotients back to a true Lisp prefix form for the expression (which would result in excessive computation). So *sq is used to tell the algebraic processor that it is dealing with a prefix form which is really a standard quotient and the second argument (t or nil) tells it whether it needs further processing (essentially, an already simplified flag).
So to get the true standard quotient form in symbolic mode, one needs cadr of the variable. E.g.,
z := cadr x;
would store in Z the standard quotient form for (a+b)^2.
Once you have this expression, you can now manipulate it as you wish. To facilitate this, a standard set of selectors and constructors are available for getting at parts of the form. Those presently defined are as follows:
REDUCE Selectors
denr | denominator of standard quotient |
lc | leading coefficient of polynomial |
ldeg | leading degree of polynomial |
lpow | leading power of polynomial |
lt | leading term of polynomial |
mvar | main variable of polynomial |
numr | numerator (of standard quotient) |
pdeg | degree of a power |
red | reductum of polynomial |
tc | coefficient of a term |
tdeg | degree of a term |
tpow | power of a term |
REDUCE Constructors
.+ | add a term to a polynomial |
./ | divide (two polynomials to get quotient) |
.* | 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:
numr z;
or to find the leading term of the numerator:
lt numr z;
Conversion between various data structures is facilitated by the use of a set of functions defined for this purpose. Those currently implemented include:
!*a2f | convert an algebraic expression to a standard form. If result is rational, an error results; |
!*a2k | converts an algebraic expression to a kernel. If this is not possible, an error results; |
!*f2a | converts a standard form to an algebraic expression; |
!*f2q | convert a standard form to a standard quotient; |
!*k2f | convert a kernel to a standard form; |
!*k2q | convert a kernel to a standard quotient; |
!*kk2f | convert a non-unique kernel to a standard form; |
!*kk2q | convert a non-unique kernel to a standard quotient; |
!*p2f | convert a standard power to a standard form; |
!*n2f | convert a number to a standard form; |
!*p2q | convert a standard power to a standard quotient; |
!*q2f | convert a standard quotient to a standard form. If the quotient denominator is not 1, an error results; |
!*q2k | convert a standard quotient to a kernel. If this is not possible, an error results; |
!*t2f | convert a standard term to a standard form |
!*t2q | convert a standard term to a standard quotient. |
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 \(\langle \)standard quotient\(\rangle \) 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:
y:= mk!*sq !*t2q lt numr z;
where y has been declared shared as above. If you now go back to algebraic mode, you can work with y in the usual way.
The following is the complete code for doing the above steps. The end result will be that the square of the leading term of \((a+b)^{2}\) is calculated.
share x,y; % declare X and Y % as shared x := (a+b)^2; % store (a+b)^2 in X symbolic; % transfer to symbolic mode z := cadr x; % store a true standard % quotient in Z lt numr z; % print the leading term % of the numerator of Z y := mk!*sq !*t2q lt numr z; % store the prefix form of % this leading term in Y algebraic; % return to algebraic mode y^2; % evaluate square of the % leading term of (a+b)^2
If one wishes to define a procedure in symbolic mode for use as an operator in algebraic mode, it is necessary to declare this fact to the system by using the declaration operator in symbolic mode. Thus
symbolic operator leadterm;
would declare the procedure leadterm as an algebraic operator. This declaration must be made in symbolic mode as the effect in algebraic mode is different. The value of such a procedure must be a prefix form.
The algebraic processor will pass arguments to such procedures in prefix form. Therefore if you want to work with the arguments as standard quotients you must first convert them to that form by using the function SIMP!*. This function takes a prefix form as argument and returns the evaluated standard quotient.
For example, if you want to define a procedure leadterm which gives the leading term of an algebraic expression, one could do this as follows:
% Declare leadterm as a symbolic mode procedure to % be used in algebraic mode. symbolic operator leadterm; % Define leadterm. symbolic procedure leadterm u; mk!*sq !*t2q lt numr simp!* u;
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.
Up | Next | Prev | PrevTail | Front |