less7 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. COMMENT
  2. REDUCE INTERACTIVE LESSON NUMBER 7
  3. David R. Stoutemyer
  4. University of Hawaii
  5. COMMENT This is lesson 7 of 7 REDUCE lessons. It was suggested that
  6. you bring a REDUCE source listing, together with a cross-reference
  7. (CREF) thereof, but this lesson is beneficial even without them.
  8. Sometimes it is desired to have a certain facility available to
  9. algebraic mode, no such facility is described in the REDUCE User's
  10. manual, and there is no easy way to implement the facility directly
  11. in algebraic mode. The possibilities are:
  12. 1. The facility exists for algebraic mode, but is undocumented.
  13. 2. The facility exists, but is available only in symbolic mode.
  14. 3. The facility is not built-in for either mode.
  15. Perusal of the source listing and CREF, together with experimentation
  16. can reveal which of these alternatives is true. (Even in case 3, an
  17. inquiry to A.C. Hearn at the Rand Corporation may reveal that someone
  18. else has already implemented the supplementary facility and can send a
  19. copy.)
  20. ;PAUSE;COMMENT
  21. A type of statement is available to both modes if its leading keyword
  22. appears in either of the equivalent statements
  23. PUT (..., 'STAT, ...)
  24. or
  25. DEFLIST('(...), 'STAT) .
  26. A symbolic-mode global variable is available to algebraic mode and
  27. vice-versa if the name of the variable appears in either of the
  28. equivalent statements
  29. SHARE ...,
  30. or
  31. FLAG('(...), 'SHARE) .
  32. A function defined in symbolic mode is directly available to
  33. algebraic mode if the function name appears in one of the statements
  34. SYMBOLIC OPERATOR ...,
  35. PUT(..., 'SIMPFN, ...),
  36. DEFLIST('(...), 'SIMPFN),
  37. FLAG('(...), 'OPFUN),
  38. FLAG('(...), 'DIRECT).
  39. Only in the latter case can the function be used as a predicate for
  40. use in IF or WHILE statements.
  41. ;PAUSE;COMMENT
  42. Other functions which are used but not defined in RLISP are the built-in
  43. LISP functions. See a description of the underlying LISP system for
  44. documentation on these functions.
  45. Particularly notable built-in features available only to symbolic
  46. mode include
  47. 1. A predicate named FIXP which returns NIL if its argument is
  48. not an integer, returning T otherwise.
  49. 2. A function named FIX, which returns the truncated integer
  50. portion of its floating-point argument.
  51. 3. A function named SPACES, which prints the number of blanks
  52. indicated by its integer argument.
  53. 4. A function named REDERR, which provokes an error interrupt
  54. after printing its arguments.
  55. 5. A predicate named KERNP, which returns NIL if its argument
  56. is not an indeterminate or a functional form.
  57. 6. A function named MATHPRINT, which prints its argument in
  58. natural mathematical notation, beginning on a new line.
  59. 7. A function named MAPRIN, which is like MATHPRINT, but does not
  60. automatically start or end a new line.
  61. 8. A function named TERPRI!*, which ends the current print-line.
  62. Thus, for example, all that we have to do to make the predicate
  63. FIXP and the function FIX available to algebraic mode is to type
  64. SYMBOLIC FLAG('(FIXP), 'DIRECT),
  65. SYMBOLIC OPERATOR FIX .
  66. When such simple remedies are unavailable, we can introduce our own
  67. statements or write our own SYMBOLIC-mode variables and procedures, then
  68. use these techniques to make them available to algebraic mode. In order
  69. to do so, it is usually necessary to understand how REDUCE represents
  70. and simplifies algebraic expressions.
  71. ;PAUSE;COMMENT
  72. One of the REDUCE representations is called Cambridge Prefix: An
  73. expression is either an atom or a list consisting of a literal atom,
  74. denoting a function or operator name, followed by arguments which are
  75. Cambridge Prefix expressions. The most common unary operator names are
  76. MINUS, LOG, SIN, and COS. The most common binary operator names are
  77. DIFFERENCE, QUOTIENT, and EXPT. The most common nary operator names are
  78. PLUS and TIMES. Thus, for example, the expression
  79. 3*x**2*y + x**(1/2) + e**(-x)
  80. could be represented as
  81. '(PLUS (TIMES 3 (EXPT X 2) Y) (EXPT X (QUOTIENT 1 2)) (EXPT E (MINUS X))
  82. The parser produces an unsimplified Cambridge Prefix version of
  83. algebraic-mode expressions typed by the user, then the simplifier
  84. returns a simplified prefix version. When a symbolic procedure that has
  85. been declared a symbolic operator is invoked from algebraic mode, the
  86. procedure is given simplified Cambridge Prefix versions of the
  87. arguments. To illustrate these ideas, here is an infix function named
  88. ISFREEOF, which determines whether its left argument is free of the
  89. indeterminate, function name, or literal subexpression which is the
  90. right argument. This is similar to the REDUCE FREEOF function but less
  91. general;
  92. PAUSE;COMMENT
  93. SYMBOLIC FLAG('(ISFREEOF), 'DIRECT);
  94. INFIX ISFREEOF;
  95. SYMBOLIC PROCEDURE CAMPRE1 ISFREEOF CAMPRE2;
  96. IF CAMPRE1=CAMPRE2 THEN NIL
  97. ELSE IF ATOM CAMPRE1 THEN T
  98. ELSE (CAR CAMPRE1 ISFREEOF CAMPRE2)
  99. AND (CDR CAMPRE1 ISFREEOF CAMPRE2);
  100. ALGEBRAIC IF LOG(5+X+COS(Y)) ISFREEOF SIN(Z-7)
  101. THEN WRITE "WORKS ONE WAY";
  102. ALGEBRAIC IF NOT(LOG(5+X+COS(Y)) ISFREEOF COS(Y))
  103. THEN WRITE "WORKS OTHER WAY TOO";
  104. COMMENT Conceivably we might wish to distinguish when CAMPRE2 is a
  105. literal atom occuring as a function name from the case when CAMPRE2 is a
  106. literal atom and occurs as an indeterminate. Accordingly, see if you
  107. can write two such more specialized infix predicates named ISFREEOFINDET
  108. and ISFREEOFFUNCTION;
  109. PAUSE;
  110. COMMENT When writing a symbolic-mode function, it is often desired
  111. to invoke the algebraic simplifier from within the function. This
  112. can be done by using the function named REVAL, which returns a
  113. simplified Cambridge Prefix version of its prefix argument.
  114. Usually, REDUCE uses and produces a different representation,
  115. which I call REDUCE prefix. The symbolic function AEVAL returns a
  116. simplified REDUCE-prefix version of its prefix argument. Both REVAL
  117. and AEVAL can take either type of prefix argument.
  118. A REDUCE-prefix expression is an integer, a floating-point number, an
  119. indeterminate, or an expression of the form
  120. ('!*SQ standardquotient . !*SQVAR!*).
  121. !*SQVAR!* is a global variable which is set to T when the REDUCE-
  122. prefix expression is originally formed. The values of !*SQVAR!* is
  123. reset to NIL if subsequent LET, MATCH, or computational ON
  124. statements could change the environment is such a way that the
  125. expression might require resimplification next time it is used.
  126. ;PAUSE;COMMENT
  127. Standard quotients are neither Cambridge nor REDUCE prefix, so the
  128. purpose of the atom '!*SQ is to make the value of all algebraic-mode
  129. variables always be some type of prefix form at the top level.
  130. A standard quotient is a unit-normal dotted pair of 2 standard forms,
  131. and a standard form is the REDUCE representation for a polynomial.
  132. Unit-normal means that the leading coefficient of the denominator is
  133. positive.
  134. REDUCE has a built-in symbolic function SIMP!*, which returns the
  135. simplified standard quotient representation of its argument, which can
  136. be either Cambridge or REDUCE prefix. REDUCE also has symbolic
  137. functions named NEGSQ, INVSQ, ADDSQ, MULTSQ, DIVSQ, DIFFSQ, and CANONSQ
  138. which respectively negate, reciprocate, add, multiply, divide,
  139. differentiate, and unit-normalize standard quotients. There is also a
  140. function named ABSQ, which negates a standard quotient if the leading
  141. coefficient of its numerator is negative, and there is a function named
  142. EXPTSQ which raises a standard quotient to an integer power. Finally,
  143. there is a function named MK!*SQ, which returns a REDUCE prefix version
  144. of its standard-quotient argument, and there is also a function named
  145. PREPSQ which returns a Cambridge prefix version of its standard-quotient
  146. argument.
  147. If there is a sequence of operations, rather than converting from
  148. prefix to standard quotient and back at each step, it is usually more
  149. efficient to do the operations on standard quotients, then use MK!*SQ
  150. to make the final result be REDUCE prefix. Also it is often more
  151. efficient to work with polynomials rather than rational functions
  152. during the intermediate steps.
  153. ;PAUSE;COMMENT
  154. The coefficient domain of polynomials is floating-point numbers,
  155. integers, integers modulo an arbitrary integer modulus, or rational
  156. numbers. However, zero is represented as NIL.
  157. The polynomial variables are called kernels, which can be
  158. indeterminates or uniquely-stored fully simplified Cambridge-prefix
  159. functional forms. The latter alternative permits the representation
  160. of expressions which could not otherwise be represented as the ratio
  161. of two expanded polynomials, such as
  162. 1. subexpressions of the form LOG(...) or SIN(...).
  163. 2. subexpressions of the form indeterminate**noninteger.
  164. 3. unexpanded polynomials, each polynomial factor being
  165. represented as a functional form.
  166. 4. rational expressions not placed over a common denominator,
  167. each quotient subexrpession being represented as a functional
  168. form.
  169. A polynomial is represented as a list of its nonzero terms in
  170. decreasing order of the degree of the leading "variable". Each term
  171. is represented as a standard power dotted with its coefficient, which
  172. is a standard form in the remaining variables. A standard power is
  173. represented as a variable dotted with a positive integer degree.
  174. ;PAUSE;COMMENT
  175. Letting ::= denote "is defined as" and letting | denote "or",
  176. we can summarize the REDUCE data representations as follows:
  177. reduceprefix ::= ('!*SQ standardquotient . !*SQVAR!*)
  178. standardquotient ::= NUMR(standardquotient) ./
  179. DENR(standardquotient)
  180. NUMR(standardquotient) ::= standardform
  181. DENR(standardquotient) ::= unitnormalstandardform
  182. domainelement ::= NIL | nonzerointeger | nonzerofloat |
  183. nonzerointeger . positiveinteger
  184. standardform ::= domainelement |
  185. LT(standardform) .+ RED(standardform)
  186. RED(standardform) ::= standardform
  187. LT(standardform) := LPOW(standardform) .* LC(standardform)
  188. LPOW(standardform) := MVAR(standardform) .** LDEG(standardform)
  189. LC(standardform) ::= standardform
  190. MVAR(standardform) ::= kernel
  191. kernel ::= indeterminate | functionalform
  192. functionalform ::= (functionname Cambridgeprefix1 Cambridgeprefix2
  193. ...)
  194. Cambridgeprefix ::= integer | float | indeterminate |
  195. functionalform
  196. LC(unitnormalstandardform) ::= positivedomainelement |
  197. unitnormalstandardform
  198. I have taken this opportunity to also introduce the major REDUCE
  199. selector macros named NUMR, DENR, LT, RED, LPOW, LC, MVAR, and LDEG,
  200. together with the major constructor macros named ./, .+, .*, and .** .
  201. The latter are just mnemonic aliases for "." A comparison of my verbal
  202. and more formal definitions also reveals that the selectors are
  203. respectively just aliases for CAR, CDR, CAR, CDR, CAAR, CDAR, CAAAR, and
  204. CDAAR. Since these selectors and constructors are macros rather than
  205. functions, they afford a more readable and modifiable programming style
  206. at no cost in ultimate efficiency. Thus you are encouraged to use them
  207. and to invent your own when convenient. As an example of how this can
  208. be done, here is the macro definition for extracting the main variable
  209. of a standard term;
  210. SYMBOLIC SMACRO PROCEDURE TVAR TRM; CAAR TRM;
  211. PAUSE;
  212. COMMENT It turns out that there are already built-in selectors named TC,
  213. TPOW, and TDEG, which respectively extract the coefficient, leading
  214. power, and leading degree of a standard term. There are also built-in
  215. constructors named !*P2F, !*K2F, !*K2Q, and !*T2Q, which respectively
  216. make a power into astandard form, a kernel into a standard form, a
  217. kernel into a standard quotient, and a term into a standard quotient.
  218. See the User's Manual for a complete list.
  219. The unary functions NEGF and ABSF respectively negate, and unit-
  220. normalize their standard-form arguments. The binary functions ADDF,
  221. MULTF, QUOTF, SUBF, EXPTF, and GCDF respectively add, multiply, divide,
  222. substitute into, raise to a positive integer power, and determine the
  223. greatest common divisor of standard forms. See if you can use them to
  224. define a macro which subtracts standard forms;
  225. PAUSE;
  226. COMMENT The best way to become adept at working with standard forms and
  227. standard quotients is to study the corresponding portions of the REDUCE
  228. source listing. The listing of ADDF and its subordinates is
  229. particularly instructive. As an exercise, see if you can write a
  230. function named ISFREEOFKERN which determines whether or not its left
  231. argument is free of the kernel which is the right argument, using REDUCE
  232. prefix rather than Cambridge prefix for the left argument;
  233. PAUSE;
  234. COMMENT As a final example of the interaction between modes, here
  235. is a function which produces simple print plots;
  236. SHARE NCOLSMINUS1;
  237. NCOLSMINUS1 := 66;
  238. SYMBOLIC OPERATOR PLOT;
  239. SYMBOLIC;
  240. PROCEDURE PLOT(EX, XINIT, DX, NDX, YINIT, DY);
  241. BEGIN COMMENT This procedure produces a print-plot of univariate
  242. expression EX, with its variable beginning at the number XINIT,
  243. and increasing by the number DX each line down for a total of
  244. integer NDX lines. The value of EX increases right by
  245. increments of number DY per column, beginning with the
  246. number YINIT at the left edge. The shared global variable
  247. named NCOLSMINUS1, initially 66, is 1 less
  248. than the number of columns used. Points are
  249. plotted using "*", except ">" is used at the right edge to
  250. indicate points further right, and "<" is used at the left edge to
  251. indicate points further left. Without supplementary rules, many
  252. REDUCE implementations will be unable to numerically evaluate
  253. expressions involving operations other than +, -, *, /, and
  254. integer powers;
  255. SCALAR X, FLOATSAV; INTEGER COL;
  256. FLOATSAV := !*FLOAT;
  257. ON FLOAT;
  258. X := LISTOFVARS EX;
  259. IF LENGTH X > 1 THEN REDERR
  260. "ERROR: 1st arg of PLOT can have at most 1 indeterminate";
  261. IF NULL X THEN X := !/FOO ELSE X := CAR X;
  262. X := ERRORCATCH(FOR J:= 0:NDX DO <<
  263. COL := ROUND REVAL((SUBST(X=XINIT+J*DX, EX) - YINIT)/DY);
  264. IF COL<0 THEN WRITE "<"
  265. ELSE IF COL > NCOLSMINUS1 THEN << SPACES(NCOLSMINUS1);
  266. PRINC ">";
  267. TERPRI!*() >>
  268. ELSE << SPACES(COL);
  269. PRINC "*";
  270. TERPRI!*() >> >> );
  271. IF NULL FLOATSAV THEN OFF FLOAT;
  272. IF NULL X THEN REDERR
  273. "ERROR: UNABLE TO PERFORM FLOATING-POINT EVALUATION OF 1ST ARG"
  274. END;
  275. PAUSE;
  276. SYMBOLIC PROCEDURE LISTOFVARS CAMPRE;
  277. IF NULL CAMPRE OR NUMBERP CAMPRE THEN NIL
  278. ELSE IF ATOM CAMPRE THEN CAMPRE
  279. ELSE VARSINARGS CDR CAMPRE;
  280. SYMBOLIC PROCEDURE VARSINARGS LISTOFCAMPRE;
  281. IF NULL LISTOFCAMPRE THEN NIL
  282. ELSE UNION(LISTOFVARS CAR LISTOFCAMPRE, VARSINARGS CDR LISTOFCAMPRE);
  283. INTEGER PROCEDURE ROUND X;
  284. BEGIN SCALAR ANS, FLOATSAV;
  285. FLOATSAV := !*FLOAT;
  286. ON FLOAT;
  287. ANS := REVAL X;
  288. IF NOT NUMBERP X THEN REDDERR "ROUND GIVEN NON-NUMERIC ARGUMENT";
  289. IF ANS >=0 THEN ANS := FIX(ANS+00.5)
  290. ELSE ANS:= FIX(ANS-0.5);
  291. IF NULL FLOATSAV THEN OFF FLOAT;
  292. RETURN ANS
  293. PLOT(X**2, 0, 0.025, 40, 0, 0.01);
  294. END;
  295. PAUSE;
  296. COMMENT We leave it as an exercise to write a more elaborate plot
  297. procedure which offers amenities such as automatic scaling, numbered
  298. ordinates, etc. In closing we suggest another exercise: The lack of
  299. lists together with operations of CAR, CDR, and "." are one of the major
  300. limitations of algebraic mode. Here is a start toward overcoming this
  301. limitation,. We leave the completion to you;
  302. ALGEBRAIC OPERATOR LIST;
  303. SYMBOLIC OPERATOR FIRSTT, REST, PRESERT;
  304. SYMBOLIC PROCEDURE FIRSTT LIS;
  305. IF ATOM LIS OR NOT(CAR LIS EQ 'LIST) THEN REDERR
  306. "FIRST MUST HAVE LIST ARGUMENT"
  307. ELSE CADR LIS;
  308. COMMENT Good luck with these exercises, with REDUCE, with computer
  309. algebra and with all of your endeavors.
  310. ;END;