prep.red 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. module prep; % Functions for converting canon. forms into prefix forms.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1987 The RAND Corporation. All rights reserved.
  4. fluid '(!*bool !*intstr);
  5. symbolic procedure prepsqxx u;
  6. % This is a top level conversion function. It is not clear if we
  7. % need prepsqxx, prepsqx, prepsq!* and prepsq, but we keep them all
  8. % for the time being.
  9. negnumberchk prepsqx u;
  10. symbolic procedure negnumberchk u;
  11. if eqcar(u,'minus) and numberp cadr u then - cadr u else u;
  12. symbolic procedure prepsqx u;
  13. if !*intstr then prepsq!* u else prepsq u;
  14. symbolic procedure prepsq u;
  15. if null numr u then 0 else sqform(u,function prepf);
  16. symbolic procedure sqform(u,v);
  17. (lambda (x,y); if y=1 then x else list('quotient,x,y))
  18. (apply1(v,numr u),apply1(v,denr u));
  19. symbolic procedure prepf u;
  20. (if null x then 0 else replus x) where x=prepf1(u,nil);
  21. symbolic procedure prepf1(u,v);
  22. if null u then nil
  23. else if domainp u then list retimes(prepd u . exchk v)
  24. else nconc!*(prepf1(lc u,if mvar u eq 'k!* then v else lpow u . v),
  25. prepf1(red u,v));
  26. symbolic procedure prepd u;
  27. if atom u then if u<0 then list('minus,-u) else u
  28. else if apply1(get(car u,'minusp),u)
  29. % then list('minus,prepd1 !:minus u)
  30. then (if null x then 0 else list('minus,x))
  31. where x=prepd1 !:minus u
  32. % else if !:onep u then 1
  33. else apply1(get(car u,'prepfn),u);
  34. symbolic procedure prepd1 u;
  35. if atom u then u else apply1(get(car u,'prepfn),u);
  36. % symbolic procedure exchk u;
  37. % begin scalar z;
  38. % for each j in u do
  39. % if cdr j=1
  40. % then if eqcar(car j,'expt) and caddar j = '(quotient 1 2)
  41. % then z := list('sqrt,cadar j) .z
  42. % else z := sqchk car j . z
  43. % else z := list('expt,sqchk car j,cdr j) . z;
  44. % return z
  45. % end;
  46. symbolic procedure exchk u; exchk1(u,nil,nil,nil);
  47. symbolic procedure exchk1(u,v,w,x);
  48. % checks forms for kernels in EXPT. U is list of powers. V is used
  49. % to build up the final answer. W is an association list of
  50. % previous non-constant (non foldable) EXPT's, X is an association
  51. % list of constant (foldable) EXPT arguments.
  52. if null u then exchk2(append(x,w),v)
  53. else if eqcar(caar u,'expt)
  54. then begin scalar y,z;
  55. y := simpexpon list('times,cdar u,caddar car u);
  56. if numberp cadaar u % constant argument
  57. then <<z := assoc2(y,x);
  58. if z then rplaca(z,car z*cadaar u)
  59. else x := (cadaar u . y) . x>>
  60. else <<z := assoc(cadaar u,w);
  61. if z then rplacd(z,addsq(y,cdr z))
  62. else w := (cadaar u . y) . w>>;
  63. return exchk1(cdr u,v,w,x)
  64. end
  65. else if cdar u=1 then exchk1(cdr u,sqchk caar u . v,w,x)
  66. else exchk1(cdr u,list('expt,sqchk caar u,cdar u) . v,w,x);
  67. symbolic procedure exchk2(u,v);
  68. if null u then v
  69. else exchk2(cdr u,
  70. % ((if eqcar(x,'quotient) and caddr x = 2
  71. % then if cadr x = 1 then list('sqrt,caar u)
  72. % else list('expt,list('sqrt,caar u),cadr x)
  73. ((if x=1 then caar u
  74. else if !*nosqrts then list('expt,caar u,x)
  75. else if x = '(quotient 1 2) then list('sqrt,caar u)
  76. else if x=0.5 then list('sqrt,caar u)
  77. else list('expt,caar u,x)) where x = prepsqx cdar u)
  78. . v);
  79. symbolic procedure assoc2(u,v);
  80. % Finds key U in second position of terms of V, or returns NIL.
  81. if null v then nil
  82. else if u = cdar v then car v
  83. else assoc2(u,cdr v);
  84. symbolic procedure replus u;
  85. if null u then 0
  86. else if atom u then u
  87. else if null cdr u then car u
  88. else 'plus . unplus u;
  89. symbolic procedure unplus u;
  90. if atom u then u
  91. else if car u = 'plus then unplus cdr u
  92. else if atom car u or not eqcar(car u,'plus)
  93. then (car u) . unplus cdr u
  94. else append(cdar u,unplus cdr u);
  95. % symbolic procedure retimes u;
  96. % % U is a list of prefix expressions. Value is prefix form for the
  97. % % product of these;
  98. % begin scalar bool,x;
  99. % for each j in u do
  100. % <<if j=1 then nil % ONEP
  101. % else if eqcar(j,'minus)
  102. % then <<bool := not bool;
  103. % if cadr j neq 1 then x := cadr j . x>> % ONEP
  104. % else if numberp j and minusp j
  105. % then <<bool := not bool;
  106. % if j neq -1 then x := (-j) . x>>
  107. % else x := j . x>>;
  108. % x := if null x then 1
  109. % else if cdr x then 'times . reverse x else car x;
  110. % return if bool then list('minus,x) else x
  111. % end;
  112. symbolic procedure retimes u;
  113. begin scalar !*bool;
  114. u := retimes1 u;
  115. u := if null u then 1
  116. else if cdr u then 'times . u
  117. else car u;
  118. return if !*bool then list('minus,u) else u
  119. end;
  120. symbolic procedure retimes1 u;
  121. if null u then nil
  122. else if car u = 1 then retimes1 cdr u
  123. else if minusp car u
  124. then <<!*bool := not !*bool; retimes1((-car u) . cdr u)>>
  125. else if atom car u then car u . retimes1 cdr u
  126. else if caar u eq 'minus
  127. then <<!*bool := not !*bool; retimes1(cadar u . cdr u)>>
  128. else if caar u eq 'times then retimes1 append(cdar u,cdr u)
  129. else car u . retimes1 cdr u;
  130. symbolic procedure sqchk u;
  131. if atom u then u
  132. else (if x then apply1(x,u) else if atom car u then u else prepf u)
  133. where x=get(car u,'prepfn2);
  134. put('!*sq,'prepfn2,'prepcadr);
  135. put('expt,'prepfn2,'prepexpt);
  136. symbolic procedure prepcadr u; prepsq cadr u;
  137. symbolic procedure prepexpt u; if caddr u=1 then cadr u else u;
  138. endmodule;
  139. end;