hacksqrt.red 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. MODULE HACKSQRT; % Routines for manipulation of sqrt expressions.
  2. % Author: James H. Davenport.
  3. FLUID '(NESTEDSQRTS THISPLACE);
  4. EXPORTS SQRTSINTREE,SQRTSINSQ,SQRTSINSQL,SQRTSINSF,SQRTSIGN;
  5. EXPORTS DEGREENEST,SORTSQRTS;
  6. IMPORTS MKVECT,INTERR,GETV,DEPENDSP,UNION;
  7. SYMBOLIC PROCEDURE SQRTSINTREE(U,VAR,SLIST);
  8. % Adds to slist all the sqrts in the prefix-type tree u.
  9. IF ATOM U
  10. THEN SLIST
  11. ELSE IF CAR U EQ '!*SQ
  12. THEN UNION(SLIST,SQRTSINSQ(CADR U,VAR))
  13. ELSE IF CAR U EQ 'SQRT
  14. THEN IF DEPENDSP(ARGOF U,VAR)
  15. THEN <<
  16. SLIST:=SQRTSINTREE(ARGOF U,VAR,SLIST);
  17. % nested square roots
  18. IF MEMBER(U,SLIST)
  19. THEN SLIST
  20. ELSE U.SLIST >>
  21. ELSE SLIST
  22. ELSE SQRTSINTREE(CAR U,VAR,SQRTSINTREE(CDR U,VAR,SLIST));
  23. SYMBOLIC PROCEDURE SQRTSINSQ(U,VAR);
  24. % Returns list of all sqrts in sq.
  25. SQRTSINSF(DENR U,SQRTSINSF(NUMR U,NIL,VAR),VAR);
  26. SYMBOLIC PROCEDURE SQRTSINSQL(U,VAR);
  27. % Returns list of all sqrts in sq list.
  28. IF NULL U
  29. THEN NIL
  30. ELSE SQRTSINSF(DENR CAR U,
  31. SQRTSINSF(NUMR CAR U,SQRTSINSQL(CDR U,VAR),VAR),VAR);
  32. SYMBOLIC PROCEDURE SQRTSINSF(U,SLIST,VAR);
  33. % Adds to slist all the sqrts in sf.
  34. IF DOMAINP U OR NULL U
  35. THEN SLIST
  36. ELSE <<
  37. IF EQCAR(MVAR U,'SQRT) AND
  38. DEPENDSP(ARGOF MVAR U,VAR) AND
  39. NOT MEMBER(MVAR U,SLIST)
  40. THEN BEGIN
  41. SCALAR SLIST2;
  42. SLIST2:=SQRTSINTREE(ARGOF MVAR U,VAR,NIL);
  43. IF SLIST2
  44. THEN <<
  45. NESTEDSQRTS:=T;
  46. SLIST:=UNION(SLIST2,SLIST) >>;
  47. SLIST:=(MVAR U).SLIST
  48. END;
  49. SQRTSINSF(LC U,SQRTSINSF(RED U,SLIST,VAR),VAR) >>;
  50. SYMBOLIC PROCEDURE EASYSQRTSIGN(SLIST,THINGS);
  51. % This procedure builds a list of all substitutions for all possible
  52. % combinations of square roots in list.
  53. IF NULL SLIST
  54. THEN THINGS
  55. ELSE EASYSQRTSIGN(CDR SLIST,
  56. NCONC(MAPCONS(THINGS,(CAR SLIST).(CAR SLIST)),
  57. MAPCONS(THINGS,
  58. LIST(CAR SLIST,'MINUS,CAR SLIST))));
  59. SYMBOLIC PROCEDURE HARDSQRTSIGN(SLIST,THINGS);
  60. % This procedure fulfils the same role for nested sqrts
  61. % ***assumption: the simpler sqrts come further up the list.
  62. IF NULL SLIST
  63. THEN THINGS
  64. ELSE BEGIN
  65. SCALAR THISPLACE,ANSWERS,POS,NEG;
  66. THISPLACE:=CAR SLIST;
  67. ANSWERS:= for each u in THINGS collect SUBLIS(U,THISPLACE) . U;
  68. POS := for each u in ANSWERS collect (THISPLACE . CAR U) . CDR U;
  69. % pos is sqrt(f) -> sqrt(innersubst f)
  70. NEG := for each u in ANSWERS
  71. collect {THISPLACE,'MINUS,CAR U} . CDR U;
  72. % neg is sqrt(f) -> -sqrt(innersubst f)
  73. RETURN HARDSQRTSIGN(CDR SLIST,NCONC(POS,NEG))
  74. END;
  75. SYMBOLIC PROCEDURE DEGREENEST(PF,VAR);
  76. % Returns the maximum degree of nesting of var
  77. % inside sqrts in the prefix form pf.
  78. IF ATOM PF
  79. THEN 0
  80. ELSE IF CAR PF EQ 'SQRT
  81. THEN IF DEPENDSP(CADR PF,VAR)
  82. THEN IADD1 DEGREENEST(CADR PF,VAR)
  83. ELSE 0
  84. ELSE IF CAR PF EQ 'EXPT
  85. THEN IF DEPENDSP(CADR PF,VAR)
  86. THEN IF EQCAR(CADDR PF,'QUOTIENT)
  87. THEN IADD1 DEGREENEST(CADR PF,VAR)
  88. ELSE DEGREENEST(CADR PF,VAR)
  89. ELSE 0
  90. ELSE DEGREENESTL(CDR PF,VAR);
  91. SYMBOLIC PROCEDURE DEGREENESTL(U,VAR);
  92. %Returns max degreenest from list of pfs u.
  93. IF NULL U
  94. THEN 0
  95. ELSE MAX(DEGREENEST(CAR U,VAR),
  96. DEGREENESTL(CDR U,VAR));
  97. SYMBOLIC PROCEDURE SORTSQRTS(U,VAR);
  98. % Sorts list of sqrts into order required by hardsqrtsign
  99. % (and many other parts of the package).
  100. BEGIN
  101. SCALAR I,V;
  102. V:=MKVECT(10); %should be good enough!
  103. WHILE U DO <<
  104. I:=DEGREENEST(CAR U,VAR);
  105. IF I IEQUAL 0
  106. THEN INTERR "Non-dependent sqrt found";
  107. IF I > 10
  108. THEN INTERR
  109. "Degree of nesting exceeds 10 (recompile with 10 increased)";
  110. PUTV(V,I,(CAR U).GETV(V,I));
  111. U:=CDR U >>;
  112. U:=GETV(V,10);
  113. FOR I :=9 STEP -1 UNTIL 1 DO
  114. U:=NCONC(GETV(V,I),U);
  115. RETURN U
  116. END;
  117. SYMBOLIC PROCEDURE SQRTSIGN(SQRTS,X);
  118. IF NESTEDSQRTS THEN HARDSQRTSIGN(SORTSQRTS(SQRTS,X),LIST NIL)
  119. ELSE EASYSQRTSIGN(SQRTS,LIST NIL);
  120. ENDMODULE;
  121. END;