hephys.red 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. module hephys; % Support for high energy physics calculations.
  2. % Author: Anthony C. Hearn.
  3. % Generalizations for n dimensional vector and gamma algebra by
  4. % Gastmans, Van Proeyen and Verbaeten, University of Leuven, Belgium.
  5. % Copyright (c) 1987 The RAND Corporation. All rights reserved.
  6. fluid '(!*sub2 ndims!*);
  7. global '(defindices!* indices!* mul!* ncmp!* ndim!*);
  8. defindices!* := nil; % Deferred indices in N dim calculations.
  9. indices!* := nil; % List of indices in High Energy Physics
  10. % tensor expressions.
  11. ndim!* := 4; % Number of dimensions in gamma algebra.
  12. % *********************** SOME DECLARATIONS *************************
  13. deflist ('((cons simpdot)),'simpfn);
  14. put('vector,'stat,'rlis);
  15. % put('vector,'formfn,'formvector);
  16. %symbolic procedure formvector(u,vars,mode);
  17. % if mode eq 'algebraic
  18. % then list('vector1,'list . formlis(cdr u,vars,'algebraic))
  19. % else u;
  20. symbolic procedure vector u; vector1 u;
  21. symbolic procedure vector1 u;
  22. for each x in u do
  23. begin scalar y;
  24. if not idp x or (y := getrtype x) and y neq 'vector
  25. then typerr(list(y,x),"high energy vector")
  26. else put(x,'rtype,'vector)
  27. end;
  28. put('vector,'fn,'vecfn);
  29. put('vector,'evfn,'veval);
  30. put('g,'simpfn,'simpgamma);
  31. flagop nospur;
  32. flag ('(g),'noncom);
  33. symbolic procedure index u;
  34. begin vector1 u; rmsubs(); indices!* := union(indices!*,u) end;
  35. symbolic procedure remind u;
  36. begin indices!* := setdiff(indices!*,u) end;
  37. symbolic procedure mass u;
  38. if null car u then rederr "No arguments to MASS"
  39. else <<for each x in u do put(cadr x,'rtype,'vector);
  40. for each x in u do put(cadr x,'mass,caddr x)>>;
  41. symbolic procedure getmas u;
  42. (lambda x; if x then x else rederr list(u,"has no mass"))
  43. get!*(u,'mass);
  44. symbolic procedure vecdim u;
  45. begin ndim!* := car u end;
  46. symbolic procedure mshell u;
  47. begin scalar x,z;
  48. a: if null u then return let0 z;
  49. x := getmas car u;
  50. z := list('equal,list('cons,car u,car u),list('expt,x,2)) . z;
  51. u := cdr u;
  52. go to a
  53. end;
  54. rlistat '(vecdim index mass mshell remind vector);
  55. % ******** FUNCTIONS FOR SIMPLIFYING HIGH ENERGY EXPRESSIONS *********
  56. symbolic procedure veval(u,v);
  57. begin scalar z;
  58. u := nssimp(u,'vector);
  59. a: if null u then return replus z
  60. else if null cdar u then rederr "Missing vector"
  61. else if cddar u
  62. then msgpri("Redundant vector in",cdar u,nil,nil,t);
  63. z := aconc!*(z,retimes(prepsq caar u . cdar u));
  64. u := cdr u;
  65. go to a
  66. end;
  67. symbolic procedure vmult u;
  68. begin scalar z;
  69. z := list list(1 . 1);
  70. a: if null u then return z;
  71. z := vmult1(nssimp(car u,'vector),z);
  72. if null z then return;
  73. u := cdr u;
  74. go to a
  75. end;
  76. symbolic procedure vmult1(u,v);
  77. begin scalar z;
  78. if null v then return;
  79. a: if null u then return z
  80. else if cddar u
  81. then msgpri("Redundant vector in",cdar u,nil,nil,t);
  82. z := nconc!*(z,mapcar(v,function (lambda j;
  83. multsq(car j,caar u) . append(cdr j,cdar u))));
  84. u := cdr u;
  85. go to a
  86. end;
  87. symbolic procedure simpdot u;
  88. mkvarg(u,function dotord);
  89. symbolic procedure dotord u;
  90. <<if xnp(u,indices!*) and not ('isimpq memq mul!*)
  91. then mul!* := aconc!*(mul!*,'isimpq) else nil;
  92. if 'a memq u
  93. then rederr "A represents only gamma5 in vector expressions"
  94. else mksq('cons . ord2(car u,carx(cdr u,'dot)),1)>>;
  95. symbolic procedure mkvarg(u,v);
  96. begin scalar z;
  97. u := vmult u;
  98. z := nil ./ 1;
  99. a: if null u then return z;
  100. z := addsq(multsq(apply1(v,cdar u),caar u),z);
  101. u := cdr u;
  102. go to a
  103. end;
  104. symbolic procedure spur u;
  105. <<rmsubs();
  106. map(u,function (lambda j;
  107. <<remflag(list car j,'nospur);
  108. remflag(list car j,'reduce)>>))>>;
  109. rlistat '(spur);
  110. symbolic procedure simpgamma u;
  111. if null u or null cdr u
  112. then rederr "Missing arguments for G operator"
  113. else begin scalar z;
  114. if not ('isimpq memq mul!*) then mul!*:= aconc!*(mul!*,'isimpq);
  115. ncmp!* := t;
  116. z := nil ./ 1;
  117. for each j in vmult cdr u do
  118. z := addsq(multsq(!*k2q('g . car u . cdr j),car j),z);
  119. return z
  120. end;
  121. symbolic procedure simpeps u;
  122. mkvarg(u,function epsord);
  123. symbolic procedure epsord u;
  124. if repeats u then nil ./ 1 else mkepsq u;
  125. symbolic procedure mkepsk u;
  126. % U is of the form (v1 v2 v3 v4).
  127. % Value is <sign flag> . <kernel for EPS(v1,v2,v3,v4)>.
  128. begin scalar x;
  129. if xnp(u,indices!*) and not 'isimpq memq mul!*
  130. then mul!* := aconc!*(mul!*,'isimpq);
  131. x := ordn u;
  132. u := permp(x,u);
  133. return u . ('eps . x)
  134. end;
  135. symbolic procedure mkepsq u;
  136. (lambda x; (lambda y; if null car x then negsq y else y)
  137. mksq(cdr x,1))
  138. mkepsk u;
  139. % ** FUNCTIONS FOR SIMPLIFYING VECTOR AND GAMMA MATRIX EXPRESSIONS **
  140. symbolic smacro procedure mkg(u,l);
  141. % Value is the standard form for G(L,U).
  142. !*p2f('g . l . u to 1);
  143. symbolic smacro procedure mka l;
  144. % Value is the standard form for G(L,A).
  145. !*p2f(list('g,l,'a) to 1);
  146. symbolic smacro procedure mkgamf(u,l);
  147. mksf('g . (l . u));
  148. symbolic procedure mkg1(u,l);
  149. if not flagp(l,'nospur) then mkg(u,l) else mkgamf(u,l);
  150. symbolic smacro procedure mkpf(u,v);
  151. multpf(u,v);
  152. symbolic procedure mkf(u,v);
  153. multf(u,v);
  154. symbolic procedure multd!*(u,v);
  155. if u=1 then v else multd(u,v); % onep
  156. symbolic smacro procedure addfs(u,v);
  157. addf(u,v);
  158. symbolic smacro procedure multfs(u,v);
  159. % U and V are pseudo standard forms.
  160. % Value is pseudo standard form for U*V.
  161. multf(u,v);
  162. symbolic procedure isimpq u;
  163. begin scalar ndims!*;
  164. ndims!* := simp ndim!*;
  165. if denr ndims!* neq 1
  166. then <<!*sub2 := t;
  167. ndims!* := multpf(mksp(list('recip,denr ndims!*),1),
  168. numr ndims!*)>>
  169. else ndims!* := numr ndims!*;
  170. a: u := isimp1(numr u,indices!*,nil,nil,nil) ./ denr u;
  171. if defindices!*
  172. then <<indices!* := union(defindices!*,indices!*);
  173. defindices!* := nil;
  174. go to a>>
  175. else if null !*sub2 then return u
  176. else return resimp u
  177. end;
  178. symbolic procedure isimp1(u,i,v,w,x);
  179. if null u then nil
  180. else if domainp u
  181. then if x then multd(u,spur0(car x,i,v,w,cdr x))
  182. else if v then rederr("Unmatched index" . i)
  183. else if w then multfs(emult w,isimp1(u,i,v,nil,x))
  184. else u
  185. else addfs(isimp2(car u,i,v,w,x),isimp1(cdr u,i,v,w,x));
  186. symbolic procedure isimp2(u,i,v,w,x);
  187. begin scalar z;
  188. if atom (z := caar u) then go to a
  189. else if car z eq 'cons and xnp(cdr z,i)
  190. then return dotsum(u,i,v,w,x)
  191. else if car z eq 'g
  192. then go to b
  193. else if car z eq 'eps then return esum(u,i,v,w,x);
  194. a: return mkpf(car u,isimp1(cdr u,i,v,w,x));
  195. b: z := gadd(appn(cddr z,cdar u),x,cadr z);
  196. return isimp1(multd!*(nb car z,cdr u),i,v,w,cdr z)
  197. end;
  198. symbolic procedure nb u;
  199. if u then 1 else -1;
  200. symbolic smacro procedure mkdot(u,v);
  201. % Returns a standard form for U . V.
  202. mksf('cons . ord2(u,v));
  203. symbolic procedure dotsum(u,i,v,w,x);
  204. begin scalar i1,n,u1,u2,v1,y,z,z1;
  205. n := cdar u;
  206. if not (car (u1 := cdaar u) member i) then u1 := reverse u1;
  207. u2 := cadr u1;
  208. u1 := car u1;
  209. v1 := cdr u;
  210. if n=2 then go to h
  211. else if n neq 1 then typerr(n,"index power");
  212. a: if u1 member i then go to a1
  213. else if null (z := mkdot(u1,u2)) then return nil
  214. else return mkf(z,isimp1(v1,i1,v,w,x));
  215. a1: i1 := delete(u1,i);
  216. if u1 eq u2 then return multf(ndims!*,isimp1(v1,i1,v,w,x))
  217. else if not (z := bassoc(u1,v)) then go to c
  218. else if u2 member i then go to d;
  219. if u1 eq car z then u1 := cdr z else u1 := car z;
  220. go to e;
  221. c: if z := memlis(u1,x)
  222. then return isimp1(v1,
  223. i1,
  224. v,
  225. w,
  226. subst(u2,u1,z) . delete(z,x))
  227. else if z := memlis(u1,w)
  228. then return esum((('eps . subst(u2,u1,z)) . 1) . v1,
  229. i1,
  230. v,
  231. delete(z,w),
  232. x)
  233. else if u2 member i and null y then go to g;
  234. return isimp1(v1,i,(u1 . u2) . v,w,x);
  235. d: z1 := u1;
  236. u1 := u2;
  237. if z1 eq car z then u2 := cdr z else u2 := car z;
  238. e: i := i1;
  239. v := delete(z,v);
  240. go to a;
  241. g: y := t;
  242. z := u1;
  243. u1 := u2;
  244. u2 := z;
  245. go to a1;
  246. h: if u1 eq u2 then rederr "2 invalid as repeated index power";
  247. i := i1 := delete(u1,i);
  248. u1 := u2;
  249. go to a
  250. end;
  251. symbolic procedure mksf u;
  252. % U is a kernel.
  253. % Value is a (possibly substituted) standard form for U.
  254. begin scalar x;
  255. x := mksq(u,1);
  256. if cdr x=1 then return car x;
  257. !*sub2 := t;
  258. return !*p2f(u to 1)
  259. end;
  260. % ********* FUNCTIONS FOR SIMPLIFYING DIRAC GAMMA MATRICES **********
  261. symbolic procedure gadd(u,v,l);
  262. begin scalar w,x; integer n;
  263. n := 0; % Number of gamma5 interchanges.
  264. if not (x := atsoc(l,v)) then go to a;
  265. v := delete(x,v);
  266. w := cddr x; % List being built.
  267. x := cadr x; % True if gamma5 remains.
  268. a: if null u then return (evenp n . (l . x . w) . v)
  269. else if car u eq 'a then go to c
  270. else w := car u . w;
  271. b: u := cdr u;
  272. go to a;
  273. c: if ndims!* neq 4
  274. then rederr "Gamma5 not allowed unless vecdim is 4";
  275. x := not x;
  276. n := length w + n;
  277. go to b
  278. end;
  279. % ***** FUNCTIONS FOR COMPUTING TRACES OF DIRAC GAMMA MATRICES *******
  280. symbolic procedure spur0(u,i,v1,v2,v3);
  281. begin scalar l,w,i1,kahp,n,z;
  282. l := car u;
  283. n := 1;
  284. z := cadr u;
  285. u := reverse cddr u;
  286. if z then u := 'a . u; % Gamma5 remains.
  287. if null u then go to end1
  288. else if null flagp(l,'nospur)
  289. then if car u eq 'a and (length u<5 or hevenp u)
  290. or not car u eq 'a and not hevenp u
  291. then return nil
  292. else if null i then <<w := reverse u; go to end1>>;
  293. a:
  294. if null u then go to end1
  295. else if car u member i
  296. then if car u member cdr u
  297. then <<if car u eq cadr u
  298. then <<i := delete(car u,i);
  299. u := cddr u;
  300. n := multf(n,ndims!*);
  301. go to a>>;
  302. kahp := t;
  303. i1 := car u . i1;
  304. go to a1>>
  305. else if car u member i1 then go to a1
  306. else if z := bassoc(car u,v1)
  307. then <<v1 := delete(z,v1);
  308. i := delete(car w,i);
  309. u := other(car u,z) . cdr u;
  310. go to a>>
  311. else if z := memlis(car u,v2)
  312. then return if flagp(l,'nospur)
  313. and null v1
  314. and null v3
  315. and null cdr v2
  316. then mkf(mkgamf(append(reverse w,u),l),
  317. multfs(n,mkepsf z))
  318. else multd!*(n,
  319. isimp1(spur0(
  320. l . (nil . append(reverse u,w)),nil,nil,delete(z,v2),v3),
  321. i,v1,list z,nil))
  322. else if z := memlis(car u,v3)
  323. then if ndims!*=4
  324. then return spur0i(u,delete(car u,i),v1,v2,
  325. delete(z,v3),l,n,w,z)
  326. else <<indices!* := delete(car u,indices!*);
  327. i := delete(car u,i);
  328. if not car u memq defindices!*
  329. then defindices!* :=
  330. car u . defindices!*;
  331. go to a1>>
  332. else rederr list("Unmatched index",car u);
  333. a1:
  334. w := car u . w;
  335. u := cdr u;
  336. go to a;
  337. end1:
  338. if kahp
  339. then if ndims!*=4
  340. then <<z := multfs(n,kahane(reverse w,i1,l));
  341. return isimp1(z,setdiff(i,i1),v1,v2,v3)>>
  342. else z := spurdim(w,i,l,nil,1)
  343. else z := spurr(w,l,nil,1);
  344. return if null z then nil
  345. else if get('eps,'klist) and not flagp(l,'nospur)
  346. then isimp1(multfs(n,z),i,v1,v2,v3)
  347. else multfs(z,isimp1(n,i,v1,v2,v3))
  348. end;
  349. symbolic procedure spur0i(u,i,v1,v2,v3,l,n,w,z);
  350. begin scalar kahp,i1;
  351. if flagp(l,'nospur) and flagp(car z,'nospur)
  352. then rederr "NOSPUR on more than one line not implemented"
  353. else if flagp(car z,'nospur) then kahp := car z;
  354. z := cdr z;
  355. i1 := car z;
  356. z := reverse cdr z;
  357. if i1 then z := 'a . z;
  358. i1 := nil;
  359. <<while null (car u eq car z) do
  360. <<i1 := car z . i1; z := cdr z>>;
  361. z := cdr z;
  362. u := cdr u;
  363. if flagp(l,'nospur)
  364. then <<w := w . (u . (i1 . z));
  365. i1 := car w;
  366. z := cadr w;
  367. u := caddr w;
  368. w := cdddr w>>;
  369. w := reverse w;
  370. if null ((null u or not eqcar(w,'a)) and (u := append(u,w)))
  371. then <<if not hevenp u then n := - n;
  372. u := 'a . append(u,cdr w)>>;
  373. if kahp then l := kahp;
  374. z :=
  375. mkf(mkg(reverse i1,l),
  376. multf(brace(u,l,i),multfs(n,mkg1(z,l))));
  377. z := isimp1(z,i,v1,v2,v3);
  378. if null z or (z := quotf(z,2)) then return z
  379. else errach list('spur0,n,i,v1,v2,v3)>>
  380. end;
  381. symbolic procedure spurdim(u,i,l,v,n);
  382. begin scalar w,x,y,z,z1; integer m;
  383. a: if null u
  384. then return if null v then n
  385. else if flagp(l,'nospur) then multfs(n,mkgamf(v,l))
  386. else multfs(n,sprgen v)
  387. else if not(car u memq cdr u)
  388. then <<v := car u . v; u := cdr u; go to a>>;
  389. x := car u;
  390. y := cdr u;
  391. w := y;
  392. m := 1;
  393. b: if x memq i then go to d
  394. else if not x eq car w then go to c
  395. else if null(w := mkdot(x,x)) then return z;
  396. if x memq i then w := ndims!*;
  397. return addfs(mkf(w,spurdim(delete(x,y),i,l,v,n)),z);
  398. c: z1 := mkdot(x,car w);
  399. if car w memq i
  400. then z := addfs(spurdim(subst(x,car w,remove(y,m)),
  401. i,l,v,2*n),z)
  402. else if z1
  403. then z := addfs(mkf(z1,spurdim(remove(y,m),i,l,v,2*n)),z);
  404. w := cdr w;
  405. n := -n;
  406. m := m+1;
  407. go to b;
  408. d: while not(x eq car w) do
  409. <<z:= addfs(spurdim(subst(car w,x,remove(y,m)),i,l,v,2*n),z);
  410. w := cdr w;
  411. n := -n;
  412. m := m+1>>;
  413. return addfs(mkf(ndims!*,spurdim(delete(x,y),i,l,v,n)),z)
  414. end;
  415. symbolic procedure appn(u,n);
  416. if n=1 then u else append(u,appn(u,n-1));
  417. symbolic procedure other(u,v);
  418. if u eq car v then cdr v else car v;
  419. symbolic procedure kahane(u,i,l);
  420. % The Kahane algorithm for Dirac matrix string reduction.
  421. % Ref: Kahane, J., Journ. Math. Phys. 9 (1968) 1732-1738.
  422. begin scalar p,r,v,w,x,y,z; integer k,m;
  423. k := 0;
  424. mark:
  425. if eqcar(u,'a) then go to a1;
  426. a: p := not p; % Vector parity.
  427. if null u then go to d else if car u member i then go to c;
  428. a1: w := aconc!*(w,car u);
  429. b: u := cdr u;
  430. go to a;
  431. c: y := car u . p;
  432. z := (x . (y . w)) . z;
  433. x := y;
  434. w := nil;
  435. k := k+1;
  436. go to b;
  437. d: z := (nil . (x . w)) . z;
  438. % Beware ... end of string has opposite convention.
  439. pass2:
  440. m := 1;
  441. l1: if null z then go to l9;
  442. u := caar z;
  443. x := cadar z;
  444. w := cddar z;
  445. z := cdr z;
  446. m := m+1;
  447. if null u then go to l2
  448. else if (car u eq car x) and exc(x,cdr u) then go to l7;
  449. w := reverse w;
  450. r := t;
  451. l2: p := not exc(x,r);
  452. x := car x;
  453. y := nil;
  454. l3: if null z
  455. then rederr("Unmatched index" .
  456. if y then if not atom cadar y then cadar y
  457. else if not atom caar y then caar y
  458. else nil
  459. else nil)
  460. else if (x eq car (i := cadar z)) and not exc(i,p)
  461. then go to l5
  462. else if (x eq car (i := caar z)) and exc(i,p) then go to l4;
  463. y := car z . y;
  464. z := cdr z;
  465. go to l3;
  466. l4: x := cadar z;
  467. w := appr(cddar z,w);
  468. r := t;
  469. go to l6;
  470. l5: x := caar z;
  471. w := append(cddar z,w);
  472. r := nil;
  473. l6: z := appr(y,cdr z);
  474. if null x then go to l8
  475. else if not eqcar(u,car x) then go to l2;
  476. l7: if w and cdr u then w := aconc!*(cdr w,car w);
  477. v := multfs(brace(w,l,nil),v); % v := ('brace . l . w) . v;
  478. go to l1;
  479. l8: v := mkg(w,l); % v := list('g . l . w);
  480. z := reverse z;
  481. k := k/2;
  482. go to l1;
  483. l9: u := 2**k;
  484. if not evenp(k-m) then u := - u;
  485. return multd!*(u,v) % return 'times . u . v;
  486. end;
  487. symbolic procedure appr(u,v);
  488. if null u then v else appr(cdr u,car u . v);
  489. symbolic procedure exc(u,v);
  490. if null cdr u then v else not v;
  491. symbolic procedure brace(u,l,i);
  492. if null u then 2
  493. else if xnp(i,u) or flagp(l,'nospur)
  494. then addf(mkg1(u,l),mkg1(reverse u,l))
  495. else if car u eq 'a
  496. then if hevenp u then addfs(mkg(u,l),
  497. negf mkg('a . reverse cdr u,l))
  498. else mkf(mka l,spr2(cdr u,l,2,nil))
  499. else if hevenp u then spr2(u,l,2,nil)
  500. else spr1(u,l,2,nil);
  501. symbolic procedure spr1(u,l,n,b);
  502. if null u then nil
  503. else if null cdr u then multd!*(n,mkg1(u,l))
  504. else begin scalar m,x,z;
  505. x := u;
  506. m := 1;
  507. a: if null x then return z;
  508. z:= addfs(mkf(mkg1(list car x,l),
  509. if null b then spurr(remove(u,m),l,nil,n)
  510. else spr1(remove(u,m),l,n,nil)),
  511. z);
  512. x := cdr x;
  513. n := - n;
  514. m := m+1;
  515. go to a
  516. end;
  517. symbolic procedure spr2(u,l,n,b);
  518. if null cddr u and null b then multd!*(n,mkdot(car u,cadr u))
  519. else (lambda x; if b then addfs(spr1(u,l,n,b),x) else x)
  520. addfs(spurr(u,l,nil,n),
  521. mkf(mka l,spurr(append(u,list 'a),l,nil,n)));
  522. symbolic procedure hevenp u;
  523. null u or not hevenp cdr u;
  524. symbolic procedure bassoc(u,v);
  525. if null v then nil
  526. else if u eq caar v or u eq cdar v then car v
  527. else bassoc(u,cdr v);
  528. symbolic procedure memlis(u,v);
  529. if null v then nil
  530. else if u member car v then car v
  531. else memlis(u,cdr v);
  532. symbolic procedure spurr(u,l,v,n);
  533. begin scalar w,x,y,z,z1; integer m;
  534. a: if null u then go to b
  535. else if car u member cdr u then go to g;
  536. v := car u . v;
  537. u := cdr u;
  538. go to a;
  539. b: return if null v then n
  540. else if flagp(l,'nospur) then multd!*(n,mkgamf(v,l))
  541. else multd!*(n,sprgen v);
  542. g: x := car u;
  543. y := cdr u;
  544. w := y;
  545. m := 1;
  546. h: if not x eq car w then go to h1
  547. else if null(w:= mkdot(x,x)) then return z
  548. else return addfs(mkf(w,spurr(delete(x,y),l,v,n)),z);
  549. h1: z1 := mkdot(x,car w);
  550. if z1 then z:= addfs(mkf(z1,spurr(remove(y,m),l,v,2*n)),z);
  551. w := cdr w;
  552. n := - n;
  553. m := m+1;
  554. go to h
  555. end;
  556. symbolic procedure sprgen v;
  557. begin scalar x,y,z;
  558. if not (car v eq 'a) then return sprgen1(v,t)
  559. else if null (x := comb(v := cdr v,4)) then return nil
  560. else if null cdr x then go to e;
  561. c: if null x then return multpf('i to 1,z);
  562. y := mkepsf car x;
  563. if asign(car x,v,1)=-1 then y := negf y;
  564. z := addf(multf(y,sprgen1(setdiff(v,car x),t)),z);
  565. d: x := cdr x;
  566. go to c;
  567. e: z := mkepsf car x;
  568. go to d
  569. end;
  570. symbolic procedure asign(u,v,n);
  571. if null u then n else asign(cdr u,v,asign1(car u,v,-1)*n);
  572. symbolic procedure asign1(u,v,n);
  573. if u eq car v then n else asign1(u,cdr v,-n);
  574. symbolic procedure sprgen1(u,b);
  575. if null u then nil
  576. else if null cddr u then (lambda x; if b then x else negf x)
  577. mkdot(car u,cadr u)
  578. else begin scalar w,x,y,z;
  579. x := car u;
  580. u := cdr u;
  581. y := u;
  582. a: if null u then return z
  583. else if null(w:= mkdot(x,car u)) then go to c;
  584. z := addf(multf(w,sprgen1(delete(car u,y),b)),z);
  585. c: b := not b;
  586. u := cdr u;
  587. go to a
  588. end;
  589. % ****************** FUNCTIONS FOR EPSILON ALGEBRA ******************
  590. put('eps,'simpfn,'simpeps);
  591. symbolic procedure mkepsf u;
  592. (lambda x; (lambda y; if null car x then negf y else y) mksf cdr x)
  593. mkepsk u;
  594. symbolic procedure esum(u,i,v,w,x);
  595. begin scalar y,z,z1;
  596. z := car u;
  597. u := cdr u;
  598. if cdr z neq 1
  599. then u := multf(exptf(mkepsf cdar z,cdr z-1),u);
  600. z := cdar z;
  601. a: if repeats z then return;
  602. b: if null z then return isimp1(u,i,v,reverse y . w,x)
  603. else if not (car z member i) then go to d
  604. else if not (z1 := bassoc(car z,v)) then go to c;
  605. v := delete(z1,v);
  606. i := delete(car z,i);
  607. z := append(reverse y,other(car z,z1) . cdr z);
  608. y := nil;
  609. go to a;
  610. c: if z1 := memlis(car z,w) then go to c1
  611. else return isimp1(u,i,v,append(reverse y,z) . w,x);
  612. c1: z := append(reverse y,z);
  613. y := xn(i,xn(z,z1));
  614. return isimp1(multfs(emult1(z1,z,y),u),
  615. setdiff(i,y),
  616. v,
  617. delete(z1,w),
  618. x);
  619. d: y := car z . y;
  620. z := cdr z;
  621. go to b
  622. end;
  623. symbolic procedure emult u;
  624. if null cdr u then mkepsf car u
  625. else if null cddr u then emult1(car u,cadr u,nil)
  626. else multfs(emult1(car u,cadr u,nil),emult cddr u);
  627. symbolic procedure emult1(u,v,i);
  628. (lambda (x,y);
  629. (lambda (m,n);
  630. if m=4 then 24*n
  631. else if m=3 then multd(6*n,mkdot(car x,car y))
  632. else multd!*(n*(if m = 0 then 1 else m),
  633. car detq maplist(x,
  634. function (lambda k;
  635. maplist(y,
  636. function (lambda j;
  637. mkdot(car k,car j) . 1))))))
  638. (length i,
  639. (lambda j; nb if permp(u,append(i,x)) then not j else j)
  640. permp(v,append(i,y))))
  641. (setdiff(u,i),setdiff(v,i));
  642. endmodule;
  643. end;