sqprint.red 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. module sqprint; % Routines for printing standard forms and quotients.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1996 RAND. All rights reserved.
  4. % Modified by A. C. Norman, 1987.
  5. fluid '(!*fort
  6. !*horner
  7. !*nat
  8. !*nero
  9. !*pri
  10. !*prin!#
  11. overflowed!*
  12. orig!*
  13. outputhandler!*
  14. posn!*
  15. testing!-width!*
  16. ycoord!*
  17. ymax!*
  18. ymin!*
  19. wtl!*);
  20. testing!-width!* := overflowed!* := nil;
  21. global '(!*eraise);
  22. switch horner;
  23. % When nat is enabled I use some programmable characters to
  24. % draw pi, fraction bars and integral signs. (symbol 's) returns
  25. % a character-object, and I use
  26. % .pi pi
  27. % bar solid horizontal bar -
  28. % int-top top hook of integral sign /
  29. % int-mid vertical mid-stroke of integral sign |
  30. % int-low lower hook of integral sign /
  31. % d curly-d for use with integral display d
  32. % sqrt square root sign sqrt
  33. % sum-top ---
  34. % sum-mid > for summation
  35. % sum-low ---
  36. % prod-top ---
  37. % prod-mid | | for products
  38. % prod-low | |
  39. % infinity infinity sign
  40. % mat!-top!-l / for display of matrices
  41. % mat!-top!-r \
  42. % mat!-low!-l \
  43. % mat!-low!-r /
  44. % vbar |
  45. symbolic procedure !*sqprint u; sqprint cadr u;
  46. put('!*sq,'prifn,'!*sqprint);
  47. symbolic procedure printsq u; <<terpri!* t; sqprint u; terpri!* u; u>>;
  48. symbolic procedure sqprint u;
  49. % Mathprints the standard quotient u.
  50. begin scalar flg,z,!*prin!#;
  51. !*prin!# := t;
  52. z := orig!*;
  53. if !*nat and posn!*<20 then orig!* := posn!*;
  54. if !*pri or wtl!* then maprin prepreform prepsq!* sqhorner!* u
  55. else if cdr u neq 1
  56. then <<flg := not domainp numr u and red numr u;
  57. xprinf(car u,flg,nil);
  58. prin2!* " / ";
  59. flg := not domainp denr u
  60. and (red denr u or lc denr u neq 1);
  61. xprinf(cdr u,flg,nil)>>
  62. else xprinf2 car u;
  63. return (orig!* := z)
  64. end;
  65. symbolic procedure prepreform u;
  66. % U is an algebraic expression prepared for output by prepsq*.
  67. % Reform inner kernel arguments if these contain references to a
  68. % variable which has been declared in a factor or order statement.
  69. prepreform1(u,append(ordl!*,factors!*));
  70. symbolic procedure prepreform1(u,l);
  71. if atom u or get(car u,'dname) then u else
  72. begin scalar w,l1;
  73. l1 := l;
  74. while null w and l1 do
  75. if smemq(car l1,cdr u) then w:=t else l1:=cdr l1;
  76. if null w then return u;
  77. if memq(car u,'(plus difference minus times quotient))
  78. or null get(car u,'simpfn) then w := nil;
  79. return if car u eq '!*sq
  80. then prepreform1(prepsq!* sqhorner!* cadr u,l)
  81. else car u . for each p in cdr u collect
  82. prepreform1(if w
  83. then prepsq!* sqhorner!* simp!* p else p,l)
  84. end;
  85. symbolic procedure sqhorner!* u;
  86. if not !*horner then u else
  87. hornersq(reorder numr u ./ hornerf reorder denr u)
  88. where kord!* = append(ordl!*,kord!*);
  89. symbolic procedure printsf u; <<prinsf u; terpri!* nil; u>>;
  90. symbolic procedure prinsf u; if null u then prin2!* 0 else xprinf2 u;
  91. symbolic procedure xprinf(u,flg,w);
  92. % U is a standard form, flg determines whether parens are needed.
  93. % W is currently unused.
  94. % Procedure prints the form and returns NIL.
  95. begin flg and prin2!* "("; xprinf2 u; flg and prin2!* ")" end;
  96. symbolic procedure xprinf2 u;
  97. begin scalar v;
  98. while not domainp u do <<xprint(lt u,v); u := red u; v := t>>;
  99. if null u then return nil
  100. else if minusf u then <<oprin 'minus; u := !:minus u>>
  101. else if v then oprin 'plus;
  102. if atom u then prin2!* u else maprin u
  103. end;
  104. symbolic procedure xprint(u,flg);
  105. % U is a standard term.
  106. % Flg is a flag which is true if a term has preceded this term.
  107. % Procedure prints the term and returns NIL.
  108. begin scalar v,w;
  109. v := tc u;
  110. u := tpow u;
  111. if (w := kernlp v) and w neq 1
  112. then <<v := quotf(v,w);
  113. if minusf w
  114. then <<oprin 'minus; w := !:minus w; flg := nil>>>>;
  115. if flg then oprin 'plus;
  116. if w and w neq 1 then <<prin2!* w; oprin 'times>>;
  117. xprinp u;
  118. if v neq 1 then <<oprin 'times; xprinf(v,red v,nil)>>
  119. end;
  120. symbolic procedure xprinp u;
  121. % U is a standard power. Procedure prints term and returns NIL.
  122. begin
  123. % Process main variable.
  124. if atom car u then prin2!* car u
  125. else if not atom caar u or caar u eq '!*sq then
  126. <<prin2!* "(";
  127. if not atom caar u then xprinf2 car u else sqprint cadar u;
  128. prin2!* ")">>
  129. else if caar u eq 'plus then maprint(car u,100)
  130. else maprin car u;
  131. % Process degree.
  132. if (u := cdr u)=1 then return nil
  133. else if !*nat and !*eraise
  134. then <<ycoord!* := ycoord!*+1;
  135. if ycoord!*>ymax!* then ymax!* := ycoord!*>>
  136. else prin2!* get('expt,'prtch);
  137. prin2!* if numberp u and minusp u then list u else u;
  138. if !*nat and !*eraise
  139. then <<ycoord!* := ycoord!*-1;
  140. if ymin!*>ycoord!* then ymin!* := ycoord!*>>
  141. end;
  142. endmodule;
  143. end;