fixsubf.red 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. module fixsubf;
  2. % Author: James H. Davenport.
  3. fluid '(!*nosubs asymplis!* dmode!* ncmp!*);
  4. % The standard version of SUBF messes with the order of variables before
  5. % calling SUBF1, something we can't afford, so we define a new version.
  6. symbolic procedure algint!-subf(a,b); algint!-subf1(a,b);
  7. symbolic procedure algint!-subsq(u,v);
  8. !*multsq(algint!-subf(numr u,v),!*invsq algint!-subf(denr u,v));
  9. symbolic procedure algint!-subf1(u,l);
  10. %U is a standard form,
  11. %L an association list of substitutions of the form
  12. %(<kernel> . <substitution>).
  13. %Value is the standard quotient for substituted expression.
  14. %Algorithm used is essentially the straight method.
  15. %Procedure depends on explicit data structure for standard form;
  16. if domainp u
  17. then if atom u then if null dmode!* then u ./ 1 else simpatom u
  18. else if dmode!* eq car u then !*d2q u
  19. else simp prepf u
  20. else begin integer n; scalar kern,m,w,x,xexp,y,y1,z;
  21. z := nil ./ 1;
  22. a0: kern := mvar u;
  23. if m := assoc(kern,asymplis!*) then m := cdr m;
  24. a: if null u or (n := degr(u,kern))=0 then go to b
  25. else if null m or n<m then y := lt u . y;
  26. u := red u;
  27. go to a;
  28. b: if not atom kern and not atom car kern then kern := prepf kern;
  29. if null l then xexp := if kern eq 'k!* then 1 else kern
  30. else if (xexp := algint!-subsublis(l,kern)) = kern
  31. and not assoc(kern,asymplis!*)
  32. then go to f;
  33. c: w := 1 ./ 1;
  34. n := 0;
  35. if y and cdaar y<0 then go to h;
  36. if (x := getrtype xexp) then typerr(x,"substituted expression");
  37. x := simp!* xexp;
  38. % SIMP!* here causes problem with HE package in subf,
  39. % but we probably need the extra power of simp!*
  40. x := reorder numr x ./ reorder denr x;
  41. % needed in case substitution variable is in XEXP;
  42. if null l and kernp x and mvar numr x eq kern then go to f
  43. else if null numr x then go to e; %Substitution of 0;
  44. for each j in y do
  45. <<m := cdar j;
  46. w := !*multsq(!*exptsq(x,m-n),w);
  47. n := m;
  48. z := !*addsq(!*multsq(w,algint!-subf1(cdr j,l)),z)>>;
  49. e: y := nil;
  50. if null u then return z
  51. else if domainp u then return !*addsq(algint!-subf1(u,l),z);
  52. go to a0;
  53. f: sub2chk kern;
  54. for each j in y do
  55. z := !*addsq(!*multsq(!*f2q !*p2f car j,
  56. algint!-subf1(cdr j,l)),z);
  57. go to e;
  58. h: %Substitution for negative powers;
  59. x := simprecip list xexp;
  60. j: y1 := car y . y1;
  61. y := cdr y;
  62. if y and cdaar y<0 then go to j;
  63. k: m := -cdaar y1;
  64. w := !*multsq(!*exptsq(x,m-n),w);
  65. n := m;
  66. z := !*addsq(!*multsq(w,algint!-subf1(cdar y1,l)),z);
  67. y1 := cdr y1;
  68. if y1 then go to k else if y then go to c else go to e
  69. end;
  70. symbolic procedure algint!-subsublis(u,v);
  71. begin scalar x;
  72. return if x := assoc(v,u) then cdr x
  73. else if atom v then v
  74. else if car v eq '!*sq then
  75. list('!*sq,algint!-subsq(cadr v,u),caddr v)
  76. % Previous two lines added by JHD 7 July 1982.
  77. % without them, CDRs in SQ expressions buried inside;
  78. % !*SQ forms are lost;
  79. else if x := get(car v,'subfunc) then apply2(x,u,v)
  80. else for each j in v collect algint!-subsublis(u,j)
  81. end;
  82. put('int,'subfunc,'algint!-subsubf);
  83. symbolic procedure algint!-subsubf(l,expn);
  84. %Sets up a formal SUB expression when necessary;
  85. begin scalar x,y;
  86. for each j in cddr expn do
  87. if (x := assoc(j,l)) then <<y := x . y; l := delete(x,l)>>;
  88. expn := sublis(l,car expn)
  89. . for each j in cdr expn
  90. collect algint!-subsublis(l,j);
  91. %to ensure only opr and individual args are transformed;
  92. if null y then return expn;
  93. expn := aconc!*(for each j in reversip!* y
  94. collect list('equal,car j,aeval cdr j),expn);
  95. return mk!*sq if l then algint!-simpsub expn
  96. else !*p2q mksp('sub . expn,1)
  97. end;
  98. symbolic procedure algint!-simpsub u;
  99. begin scalar !*nosubs,w,x,z;
  100. a: if null cdr u
  101. then <<if getrtype car u or eqcar(car u,'equal)
  102. then typerr(car u,"scalar");
  103. u := simp!* car u;
  104. z := reversip!* z; % to put replacements in same
  105. % order as input.
  106. return quotsq(algint!-subf(numr u,z),
  107. algint!-subf(denr u,z))>>;
  108. !*nosubs := t; % We don't want left side of eqns to change.
  109. w := reval car u;
  110. !*nosubs := nil;
  111. if getrtype w eq 'list
  112. then <<u := append(cdr w,cdr u); go to a>>
  113. else if not eqexpr w then errpri2(car u,t);
  114. x := cadr w;
  115. if null getrtype x then x := !*a2k x;
  116. z := (x . caddr w) . z;
  117. u := cdr u;
  118. go to a;
  119. end;
  120. endmodule;
  121. end;