intro.red 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. module intro; % Introductory material for algebraic mode.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1991 RAND. All rights reserved.
  4. fluid '(!*cref !*exp !*factor !*fort !*ifactor !*intstr !*lcm !*mcd
  5. !*msg !*mode !*nat !*nero !*period !*precise !*pri !*protfg
  6. !*rationalize !*reduced !*sub2 !*varopt posn!* subfg!*);
  7. global '(!*resubs
  8. !*val
  9. erfg!*
  10. exlist!*
  11. initl!*
  12. nat!*!*
  13. ofl!*
  14. simpcount!*
  15. simplimit!*
  16. tstack!*);
  17. % Non-local variables needing top level initialization.
  18. !*exp := t; % expansion control flag;
  19. !*lcm := t; % least common multiple computation flag;
  20. !*mcd := t; % common denominator control flag;
  21. !*mode := 'symbolic; % current evaluation mode;
  22. !*msg := t; % flag controlling message printing;
  23. !*nat := t; % specifies natural printing mode;
  24. !*period := t; % prints a period after a fixed coefficient
  25. % when FORT is on;
  26. !*precise := t; % Specifies more precise handling of surds.
  27. !*resubs := t; % external flag controlling resubstitution;
  28. !*val := t; % controls operator argument evaluation;
  29. !*varopt := t; % Used by SOLVE, etc.
  30. exlist!* := '((!*)); % property list for standard forms used as
  31. % kernels;
  32. initl!* := append('(subfg!* !*sub2 tstack!*),initl!*);
  33. simpcount!* := 0; % depth of recursion within simplifier;
  34. simplimit!* := 2000; % allowed recursion limit within simplifier;
  35. subfg!* := t; % flag to indicate whether substitution
  36. % is required during evaluation;
  37. tstack!* := 0; % stack counter in SIMPTIMES;
  38. % Initial values of some global variables in BEGIN1 loops.
  39. put('subfg!*,'initl,t);
  40. put('tstack!*,'initl,0);
  41. % Description of some non-local variables used in algebraic mode.
  42. % alglist!* := nil . nil; %association list for previously simplified
  43. %expressions;
  44. % asymplis!* := nil; %association list of asymptotic replacements;
  45. % cursym!* current symbol (i. e. identifier, parenthesis,
  46. % delimiter, e.t.c,) in input line;
  47. % dmode!* := nil; %name of current polynomial domain mode if not
  48. %integer;
  49. % domainlist!* := nil; %list of currently supported poly domain modes;
  50. % dsubl!* := nil; %list of previously calculated derivatives of
  51. % expressions;
  52. % exptl!* := nil; %list of exprs with non-integer exponents;
  53. % frlis!* := nil; %list of renamed free variables to be found in
  54. %substitutions;
  55. % kord!* := nil; %kernel order in standard forms;
  56. % kprops!* := nil; %list of active non-atomic kernel plists;
  57. % mchfg!* := nil; %indicates that a pattern match occurred during
  58. %a cycle of the matching routines;
  59. % mul!* := nil; %list of additional evaluations needed in a
  60. %given multiplication;
  61. % nat!*!* := nil; %temporary variable used in algebraic mode;
  62. % ncmp!* := nil; %flag indicating non-commutative multiplication
  63. %mode;
  64. % ofl!* := nil; %current output file name;
  65. % posn!* := nil; %used to store output character position in
  66. %printing functions;
  67. % powlis!* := nil; %association list of replacements for powers;
  68. % powlis1!* := nil; %association list of conditional replacements
  69. %for powers;
  70. % subl!* := nil; %list of previously evaluated expressions;
  71. % wtl!* := nil; %tells that a WEIGHT assignment has been made;
  72. % !*ezgcd := nil; %ezgcd calculation flag;
  73. % !*float := nil; %floating arithmetic mode flag;
  74. % !*fort := nil; %specifies FORTRAN output;
  75. % !*gcd := nil; %greatest common divisor mode flag;
  76. % !*group := nil; %causes expressions to be grouped when EXP off;
  77. % !*intstr := nil; %makes expression arguments structured;
  78. % !*int indicates interactive system use;
  79. % !*match := nil; %list of pattern matching rules;
  80. % !*nero := nil; %flag to suppress printing of zeros;
  81. % !*nosubs := nil; %internal flag controlling substitution;
  82. % !*numval := nil; %used to indicate that numerical expressions
  83. %should be converted to a real value;
  84. % !*outp := nil; %holds prefix output form for extended output
  85. %package;
  86. % !*pri := nil; %indicates that fancy output is required;
  87. % !*reduced := nil; %causes arguments of radicals to be factored.
  88. %E.g., sqrt(-x) --> i*sqrt(x);
  89. % !*sub2 := nil; %indicates need for call of RESIMP;
  90. % ***** UTILITY FUNCTIONS *****.
  91. symbolic procedure mkid(x,y);
  92. % creates the ID XY from identifier X and (evaluated) object Y.
  93. if not idp x then typerr(x,"MKID root")
  94. else if atom y and (idp y or fixp y and not minusp y)
  95. then intern compress nconc(explode x,explode y)
  96. else typerr(y,"MKID index");
  97. flag('(mkid),'opfn);
  98. symbolic procedure multiple!-result(z,w);
  99. % Z is a list of items (n . prefix-form), in ordering in descending
  100. % order wrt n, which must be non-negative. W is either an array
  101. % name, another id, a template for a multi-dimensional array or NIL.
  102. % Elements of Z are accordingly stored in W if it is non-NIL, or
  103. % returned as a list otherwise.
  104. begin scalar x,y;
  105. if null w then return 'list . reversip!* fillin z;
  106. x := getrtype w;
  107. if x and not(x eq 'array) then typerr(w,"array or id");
  108. lpriw("*****",
  109. list(if x eq 'array then "ARRAY" else "ID",
  110. "fill no longer supported --- use lists instead"));
  111. if atom w then (if not arrayp w
  112. then (if numberp(w := reval w) then typerr(w,'id)))
  113. else if not arrayp car w then typerr(car w,'array)
  114. else w := car w . for each x in cdr w
  115. collect if x eq 'times then x else reval x;
  116. x := length z-1; % don't count zeroth element;
  117. if not((not atom w and atom car w
  118. and (y := dimension car w))
  119. or ((y := dimension w) and null cdr y))
  120. then <<y := explode w;
  121. w := nil;
  122. for each j in z do
  123. <<w := intern compress append(y,explode car j) . w;
  124. setk1(car w,cdr j,t)>>;
  125. lprim if length w=1 then list(car w,"is non zero")
  126. else aconc!*(reversip!* w,"are non zero");
  127. return x>>
  128. else if atom w
  129. then <<if caar z neq (car y-1)
  130. then <<y := list(caar z+1);
  131. % We don't use put!-value here.
  132. put(w,'avalue,
  133. {'array,mkarray1(y,'algebraic)});
  134. put(w,'dimension,y)>>;
  135. w := list(w,'times)>>;
  136. y := pair(cdr w,y);
  137. while y and not smemq('times,caar y) do y := cdr y;
  138. if null y then errach "MULTIPLE-RESULT";
  139. y := cdar y-reval subst(0,'times,caar y)-1;
  140. %-1 needed since DIMENSION gives length, not highest index;
  141. if caar z>y
  142. then rerror(alg,3,list("Index",caar z,"out of range"));
  143. repeat
  144. if null z or y neq caar z
  145. then setelv(subst(y,'times,w),0)
  146. else <<setelv(subst(y,'times,w),cdar z); z := cdr z>>
  147. until (y := y-1) < 0;
  148. return x
  149. end;
  150. symbolic procedure fillin u;
  151. % fills in missing terms in multiple result argument list u
  152. % and returns list of coefficients.
  153. if null u then nil else fillin1(u,caar u);
  154. symbolic procedure fillin1(u,n);
  155. if n<0 then nil
  156. else if u and caar u=n then cdar u . fillin1(cdr u,n-1)
  157. else 0 . fillin1(u,n-1);
  158. % ***** FUNCTIONS FOR PRINTING DIAGNOSTIC AND ERROR MESSAGES *****
  159. symbolic procedure msgpri(u,v,w,x,y);
  160. begin integer posn!*; scalar nat1,z,pline!*;
  161. if null y and null !*msg then return;
  162. nat1 := !*nat;
  163. !*nat := nil;
  164. if ofl!* and (!*fort or not nat1) then go to c;
  165. a: terpri();
  166. lpri ((if null y then "***" else "*****")
  167. . if u and atom u then list u else u);
  168. posn!* := posn();
  169. maprin v;
  170. prin2 " ";
  171. lpri if w and atom w then list w else w;
  172. posn!* := posn();
  173. maprin x;
  174. terpri!*(t); % if not y or y eq 'hold then terpri();
  175. if null z then go to b;
  176. wrs cdr z;
  177. go to d;
  178. b: if null ofl!* then go to d;
  179. c: z := ofl!*;
  180. wrs nil;
  181. go to a;
  182. d: !*nat := nat1;
  183. if y then if y eq 'hold then erfg!* := y else error1()
  184. end;
  185. symbolic procedure errach u;
  186. begin
  187. terpri!* t;
  188. lprie "CATASTROPHIC ERROR *****";
  189. printty u;
  190. lpriw(" ",nil);
  191. rerror(alg,4,
  192. "Please send output and input listing to A. C. Hearn")
  193. end;
  194. symbolic procedure errpri1 u;
  195. msgpri("Substitution for",u,"not allowed",nil,t); % was 'HOLD
  196. symbolic procedure errpri2(u,v);
  197. msgpri("Syntax error:",u,"invalid",nil,v);
  198. symbolic procedure redmsg(u,v);
  199. if null !*msg or v neq "operator" then nil
  200. else if terminalp() then yesp list("Declare",u,v,"?") or error1()
  201. else lprim list(u,"declared",v);
  202. symbolic procedure typerr(u,v);
  203. % Note this replaces definition in rlisp/lpri.
  204. <<if not !*protfg
  205. then <<terpri!* t;
  206. prin2!* "***** ";
  207. if not atom u and atom car u and cdr u and atom cadr u
  208. and null cddr u
  209. then <<prin2!* car u; prin2!* " "; prin2!* cadr u>>
  210. else if null u then prin2!* u
  211. else maprin u;
  212. prin2!* " invalid as "; prin2!* v;
  213. terpri!* nil>>;
  214. erfg!* := t; error1()>>;
  215. % ***** ALGEBRAIC MODE DECLARATIONS *****
  216. flag ('(aeval cond getel go prog progn prog2 return
  217. reval setq setk setel assgnpri !*s2i),'nochange);
  218. flag ('(or and not member memq equal neq eq geq greaterp leq
  219. fixp lessp numberp ordp freeof),'boolean);
  220. flag ('(or and not),'boolargs);
  221. deflist ('((exp ((nil (rmsubs)) (t (rmsubs))))
  222. (factor ((nil (setq !*exp t) (rmsubs))
  223. (t (setq !*exp nil) (rmsubs))))
  224. (fort ((nil (setq !*nat nat!*!*)) (t (setq !*nat nil))))
  225. (gcd ((t (rmsubs))))
  226. (intstr ((nil (rmsubs)) (t (rmsubs))))
  227. (mcd ((nil (rmsubs)) (t (rmsubs))))
  228. (nat ((nil (setq nat!*!* nil)) (t (setq nat!*!* t))))
  229. (numval ((t (rmsubs))))
  230. (rationalize ((t (rmsubs))))
  231. (reduced ((t (rmsubs))))
  232. (val ((t (rmsubs))))),'simpfg);
  233. switch exp,cref,factor,fort,gcd,ifactor,intstr,lcm,mcd,nat,nero,numval,
  234. period,precise,pri,rationalize,reduced,varopt; % resubs, val.
  235. endmodule;
  236. end;