str.red 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. module str; % Routines for structuring expressions.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1991 The RAND Corporation. All rights reserved.
  4. fluid '(!*fort !*nat !*savestructr scountr svar svarlis);
  5. global '(varnam!*);
  6. varnam!* := 'ans;
  7. switch savestructr;
  8. flag('(structr),'intfn); % To fool the supervisor into printing
  9. % results of STRUCTR.
  10. % ***** two essential uses of RPLACD occur in this module.
  11. symbolic procedure structr u;
  12. begin scalar scountr,fvar,svar,svarlis;
  13. % SVARLIS is a list of elements of form:
  14. % (<unreplaced expression> . <newvar> . <replaced exp>);
  15. scountr :=0;
  16. fvar := svar := varnam!*;
  17. if cdr u
  18. then <<fvar := svar := cadr u; if cddr u then fvar := caddr u>>;
  19. u := structr1 aeval car u;
  20. if !*fort then svarlis := reversip!* svarlis
  21. else if not !*savestructr
  22. then <<assgnpri(u,nil,'only);
  23. if not eqcar(u,'mat) then terpri(); % MAT already has eol
  24. if scountr=0 then return nil
  25. else <<if null !*nat then terpri();
  26. prin2t " where">>>>;
  27. if !*fort or not !*savestructr
  28. then for each x in svarlis do
  29. <<terpri!* t;
  30. if null !*fort then prin2!* " ";
  31. assgnpri(cddr x,list cadr x,t)>>;
  32. if !*fort then assgnpri(u,list fvar,t)
  33. else if !*savestructr
  34. then return 'list . u .
  35. foreach x in svarlis
  36. collect list('equal,cadr x,
  37. mkquote cddr x)
  38. end;
  39. rlistat '(structr);
  40. symbolic procedure structr1 u;
  41. % This routine considers special case STRUCTR arguments. It could be
  42. % easily generalized.
  43. if atom u then u
  44. else if car u eq 'mat
  45. then car u .
  46. (for each j in cdr u collect for each k in j collect structr1 k)
  47. else if car u eq 'list
  48. then 'list . for each j in cdr u collect structr1 j
  49. else if car u eq 'equal then list('equal,cadr u,structr1 caddr u)
  50. else if car u eq '!*sq
  51. then mk!*sq(structf numr cadr u ./ structf denr cadr u)
  52. else if getrtype u then typerr(u,"STRUCTR argument")
  53. else u;
  54. symbolic procedure structf u;
  55. if null u then nil
  56. else if domainp u then u
  57. else begin scalar x,y;
  58. x := mvar u;
  59. if sfp x then if y := assoc(x,svarlis) then x := cadr y
  60. else x := structk(prepsq!*(structf x ./ 1),
  61. structvar(),x)
  62. % else if not atom x and not atomlis cdr x
  63. else if not atom x
  64. and not(atom car x and flagp(car x,'noreplace))
  65. then if y := assoc(x,svarlis) then x := cadr y
  66. else x := structk(x,structvar(),x);
  67. % Suggested patch by Rainer Schoepf to cache powers.
  68. % if ldeg u = 1
  69. % then return x .** ldeg u .* structf lc u .+ structf red u;
  70. % z := retimes exchk list (x .** ldeg u);
  71. % if y := assoc(z,svarlis) then x := cadr y
  72. % else x := structk(z, structvar(), z);
  73. % return x .** 1 .* mystructf lc u .+ mystructf red u
  74. return x .** ldeg u .* structf lc u .+ structf red u
  75. end;
  76. symbolic procedure structk(u,id,v);
  77. begin scalar x;
  78. if x := subchk1(u,svarlis,id)
  79. then rplacd(x,(v . id . u) . cdr x)
  80. else if x := subchk2(u,svarlis)
  81. then svarlis := (v . id . x) . svarlis
  82. else svarlis := (v . id . u) . svarlis;
  83. return id
  84. end;
  85. symbolic procedure subchk1(u,v,id);
  86. begin scalar w;
  87. while v do
  88. <<smember(u,cddar v)
  89. and <<w := v; rplacd(cdar v,subst(id,u,cddar v))>>;
  90. v := cdr v>>;
  91. return w
  92. end;
  93. symbolic procedure subchk2(u,v);
  94. begin scalar bool;
  95. for each x in v do
  96. smember(cddr x,u)
  97. and <<bool := t; u := subst(cadr x,cddr x,u)>>;
  98. if bool then return u else return nil
  99. end;
  100. symbolic procedure structvar;
  101. begin
  102. scountr := scountr + 1;
  103. return if arrayp svar then list(svar,scountr)
  104. else intern compress append(explode svar,explode scountr)
  105. end;
  106. endmodule;
  107. end;