intro.red 11 KB

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