maxmin.red 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. module maxmin; % Support for generalized MAX and MIN.
  2. % Author: F.J. Wright, QMW, London (fjw@maths.qmw.ac.uk) 7/7/90.
  3. % Provide support for the MAX and MIN functions to allow:-
  4. % any number domain;
  5. % any symbolic arguments remain so;
  6. % nested algebraic-level lists of arguments;
  7. % and to discard redundant nested max and min.
  8. % The Lisp functions max and min are not affected.
  9. % Revision : W. Neun, ZIB Berlin, 25/6/94
  10. % added handling of max(n,n+1,n-1) => n+1
  11. put('max, 'simpfn, 'simpmax);
  12. symbolic procedure simpmax u;
  13. S_simpmaxmin('max, function evalgreaterp, u, nil);
  14. put('min, 'simpfn, 'simpmin);
  15. symbolic procedure simpmin u;
  16. S_simpmaxmin('min, function evallessp, u, nil);
  17. flag('(max min),'listargp);
  18. symbolic smacro procedure difflist(u,v);
  19. for each uu in u collect reval list('difference,uu ,v);
  20. symbolic procedure S_simpmaxmin(maxmin, relation, u,rec);
  21. begin scalar arglist, arglistp, mval, x;
  22. if null u then return nil ./ 1; % 0 returned for empty args.
  23. arglistp := arglist := list nil; % Dummy car with cdr to rplacd.
  24. for each val in flattenmaxmin(maxmin, revlis u) do
  25. if atom denr(x := simp!* val)
  26. and (atom numr x or car numr x memq '(!:rd!: !:rn!:))
  27. % extremize numerical args:
  28. then (if null mval or apply2(relation,val, mval)
  29. then mval := val)
  30. else
  31. % successively append symbolic args efficiently:
  32. << rplacd(arglistp, list val); arglistp := cdr arglistp >>;
  33. arglist := cdr arglist; % Discard dummy car
  34. % Put any numerical extreme value at head of arg list:
  35. if mval then arglist := mval . arglist;
  36. % If more than one arg then keep as a max or min:
  37. if cdr arglist and rec then
  38. return !*kk2f(maxmin . !*trim arglist) ./ 1;
  39. if cdr arglist then
  40. if length cdr arglist >= 1 and
  41. not eqcar(prepsq(mval :=S_simpmaxmin(maxmin,relation,
  42. difflist(arglist,car arglist),T)),maxmin)
  43. then return addsq(mval,simp!* car arglist)
  44. else return !*kk2f(maxmin . !*trim arglist) ./ 1;
  45. % Otherwise just return the single (extreme) value:
  46. return simp car arglist
  47. end; % simpmaxmin
  48. symbolic procedure !*trim u;
  49. % Trim repeated elements from u.
  50. if null u then nil
  51. else if car u member cdr u then !*trim cdr u
  52. else car u . !*trim cdr u;
  53. symbolic procedure flattenmaxmin(maxmin, u);
  54. % Flatten algebraic-mode lists and already recursively simplified
  55. % calls of max/min as appropriate.
  56. for each el in u join
  57. if atom el then list el
  58. else if car el eq 'list then flattenmaxmin(maxmin, cdr el)
  59. else if car el eq maxmin then cdr el
  60. else if car el='MAT then for each r in cdr el join r
  61. else list el;
  62. endmodule;
  63. end;