pm.red 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. module pm; % The PM Pattern Matcher.
  2. % Author: Kevin McIsaac.
  3. create!-package('(pm pmpatch pattdefn pmintrfc pattperm unify pmrules),
  4. '(contrib pm));
  5. remflag('(i),'reserved); % This package uses I as a global index!!
  6. remprop('gamma,'simpfn); % These routines clash with SPECFN.
  7. Comment This is a fairly basic set of definitions for Ap, Map and Ar.
  8. It needs some work. The routine Ar is particularly bad;
  9. % Pattern directed application.
  10. symbolic operator ap;
  11. symbolic procedure ap(f,v);
  12. if car v neq 'list then typerr(v,'ap)
  13. else if not genexp f then
  14. if atom f then f . cdr v
  15. else append(f,cdr v)
  16. else
  17. begin scalar nv;
  18. nv := idsort union(findnewvars f,nil);
  19. v := cdr v;
  20. f := sublis(npair(nv, v), f);
  21. if length nv < length v then f := append(f,pnth(v,length nv +1));
  22. return f
  23. end;
  24. symbolic procedure npair(u, v);
  25. % Forms list of pairs from unequal length list. Terminates at end of
  26. % shortest list.
  27. if u and v then (car u . car v) . npair(cdr u, cdr v) else nil;
  28. %Pattern directed MAP
  29. put('map,'psopfn,'map0);
  30. symbolic procedure map0 arg;
  31. if length arg < 2 then nil
  32. else map1(car arg,cadr arg,if length arg >= 3 then caddr arg else 1);
  33. symbolic procedure map1(fn,v,dep);
  34. if dep>0 then car v . for each j in cdr v collect map1(fn,j,dep-1)
  35. else ap(fn,if atom v or car v neq 'list then list('list, v) else v);
  36. put('ar, 'psopfn, 'ar0);
  37. % ARange of ARray statement.
  38. symbolic procedure ar0 arg;
  39. if length arg <= 1 then nil
  40. else ar1(car arg, if length arg >= 2 then cadr arg else 'list);
  41. symbolic procedure ar1(arg,fn);
  42. if fixp arg then ar4(list(list(1,arg,1)),fn)
  43. else if atom arg or car arg neq 'list then typerr(arg,'ar)
  44. else ar4(for each j in cdr arg collect aarg(j), fn);
  45. symbolic procedure aarg(arg);
  46. revlis(
  47. if fixp arg or genp(arg) then list(1, arg, 1)
  48. else if atom arg or car arg neq 'list then typerr(arg,'ar)
  49. else begin scalar l;
  50. arg := cdr arg;
  51. l := length arg;
  52. return if l = 1 then list(1, car arg, 1)
  53. else if l = 2 then list(car arg, cadr arg, 1)
  54. else if l = 3 then list(car arg, cadr arg, caddr arg)
  55. else typerr(arg,"Ar")
  56. end);
  57. symbolic procedure ar4(lst,fn);
  58. begin scalar s, u, v, w;
  59. u := caar lst; v := cadar lst; w := caddar lst; lst := cdr lst;
  60. while u <= v do
  61. << s := append(s,list u);
  62. u := u + w>>;
  63. return if length(lst)=0 then
  64. if fn eq 'list then 'list . s
  65. else map1(fn, 'list . s, 1)
  66. else 'list . for each j in cdr map1(list(lst, fn),'list . s, 1)
  67. collect ar4(car j, cdr j);
  68. end;
  69. put('cat, 'psopfn, 'catx);
  70. symbolic procedure catx u;
  71. % Concatenate two lists.
  72. (if not eqcar(x,'list) then typerr(car u,"list")
  73. else if not eqcar(y,'list) then typerr(cadr u,"list")
  74. else 'list . append(cdr x,cdr y))
  75. where x=reval car u, y=reval cadr u;
  76. %Relational operators.
  77. symbolic procedure simpeq(arg);
  78. begin scalar x;
  79. if length arg < 2 then typerr('equal . arg,"relation");
  80. arg := reval('difference . arg);
  81. arg := if numberp arg then reval(arg = 0)
  82. else <<arg := list('equal,arg, 0);
  83. if x := opmtch(arg) then x else arg>>;
  84. return mksq(arg,1)
  85. end;
  86. symbolic procedure simpgt(arg);
  87. begin scalar x;
  88. if length arg < 2 then typerr('greaterp . arg,"relation");
  89. arg := reval('difference . arg);
  90. arg := if numberp arg then reval(arg > 0)
  91. else <<arg := list('greaterp,arg, 0);
  92. if x := opmtch(arg) then x else arg>>;
  93. return mksq(arg,1)
  94. end;
  95. symbolic procedure simpge(arg);
  96. begin scalar x;
  97. if length arg < 2 then typerr('geq . arg,"relation");
  98. arg := reval('difference . arg);
  99. arg := if numberp arg then reval(arg >= 0)
  100. else <<arg := list('geq,arg, 0);
  101. if x := opmtch(arg) then x else arg>>;
  102. return mksq(arg,1)
  103. end;
  104. symbolic procedure simplt(arg);
  105. simpgt(list(cadr arg,car arg));
  106. symbolic procedure simple(arg);
  107. simpge(list(cadr arg,car arg));
  108. put('equal, 'simpfn, 'simpeq);
  109. put('greaterp, 'simpfn, 'simpgt);
  110. put('geq, 'simpfn, 'simpge);
  111. put('lessp, 'simpfn, 'simplt);
  112. put('leq, 'simpfn, 'simple);
  113. % Form function for !?.
  114. symbolic procedure formgen(u,vars,mode);
  115. begin scalar x;
  116. u := cadr u;
  117. if atom u
  118. then if u eq '!?
  119. then <<u := intern '!?!?;
  120. x := list(mkquote u,mkquote 'mgen,t)>>
  121. else <<u := intern compress('!! . '!? . explode u);
  122. x := list(mkquote u,mkquote 'gen,t)>>
  123. else if car u neq '!?
  124. then <<u := intern compress('!! . '!? . explode car u) . cdr u;
  125. x := list(mkquote car u,mkquote 'gen,t)>>
  126. else if car u eq '!? and atom cadr u
  127. then <<u := intern compress('!! . '!? . '!! . '!?
  128. . explode cadr u);
  129. x := list(mkquote u,mkquote 'mgen,t)>>
  130. else
  131. <<u := cadr u;
  132. u := intern compress('!! . '!? . '!! . '!? . explode car u)
  133. . cdr u;
  134. x := list(mkquote car u,mkquote 'gen,t)>>;
  135. return list('progn,'put . x,form1(u,vars,mode))
  136. end;
  137. put('!?,'formfn,'formgen)$
  138. endmodule;
  139. end;
  140. endmodule;
  141. end;