antisubs.red 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. MODULE ANTISUBS;
  2. % Author: James H. Davenport.
  3. EXPORTS ANTISUBS;
  4. IMPORTS INTERR,DEPENDSP,setdiff;
  5. SYMBOLIC PROCEDURE ANTISUBS(PLACE,X);
  6. % Produces the inverse substitution to a substitution list.
  7. BEGIN
  8. SCALAR ANSWER,W;
  9. WHILE PLACE AND
  10. (X=CAAR PLACE) DO<<
  11. W:=CDAR PLACE;
  12. % w is the substitution rule.
  13. IF ATOM W
  14. THEN IF W NEQ X
  15. THEN INTERR "False atomic substitution"
  16. ELSE NIL
  17. ELSE ANSWER:=(X.ANTI2(W,X)).ANSWER;
  18. PLACE:=CDR PLACE>>;
  19. IF NULL ANSWER
  20. THEN ANSWER:=(X.X).ANSWER;
  21. RETURN ANSWER
  22. END;
  23. SYMBOLIC PROCEDURE ANTI2(EEXPR,X);
  24. %Produces the function inverse to the eexpr provided.
  25. IF ATOM EEXPR
  26. THEN IF EEXPR EQ X
  27. THEN X
  28. ELSE INTERR "False atom"
  29. ELSE IF CAR EEXPR EQ 'PLUS
  30. THEN DEPLUS(CDR EEXPR,X)
  31. ELSE IF CAR EEXPR EQ 'MINUS
  32. THEN SUBST(LIST('MINUS,X),X,ANTI2(CADR EEXPR,X))
  33. ELSE IF CAR EEXPR EQ 'QUOTIENT
  34. THEN IF DEPENDSP(CADR EEXPR,X)
  35. THEN IF DEPENDSP(CADDR EEXPR,X)
  36. THEN INTERR "Complicated division"
  37. ELSE SUBST(LIST('TIMES,CADDR EEXPR,X),X,ANTI2(CADR EEXPR,X))
  38. ELSE IF DEPENDSP(CADDR EEXPR,X)
  39. THEN SUBST(LIST('QUOTIENT,CADR EEXPR,X),X,
  40. ANTI2(CADDR EEXPR,X))
  41. ELSE INTERR "No division"
  42. ELSE IF CAR EEXPR EQ 'EXPT
  43. THEN IF CADDR EEXPR IEQUAL 2
  44. THEN SUBST(LIST('SQRT,X),X,ANTI2(CADR EEXPR,X))
  45. ELSE INTERR "Unknown root"
  46. ELSE IF CAR EEXPR EQ 'TIMES
  47. THEN DETIMES(CDR EEXPR,X)
  48. ELSE IF CAR EEXPR EQ 'DIFFERENCE
  49. THEN DEPLUS(LIST(CADR EEXPR,LIST('MINUS,CADDR EEXPR)),X)
  50. ELSE INTERR "Unrecognised form in antisubs";
  51. SYMBOLIC PROCEDURE DETIMES(P!-LIST,VAR);
  52. % Copes with lists 'times.
  53. BEGIN
  54. SCALAR U,V;
  55. U:=DEPLIST(P!-LIST,VAR);
  56. V:=setdiff(P!-LIST,u);
  57. IF NULL V
  58. THEN V:=VAR
  59. ELSE IF NULL CDR V
  60. THEN V:=LIST('QUOTIENT,VAR,CAR V)
  61. ELSE V:=LIST('QUOTIENT,VAR,'TIMES.V);
  62. IF (NULL U) OR
  63. (CDR U)
  64. THEN INTERR "Weird multiplication";
  65. RETURN SUBST(V,VAR,ANTI2(CAR U,VAR))
  66. END;
  67. SYMBOLIC PROCEDURE DEPLIST(P!-LIST,VAR);
  68. % Returns a list of those elements of p!-list which depend on var.
  69. IF NULL P!-LIST
  70. THEN NIL
  71. ELSE IF DEPENDSP(CAR P!-LIST,VAR)
  72. THEN (CAR P!-LIST).DEPLIST(CDR P!-LIST,VAR)
  73. ELSE DEPLIST(CDR P!-LIST,VAR);
  74. SYMBOLIC PROCEDURE DEPLUS(P!-LIST,VAR);
  75. % Copes with lists 'plus.
  76. BEGIN
  77. SCALAR U,V;
  78. U:=DEPLIST(P!-LIST,VAR);
  79. V:=setdiff(P!-LIST,u);
  80. IF NULL V
  81. THEN V=VAR
  82. ELSE IF NULL CDR V
  83. THEN V:=LIST('PLUS,VAR,LIST('MINUS,CAR V))
  84. ELSE V:=LIST('PLUS,VAR,LIST('MINUS,'PLUS.V));
  85. IF (NULL U) OR
  86. (CDR U)
  87. THEN INTERR "Weird addition";
  88. RETURN SUBST(V,VAR,ANTI2(CAR U,VAR))
  89. END;
  90. ENDMODULE;
  91. END;