Communicating with Algebraic Mode
Date: 2020-10-07 18:10:00

Up | Next | Prev | PrevTail | Tail

### 17.9 Communicating with Algebraic Mode

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 deﬁned in the basic system source code, or reﬁne their algebraic code deﬁnitions to make them more eﬃcient, 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: preﬁx form, which follow the normal Lisp rules of function composition, and so-called canonical form, which uses a completely diﬀerent 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 identiﬁers 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.

#### 17.9.1 Passing Algebraic Mode Values to 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 preﬁx form with the syntax:

(*SQ <standard quotient> T)

This particular format reﬂects the fact that the algebraic mode processor currently likes to transfer preﬁx forms from command to command, but doesn’t like to reconvert standard forms (which represent polynomials) and standard quotients back to a true Lisp preﬁx 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 preﬁx form which is really a standard quotient and the second argument (T or NIL) tells it whether it needs further processing (essentially, an already simpliﬁed ﬂag).

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 deﬁned are as follows:

REDUCE Selectors

  DENR | denominator of standard quotient
  LC | leading coeﬃcient 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 | coeﬃcient 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 coeﬃcient to produce term
  .^ | raise a variable to a power

For example, to ﬁnd the numerator of the standard quotient above, one could say:

numr z;

or to ﬁnd the leading term of the numerator:

lt numr z;

Conversion between various data structures is facilitated by the use of a set of functions deﬁned 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;
!*P2F | convert a standard power 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.

#### 17.9.2 Passing Symbolic Mode Values to Algebraic Mode

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 preﬁx 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:

1. If it is a standard quotient, call PREPSQ on it. This takes a standard quotient as argument, and returns a preﬁx expression. Alternatively, you can call MK!*SQ on it, which returns a preﬁx form like (*SQ ⟨standard quotient⟩ T) and avoids translation of the expression into a true preﬁx form.
2. If it is a standard form, call PREPF on it. This takes a standard form as argument, and returns the equivalent preﬁx expression. Alternatively, you can convert it to a standard quotient and then call MK!*SQ.
3. If it is a part of a standard form, you must usually ﬁrst build up a standard form out of it, and then go to step 2. The conversion functions described earlier may be used for this purpose. For example,
   1. If Z is an expression which is a term, !*T2F Z is a standard form.
   2. If Z is a standard power, !*P2F Z is a standard form.
   3. If Z is a variable, you can pass it direct to algebraic mode.

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.

#### 17.9.3 Complete Example

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
% numerataor 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

#### 17.9.4 Deﬁning Procedures for Intermode Communication

If one wishes to deﬁne 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 eﬀect in algebraic mode is diﬀerent. The value of such a procedure must be a preﬁx form.

The algebraic processor will pass arguments to such procedures in preﬁx form. Therefore if you want to work with the arguments as standard quotients you must ﬁrst convert them to that form by using the function SIMP!*. This function takes a preﬁx form as argument and returns the evaluated standard quotient.

For example, if you want to deﬁne a procedure LEADTERM which gives the leading term of an algebraic expression, one could do this as follows:

symbolic operator leadterm; % Declare LEADTERM as a symbolic
% mode procedure to be used in
% algebraic mode.
symbolic procedure leadterm u; % Define LEADTERM.
mk!*sq !*t2q lt numr simp!* u;

Note that this operator has a diﬀerent eﬀect 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 deﬁnition, the function REVAL can be used. The one argument of REVAL must be the preﬁx form of an expression. REVAL returns the evaluated expression as a true Lisp preﬁx form.

Up | Next | Prev | PrevTail | Front