hephys.red 24 KB

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