subs3q.red 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. module subs3q; % Routines for matching products.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1992 RAND. All rights reserved.
  4. fluid '(!*mcd powlis1!* !*sub2 subfg!*);
  5. global '(!*match !*resubs mchfg!*);
  6. symbolic procedure subs3q u;
  7. %U is a standard quotient.
  8. %Value is a standard quotient with all product substitutions made;
  9. begin scalar x;
  10. x := mchfg!*; %save value in case we are in inner loop;
  11. mchfg!* := nil;
  12. u := quotsq(subs3f numr u,subs3f denr u);
  13. mchfg!* := x;
  14. return u
  15. end;
  16. symbolic procedure subs3f u;
  17. %U is a standard form.
  18. %Value is a standard quotient with all product substitutions made;
  19. subs3f1(u,!*match,t);
  20. symbolic procedure subs3f1(u,l,bool);
  21. %U is a standard form.
  22. %L is a list of possible matches.
  23. %BOOL is a boolean variable which is true if we are at top level.
  24. %Value is a standard quotient with all product substitutions made;
  25. begin scalar x,z;
  26. z := nil ./ 1;
  27. a: if null u then return z
  28. else if domainp u then return addsq(z,u ./ 1)
  29. else if bool and domainp lc u then go to c;
  30. x := subs3t(lt u,l);
  31. if not bool %not top level;
  32. or not mchfg!* then go to b; %no replacement made;
  33. mchfg!* := nil;
  34. if numr x = u and denr x = 1 then <<x := u ./ 1; go to b>>
  35. % also shows no replacement made (sometimes true with non
  36. % commuting expressions)
  37. else if null !*resubs then go to b
  38. else if !*sub2 or powlis1!* then x := subs2q x;
  39. %make another pass;
  40. x := subs3q x;
  41. b: z := addsq(z,x);
  42. u := cdr u;
  43. go to a;
  44. c: x := list lt u ./ 1;
  45. go to b
  46. end;
  47. symbolic procedure subs3t(u,v);
  48. % U is a standard term, V a list of matching templates.
  49. % Value is a standard quotient for the substituted term.
  50. begin scalar bool,w,x,y,z;
  51. x := mtchk(car u,if domainp cdr u then sizchk(v,1) else v);
  52. if null x then go to a %lpow doesn't match;
  53. else if null caar x then go to b; %complete match found;
  54. y := subs3f1(cdr u,x,nil); %check tc for match;
  55. if mchfg!* then return multpq(car u,y);
  56. a: return list u . 1; %no match;
  57. b: x := cddar x; %list(<subst value>,<denoms>);
  58. z := caadr x; %leading denom;
  59. mchfg!* := nil; %initialize for tc check;
  60. y := subs3f1(cdr u,!*match,nil);
  61. mchfg!* := t;
  62. if car z neq caar u then go to e
  63. else if z neq car u %powers don't match;
  64. then y := multpq(caar u .** (cdar u-cdr z),y);
  65. b1: y := multsq(simpcar x,y);
  66. x := cdadr x;
  67. if null x then return y;
  68. z := 1; %unwind remaining denoms;
  69. c: if null x then go to d;
  70. w:= if atom caar x or sfp caar x then caar x else
  71. ((lambda ww;
  72. if kernp ww and eqcar(ww := mvar numr ww,car caar x)
  73. then ww
  74. else revop1 caar x)
  75. (simp caar x) where subfg!* = nil);
  76. % In the non-commutative case we have to be very careful about
  77. % order of terms in a product. Introducing negative powers
  78. % solves this problem.
  79. if noncomp w or not !*mcd then bool := t;
  80. % z := multpf(mksp(w,if null bool then cdar x else -cdar x),z);
  81. % original line
  82. z := multf(z,!*p2f mksp(w,
  83. if null bool then cdar x else -cdar x));
  84. % kernel CAAR X is not unique here. Earlier versions used just
  85. % CAAR X, but this leads to sums of terms in the wrong order.
  86. % The code here is probably still not correct in all cases, and
  87. % may lead to unbounded calculations. Maybe SIMP should be used
  88. % instead of REVOP1, with appropriate adjustments in the code
  89. % to construct Z.
  90. x := cdr x;
  91. go to c;
  92. d: return if not bool then car y . multf(z,cdr y)
  93. else multf(z,car y) . cdr y;
  94. e: if simp car z neq simp caar u then errach list('subs3t,u,x,z);
  95. %maybe arguments were in different order, otherwise it's fatal;
  96. if cdr z neq cdar u
  97. then y:= multpq(caar u .** (cdar u-cdr z),y);
  98. go to b1
  99. end;
  100. symbolic procedure sizchk(u,n);
  101. if null u then nil
  102. else if length caar u>n then sizchk(cdr u,n)
  103. else car u . sizchk(cdr u,n);
  104. symbolic procedure mtchk(u,v);
  105. %U is a standard power, V a list of matching templates.
  106. %If a match is made, value is of the form:
  107. %list list(NIL,<boolean form>,<subst value>,<denoms>),
  108. %otherwise value is an updated list of templates;
  109. begin scalar flg,v1,w,x,y,z;
  110. flg := noncomp car u;
  111. a0: if null v then return z;
  112. v1 := car v;
  113. w := car v1;
  114. a: if null w then go to d;
  115. x := mtchp1(u,car w,caadr v1,cdadr v1);
  116. b: if null x then go to c
  117. else if car (y := subla(car x,delete(car w,car v1))
  118. . list(subla(car x,cadr v1),
  119. subla(car x,caddr v1),
  120. subla(car x,car w)
  121. . cadddr v1))
  122. then z := y . z
  123. else if lispeval subla(car x,cdadr v1) then return list y;
  124. x := cdr x;
  125. go to b;
  126. c: if null flg then <<w := cdr w; go to a>>
  127. else if cadddr v1 and nocp w then go to e;
  128. d: z :=aconc(z,v1); % Could also be append(z,list v1).
  129. e: v := cdr v;
  130. go to a0
  131. end;
  132. symbolic procedure nocp u;
  133. null u or (noncomp caar u and nocp cdr u);
  134. endmodule;
  135. end;