3. David R. Stoutemyer
  4. University of Hawaii
  5. COMMENT This is lesson 5 of 7 REDUCE lessons.
  6. There are at least two good reasons for wanting to save REDUCE
  7. expression assignments on secondary storage:
  8. 1. So that one can logout, then resume computation at a later
  9. time.
  10. 2. So that needed storage space can be cleared without
  11. irrecoverably losing the values of variables which are not
  12. needed in the next expression but will be needed later.
  13. Using trivial small expressions, the following sequence illustrates
  14. how this could be done:
  15. OFF NAT,
  16. OUT TEMP,
  17. F1 := (F + G)**2,
  18. G1 := G*F1,
  19. OUT T,
  20. CLEAR F1,
  21. H1 := H*G1,
  22. OUT TEMP,
  23. CLEAR G1,
  24. H2 := F*H1,
  25. CLEAR H1,
  26. SHUT TEMP,
  27. IN TEMP,
  28. F1,
  29. ON NAT,
  30. F1 .
  31. ON NAT yields the natural output style with raised exponents, which
  32. is unsuitable for subsequent input.
  33. The OUT-statement causes subsequent output to be directed to the file
  34. named in the statement, until overridden by a different OUT-statement
  35. or until the file is closed by a SHUT-statement. File T is the
  36. terminal, and any other name designates a file on secondary storage.
  37. Such names must comply with the local file-naming conventions as well
  38. as with the REDUCE syntax. If the output is not of lasting
  39. importance, I find that including something like "TEMPORARY" or
  40. "SCRATCH" in the name helps remind me to delete it later.
  41. Successive OUT-statements to the same file will append rather than
  42. overwrite output if and only if there is no intervening SHUT-
  43. statement for that file. The SHUT-statement also has the effect of
  44. an implied OUT T.
  45. Note:
  46. 1. The generated output is the simplified expression rather than
  47. the raw form entered at the terminal.
  48. 2. Each output assignment automatically has a dollar-sign
  49. appended so that it is legal input and so that (perhaps
  50. lengthy) output will not unavoidably be generated at the
  51. terminal when the file is read in later.
  52. 3. Output cannot be sent simultaneously to 2 or more files.
  53. 4. Statements entered at the terminal which do not generate
  54. output -- such as declarations, LET rules, and procedure
  55. definitions -- do not appear in the secondary storage file.
  56. 5. One could get declarations, procedure definitions, rules, etc.
  57. written on secondary storage from the terminal by typing
  58. statements such as
  59. WRITE "
  61. ... " .
  62. This could serve as a means of generating permanent copies
  63. of LET rules, procedures, etc., but it is quite awkward
  64. compared with the usual way, which is to generate a file
  65. containing the REDUCE program by using a text editor, then
  66. load the program by using the IN-statement. If you have
  67. refrained from learning a local text editor and the operating-
  68. system file-management commands, hesitate no longer. A half
  69. dozen of the most basic commands will enable you to produce
  70. (and modify!) programs more conveniently than any other method.
  71. To keep from confusing the editor from REDUCE, I suggest that
  72. your first text-editing exercise be to create an IN file for
  73. (re)defining the function FACTORIAL(n).
  74. 5. The reason I didn't actually execute the above sequence of
  75. statements is that when the input to REDUCE comes from a batch
  76. file, both the input and output are sent to the output file,
  77. (which is convenient for producing a file containing both the
  78. input and output of a demonstration.) Consequently, you would
  79. have seen none of the statements between the "OUT TEMP" and
  80. "OUT T" as well as between the second "OUT TEMP" and the
  81. "SHUT TEMP", until the IN statement was executed. The example
  82. is confusing enough without having things scrambled from the
  83. order you would type them. To clarify all of this, I encourage
  84. you to actually execute the above sequence, with an
  85. appropriately chosen file name and using semicolons rather
  86. than commas. Afterwards, to return to the lesson, type CONT;
  87. PAUSE;
  88. COMMENT Suppose you and your colleagues developed or obtained a set
  89. of REDUCE files containing supplementary packages such as trigono-
  90. metric simplification, Laplace transforms, etc. It would be a waste
  91. of time (and perhaps paper) to have these files printed at the
  92. terminal every time they were loaded, so this printing can be
  93. suppressed by inserting the statement "OFF ECHO" at the beginning of
  94. the file, together with the statement "ON ECHO" at the end of the
  95. file.
  96. The lessons have amply demonstrated the PAUSE-statement, which is
  97. useful for insertion in batch files at the top-level or within
  98. functions when input from the user is necessary or desired.
  99. It often happens that after generating an expression, one decides
  100. that it would be convenient to use it as the body of a function
  101. definition, with one or more of the indeterminates therein as
  102. parameters. This can be done as follows (say yes to the define
  103. operator prompt);
  104. (1-(V/C)**2)**(1/2);
  106. F(5);
  107. COMMENT Here the indeterminate V became a parameter of F.
  108. Alternatively, we can save the previous expression as an indeterminate;
  109. SAVEAS FOF5;
  110. FOF5;
  111. COMMENT I find this technique more convenient than referring to the
  112. special variable WS;
  113. PAUSE;
  114. COMMENT The FOR-loop provides a convenient way to form finite sums or
  115. products with specific integer index limits. However, this need is
  116. so ubiquitous that REDUCE provides even more convenient syntax of
  117. the forms
  118. FOR index := initial STEP increment UNTIL final SUM expression,
  119. FOR index := initial STEP increment UNTIL final PRODUCT expression.
  120. As before, ":" is an acceptable abbreviation for "STEP 1 UNTIL". As
  121. an example of their use, here is a very concise definition of a
  122. function which computes Taylor-series expansions of symbolic
  123. expressions:;
  125. COMMENT This function returns the degree N Taylor-series
  126. expansion of expression EX with respect to indeterminate X,
  127. expanded about expression PT. For a series-like appearance,
  128. display the answer under the influence of FACTOR X, ON RAT,
  129. and perhaps also ON DIV;
  130. SUB(X=PT, EX) + FOR K:=1:N SUM(SUB(X=PT, DF(EX,X,K))*(X-PT)**K
  131. / FOR J:=1:K PRODUCT J);
  133. G1 := TAYLOR(E**X, X, 0, 4);
  134. G2 := TAYLOR(E**COS(X)*COS(SIN(X)), X, 0, 3);
  135. %This illustrates the Zero denominator limitation, continue anyway;
  136. TAYLOR(LOG(X), X, 0, 4);
  137. COMMENT It would, of course, be more efficient to compute each
  138. derivative and factorial from the preceding one. (Similarly for
  139. (X-PT)**K if and only if PT NEQ 0).
  140. The Fourier series expansion of our example E**COS(X)*COS(SIN(X))
  141. is 1 + cos(x) + cos(2*x)/2 + cos(3*x)/(3*2) + ... .
  142. Use the above SUM and PRODUCT features to generate the partial sum of
  143. this series through terms of order COS(6*X);
  144. PAUSE;
  145. COMMENT Closed-form solutions are often unobtainable for nontrivial
  146. problems, even using computer algebra. When this is the case,
  147. truncated symbolic series solutions are often worth trying before
  148. resorting to approximate numerical solutions.
  149. When we combine truncated series it is pointless (and worse yet,
  150. misleading) to retain terms of higher order than is justified by the
  151. constituents. For example, if we wish to multiply together the
  152. truncated series G1 and G2 generated above, there is no point in
  153. retaining terms higher than third degree in X. We can avoid even
  154. generating such terms as follows;
  155. LET X**4 = 0;
  156. G3 := G1*G2;
  157. COMMENT Replacing X**4 with 0 has the effect of also replacing all
  158. higher powers of X with 0. We could, of course, use our TAYLOR
  159. function to compute G3 directly, but differentiation is time
  160. consuming compared to truncated polynomial algebra. Moreover, our
  161. TAYLOR function requires a closed-form expression to begin with,
  162. whereas iterative techniques often permit us to construct symbolic
  163. series solutions even when we have no such closed form.
  164. Now consider the truncated series;
  166. H1 := TAYLOR(COS Y, Y, 0, 6);
  167. COMMENT Suppose we regard terms of order X**N in G1 as being
  168. comparable to terms of order Y**(2*N) in H1, and we want to form
  169. (G1*H1)**2. This can be done as follows;
  170. LET Y**7 = 0;
  171. F1 := (G1*H1)**2;
  172. COMMENT Note however that any terms of the form C*X**M*Y**N with
  173. 2*M+N > 6 are inconsistent with the accuracy of the constituent
  174. series, and we have generated several such misleading terms by
  175. independently truncating powers of X and Y. To avoid generating
  176. such junk, we can specify that a term be replaced by 0 whenever a
  177. weighted sum of exponents of specified indeterminates and functional
  178. forms exceeds a specified weight level. In our example this is done
  179. as follows;
  180. WEIGHT X=2, Y=1;
  181. WTLEVEL 6;
  182. F1 := F1;
  183. COMMENT variables not mentioned in a WEIGHT declaration have a
  184. weight of 0, and the default weight-level is 2;
  185. PAUSE;
  186. COMMENT In lesson 2 I promised to show you ways to overcome the lack
  187. in most REDUCE implementations of automatic numerical techniques
  188. for approximating fractional powers and transcendental functions of
  189. numerical values. One way is to provide a supplementary LET rule
  190. for numerical arguments. For example, since our TAYLOR function
  191. would reveal that the Taylor series for cos x is
  192. 1 - x**2/2! + x**4/4! - ...;
  194. EPSRECIP := 1024 $
  195. ON ROUNDED;
  196. WHILE 1.0 + 1.0/EPSRECIP NEQ 1.0 DO
  199. BEGIN COMMENT X is integer, real, or a rational number. This rule
  200. returns the Taylor-series approximation to COS X, truncated when
  201. the last included term is less than (1/EPSRECIP) of the returned
  202. answer. EPSRECIP is a global variable initialized to a value
  203. that is appropriate to the local floating-point precision.
  204. Arbitrarily larger values are justifiable when X is exact and
  205. ROUNDED is off. No angle reduction is performed, so this
  206. function is not recommended for ABS(X) >= about PI/2;
  208. K := 1;
  209. MXSQ := -X*X;
  210. TERM := MXSQ/2;
  211. ANS := TERM + 1;
  213. << TERM:= TERM*MXSQ/K/(K+1);
  214. ANS:= TERM + ANS;
  215. K := K+2 >>;
  217. END;
  218. COS(F) + COS(1/2);
  220. COS(1/2);
  221. COMMENT As an exercise, write a similar rule for the SIN or LOG, or
  222. replace the COS rule with an improved one which uses angle reduction
  223. so that angles outside a modest range are represented as equivalent
  224. angles within the range, before computing the Taylor series;
  225. PAUSE;
  226. COMMENT There is a REDUCE compiler, and you may wish to learn the
  227. local incantations for using it. However, even if rules such as
  228. the above ones are compiled, they will be slow compared to the
  229. implementation-dependent hand-coded ones used by most FORTRAN-like
  230. systems, so REDUCE provides a way to generate FORTRAN programs which
  231. can then be compiled and executed in a subsequent job step. This is
  232. useful when there is a lot of floating-point computation or when we
  233. wish to exploit an existing FORTRAN program. Suppose, for example,
  234. that we wish to utilize an existing FORTRAN subroutine which uses the
  235. Newton-Rapheson iteration
  236. Xnew := Xold - SUB(X=Xold, F(X)/DF(F(X),X))
  237. to attempt an approximate solution to the equation F(X)=0. Most such
  238. subroutines require the user to provide a FORTRAN function or
  239. subroutine which, given Xold, returns F(X)/DF(F(X),X) evaluated at
  240. X=Xold. If F(X) is complicated, manual symbolic derivation of
  241. DF(F(X),X) is a tedious and error-prone process. We can get
  242. REDUCE to relieve us of this responsibility as is illustrated below
  243. for the trivial example F(X) = X*E**X - 1:
  247. WRITE " REAL XOLD, F",
  248. F := XOLD*E**XOLD - 1.0,
  249. FONDF := F/DF(F,XOLD),
  250. WRITE " RETURN",
  251. WRITE " END",
  253. COMMENT Under the influence of ON FORT, the output generated by
  254. assignments is printed as valid FORTRAN assignment statements, using
  255. as many continuation lines as necessary up to the amount specified
  256. by the global variable !*CARDNO, which is initially set to 20. The
  257. output generated by an expression which is not an assignment is a
  258. corresponding assignment to a variable named ANS. In either case,
  259. expressions which would otherwise exceed !*CARDNO continuation
  260. lines are evaluated piecewise, using ANS as an intermediate variable.
  261. Try executing the above sequence, using an appropriate filename and
  262. using semicolons rather than commas at the end of the lines, then
  263. print the file after the lesson to see how it worked;
  264. PAUSE;
  266. COMMENT To make this technique usable by non-REDUCE programmers, we
  267. could write a more general REDUCE program which given merely the
  268. expression F by the user, outputs not only the function FONDF, but
  269. also any necessary Job-control commands and an appropriate main
  270. program for calling the Newton-Rapheson subroutine and printing the
  271. results.
  272. Sometimes it is desirable to modify or supplement the syntax
  273. of REDUCE. For example:
  274. 1. Electrical engineers may prefer to input J as the representation
  275. of (-1)**(1/2).
  276. 2. Many users may prefer to input LN to denote natural logarithms.
  277. 3. A user with previous exposure to the PL/I-FORMAC computer-
  278. algebra system might prefer to use DERIV instead of DF to
  279. request differentiation.
  280. Such lexical macros can be established by the DEFINE declaration:;
  281. CLEAR X,J;
  283. COMMENT Now watch!;
  284. N := 3;
  285. G1 := SUB(X=LN(J**3*X), DERIV(X**2,X));
  286. COMMENT Each "equation" in a DEFINE declaration must be of the form
  287. "name = item", where each item is an expression, an operator, or a
  288. REDUCE-reserved word such as "FOR". Such replacements take place
  289. during the lexical scanning, before any evaluation, LET rules, or
  290. built-in simplification. Think of a good application for this
  291. facility, then try it;
  292. PAUSE;
  293. COMMENT When REDUCE is being run in batch mode, it is preferable to
  294. have REDUCE make reasonable decisions and proceed when it encounters
  295. apparently undeclared operators, divisions by zero, etc. In
  296. interactive mode, it is preferable to pause and query the user. ON
  297. INT specifies the latter style, and OFF INT specifies the
  298. former. Under the influence of OFF INT, we can also have most
  299. error messages suppressed by specifying OFF MSG. This is sometimes
  300. useful when we expect abnormal conditions and do not want our listing
  301. marred by the associated messages. INT is automatically turned off
  302. during input from a batch file in response to an IN-command from a
  303. terminal.
  304. Some implementations permit the user to dynamically request more
  305. storage by executing a command of the form
  306. CORE number,
  307. where the number is an integer specifying the total desired core in
  308. some units such as bytes, words, kilobytes, or kilowords;
  309. PAUSE;
  310. COMMENT Some implementations have a trace command for debugging,
  311. which employs the syntax
  312. TR functionname1, functionname2, ..., functionnameN .
  313. An analogous command named UNTR removes function names from trace
  314. status;
  315. PAUSE;
  316. COMMENT Some implementations have an assignment-tracing command for
  317. debugging, which employs the syntax
  318. TRST functionname1, functionname2, ..., functionnameN.
  319. An analogous command named UNTRST removes functionnames from
  320. this status. All assignments in the designated functions are
  321. reported, except for assignments to array elements. Such functions
  322. must be uncompiled and must have a top-level BEGIN-block. To apply
  323. both TRST and TR to a function simultaneously, it is crucial to
  324. request them in that order, and it is necessary to relinquish the two
  325. kinds of tracing in the opposite order;
  326. PAUSE;
  327. COMMENT The REDUCE algebraic algorithms are written in a subset of
  328. REDUCE called RLISP. In turn, the more sophisticated features of
  329. RLISP are written in a small subset of RLISP which is written in a
  330. subset of LISP that is relatively common to most LISP systems.
  331. RLISP is ideal for implementing algebraic algorithms, but the RLISP
  332. environment is not most suitable for the routine use of these
  333. algorithms in the natural mathematical style of the preceding
  334. lessons. Accordingly, REDUCE jobs are initially in a mode called
  335. ALGEBRAIC, which provides the user with the environment illustrated
  336. in the preceding lessons, while insulating him from accidental
  337. interaction with the numerous functions, global variables, etc.
  338. necessary for implementing the built-in algebra. In contrast, the
  339. underlying RLISP system together with all of the algebraic
  340. simplification algorithms written therein is called SYMBOLIC mode.
  341. As we have seen, algebraic-mode rules and procedures can be used to
  342. extend the built-in algebraic capabilities. However, some extensions
  343. can be accomplished most easily or efficiently by descending to
  344. SYMBOLIC mode.
  345. To make REDUCE operate in symbolic mode, we merely execute the top
  346. level mode-declaration statement consisting of the word SYMBOLIC. We
  347. can subsequently switch back by executing the statement consisting of
  348. the word ALGEBRAIC.
  349. RLISP has the semantics of LISP with the syntax of our by-now-familiar
  350. algebraic-mode REDUCE, so RLISP provides a natural tool for many
  351. applications besides computer algebra, such as games, theorem-proving,
  352. natural-language translation, computer-aided instruction, and
  353. artificial intelligence in general. For this reason, it is possible
  354. to run RLISP without any of the symbolic-mode algebraic algorithms
  355. that are written in RLISP, and it is advisable to thus save space
  356. when the application does not involve computer algebra.
  357. We have now discussed virtually every feature that is available in
  358. algebraic mode, so lesson 6 will deal solely with RLISP, and
  359. lesson 7 will deal with communication between ALGEBRAIC and
  360. SYMBOLIC mode for mathematical purposes. However, I suggest that
  361. you proceed to those lessons only if and when:
  362. 1. You have consolidated and fully absorbed the information in
  363. lessons 1 through 5 by considerable practice beyond the
  364. exercises therein. (The exercises were intended to also
  365. suggest good related project ideas.)
  366. 2. You feel the need for a facility which you believe is impossible
  367. or quite awkward to implement solely in ALGEBRAIC mode.
  368. 3. You have read the pamphlet "Introduction to LISP", by D. Lurie,
  369. or an equivalent.
  370. 4. You are familiar with definition of Standard LISP, as described
  371. in the "Standard LISP Report" which was published in the October
  372. 1979 SIGPLAN Notices.
  373. Remember, when you decide to take lesson 6, it is better to do so from
  374. a RLISP job than from a REDUCE job. Also, don't forget to print your
  375. newly generated FORTRAN file and to delete any temporary files created
  376. by this lesson.
  377. ;END;