Origin for each line in Lesson_7.red from check-in f2c04ccdad:

f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT
f2c04ccdad 2021-03-03 trnsz@pobox.c:  
f2c04ccdad 2021-03-03 trnsz@pobox.c:                   REDUCE INTERACTIVE LESSON NUMBER 7
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:                          David R. Stoutemyer
f2c04ccdad 2021-03-03 trnsz@pobox.c:                          University of Hawaii
f2c04ccdad 2021-03-03 trnsz@pobox.c:  
f2c04ccdad 2021-03-03 trnsz@pobox.c:  
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT This is lesson 7 of 7 REDUCE lessons.  Sometimes it is desired
f2c04ccdad 2021-03-03 trnsz@pobox.c: to have a certain facility available to algebraic mode, no such
f2c04ccdad 2021-03-03 trnsz@pobox.c: facility is described in the REDUCE User's Manual, and there is no
f2c04ccdad 2021-03-03 trnsz@pobox.c: easy way to implement the facility directly in algebraic mode.  The
f2c04ccdad 2021-03-03 trnsz@pobox.c: possibilities are:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  The facility exists for algebraic mode, but is undocumented.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  The facility exists, but is available only in symbolic mode.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    3.  The facility is not built-in for either mode.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Perusal of the REDUCE source code (see
f2c04ccdad 2021-03-03 trnsz@pobox.c: https://sourceforge.net/p/reduce-algebra/code/HEAD/tree/trunk/packages/
f2c04ccdad 2021-03-03 trnsz@pobox.c: -- alg contains the core algebra facilities), together with
f2c04ccdad 2021-03-03 trnsz@pobox.c: experimentation can reveal which of these alternatives is true.  (Even
f2c04ccdad 2021-03-03 trnsz@pobox.c: in case 3, an inquiry via the REDUCE Project Forum or Mailing List --
f2c04ccdad 2021-03-03 trnsz@pobox.c: see https://sourceforge.net/projects/reduce-algebra/support -- may
f2c04ccdad 2021-03-03 trnsz@pobox.c: reveal that someone else has already implemented the supplementary
f2c04ccdad 2021-03-03 trnsz@pobox.c: facility and can provide the code.);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT A type of statement is available to both modes if its leading
f2c04ccdad 2021-03-03 trnsz@pobox.c: keyword appears in either of the equivalent statements
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       PUT (..., 'STAT, ...)
f2c04ccdad 2021-03-03 trnsz@pobox.c: or
f2c04ccdad 2021-03-03 trnsz@pobox.c:       DEFLIST('(...), 'STAT).
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: A symbolic-mode global variable is available to algebraic mode and
f2c04ccdad 2021-03-03 trnsz@pobox.c: vice-versa if the name of the variable appears in either of the
f2c04ccdad 2021-03-03 trnsz@pobox.c: equivalent statements
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       SHARE ...,
f2c04ccdad 2021-03-03 trnsz@pobox.c: or
f2c04ccdad 2021-03-03 trnsz@pobox.c:       FLAG('(...), 'SHARE).
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: A function defined in symbolic mode is directly available to algebraic
f2c04ccdad 2021-03-03 trnsz@pobox.c: mode if the function name appears in one of the statements
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       SYMBOLIC OPERATOR ...,
f2c04ccdad 2021-03-03 trnsz@pobox.c:       PUT(..., 'SIMPFN, ...),
f2c04ccdad 2021-03-03 trnsz@pobox.c:       DEFLIST('(...), 'SIMPFN),
f2c04ccdad 2021-03-03 trnsz@pobox.c:       FLAG('(...), 'OPFN).
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: In addition, if you want a function to be used as a predicate in IF or
f2c04ccdad 2021-03-03 trnsz@pobox.c: WHILE statements, it should be flagged BOOLEAN, as in
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       FLAG('(...), 'BOOLEAN);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Other functions which are used but not defined in RLISP are
f2c04ccdad 2021-03-03 trnsz@pobox.c: the built-in LISP functions.  See a description of the underlying LISP
f2c04ccdad 2021-03-03 trnsz@pobox.c: system (normally either PSL or CSL) for documentation on these
f2c04ccdad 2021-03-03 trnsz@pobox.c: functions.  All Standard Lisp functions should be available.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Particularly notable built-in features available only to symbolic mode
f2c04ccdad 2021-03-03 trnsz@pobox.c: include
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  A function named SPACES, which outputs the number of blanks
f2c04ccdad 2021-03-03 trnsz@pobox.c:        indicated by its integer argument.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  A function named REDERR, which provokes an error interrupt
f2c04ccdad 2021-03-03 trnsz@pobox.c:        after outputting its arguments.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    3.  A predicate named KERNP, which returns NIL if its argument
f2c04ccdad 2021-03-03 trnsz@pobox.c:        is not an indeterminate or a functional form.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    4.  A function named MATHPRINT, which outputs its argument in
f2c04ccdad 2021-03-03 trnsz@pobox.c:        natural mathematical notation, beginning on a new line.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    5.  A function named MAPRIN, which is like MATHPRINT, but does not
f2c04ccdad 2021-03-03 trnsz@pobox.c:        automatically start or end a new line.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    6.  A function named TERPRI!*, which ends the current output-line.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Thus, for example, all that we have to do to make the predicate KERNP
f2c04ccdad 2021-03-03 trnsz@pobox.c: and the function SPACES available to algebraic mode is to type
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       FLAG('(KERNP), 'BOOLEAN),
f2c04ccdad 2021-03-03 trnsz@pobox.c:       SYMBOLIC OPERATOR SPACES.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: When such simple remedies are unavailable, we can introduce our own
f2c04ccdad 2021-03-03 trnsz@pobox.c: statements or write our own SYMBOLIC-mode variables and procedures,
f2c04ccdad 2021-03-03 trnsz@pobox.c: then use these techniques to make them available to algebraic mode.
f2c04ccdad 2021-03-03 trnsz@pobox.c: In order to do so, it is usually necessary to understand how REDUCE
f2c04ccdad 2021-03-03 trnsz@pobox.c: represents and simplifies algebraic expressions.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT One of the REDUCE representations is called Cambridge Prefix.
f2c04ccdad 2021-03-03 trnsz@pobox.c: An expression is either an atom or a list consisting of a literal
f2c04ccdad 2021-03-03 trnsz@pobox.c: atom, denoting a function or operator name, followed by arguments
f2c04ccdad 2021-03-03 trnsz@pobox.c: which are Cambridge Prefix expressions.  The most common unary
f2c04ccdad 2021-03-03 trnsz@pobox.c: operator names are MINUS, LOG, SIN, and COS.  The most common binary
f2c04ccdad 2021-03-03 trnsz@pobox.c: operator names are DIFFERENCE, QUOTIENT, and EXPT.  The most common
f2c04ccdad 2021-03-03 trnsz@pobox.c: nary operator names are PLUS and TIMES.  Thus, for example, the
f2c04ccdad 2021-03-03 trnsz@pobox.c: expression
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       3*x^2*y + x^(1/2) + e^(-x)
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: could be represented as
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: '(PLUS (TIMES 3 (EXPT X 2) Y) (EXPT X (QUOTIENT 1 2)) (EXPT E (MINUS X))
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: The parser produces an unsimplified Cambridge Prefix version of
f2c04ccdad 2021-03-03 trnsz@pobox.c: algebraic-mode expressions typed by the user, then the simplifier
f2c04ccdad 2021-03-03 trnsz@pobox.c: returns a simplified prefix version.  When a symbolic procedure that
f2c04ccdad 2021-03-03 trnsz@pobox.c: has been declared a symbolic operator is invoked from algebraic mode,
f2c04ccdad 2021-03-03 trnsz@pobox.c: the procedure is given simplified Cambridge Prefix versions of the
f2c04ccdad 2021-03-03 trnsz@pobox.c: arguments.  To illustrate these ideas, here is an infix function named
f2c04ccdad 2021-03-03 trnsz@pobox.c: ISFREEOF, which determines whether its left argument is free of the
f2c04ccdad 2021-03-03 trnsz@pobox.c: indeterminate, function name, or literal sub-expression which is the
f2c04ccdad 2021-03-03 trnsz@pobox.c: right argument.  ISFREEOF is similar to the REDUCE FREEOF function but
f2c04ccdad 2021-03-03 trnsz@pobox.c: less general.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: flag('(isfreeof), 'boolean);
f2c04ccdad 2021-03-03 trnsz@pobox.c: infix isfreeof;
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure campre1 isfreeof campre2;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if campre1=campre2 then nil
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else if atom campre1 then t
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else (car campre1 isfreeof campre2)
f2c04ccdad 2021-03-03 trnsz@pobox.c:       and (cdr campre1 isfreeof campre2);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: algebraic if log(5+x+cos(y)) isfreeof sin(z-7)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    then write "WORKS ONE WAY";
f2c04ccdad 2021-03-03 trnsz@pobox.c: algebraic if not(log(5+x+cos(y)) isfreeof cos(y))
f2c04ccdad 2021-03-03 trnsz@pobox.c:    then write "WORKS OTHER WAY TOO";
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Conceivably we might wish to distinguish when CAMPRE2 is a
f2c04ccdad 2021-03-03 trnsz@pobox.c: literal atom occurring as a function name from the case when CAMPRE2
f2c04ccdad 2021-03-03 trnsz@pobox.c: is a literal atom and occurs as an indeterminate.  Accordingly, see if
f2c04ccdad 2021-03-03 trnsz@pobox.c: you can write two such more specialized infix predicates named
f2c04ccdad 2021-03-03 trnsz@pobox.c: ISFREEOFINDET and ISFREEOFFUNCTION.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT When writing a symbolic-mode function, it is often desired to
f2c04ccdad 2021-03-03 trnsz@pobox.c: invoke the algebraic simplifier from within the function.  This can be
f2c04ccdad 2021-03-03 trnsz@pobox.c: done by using the function named REVAL, which returns a simplified
f2c04ccdad 2021-03-03 trnsz@pobox.c: Cambridge Prefix version of its prefix argument.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Usually, REDUCE uses and produces a different representation, which I
f2c04ccdad 2021-03-03 trnsz@pobox.c: call REDUCE prefix.  The symbolic function AEVAL returns a simplified
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE-prefix version of its prefix argument.  Both REVAL and AEVAL
f2c04ccdad 2021-03-03 trnsz@pobox.c: can take either type of prefix argument.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: A REDUCE-prefix expression is an integer, a floating-point number, an
f2c04ccdad 2021-03-03 trnsz@pobox.c: indeterminate, or an expression of the form
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       ('!*SQ standardquotient . !*SQVAR!*).
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: !*SQVAR!* is a global variable which is set to T when the REDUCE-
f2c04ccdad 2021-03-03 trnsz@pobox.c: prefix expression is originally formed.  The value of !*SQVAR!* is
f2c04ccdad 2021-03-03 trnsz@pobox.c: reset to NIL if subsequent LET, MATCH, or computational ON statements
f2c04ccdad 2021-03-03 trnsz@pobox.c: could change the environment is such a way that the expression might
f2c04ccdad 2021-03-03 trnsz@pobox.c: require resimplification next time it is used.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Standard quotients are neither Cambridge nor REDUCE prefix, so
f2c04ccdad 2021-03-03 trnsz@pobox.c: the purpose of the atom '!*SQ is to make the value of all algebraic-
f2c04ccdad 2021-03-03 trnsz@pobox.c: mode variables always be some type of prefix form at the top level.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: A standard quotient is a unit-normal dotted pair of 2 standard forms,
f2c04ccdad 2021-03-03 trnsz@pobox.c: and a standard form is the REDUCE representation for a polynomial.
f2c04ccdad 2021-03-03 trnsz@pobox.c: Unit-normal means that the leading coefficient of the denominator is
f2c04ccdad 2021-03-03 trnsz@pobox.c: positive.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE has a built-in symbolic function SIMP!*, which returns the
f2c04ccdad 2021-03-03 trnsz@pobox.c: simplified standard quotient representation of its argument, which can
f2c04ccdad 2021-03-03 trnsz@pobox.c: be either Cambridge or REDUCE prefix.  REDUCE also has symbolic
f2c04ccdad 2021-03-03 trnsz@pobox.c: functions named NEGSQ, INVSQ, ADDSQ, MULTSQ, DIVSQ, DIFFSQ, and
f2c04ccdad 2021-03-03 trnsz@pobox.c: CANONSQ which respectively negate, reciprocate, add, multiply, divide,
f2c04ccdad 2021-03-03 trnsz@pobox.c: differentiate, and unit-normalize standard quotients.  There is also a
f2c04ccdad 2021-03-03 trnsz@pobox.c: function named ABSQ, which negates a standard quotient if the leading
f2c04ccdad 2021-03-03 trnsz@pobox.c: coefficient of its numerator is negative, and there is a function
f2c04ccdad 2021-03-03 trnsz@pobox.c: named EXPTSQ which raises a standard quotient to an integer power.
f2c04ccdad 2021-03-03 trnsz@pobox.c: Finally, there is a function named MK!*SQ, which returns a REDUCE
f2c04ccdad 2021-03-03 trnsz@pobox.c: prefix version of its standard-quotient argument, and there is also a
f2c04ccdad 2021-03-03 trnsz@pobox.c: function named PREPSQ which returns a Cambridge prefix version of its
f2c04ccdad 2021-03-03 trnsz@pobox.c: standard-quotient argument.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: If there is a sequence of operations, rather than converting from
f2c04ccdad 2021-03-03 trnsz@pobox.c: prefix to standard quotient and back at each step, it is usually more
f2c04ccdad 2021-03-03 trnsz@pobox.c: efficient to do the operations on standard quotients, then use MK!*SQ
f2c04ccdad 2021-03-03 trnsz@pobox.c: to make the final result be REDUCE prefix.  Also it is often more
f2c04ccdad 2021-03-03 trnsz@pobox.c: efficient to work with polynomials rather than rational functions
f2c04ccdad 2021-03-03 trnsz@pobox.c: during the intermediate steps.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT The coefficient domain of polynomials is floating-point
f2c04ccdad 2021-03-03 trnsz@pobox.c: numbers, integers, integers modulo an arbitrary integer modulus, or
f2c04ccdad 2021-03-03 trnsz@pobox.c: rational numbers.  However, zero is represented as NIL.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: The polynomial variables are called kernels, which can be
f2c04ccdad 2021-03-03 trnsz@pobox.c: indeterminates or uniquely-stored fully simplified Cambridge-prefix
f2c04ccdad 2021-03-03 trnsz@pobox.c: functional forms.  The latter alternative permits the representation
f2c04ccdad 2021-03-03 trnsz@pobox.c: of expressions which could not otherwise be represented as the ratio
f2c04ccdad 2021-03-03 trnsz@pobox.c: of two expanded polynomials, such as
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  sub-expressions of the form LOG(...) or SIN(...),
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  sub-expressions of the form indeterminate^noninteger,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    3.  unexpanded polynomials, each polynomial factor being
f2c04ccdad 2021-03-03 trnsz@pobox.c:        represented as a functional form,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    4.  rational expressions not placed over a common denominator,
f2c04ccdad 2021-03-03 trnsz@pobox.c:        each quotient sub-expression being represented as a functional
f2c04ccdad 2021-03-03 trnsz@pobox.c:        form.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: A polynomial is represented as a list of its nonzero terms in
f2c04ccdad 2021-03-03 trnsz@pobox.c: decreasing order of the degree of the leading "variable".  Each term
f2c04ccdad 2021-03-03 trnsz@pobox.c: is represented as a standard power dotted with its coefficient, which
f2c04ccdad 2021-03-03 trnsz@pobox.c: is a standard form in the remaining variables.  A standard power is
f2c04ccdad 2021-03-03 trnsz@pobox.c: represented as a variable dotted with a positive integer degree.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Letting ::= denote "is defined as" and letting | denote "or",
f2c04ccdad 2021-03-03 trnsz@pobox.c: we can summarize the REDUCE data representations as follows:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    reduceprefix ::= ('!*SQ standardquotient . !*SQVAR!*)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    standardquotient ::= NUMR(standardquotient) ./
f2c04ccdad 2021-03-03 trnsz@pobox.c:                                DENR(standardquotient)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    NUMR(standardquotient) ::= standardform
f2c04ccdad 2021-03-03 trnsz@pobox.c:    DENR(standardquotient) ::= unitnormalstandardform
f2c04ccdad 2021-03-03 trnsz@pobox.c:    domainelement ::= NIL | nonzerointeger | nonzerofloat |
f2c04ccdad 2021-03-03 trnsz@pobox.c:                      nonzerointeger . positiveinteger
f2c04ccdad 2021-03-03 trnsz@pobox.c:    standardform ::= domainelement |
f2c04ccdad 2021-03-03 trnsz@pobox.c:                     LT(standardform) .+ RED(standardform)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    RED(standardform) ::= standardform
f2c04ccdad 2021-03-03 trnsz@pobox.c:    LT(standardform) := LPOW(standardform) .* LC(standardform)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    LPOW(standardform) := MVAR(standardform) .^ LDEG(standardform)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    LC(standardform) ::= standardform
f2c04ccdad 2021-03-03 trnsz@pobox.c:    MVAR(standardform) ::= kernel
f2c04ccdad 2021-03-03 trnsz@pobox.c:    kernel ::= indeterminate | functionalform
f2c04ccdad 2021-03-03 trnsz@pobox.c:    functionalform ::= (functionname Cambridgeprefix1 Cambridgeprefix2
f2c04ccdad 2021-03-03 trnsz@pobox.c:                        ...)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    Cambridgeprefix ::= integer | float | indeterminate |
f2c04ccdad 2021-03-03 trnsz@pobox.c:                           functionalform
f2c04ccdad 2021-03-03 trnsz@pobox.c:    LC(unitnormalstandardform) ::= positivedomainelement |
f2c04ccdad 2021-03-03 trnsz@pobox.c:                                  unitnormalstandardform
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: I have taken this opportunity to also introduce the major REDUCE
f2c04ccdad 2021-03-03 trnsz@pobox.c: selector macros named NUMR, DENR, LT, RED, LPOW, LC, MVAR, and LDEG,
f2c04ccdad 2021-03-03 trnsz@pobox.c: together with the major constructor macros named ./, .+, .*, and .^ .
f2c04ccdad 2021-03-03 trnsz@pobox.c: The latter are just mnemonic aliases for ".".  A comparison of my
f2c04ccdad 2021-03-03 trnsz@pobox.c: verbal and more formal definitions also reveals that the selectors are
f2c04ccdad 2021-03-03 trnsz@pobox.c: respectively just aliases for CAR, CDR, CAR, CDR, CAAR, CDAR, CAAAR,
f2c04ccdad 2021-03-03 trnsz@pobox.c: and CDAAR.  Since these selectors and constructors are macros rather
f2c04ccdad 2021-03-03 trnsz@pobox.c: than functions, they afford a more readable and modifiable programming
f2c04ccdad 2021-03-03 trnsz@pobox.c: style at no cost in ultimate efficiency.  Thus you are encouraged to
f2c04ccdad 2021-03-03 trnsz@pobox.c: use them and to invent your own when convenient.  As an example of how
f2c04ccdad 2021-03-03 trnsz@pobox.c: this can be done, here is the macro definition for extracting the main
f2c04ccdad 2021-03-03 trnsz@pobox.c: variable of a standard term:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: %   symbolic smacro procedure tvar trm; caar trm;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT It turns out that there are already built-in selectors named
f2c04ccdad 2021-03-03 trnsz@pobox.c: TC, TPOW, and TDEG, which respectively extract the coefficient,
f2c04ccdad 2021-03-03 trnsz@pobox.c: leading power, and leading degree of a standard term.  There are also
f2c04ccdad 2021-03-03 trnsz@pobox.c: built-in constructors named !*P2F, !*K2F, !*K2Q, and !*T2Q, which
f2c04ccdad 2021-03-03 trnsz@pobox.c: respectively make a power into a standard form, a kernel into a
f2c04ccdad 2021-03-03 trnsz@pobox.c: standard form, a kernel into a standard quotient, and a term into a
f2c04ccdad 2021-03-03 trnsz@pobox.c: standard quotient.  See the REDUCE User's Manual for a complete list.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: The unary functions NEGF and ABSF respectively negate, and unit-
f2c04ccdad 2021-03-03 trnsz@pobox.c: normalize their standard-form arguments.  The binary functions ADDF,
f2c04ccdad 2021-03-03 trnsz@pobox.c: MULTF, QUOTF, SUBF, EXPTF, and GCDF respectively add, multiply, divide,
f2c04ccdad 2021-03-03 trnsz@pobox.c: substitute into, raise to a positive integer power, and determine the
f2c04ccdad 2021-03-03 trnsz@pobox.c: greatest common divisor of standard forms.  See if you can use them to
f2c04ccdad 2021-03-03 trnsz@pobox.c: define a macro which subtracts standard forms.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT The best way to become adept at working with standard forms
f2c04ccdad 2021-03-03 trnsz@pobox.c: and standard quotients is to study the corresponding portions of the
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE source listing.  The listing of ADDF and its subordinates is
f2c04ccdad 2021-03-03 trnsz@pobox.c: particularly instructive.  As an exercise, see if you can write a
f2c04ccdad 2021-03-03 trnsz@pobox.c: function named ISFREEOFKERN which determines whether or not its left
f2c04ccdad 2021-03-03 trnsz@pobox.c: argument is free of the kernel which is the right argument, using
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE prefix rather than Cambridge prefix for the left argument.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT As a final example of the interaction between modes, here is a
f2c04ccdad 2021-03-03 trnsz@pobox.c: function which produces simple character-based plots.  Note that, to
f2c04ccdad 2021-03-03 trnsz@pobox.c: keep the implementation as simple as possible, values of the
f2c04ccdad 2021-03-03 trnsz@pobox.c: indeterminate ("x") increase downwards and values of the expression
f2c04ccdad 2021-03-03 trnsz@pobox.c: plotted ("y") increase to the right.  This is the conventional
f2c04ccdad 2021-03-03 trnsz@pobox.c: orientation rotated clockwise through 90 degrees!;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: share ncols;
f2c04ccdad 2021-03-03 trnsz@pobox.c: ncols := 66;
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic operator plot;
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure plot(ex, xinit, dx, ndx, yinit, dy);
f2c04ccdad 2021-03-03 trnsz@pobox.c:    begin COMMENT This procedure produces a character-plot of univariate
f2c04ccdad 2021-03-03 trnsz@pobox.c:       expression EX where,
f2c04ccdad 2021-03-03 trnsz@pobox.c:          XINIT is the initial value of the indeterminate,
f2c04ccdad 2021-03-03 trnsz@pobox.c:          DX is the increment per line of the indeterminate,
f2c04ccdad 2021-03-03 trnsz@pobox.c:          NDX is the number of lines plotted,
f2c04ccdad 2021-03-03 trnsz@pobox.c:          YINIT is the value represented at the left edge,
f2c04ccdad 2021-03-03 trnsz@pobox.c:          DY is incremental value per column.
f2c04ccdad 2021-03-03 trnsz@pobox.c:       The shared variable NCOLS, initially 66, is the number of columns
f2c04ccdad 2021-03-03 trnsz@pobox.c:       used.  Points are plotted using "*", except "<" and ">" are used
f2c04ccdad 2021-03-03 trnsz@pobox.c:       at the left and right edges to indicate out of bounds points.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    scalar x, f, y;  integer col, ncolsminus1;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    ncolsminus1 := ncols - 1;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    write "Starting the plot of ",ex;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    x := listofvars ex;          % find indeterminates;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if length x > 1 then rederr
f2c04ccdad 2021-03-03 trnsz@pobox.c:      "ERROR: PLOT expression can have at most 1 indeterminate";
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if null x then <<
f2c04ccdad 2021-03-03 trnsz@pobox.c:       write "ERROR: no indeterminates in ", ex;
f2c04ccdad 2021-03-03 trnsz@pobox.c:       rederr "" >>
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else x := car x;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    write " in variable ", x;  terpri();
f2c04ccdad 2021-03-03 trnsz@pobox.c:    COMMENT Convert args from algebraic to symbolic values;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    xinit := revalx xinit;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    dx := revalx dx;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    yinit := revalx yinit;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    dy := revalx dy;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    for j:= 0:ndx do <<
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       % generate expression with current value substituted for x
f2c04ccdad 2021-03-03 trnsz@pobox.c:       f := subst(xinit + j*dx, x, ex);
f2c04ccdad 2021-03-03 trnsz@pobox.c:       y := eval(f);                      % eval expression
f2c04ccdad 2021-03-03 trnsz@pobox.c:       col := rnd((y - yinit)/dy);        % scale and round for cols
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:       if col<0 then write "<"
f2c04ccdad 2021-03-03 trnsz@pobox.c:       else if col > ncolsminus1 then << spaces(ncolsminus1);
f2c04ccdad 2021-03-03 trnsz@pobox.c:          prin2 ">";
f2c04ccdad 2021-03-03 trnsz@pobox.c:          terpri() >>
f2c04ccdad 2021-03-03 trnsz@pobox.c:       else << spaces(col);
f2c04ccdad 2021-03-03 trnsz@pobox.c:          prin2 "*";
f2c04ccdad 2021-03-03 trnsz@pobox.c:          terpri() >>
f2c04ccdad 2021-03-03 trnsz@pobox.c:       >> ;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if null y then rederr
f2c04ccdad 2021-03-03 trnsz@pobox.c:      "ERROR: UNABLE TO PERFORM FLOATING-POINT EVALUATION OF 1ST ARG"
f2c04ccdad 2021-03-03 trnsz@pobox.c:    end;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure listofvars campre;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if null campre or numberp campre then nil
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else if atom campre then list campre
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else varsinargs cdr campre;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure varsinargs listofcampre;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if null listofcampre then nil
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else union(listofvars car listofcampre, varsinargs cdr listofcampre);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure rnd x;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    begin scalar ans;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    ans := revalx x;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if not numberp x then redderr "RND GIVEN NON-NUMERIC ARGUMENT";
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if ans >=0 then ans := fix(ans+00.5)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    else ans:= fix(ans-0.5);
f2c04ccdad 2021-03-03 trnsz@pobox.c:    return ans
f2c04ccdad 2021-03-03 trnsz@pobox.c:    end;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure revalx u;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    % MAKE SURE WE GET TRUE FLOATS IN SYMBOLIC MODE.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if eqcar(u,'!:rd!:) then rdprepx u else u;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: symbolic procedure rdprepx u;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    if floatp cdr u then cdr u else bf2flr u;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: on rounded;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: plot(y^2,     0, 0.25, 10, 0, 0.25);
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: plot((a+1)^2, 0, 0.25, 10, 0, 0.25);
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: b := a*2;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: plot(a*b,     0, 0.25, 10, 0, 0.25);
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT We leave it as an exercise to write a more elaborate plot
f2c04ccdad 2021-03-03 trnsz@pobox.c: procedure which offers amenities such as automatic scaling, numbered
f2c04ccdad 2021-03-03 trnsz@pobox.c: ordinates, etc.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Good luck with these exercises, with REDUCE, with computer algebra and
f2c04ccdad 2021-03-03 trnsz@pobox.c: with all of your endeavors.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: ;end;

iCAS Bundled REDUCE Scripts
Homepage | GitHub Mirror | SourceHut Mirror | NotABug Mirror | Chisel Mirror | Chisel RSS ]