a2dip.red 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. module a2dip;
  2. %/*Convert an algebraic (prefix) form to distributive polynomial*/
  3. %/*Authors: R. Gebauer, A. C. Hearn, H. Kredel*/
  4. % Modified by: H. Melenk.
  5. fluid '(dipvars!* dipzero !*vdpinteger);
  6. symbolic procedure a2dip u;
  7. % /*Converts the algebraic (prefix) form u to a distributive poly.
  8. % We assume that all variables used have been previously
  9. % defined in dipvars!*, but a check is also made for this*/
  10. if atom u then a2dipatom u
  11. else if not atom car u or not idp car u
  12. then typerr(car u,"dipoly operator")
  13. % Handling expt separately because the exponents should
  14. % not be simplified as domain elements.
  15. else if car u = 'expt then dipfnpow(a2dip cadr u,caddr u)
  16. else (if x then apply(x,list for each y in cdr u collect a2dip y)
  17. else a2dipatom u)
  18. where x = get(car u,'dipfn);
  19. expr procedure a2dipatom u;
  20. % /*Converts the atom (or kernel) u into a distributive polynomial*/
  21. if u=0 then dipzero
  22. else if numberp u or not(u member dipvars!*)
  23. then dipfmon(a2bc u,evzero())
  24. else dipfmon(a2bc 1,mkexpvec u);
  25. expr procedure dipfnsum u;
  26. % /*U is a list of dip expressions. Result is the distributive poly
  27. % representation for the sum*/
  28. (<<for each y in cdr u do x := dipsum(x,y); x>>) where x = car u;
  29. put('plus,'dipfn,'dipfnsum);
  30. put('plus2,'dipfn,'dipfnsum);
  31. expr procedure dipfnprod u;
  32. % /*U is a list of dip expressions. Result is the distributive poly
  33. % representation for the product*/
  34. % /*Maybe we should check for a zero*/
  35. (<<for each y in cdr u do x := dipprod(x,y); x>>) where x = car u;
  36. put('times,'dipfn,'dipfnprod);
  37. put('times2,'dipfn,'dipfnprod);
  38. expr procedure dipfndif u;
  39. % /*U is a list of two dip expressions. Result is the distributive
  40. % polynomial representation for the difference*/
  41. dipsum(car u,dipneg cadr u);
  42. put('difference,'dipfn,'dipfndif);
  43. symbolic procedure dipfnpow(v,n);
  44. % V is a dip. Result is the distributive poly v**n.
  45. (if not fixp n or n<0
  46. then typerr(n,"distributive polynomial exponent")
  47. else if n=0 then if dipzero!? v then rerror(dipoly,1,"0**0 invalid")
  48. else w
  49. else if dipzero!? v or n=1 then v
  50. else if dipzero!? dipmred v
  51. then dipfmon(bcpow(diplbc v,n),intevprod(n,dipevlmon v))
  52. else <<while n>0 do
  53. <<if not evenp n then w := dipprod(w,v);
  54. n := n/2;
  55. if n>0 then v := dipprod(v,v)>>;
  56. w>>)
  57. where w := dipfmon(a2bc 1,evzero());
  58. % put('expt,'dipfn,'dipfnpow);
  59. expr procedure dipfnneg u;
  60. % /*U is a list of one dip expression. Result is the distributive
  61. % polynomial representation for the negative*/
  62. (if dipzero!? v then v
  63. else dipmoncomp(bcneg diplbc v,dipevlmon v,dipmred v))
  64. where v = car u;
  65. put('minus,'dipfn,'dipfnneg);
  66. symbolic procedure dipfnquot u;
  67. % /*U is a list of two dip expressions. Result is the distributive
  68. % polynomial representation for the quotient*/
  69. if dipzero!? cadr u or not dipzero!? dipmred cadr u
  70. or not evzero!? dipevlmon cadr u
  71. or (!*vdpinteger and not bcone!? diplbc cadr u)
  72. then typerr(dip2a cadr u,"distributive polynomial denominator")
  73. else dipfnquot1(car u,diplbc cadr u);
  74. expr procedure dipfnquot1(u,v);
  75. if dipzero!? u then u
  76. else dipmoncomp(bcquot(diplbc u,v),
  77. dipevlmon u,
  78. dipfnquot1(dipmred u,v));
  79. put('quotient,'dipfn,'dipfnquot);
  80. endmodule;
  81. end;