wedge.red 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. module wedge;
  2. % Author: Eberhard Schruefer;
  3. global '(dimex!* lftshft!* wedgemtch!*);
  4. newtok '((!^) wedge);
  5. flag('(wedge),'nary);
  6. infix wedge;
  7. precedence wedge,times;
  8. smacro procedure wedgeordp(u,v); worderp(u,v);
  9. put('wedge,'simpfn,'simpwedge);
  10. put('wedge,'rtypefn,'getrtypeor);
  11. put('wedge,'partitfn,'partitwedge);
  12. symbolic procedure partitwedge u;
  13. if null cdr u then partitop car u
  14. else mkuniquewedge xpndwedge u;
  15. symbolic procedure oddp m;
  16. if not fixp m then typerr(m,"integer") else remainder(m,2) neq 0;
  17. symbolic procedure mksgnsq u;
  18. if null (u := evenfree u) then 1 ./ 1
  19. else if u = 1 then (-1) ./ 1
  20. else simpexpt list(-1,mk!*sq(u ./ 1));
  21. symbolic procedure evenfree u;
  22. if null u then nil
  23. else if numberp u then absf cdr qremd(u,2)
  24. else addf(absf cdr qremd(!*t2f lt u,2),evenfree red u);
  25. symbolic procedure mkwedge u; !*k2pf u;
  26. symbolic procedure wedgemtch u;
  27. begin scalar x,y,z;
  28. y := u;
  29. a: x := car y . x;
  30. if z := assoc(reverse x,wedgemtch!*) then
  31. return if cdr z then if cdr y then
  32. 'wedge . append(cdr z,cdr y)
  33. else cdr z
  34. else 0;
  35. y := cdr y;
  36. if y then go to a else return nil
  37. end;
  38. symbolic procedure simpwedge u;
  39. !*pf2sq partitwedge u;
  40. symbolic procedure xpndwedge u;
  41. if null cdr u
  42. then mkunarywedge partitop car u
  43. else wedgepf2(partitop car u,xpndwedge cdr u);
  44. symbolic procedure mkunarywedge u;
  45. if null u then nil
  46. else list ldpf u .* lc u .+ mkunarywedge red u;
  47. symbolic procedure mkuniquewedge u;
  48. if null u then nil
  49. else addpf(multpfsq(mkuniquewedge1 ldpf u,lc u),
  50. mkuniquewedge red u);
  51. symbolic procedure mkuniquewedge1 u;
  52. if null cdr u
  53. then mkupf car u
  54. else begin scalar x;
  55. return if wedgemtch!* and (x := wedgemtch u)
  56. then partitop x
  57. else mkupf('wedge . u)
  58. end;
  59. symbolic procedure wedgepf2(u,v);
  60. %Basic binary exterior product routine.
  61. %v is an exterior product (without wedge tag), u a form.
  62. if null u or null v then nil
  63. else addpf(wedget2(lt u,lt v),
  64. addpf(wedgepf2(lt u .+ nil,red v),wedgepf2(red u,v)));
  65. smacro procedure multwedgesq(u,v);
  66. %possible entry for lazy multiplication.
  67. multsq(u,v);
  68. symbolic procedure wedget2(u,v);
  69. if car u = 1 then car v .* multsq(cdr u,cdr v) .+ nil
  70. else if caar v = 1 then list car u .* multsq(cdr u,cdr v) .+ nil
  71. else multpfsq(wedgek2(car u,car v,nil),multwedgesq(tc u,tc v));
  72. symbolic procedure wedgek2(u,v,w);
  73. if u eq car v and null eqcar(u,'wedge)
  74. then if (fixp n and oddp n) where n = deg!*form u then nil
  75. else multpfsq(wedgef(u . v),mksgnsq w)
  76. else if eqcar(car v,'wedge) then wedgek2(u,cdar v,w)
  77. else if eqcar(u,'wedge)
  78. then multpfsq(wedgewedge(cdr u,v),mksgnsq w)
  79. else if wedgeordp(u,car v)
  80. then multpfsq(wedgef(u . v),mksgnsq w)
  81. else if cdr v
  82. then wedgepf2(!*k2pf car v,
  83. wedgek2(u,cdr v,addf(w,multf(deg!*form u,
  84. deg!*form car v))))
  85. else multpfsq(wedgef list(car v,u),
  86. mksgnsq addf(w,multf(deg!*form u,deg!*form car v)));
  87. symbolic procedure wedgewedge(u,v);
  88. if null cdr u then wedgepf2(!*k2pf car u,!*k2pf v)
  89. else wedgepf2(!*k2pf car u,wedgewedge(cdr u,v));
  90. symbolic procedure wedgef u;
  91. if dim!<deg u then nil
  92. else if eqcar(car u,'hodge) then
  93. (if m = deg!*farg cdr u then
  94. multpfsq(wedgepf2(!*k2pf cadar u,
  95. mkunarywedge
  96. hodgepf if cddr u
  97. then mkuniquewedge1 cdr u
  98. else !*k2pf cadr u),
  99. mksgnsq multf(m,addf(m,negf dimex!*)))
  100. else mkwedge u)
  101. where m = deg!*form cadar u
  102. else if eqcar(car u,'d) and (flagp('d,'noxpnd)
  103. or lftshftp cadar u) then
  104. addpf(mkunarywedge dwedge(cadar u . cdr u),
  105. multpfsq(wedgepf2(!*k2pf cadar u,
  106. mkunarywedge
  107. if cddr u
  108. then dwedge cdr u
  109. else exdfk cadr u),
  110. negsq mksgnsq deg!*form cadar u))
  111. else mkwedge u;
  112. put('wedge,'fancy!-infix!-symbol,217);
  113. endmodule;
  114. end;