mksp.red 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. module mksp; % Functions for making standard powers.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1991 RAND. All rights reserved.
  4. % This module has a non-trivial use of ACONC.
  5. fluid '(!*nosubs !*sub2 asymplis!* powlis!* subfg!* wtl!*);
  6. % fluid '(varstack!*);
  7. global '(!*resubs);
  8. % exports mksfpf,mksp,mksq,to;
  9. % imports !*p2f,aconc,eqcar,exptf,exptsq,leq,mkprod!*,module,multsq,
  10. % ordad,over,simpcar,union;
  11. symbolic procedure getpower(u,n);
  12. %U is a list (<kernel> . <properties>), N a positive integer.
  13. %Value is the standard power of U**N;
  14. <<if eqcar(car u,'expt) and n>1 then !*sub2 := t; car u . n>>;
  15. % begin scalar v;
  16. % v := cadr u;
  17. % if null v then return caar rplaca(cdr u,list (car u . n));
  18. % a: if n=cdar v then return car v
  19. % else if n<cdar v
  20. % then return car rplacw(v,(caar v . n) . (car v . cdr v))
  21. % else if null cdr v
  22. % then return cadr rplacd(v,list (caar v . n));
  23. % v := cdr v;
  24. % go to a
  25. % end;
  26. symbolic procedure mksp(u,p);
  27. %U is a (non-unique) kernel and P a non-zero integer
  28. %Value is the standard power for U**P;
  29. getpower(fkern u,p);
  30. symbolic procedure u to p;
  31. %U is a (unique) kernel and P a non-zero integer;
  32. %Value is the standard power of U**P;
  33. u . p;
  34. % getpower(fkern u,p);
  35. symbolic procedure mksp!*(u,n);
  36. % Returns a standard form for U**N. If U is a kernel product,
  37. % direct exponentiation is used. Otherwise, U is first made
  38. % positive and then converted into a kernel.
  39. begin scalar b;
  40. if null u or kernlp u then return exptf(u,n)
  41. else if minusf u then <<b := t; u := negf u>>;
  42. u := !*p2f mksp(u,n);
  43. return if b and not evenp n then negf u else u
  44. end;
  45. symbolic procedure mksfpf(u,n);
  46. % Raises form U to power N with EXP off. Returns a form.
  47. % If we assume that MKPROD returns a kernlp form, check for red x
  48. % is redundant.
  49. (if n=1 then x
  50. else if domainp x then !:expt(x,n)
  51. else if n>=0 and onep lc x and null red x
  52. then (((if subfg!* and z and cdr z<=m then nil
  53. else !*p2f mksp(y,m))
  54. where z=assoc(y,asymplis!*)) where m=ldeg x*n,y=mvar x)
  55. else exptf2(x,n))
  56. where x=mkprod u;
  57. symbolic procedure mksq(u,n);
  58. % U is a kernel, N a non-zero integer.
  59. % Value is a standard quotient of U**N, after making any
  60. % possible substitutions for U.
  61. begin scalar x,y,z;
  62. % (begin scalar x,y,z;
  63. if null subfg!* then go to a1
  64. else if (y := assoc(u,wtl!*))
  65. and null car(y := mksq('k!*,n*cdr y)) then return y
  66. else if not atom u then go to b
  67. else if null !*nosubs and (z:= get(u,'avalue)) then go to c;
  68. if idp u then flag(list u,'used!*);
  69. %tell system U used as algebraic var (unless it's a string);
  70. a: if !*nosubs or n=1 then go to a1
  71. else if (z:= assoc(u,asymplis!*)) and cdr z<=n
  72. then return nil ./ 1
  73. else if ((z:= assoc(u,powlis!*))
  74. or not atom u and car u memq '(expt sqrt)
  75. and (z := assoc(cadr u,powlis!*)))
  76. and not(n*cadr z<0)
  77. % Implements explicit sign matching.
  78. then !*sub2 := t;
  79. a1: if null x then x := fkern u;
  80. x := !*p2f getpower(x,n) ./ 1;
  81. return if y then multsq(y,x) else x;
  82. b: if null !*nosubs and atom car u
  83. and ((z := get(car u,'mksqsubfn)) and (z := apply1(z,u))
  84. or (z:= assoc(u,get(car u,'kvalue))))
  85. then go to c
  86. else if not('used!* memq cddr (x := fkern u))
  87. then aconc(x,'used!*);
  88. go to a;
  89. c: z := cdr z;
  90. % varstack!* := u . varstack!*; % I don't think this is needed.
  91. %optimization is possible as shown if all expression
  92. %dependency is known;
  93. %if cdr z then return exptsq(cdr z,n); % Value already computed.
  94. if null !*resubs then !*nosubs := t;
  95. x := simpcar z;
  96. !*nosubs := nil;
  97. %rplacd(z,x); % Save simplified value.
  98. %subl!* := z . subl!*;
  99. return exptsq(x,n)
  100. end;
  101. % end) where varstack!* := varstack!*; % I don't think this is needed.
  102. endmodule;
  103. end;