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;