eqn.red 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. module eqn; % Support for equations as top level structures.
  2. % Author: Anthony C. Hearn.
  3. % Copyright (c) 1990 The RAND Corporation. All rights reserved.
  4. % At the moment "EQUAL" is the tag for such structures.
  5. % Evalequal is defined in alg/algbool.
  6. fluid '(!*evallhseqp);
  7. switch evallhseqp;
  8. !*evallhseqp := t; % Default is currently on.
  9. symbolic procedure equalreval u;
  10. % This definition really needs to know whether we are trying
  11. % to produce a tagged standard quotient or a prefix form.
  12. % It would also be more efficient to leave a *SQ form unchanged
  13. % on the right hand side as shown. However, it messes up printing.
  14. (if !*evallhseqp or not atom car u and flagp(caar u,'immediate)
  15. then list('equal,reval car u,x)
  16. else list('equal,car u,x))
  17. where x= reval y % (if eqcar(y,'!*sq) then aeval y else reval y)
  18. where y=cadr u;
  19. put('equal,'psopfn,'equalreval);
  20. put('equal,'rtypefn,'quoteequation);
  21. put('equal,'i2d,'eqnerr);
  22. symbolic procedure eqnerr u; typerr(u,"equation");
  23. put('equation,'evfn,'evaleqn);
  24. % symbolic procedure evaleqn(u,v);
  25. % begin scalar op,x;
  26. % if null cdr u or not eqcar(cadr u,'equal)
  27. % then rerror(alg,26,"Invalid equation structure");
  28. % op := car u;
  29. % if null cddr u
  30. % then return 'equal . for each j in cdadr u
  31. % collect if op eq 'eqneval then reval1(j,v) else list(op,j)
  32. % else if eqcar(caddr u,'equal) or cdddr u
  33. % then rerror(alg,27,"Invalid equation structure");
  34. % x := caddr u;
  35. % return 'equal . for each j in cdadr u collect list(op,j,x)
  36. % end;
  37. % put('eqneval,'rtypefn,'getrtypecar);
  38. symbolic procedure evaleqn(u,v);
  39. % This function allows us to perform elementary equation arithmetic
  40. % combining one equation and scalars by + - * / ^, and to compute
  41. % sums and differences of equations. Restriction: the equation must
  42. % be the leftmost term in the arithmetic expression.
  43. begin scalar e,l,r,w,op,x,found;
  44. if (x:=get(u,'avalue)) then u:=cadr x;
  45. if not !*evallhseqp then
  46. <<if eqcar(u,'equal) then return equalreval cdr u else
  47. typerr(u,"algebraic expression when evallhseqp is off")>>;
  48. op:=car u; w:=cdr u;
  49. if op='plus or op='difference or op='minus then
  50. <<for each q in w do
  51. <<q:=reval q;
  52. if eqcar(q,'equal)
  53. then <<l:=cadr q.l; r:=caddr q.r;found:=t>>
  54. else <<l:=q.l; r:=q.r>>;
  55. >>;
  56. r:=op.reverse r; l:=op.reverse l;
  57. >>
  58. else
  59. << u:=op . for each q in w collect reval q;
  60. e:=evaleqn1(u,u,nil);
  61. if e then
  62. <<l:=subst(cadr e,e,u); r:=subst(caddr e,e,u); found:=t>>;
  63. >>;
  64. if not found then rederr
  65. "failed to locate equal sign in equation processing";
  66. return {'equal, reval1(l,v), reval1(r,v)}
  67. end;
  68. symbolic procedure evaleqn1(u,u0,e);
  69. if atom u then e
  70. else
  71. if car u='equal then
  72. (if e then typerr(u0,"equation expression") else u)
  73. else evaleqn1(cdr u,u0,evaleqn1(car u,u0,e));
  74. % put(equal,'prifn,'equalpri);
  75. % put('equal,'lengthfn,'eqnlength);
  76. symbolic procedure lhs u;
  77. % Returns the left-hand-side of an equation.
  78. lhs!-rhs(u,'cadr);
  79. symbolic procedure rhs u;
  80. % Returns the right-hand-side of an equation.
  81. lhs!-rhs(u,'caddr);
  82. symbolic procedure lhs!-rhs(u,op);
  83. <<if not(pairp u and get(car u,'infix) and cdr u and cddr u
  84. and null cdddr u)
  85. then typerr(u,"argument for LHS or RHS");
  86. apply1(op,u)>>;
  87. flag('(lhs rhs),'opfn); % Make symbolic operators.
  88. % Explicit substitution code for equations.
  89. symbolic procedure eqnsub(u,v);
  90. if !*evallhseqp or not atom car u and flagp(caar u,'immediate)
  91. then 'equal . for each x in cdr v collect subeval1(u,x)
  92. else list('equal,cadr v,subeval1(u,caddr v));
  93. put('equation,'subfn,'eqnsub);
  94. put('equation,'lengthfn,'eqnlength);
  95. symbolic procedure eqnlength u; length cdr u;
  96. endmodule;
  97. end;