dummycnt.red 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. module dummycnt;
  2. fluid '(g_dvnames g_dvbase g_sc_ve g_init_stree g_skip_to_level
  3. !*distribute);
  4. %%%%%%%%%%%%%%%%%%%%%%% MISCELANEOUS ROUTINES %%%%%%%%%%%%%%%%%%%%%%%%%
  5. symbolic procedure ad_splitname(u);
  6. if idp u then
  7. begin scalar uu, nn;
  8. uu := reverse(explode u);
  9. while uu and (charnump!: car uu) do
  10. <<
  11. nn := car uu . nn;
  12. uu := cdr uu;
  13. >>;
  14. if uu then uu := intern(compress(reverse(uu)));
  15. if nn then nn := compress(nn);
  16. return (uu.nn);
  17. end;
  18. symbolic procedure anticom_assoc(u,v);
  19. begin scalar next_cell;
  20. if null v then
  21. return nil
  22. else if u = caar v then
  23. return (1 . car v)
  24. else
  25. <<
  26. next_cell := anticom_assoc(u, cdr v);
  27. if null next_cell then return nil;
  28. if oddp(length(cdar v)) then
  29. rplaca(next_cell, - car next_cell);
  30. return next_cell;
  31. >>;
  32. end;
  33. %%%%%%%%%%%%%%%%%%%%%%% ORDERING FUNCTIONS %%%%%%%%%%%%%%%%%%%%
  34. symbolic procedure ad_signsort(l, fn);
  35. begin scalar tosort, sorted, insertl, dig;
  36. integer thesign;
  37. tosort := copy l;
  38. thesign := 1;
  39. sorted := nil;
  40. while tosort do
  41. if null sorted then
  42. <<
  43. sorted := car tosort . sorted;
  44. tosort := cdr tosort;
  45. >>
  46. else if car tosort = car sorted then
  47. <<
  48. thesign := 0;
  49. sorted := tosort := nil;
  50. >>
  51. else if apply(fn, {car sorted, car tosort}) then
  52. <<
  53. sorted := car tosort . sorted;
  54. tosort := cdr tosort;
  55. >>
  56. else
  57. <<
  58. thesign := - thesign;
  59. insertl := sorted;
  60. dig := t;
  61. while dig do
  62. if null cdr insertl then
  63. dig := nil
  64. else if cadr insertl = car tosort then
  65. <<
  66. insertl := {nil};
  67. dig := nil;
  68. thesign := 0;
  69. sorted := tosort := nil;
  70. >>
  71. else if not apply(fn, {cadr insertl, car tosort}) then
  72. <<
  73. insertl := cdr insertl;
  74. thesign := - thesign;
  75. >>
  76. else
  77. dig := nil;
  78. if tosort then
  79. <<
  80. rplacd(insertl, (car tosort) . cdr insertl);
  81. tosort := cdr tosort;
  82. >>;
  83. >>;
  84. return (thesign . reverse sorted);
  85. end;
  86. symbolic procedure cdr_sort(lst, fn);
  87. begin scalar tosort, sorted, insertl;
  88. tosort := lst;
  89. while tosort do
  90. <<
  91. if (null sorted) or apply(fn, {cdar sorted, cdar tosort}) then
  92. <<
  93. sorted := car tosort . sorted;
  94. tosort := cdr tosort;
  95. >>
  96. else
  97. <<
  98. insertl := sorted;
  99. while (cdr insertl) and
  100. not(apply(fn, {cdadr insertl, cdar tosort})) do
  101. insertl := cdr insertl;
  102. rplacd(insertl, (car tosort) . cdr insertl);
  103. tosort := cdr tosort
  104. >>
  105. >>;
  106. return reverse sorted;
  107. end;
  108. symbolic procedure cdr_signsort(l, fn);
  109. begin scalar tosort, sorted, insertl, dig;
  110. integer thesign;
  111. tosort := copy l;
  112. thesign := 1;
  113. sorted := nil;
  114. while tosort do
  115. if null sorted then
  116. <<
  117. sorted := car tosort . sorted;
  118. tosort := cdr tosort;
  119. >>
  120. else if cdar tosort = cdar sorted then
  121. <<
  122. thesign := 0;
  123. sorted := tosort := nil;
  124. >>
  125. else if apply(fn, {cdar sorted, cdar tosort}) then
  126. <<
  127. sorted := car tosort . sorted;
  128. tosort := cdr tosort;
  129. >>
  130. else
  131. <<
  132. thesign := - thesign;
  133. insertl := sorted;
  134. dig := t;
  135. while dig do
  136. if null cdr insertl then
  137. dig := nil
  138. else if cdadr insertl = cdar tosort then
  139. <<
  140. dig := nil;
  141. thesign := 0;
  142. sorted := tosort := nil;
  143. >>
  144. else if not apply(fn, {cdadr insertl, cdar tosort}) then
  145. <<
  146. insertl := cdr insertl;
  147. thesign := - thesign;
  148. >>
  149. else
  150. dig := nil;
  151. if tosort then
  152. <<
  153. rplacd(insertl, (car tosort) . cdr insertl);
  154. tosort := cdr tosort
  155. >>;
  156. >>;
  157. return (thesign . reverse sorted);
  158. end;
  159. symbolic procedure num_signsort(l);
  160. ad_signsort(l, function(lambda(x,y); x <= y));
  161. symbolic procedure cons_ordp(u,v, fn);
  162. if null u then t
  163. else if null v then nil
  164. else if pairp u then
  165. if pairp v then
  166. if car u = car v then
  167. cons_ordp(cdr u, cdr v, fn)
  168. else
  169. cons_ordp(car u, car v, fn)
  170. else
  171. nil
  172. else if pairp v then t
  173. else apply2(fn,u,v);
  174. symbolic procedure atom_compare(u,v);
  175. if numberp u then numberp v and not(u < v)
  176. else if idp v then orderp(u,v)
  177. else numberp v;
  178. symbolic procedure idcons_ordp(u,v);
  179. cons_ordp(u, v, function atom_compare);
  180. symbolic procedure skp_ordp(u,v);
  181. cons_ordp(car u, car v, function atom_compare);
  182. symbolic procedure numlist_ordp(u,v);
  183. cons_ordp(u,v,function(lambda(x,y); x <= y));
  184. symbolic procedure ad_numsort(l);
  185. sort(l,function(lambda(x,y); x <= y));
  186. %%%%%%%%%%%%%%%%%%%%%%% ACCESS ROUTINES %%%%%%%%%%%%%%%%%%%%%%%%%
  187. symbolic procedure sc_kern(ind);
  188. caddr venth(g_sc_ve, ind);
  189. symbolic procedure sc_rep(ind);
  190. cadr venth(g_sc_ve, ind);
  191. symbolic procedure sc_desc(ind);
  192. car venth(g_sc_ve, ind);
  193. symbolic procedure dummyp(var);
  194. begin scalar varsplit;
  195. integer count, res;
  196. if not idp var then return nil;
  197. count := 1;
  198. while count <= upbve(g_dvnames) do
  199. <<
  200. if var = venth(g_dvnames, count) then
  201. <<
  202. res := count;
  203. count := upbve(g_dvnames) + 1
  204. >>
  205. else
  206. count := count + 1;
  207. >>;
  208. if res eq 0 then
  209. <<
  210. varsplit := ad_splitname(var);
  211. if (car varsplit eq g_dvbase) then
  212. return cdr varsplit
  213. >>
  214. else return res;
  215. end;
  216. symbolic procedure dv_ind2var(ind);
  217. if ind <= upbve(g_dvnames) then
  218. venth(g_dvnames, ind)
  219. else
  220. mkid(g_dvbase, ind);
  221. %%%%%%%%%%%%%%%%%%%%%% SYMMETRY CELLS %%%%%%%%%%%%%%%%%%%%%%%%%%
  222. symbolic procedure sc_repkern(s_cell, n);
  223. if car s_cell eq '!* then % nil symmetric cell
  224. begin scalar kern, rest, next_rest;
  225. integer head, rep;
  226. rest := cdr s_cell;
  227. rep := 0;
  228. while rest do
  229. <<
  230. head := car rest;
  231. kern := {head} . kern;
  232. rest := cdr rest;
  233. next_rest := nil;
  234. rep := rep*2 + 1;
  235. for each elt in rest do
  236. <<
  237. if elt eq head then
  238. rep := rep * 2 + 1
  239. else
  240. <<
  241. rep := rep * 2;
  242. next_rest := elt . next_rest
  243. >>
  244. >>;
  245. rest := reverse next_rest;
  246. >>;
  247. return {rep, pa_list2vect(reverse kern, n)};
  248. end
  249. else
  250. begin scalar count, replist, rep, kern;
  251. integer last_count;
  252. s_cell := cdr s_cell; % s_cell supposed sorted
  253. for each elt in s_cell do
  254. if (count := assoc(elt, replist)) then
  255. rplacd (count, cdr count + 1)
  256. else
  257. replist := (elt . 1) . replist;
  258. replist := sort(replist, function(lambda(x,y); cdr x <= cdr y));
  259. last_count := 0;
  260. for each elt in replist do
  261. if (cdr elt neq last_count) then
  262. <<
  263. rep := (cdr elt . 1) . rep;
  264. kern := {car elt} . kern;
  265. last_count := cdr elt;
  266. >>
  267. else
  268. <<
  269. rplacd(car rep, cdar rep + 1);
  270. rplaca(kern, car elt . car kern)
  271. >>;
  272. return {rep , pa_list2vect(kern, n)};
  273. end;
  274. %%%%%%%%%%%%%%%%%%%%% PARTITIONS COMP %%%%%%%%%%%%%%%%%%%%%%%%%%
  275. symbolic procedure pa_list2vect(pa, n);
  276. begin scalar ve, reps;
  277. integer abs;
  278. ve := mkve(n);
  279. for each cell in pa do
  280. <<
  281. reps := eval('min . cell) . reps;
  282. for each elt in cell do putve(ve, elt, car reps);
  283. >>;
  284. for count := 1:n do
  285. <<
  286. if null venth(ve, count) then
  287. <<
  288. if abs = 0 then
  289. <<
  290. abs := count;
  291. reps := abs . reps
  292. >>;
  293. putve(ve, count, abs)
  294. >>
  295. >>;
  296. return ((reverse reps) . ve);
  297. end;
  298. symbolic procedure pa_part2list(p);
  299. begin scalar ve;
  300. integer len, rep;
  301. len := upbve(cdr p);
  302. ve := mkve(len);
  303. for count := len step -1 until 1 do
  304. <<
  305. rep := venth(cdr p, count);
  306. putve(ve, rep, count . venth(ve, rep));
  307. >>;
  308. return for each count in car p join copy
  309. venth(ve,count);
  310. end;
  311. symbolic procedure pa_vect2list(pa);
  312. begin scalar ve;
  313. integer count, rep;
  314. ve := mkve(upbve(cdr pa));
  315. for count := 1 : upbve(cdr pa) do
  316. <<
  317. rep := venth(cdr pa, count);
  318. putve(ve, rep, count . venth(ve,rep));
  319. >>;
  320. return for each rep in (car pa) collect ordn(venth(ve, rep));
  321. end;
  322. symbolic procedure pa_coinc_split(p1, p2);
  323. begin
  324. scalar ve1, ve2, cursplit, split_alist, split_info, coinc, split;
  325. integer count, plength;
  326. plength := upbve(cdr p1);
  327. ve1 := mkve(plength);
  328. ve2 := mkve(plength);
  329. split := mkve(plength);
  330. count := 0;
  331. for each rep in car p1 do
  332. <<
  333. count := count + 1;
  334. putve(ve1, rep, count)
  335. >>;
  336. count := 0;
  337. for each rep in car p2 do
  338. <<
  339. count := count + 1;
  340. putve(ve2, rep, count)
  341. >>;
  342. for count := 1 : plength do
  343. <<
  344. cursplit := (venth(ve1, venth(cdr p1, count)) .
  345. venth(ve2, venth(cdr p2, count)));
  346. if (split_info := assoc(cursplit, split_alist)) then
  347. <<
  348. rplacd(cdr split_info, cddr split_info + 1);
  349. putve(split, count, cadr split_info)
  350. >>
  351. else
  352. <<
  353. split_info := cursplit . (count . 1);
  354. split_alist := split_info . split_alist;
  355. putve(split, count, count)
  356. >>
  357. >>;
  358. split_alist :=
  359. sort(split_alist,
  360. function(lambda x,y;
  361. if caar x < caar y then t
  362. else if caar y < caar x then nil
  363. else cdar x leq cdar y));
  364. split := (for each cell in split_alist collect cadr cell) . split;
  365. coinc := for each cell in split_alist collect
  366. (car cell) . (cddr cell);
  367. return coinc . split;
  368. end;
  369. %%%%%%%%%%%%%%%%%%%%% SYMMETRY TREES %%%%%%%%%%%%%%%%%%%%%%%%%%%
  370. symbolic procedure st_flatten(stree);
  371. if numberp(cadr stree) then
  372. cdr stree
  373. else
  374. for each elt in cdr stree join copy st_flatten(elt);
  375. symbolic procedure st_extract_symcells(stree, maxind);
  376. begin scalar ve, symcells;
  377. integer count;
  378. if null stree then return (nil . mkve(0));
  379. symcells := st_extract_symcells1(st_consolidate(stree),nil,1);
  380. stree := car symcells;
  381. if not listp stree then % stree is a single symcell
  382. stree := {'!* , stree};
  383. symcells := cadr symcells;
  384. ve := mkve(length(symcells));
  385. count := upbve(ve);
  386. while symcells do
  387. <<
  388. putve(ve, count, car symcells . sc_repkern(car symcells, maxind));
  389. symcells := cdr symcells;
  390. count := count - 1
  391. >>;
  392. return(st_consolidate(stree) . ve);
  393. end;
  394. symbolic procedure st_extract_symcells1(stree, symcells, count);
  395. begin scalar res, new_stree;
  396. if not listp cadr stree then % stree is a symcell
  397. return { count , stree . symcells, count + 1}
  398. else
  399. <<
  400. new_stree := car stree .
  401. for each inner_stree in cdr stree collect
  402. <<
  403. res := st_extract_symcells1(inner_stree, symcells, count);
  404. symcells := cadr res;
  405. count := caddr res;
  406. if numberp car res then
  407. {'!*, car res}
  408. else
  409. car res
  410. >>;
  411. return ({ new_stree, symcells, count })
  412. >>;
  413. end;
  414. symbolic procedure st_signchange(ve1, ve2);
  415. car st_signchange1(g_init_stree, vect2list ve1) *
  416. car st_signchange1(g_init_stree, vect2list ve2);
  417. symbolic procedure st_signchange1(stree, eltlist);
  418. begin scalar levlist, elt_levlist, subsign;
  419. integer the_sign;
  420. the_sign := 1;
  421. levlist := for each child in cdr stree collect
  422. if numberp child then
  423. child
  424. else
  425. <<
  426. subsign := st_signchange1(child, eltlist);
  427. the_sign := the_sign * car subsign;
  428. cdr subsign
  429. >>;
  430. if not cdr levlist then return (the_sign . car levlist);
  431. elt_levlist := eltlist;
  432. if member(car eltlist, levlist) then
  433. elt_levlist := 0 . elt_levlist
  434. else while not member(cadr elt_levlist, levlist) do
  435. elt_levlist := cdr elt_levlist;
  436. %% cdr elt_levlist starts with the elements of levlist
  437. %% Compute the sign change
  438. if car stree eq '!- and not permp(levlist, cdr elt_levlist) then
  439. the_sign := - the_sign;
  440. %% remove from elt_levlist (and thus from eltlist)
  441. %% the elements of levlist except the last (which will be the
  442. %% ref).
  443. rplacd(elt_levlist, pnth(cdr elt_levlist, length(levlist)));
  444. return (the_sign . cadr elt_levlist);
  445. end;
  446. symbolic procedure st_sorttree(stree, ve, fn);
  447. cdr st_sorttree1(stree, ve, fn);
  448. symbolic procedure st_sorttree1(stree, ve, fn);
  449. begin scalar schild, vallist, sorted, thesign, tosort;
  450. thesign := 1;
  451. if numberp cadr stree then
  452. <<
  453. if car stree eq '!* then
  454. <<
  455. vallist := for each elt in cdr stree collect venth(ve,elt);
  456. return (vallist . (1 . stree))
  457. >>;
  458. tosort := for each elt in cdr stree collect
  459. elt . venth(ve,elt);
  460. >>
  461. else
  462. <<
  463. if (car stree) eq '!* then
  464. <<
  465. for each child in cdr stree do
  466. if thesign neq 0 then
  467. <<
  468. schild := st_sorttree1(child, ve, fn);
  469. thesign := thesign * cadr schild;
  470. vallist := (car schild) . vallist;
  471. sorted := (cddr schild) . sorted;
  472. >>;
  473. if thesign = 0 then
  474. return (nil . 0 . nil)
  475. else
  476. <<
  477. sorted := reverse sorted;
  478. vallist := reverse vallist;
  479. return (vallist . (thesign . ('!* . sorted)));
  480. >>
  481. >>;
  482. for each child in cdr stree do
  483. if thesign neq 0 then
  484. <<
  485. schild := st_sorttree1(child, ve, fn);
  486. thesign := thesign * cadr schild;
  487. tosort := ((cddr schild) . (car schild)) . tosort;
  488. >>;
  489. >>;
  490. if thesign = 0 then return (nil . (0 . nil));
  491. if car stree = '!+ then
  492. tosort := cdr_sort(tosort, fn)
  493. else
  494. <<
  495. tosort := cdr_signsort(tosort, fn);
  496. if car tosort = 0 then
  497. return (nil . (0 . nil))
  498. else
  499. thesign := thesign * car tosort;
  500. tosort := cdr tosort;
  501. >>;
  502. % fill up return structures
  503. while tosort do
  504. <<
  505. sorted := (caar tosort) . sorted;
  506. vallist := (cdar tosort) . vallist;
  507. tosort := cdr tosort;
  508. >>;
  509. sorted := (car stree) . reverse sorted;
  510. vallist := reverse(vallist);
  511. return (vallist . (thesign . sorted));
  512. end;
  513. symbolic procedure st_ad_numsorttree(stree);
  514. begin scalar sorted;
  515. sorted := st_ad_numsorttree1(stree);
  516. return car sorted . cadr sorted;
  517. end;
  518. symbolic procedure st_ad_numsorttree1(stree);
  519. begin scalar subtree, contents, tosort;
  520. integer thesign;
  521. if numberp stree then return {1, stree, stree};
  522. thesign := 1;
  523. if car stree eq '!* then
  524. <<
  525. stree := '!* . for each elt in cdr stree collect
  526. <<
  527. subtree := st_ad_numsorttree1(elt);
  528. thesign := thesign * car subtree;
  529. contents := cddr subtree . contents;
  530. cadr subtree
  531. >>;
  532. contents := ad_numsort(for each elt in contents join elt);
  533. return thesign . (stree . contents);
  534. >>;
  535. tosort := for each elt in cdr stree collect
  536. <<
  537. subtree := st_ad_numsorttree1(elt);
  538. thesign := thesign * car subtree;
  539. cdr subtree
  540. >>;
  541. if car stree eq '!+ then
  542. <<
  543. tosort := cdr_sort(tosort, function numlist_ordp);
  544. tosort := for each elt in tosort collect
  545. <<
  546. contents := (cdr elt) . contents;
  547. car elt
  548. >>;
  549. contents := ad_numsort(for each elt in reverse contents join elt);
  550. return (thesign . (('!+ . tosort) . contents));
  551. >>;
  552. if car stree eq '!- then
  553. <<
  554. tosort := cdr_signsort(tosort, function numlist_ordp);
  555. thesign := car tosort;
  556. tosort := for each elt in cdr tosort collect
  557. <<
  558. contents := (cdr elt) . contents;
  559. car elt
  560. >>;
  561. contents := ad_numsort(for each elt in reverse contents join elt);
  562. return (thesign . (('!- . tosort) . contents));
  563. >>;
  564. end;
  565. symbolic procedure st_consolidate(stree);
  566. begin scalar join_cells, children, tmp;
  567. if null stree then return nil;
  568. if numberp cadr stree then return stree;
  569. join_cells := t;
  570. for each child in reverse(cdr stree) do
  571. <<
  572. tmp := st_consolidate(child);
  573. if tmp then
  574. <<
  575. if cddr tmp then
  576. join_cells := nil
  577. else
  578. tmp := {'!*, cadr tmp};
  579. children := tmp . children;
  580. >>;
  581. >>;
  582. if children then
  583. <<
  584. if null cdr children then
  585. return car children;
  586. if join_cells then
  587. children := for each elt in children collect cadr elt;
  588. return (car stree) . children
  589. >>
  590. else
  591. return nil;
  592. end;
  593. %%%%%%%%%%%%%%%%%%%%%% SKELETONS %%%%%%%%%%%%%%%%%%%%%%%%%%
  594. symbolic procedure dv_cambhead(camb);
  595. begin
  596. if listp camb then
  597. <<
  598. if member(car camb, {'expt, 'minus}) then
  599. return dv_cambhead(cadr camb);
  600. if listp camb then return car camb;
  601. >>;
  602. end;
  603. symbolic procedure dv_skelhead(skelpair);
  604. dv_cambhead car(skelpair);
  605. symbolic procedure dv_skelsplit(camb);
  606. begin scalar skel, stree, subskels;
  607. integer count, ind, maxind, thesign;
  608. thesign := 1;
  609. if not listp camb then
  610. if (ind := dummyp(camb)) then
  611. return {1, ind, ('!~dv . {'!*, ind})}
  612. else
  613. return {1, 0, (camb . nil)};
  614. stree := get(car camb, 'symtree);
  615. if not stree then
  616. <<
  617. stree := for count := 1 : length(cdr camb) collect count;
  618. if flagp(car camb, 'symmetric) then
  619. stree := '!+ . stree
  620. else if flagp(car camb, 'antisymmetric) then
  621. stree := '!- . stree
  622. else
  623. stree := '!* . stree
  624. >>;
  625. subskels := mkve(length(cdr camb));
  626. count := 0;
  627. for each arg in cdr camb do
  628. <<
  629. count := count + 1;
  630. if listp arg then
  631. putve(subskels, count, (arg . nil))
  632. else if (ind := dummyp(arg)) then
  633. <<
  634. maxind := max(maxind, ind);
  635. putve(subskels, count, ('!~dv . {'!*, ind}))
  636. >>
  637. else
  638. putve(subskels, count, (arg . nil));
  639. >>;
  640. stree := st_sorttree(stree, subskels, function skp_ordp);
  641. if stree and (car stree = 0) then return nil;
  642. thesign := car stree;
  643. skel := dv_skelsplit1(cdr stree, subskels);
  644. stree := st_consolidate(cdr skel);
  645. skel := (car camb) . car skel;
  646. return {thesign, maxind, skel . stree};
  647. end;
  648. symbolic procedure dv_skelsplit1(stree, skelve);
  649. begin scalar
  650. cell_stree, child_list, cur_cell, dv_stree, part, skel, ve;
  651. integer count, len;
  652. if numberp cadr stree then
  653. <<
  654. ve := skelve;
  655. child_list := cdr stree;
  656. skel := for each elt in cdr stree collect car venth(ve,elt);
  657. >>
  658. else
  659. <<
  660. len := length(cdr stree);
  661. ve := mkve(len);
  662. count := len;
  663. for each child in reverse(cdr stree) do
  664. <<
  665. putve(ve, count, dv_skelsplit1(child, skelve));
  666. skel := car(venth(ve,count)) . skel;
  667. child_list := count . child_list;
  668. count := count - 1;
  669. >>;
  670. skel := for each elt in skel join copy elt;
  671. >>;
  672. %% if root of stree is * node, then
  673. %% no partition of children is necessary
  674. if car stree eq '!* then
  675. <<
  676. for each elt in reverse(child_list) do
  677. if cdr venth(ve, elt) then
  678. dv_stree := cdr venth(ve, elt) . dv_stree;
  679. if length(dv_stree) = 1 then
  680. dv_stree := car dv_stree
  681. else if dv_stree then
  682. dv_stree := '!* . dv_stree;
  683. return (skel . dv_stree);
  684. >>;
  685. %% regroup children with equal skeletons
  686. for each elt in child_list do
  687. if null cur_cell then % new skeleton
  688. cur_cell := car venth(ve, elt) . {cdr venth(ve, elt)}
  689. else if (car venth(ve, elt)) = (car cur_cell) then
  690. rplacd(cur_cell, (cdr venth(ve,elt)) . cdr cur_cell)
  691. else
  692. <<
  693. part := cur_cell . part;
  694. cur_cell := car venth(ve, elt) . {cdr venth(ve, elt)};
  695. >>;
  696. part := cur_cell . part;
  697. %% prepend contribution of each cell to dv_stree
  698. %% note that cells of part are in reverse order,
  699. %% as are elements of each cell
  700. for each cell in part do
  701. if cdr cell then
  702. <<
  703. cell_stree := car stree . reverse(cdr cell);
  704. dv_stree := cell_stree . dv_stree
  705. >>;
  706. %% now set type of dv_stree, if it has more than one element
  707. if length(dv_stree) neq 1 then
  708. dv_stree := '!* . dv_stree
  709. else
  710. dv_stree := car dv_stree;
  711. return skel . dv_stree;
  712. end;
  713. symbolic procedure nodum_varp u;
  714. % u is a list or an atom (index) or !~dv or !~dva
  715. % returns true if it is neither a list nor a dummy var
  716. % nor !~dv or !~dva.
  717. if listp u then t
  718. else
  719. if flagp(u,'dummy) or car ad_splitname u = g_dvbase
  720. or u member {'!~dv,'!~dva}
  721. then nil
  722. else t;
  723. symbolic procedure list_is_all_free u;
  724. % u is a list of indices
  725. % returns nil if there is at least one dummy index
  726. % or if one of them is !~dv or !~dva.
  727. if null u then t
  728. else
  729. if nodum_varp car u then list_is_all_free cdr u
  730. else nil;
  731. symbolic procedure dv_skelprod(sklist, maxind);
  732. % This is the corrected function for commuting
  733. % operators which do not depend on dummy variables.
  734. begin scalar
  735. skform, stree, symcells, skel, apair, anticom_alist,
  736. com_alist, noncom_alist, acom_odd, acom_even, idvect,
  737. varskel;
  738. integer the_sign, count;
  739. %% sort skeletons according to lexicograpical order of dv_skelhead,
  740. %% placing commuting factors before anticommuting factors
  741. the_sign := 1;
  742. for each skelpair in sklist do
  743. <<
  744. skel := car skelpair;
  745. varskel:=if listp skel then
  746. if car skel neq 'expt then cdr skel;
  747. % else
  748. % if car skel neq 'expt then cdr skel;
  749. if flagp(dv_skelhead skelpair , 'anticom) then
  750. <<
  751. if (apair := anticom_assoc(skel, anticom_alist)) then
  752. <<
  753. if member(cdr skelpair, cddr apair) then
  754. the_sign := 0
  755. else
  756. the_sign := the_sign * car apair;
  757. rplacd(cdr apair, (cdr skelpair) . (cddr apair))
  758. >>
  759. else
  760. anticom_alist := (skel . {cdr skelpair}) . anticom_alist;
  761. >>
  762. else if flagp(dv_skelhead skelpair, 'noncom) then
  763. noncom_alist := (skel . {cdr skelpair}) . noncom_alist
  764. % we do not need the "else if" for commuting operators
  765. % if no dummy variable is involved:
  766. % else if null list_is_all_free varskel or atom skel then
  767. % if(apair := assoc(skel, com_alist)) then
  768. else if ( (null list_is_all_free varskel or atom skel) and
  769. (apair := assoc(skel, com_alist)) ) then
  770. rplacd (apair, (cdr skelpair) . (cdr apair))
  771. % else nil
  772. else
  773. com_alist := (skel . {cdr skelpair}) . com_alist;
  774. >>;
  775. if the_sign = 0 then return nil;
  776. %% restore order of factors for each anticom cell
  777. anticom_alist := for each elt in anticom_alist collect
  778. (car elt) . reverse(cdr elt);
  779. %% sort com_alist
  780. com_alist := sort(com_alist,
  781. function(lambda(x,y); idcons_ordp(car x, car y)));
  782. %% sort anticom_alist, taking care of sign changes
  783. %% isolate even prod of anticoms from odd prod of anticoms
  784. for each elt in anticom_alist do
  785. if evenp(length(cdr elt)) then
  786. acom_even := elt . acom_even
  787. else
  788. acom_odd := elt . acom_odd;
  789. acom_even := sort(acom_even,
  790. function(lambda(x,y); idcons_ordp(car x, car y)));
  791. anticom_alist := ad_signsort(acom_odd,
  792. function(lambda(x,y); idcons_ordp(car x, car y)));
  793. the_sign := the_sign * car anticom_alist;
  794. anticom_alist :=
  795. merge_list1(acom_even, cdr anticom_alist, function idcons_ordp);
  796. skform := append(com_alist, anticom_alist);
  797. skform := append(skform, reverse noncom_alist);
  798. if maxind = 0 then
  799. <<
  800. if the_sign = -1 then skform := ((-1) . {nil}) . skform;
  801. return skform . nil;
  802. >>;
  803. %% build complete symtree,
  804. %% omiting skels which do not depend on dummy variables
  805. for each elt in reverse noncom_alist do
  806. stree := cadr elt . stree;
  807. for each elt in reverse anticom_alist do
  808. if length(cdr elt) > 1 then
  809. stree := ('!- . cdr elt) . stree
  810. else if (cdr elt) then
  811. stree := cadr elt . stree;
  812. for each elt in reverse com_alist do
  813. if length(cdr elt) > 1 then
  814. stree := ('!+ . cdr elt) . stree
  815. else if (cdr elt) then
  816. stree := cadr elt . stree;
  817. if length(stree) > 1 then
  818. stree := '!* . stree
  819. else
  820. stree := car stree;
  821. stree := st_consolidate(stree);
  822. idvect := mkve(maxind);
  823. for count := 1 : maxind do putve(idvect, count, count);
  824. stree := st_sorttree(stree, idvect, function numlist_ordp);
  825. %% the sign change for sorting the symmetry tree does not influence
  826. %% the sign of the expression. Indeed, the symtree used to fill up
  827. %% the blanks in the expression is the symtree stored with the
  828. %% skeleton, which is not sorted. Note however that if the sign here
  829. %% is 0, then the expression is null.
  830. % the_sign := the_sign * car stree;
  831. if car stree = 0 then return nil;
  832. if the_sign = -1 then
  833. skform := ((-1) . {nil}) . skform;
  834. symcells := st_extract_symcells(cdr stree, maxind);
  835. return skform . symcells;
  836. end;
  837. symbolic procedure dv_skel2factor1(skel_kern, dvars);
  838. begin scalar dvar,scr;
  839. if null skel_kern then return nil;
  840. return
  841. if listp skel_kern then
  842. <<scr:=dv_skel2factor1(car skel_kern, dvars);
  843. scr:=scr . dv_skel2factor1(cdr skel_kern, dvars)
  844. >>
  845. else
  846. if skel_kern eq '!~dv then
  847. <<
  848. dvar := car dvars;
  849. if cdr dvars then
  850. <<
  851. rplaca(dvars, cadr dvars);
  852. rplacd(dvars, cddr dvars);
  853. >>;
  854. dvar
  855. >>
  856. else
  857. skel_kern;
  858. end;
  859. %%%%%%%%%%%%%%% PARTITION SYMMETRY TREES %%%%%%%%%%%%%%%%%%
  860. symbolic procedure pst_termnodep(pst);
  861. null cdr venth(cdr pst, 1);
  862. symbolic procedure pst_mkpst(stree);
  863. pst_equitable(nil . pst_mkpst1(stree));
  864. symbolic procedure st_multtermnodep(stree);
  865. begin
  866. scalar res, subtrees;
  867. if car stree neq '!* then return nil;
  868. subtrees := cdr stree;
  869. res := t;
  870. while subtrees do
  871. <<
  872. if numberp cadar subtrees then
  873. subtrees := cdr subtrees
  874. else
  875. <<
  876. subtrees := nil;
  877. res := nil;
  878. >>
  879. >>;
  880. return res;
  881. end;
  882. symbolic procedure pst_mkpst1(stree);
  883. begin
  884. scalar
  885. subtrees, s_cells, ve, pst, cell;
  886. integer
  887. count, lastcount;
  888. if null stree then return nil;
  889. ve := mkve(length(cdr stree));
  890. subtrees := cdr stree;
  891. count := 1;
  892. if numberp(car subtrees) then % terminal node with single cell
  893. while subtrees do
  894. <<
  895. putve(ve, count, ({car subtrees} . nil));
  896. count := count + 1;
  897. subtrees := cdr subtrees;
  898. >>
  899. % check if valid as pst terminal node with several cells
  900. else if st_multtermnodep(stree) then
  901. <<
  902. ve := mkve(for each cell in subtrees sum (length(cdr cell)));
  903. lastcount := 0;
  904. for each s_cell in subtrees do
  905. <<
  906. cell := cdr s_cell;
  907. if car s_cell eq '!* then
  908. for count := 1 : length(cell) do
  909. pst := {count + lastcount} . pst
  910. else
  911. pst := (
  912. for count := 1 : length(cell) collect (count + lastcount)
  913. ) . pst;
  914. count := lastcount + 1;
  915. lastcount := lastcount + length(cell);
  916. for each elt in cell do
  917. <<
  918. putve(ve,count, {{elt}});
  919. count := count + 1;
  920. >>;
  921. >>;
  922. return (reverse pst . ve);
  923. >>
  924. else
  925. while subtrees do
  926. <<
  927. pst := pst_mkpst1(car subtrees);
  928. s_cells := nil;
  929. for count2 := 1 : upbve(cdr pst) do
  930. s_cells := append(car venth(cdr pst, count2), s_cells);
  931. putve(ve, count, (s_cells . pst));
  932. count := count + 1;
  933. subtrees := cdr subtrees;
  934. >>;
  935. if ((car stree) eq '!*) then % discrete partition
  936. pst := ((for count := 1 : upbve(ve) collect {count}) . ve)
  937. else % single cell partition
  938. pst := ({(for count := 1 : upbve(ve) join {count})} . ve);
  939. return pst;
  940. end;
  941. symbolic procedure pst_subpst(pst, ind);
  942. venth(cdr pst, ind);
  943. symbolic procedure pst_reduce(pst);
  944. begin
  945. scalar
  946. isolated, f_cell, rpst, tmp, npart, nsubs;
  947. integer
  948. ind, count;
  949. if null pst then return (nil . nil);
  950. if null cdr pst then return pst;
  951. f_cell := caar pst;
  952. while length(f_cell) eq 1 do
  953. <<
  954. ind := car f_cell; % index of pst_subpst
  955. if pst_termnodep(pst) then
  956. <<
  957. isolated := append(isolated, {caar venth(cdr pst, ind)});
  958. %% remove first cell from pst, and set f_cell
  959. if cdar pst then % pst is not fully reduced
  960. <<
  961. %% remove first cell
  962. rplaca(pst, cdar pst);
  963. %% update pst representation
  964. npart := for each cell in car pst collect
  965. for each elt in cell collect
  966. if (elt > ind) then elt - 1 else elt;
  967. nsubs := mkve(upbve(cdr pst)-1);
  968. for count := 1 : upbve(nsubs) do
  969. if count geq ind then
  970. putve(nsubs, count, venth(cdr pst, count+1))
  971. else
  972. putve(nsubs, count, venth(cdr pst, count));
  973. rplaca(pst, npart);
  974. rplacd(pst, nsubs);
  975. f_cell := caar pst;
  976. >>
  977. else % pst fully reduced
  978. f_cell := pst := nil;
  979. >>
  980. else
  981. <<
  982. rpst := pst_reduce(cdr pst_subpst(pst,ind));
  983. if car rpst then
  984. %% new isolates
  985. <<
  986. %% add new isolates to isolated
  987. isolated := append(isolated, car rpst);
  988. if cdr rpst then
  989. %% first subtree in pst was not discrete, update subtree spec
  990. <<
  991. tmp := pst_subpst(pst,ind);
  992. rplaca(tmp, setdiff(car tmp, car rpst));
  993. rplacd(tmp, cdr rpst);
  994. f_cell := nil;
  995. >>
  996. else % first subtree in pst was discrete, so remove it
  997. <<
  998. if cdar pst then % pst not fully reduced
  999. <<
  1000. rplaca(pst, cdar pst);
  1001. npart := for each cell in car pst collect
  1002. for each elt in cell collect
  1003. if (elt > ind) then elt - 1 else elt;
  1004. nsubs := mkve(upbve(cdr pst)-1);
  1005. for count := 1 : upbve(nsubs) do
  1006. if count geq ind then
  1007. putve(nsubs, count, venth(cdr pst, count+1))
  1008. else
  1009. putve(nsubs, count, venth(cdr pst, count));
  1010. rplaca(pst, npart);
  1011. rplacd(pst, nsubs);
  1012. f_cell := caar pst;
  1013. >>
  1014. else
  1015. f_cell := pst := nil;
  1016. >>;
  1017. >>
  1018. else
  1019. %% car rpst is nil, so no more isolated d-elts
  1020. <<
  1021. f_cell := nil;
  1022. >>;
  1023. >>
  1024. >>;
  1025. return (isolated . pst);
  1026. end;
  1027. symbolic procedure pst_isolable(rpst);
  1028. begin
  1029. scalar
  1030. ve, f_cell;
  1031. %% verify if fully reduced.
  1032. if null cdr rpst then return nil;
  1033. %% f_cell is list of elts in first cell in rpst.
  1034. %% ve is vector of descriptions of elts in f_cell
  1035. f_cell := caadr rpst;
  1036. ve := cddr rpst;
  1037. %% if the elts in f_cell are d-elts, then return the list of d-elts
  1038. if null cdr venth(ve, car f_cell) then
  1039. return for each ind in f_cell collect caar venth(ve, ind);
  1040. return for each ind in f_cell join copy
  1041. pst_isolable(nil . cdr venth(ve, ind));
  1042. end;
  1043. symbolic procedure pst_isolate(s_cell, rpst);
  1044. begin
  1045. scalar
  1046. redisol;
  1047. redisol := pst_reduce(pst_isolate1(s_cell, cdr rpst));
  1048. rplaca(redisol, append(car rpst, car redisol));
  1049. return redisol;
  1050. end;
  1051. symbolic procedure pst_isolate1(s_cell, pst);
  1052. begin
  1053. scalar
  1054. fcell, tmp, spst;
  1055. integer
  1056. ind;
  1057. %% fcell is the list of elts in the first cell of rpst
  1058. %% ve is the vector of descriptions of elts in fcell
  1059. fcell := caar pst;
  1060. %% find out which elt of fcell needs to be set aside, if any
  1061. tmp := fcell;
  1062. while (ind = 0) do
  1063. <<
  1064. if null tmp then ind := -1;
  1065. ind := car tmp;
  1066. tmp := cdr tmp;
  1067. if not member(s_cell, car (spst := pst_subpst(pst, ind))) then
  1068. ind := 0
  1069. >>;
  1070. %% if no elt should be set aside, then s_cell is not isolable
  1071. if (ind = -1) then return nil;
  1072. %% effectively isolate, splitting first cell if necessary
  1073. if (length(fcell) > 1) then
  1074. <<
  1075. tmp := delete(ind, fcell) . cdar pst;
  1076. tmp := {ind} . tmp;
  1077. rplaca(pst, tmp)
  1078. >>;
  1079. %% if the set aside elt is not a mere dummy variable, then isolate
  1080. %% s_cell in the partition it represents.
  1081. if not pst_termnodep(pst) then
  1082. <<
  1083. spst := car spst . pst_isolate1(s_cell, cdr spst);
  1084. putve(cdr pst, ind, spst)
  1085. >>;
  1086. return pst;
  1087. end;
  1088. symbolic procedure pst_equitable(rpst);
  1089. begin
  1090. scalar
  1091. nrpst, reduced, isol;
  1092. if null cdr rpst then return rpst;
  1093. isol := car rpst;
  1094. nrpst := pst_reduce(cdr rpst);
  1095. rplaca(nrpst, append(isol, car nrpst));
  1096. repeat
  1097. <<
  1098. isol := car nrpst;
  1099. nrpst := isol . pst_equitable1(isol, cdr nrpst);
  1100. reduced := pst_reduce(cdr nrpst);
  1101. if car reduced then
  1102. nrpst := (append(isol, car reduced) . cdr reduced);
  1103. reduced := car reduced
  1104. >>
  1105. until not reduced;
  1106. return nrpst;
  1107. end;
  1108. symbolic procedure pst_equitable1(isolated, pst);
  1109. begin
  1110. scalar
  1111. isol, ve, alpha, beta, p1, equit, cell, psi;
  1112. integer
  1113. len, k, n_delems;
  1114. if null pst then return nil;
  1115. %% make partition to equitate, merging isolated and car pst
  1116. isol := isolated;
  1117. len := length(isolated);
  1118. ve := mkve(upbve(cdr pst) + len);
  1119. for count := 1 : upbve(cdr pst) do
  1120. putve(ve, count, car venth(cdr pst, count));
  1121. alpha := car pst;
  1122. for count := upbve(cdr pst) + 1 : upbve(ve) do
  1123. <<
  1124. putve(ve, count, {car isol});
  1125. isol := cdr isol;
  1126. alpha := {count} . alpha;
  1127. >>;
  1128. p1 := fullcopy alpha;
  1129. len := length(p1);
  1130. n_delems := upbve(ve);
  1131. while (alpha and len < n_delems) do
  1132. <<
  1133. beta := car alpha;
  1134. alpha := cdr alpha;
  1135. equit := nil;
  1136. len := 0;
  1137. while(p1) do
  1138. <<
  1139. cell := car p1;
  1140. p1 := cdr p1;
  1141. psi := if cdr cell then
  1142. pst_partition(cell, beta, ve) else {cell};
  1143. k := length(psi);
  1144. equit := append(equit, psi);
  1145. len := len + k;
  1146. if k geq 2 then alpha := append(cdr psi, alpha);
  1147. >>;
  1148. p1 := equit;
  1149. >>;
  1150. equit := pnth(p1,length(isolated)+1);
  1151. %%% make every child of pst equitable w.r.t. isolated
  1152. if not pst_termnodep(pst) then
  1153. for count := 1 : upbve(cdr pst) do
  1154. <<
  1155. p1 := venth(cdr pst, count);
  1156. putve(cdr pst, count,
  1157. (car p1 . pst_equitable1(isolated, cdr p1)));
  1158. >>;
  1159. return (equit . cdr pst);
  1160. end;
  1161. symbolic procedure pst_d1(d1,d2, ve);
  1162. for each e1 in venth(ve,d1) collect ordn
  1163. for each e2 in venth(ve, d2) collect ordn
  1164. car pa_coinc_split(sc_kern(e1), sc_kern(e2));
  1165. symbolic procedure pst_d(d1, d2, ve);
  1166. if listp d1 then
  1167. if listp d2 then
  1168. ordn for each e1 in d1 collect
  1169. ordn for each e2 in d2 collect pst_d(e1, e2, ve)
  1170. else
  1171. ordn for each e1 in d1 collect pst_d(e1, d2, ve)
  1172. else
  1173. if listp d2 then
  1174. ordn for each e2 in d2 collect pst_d(d1, e2, ve)
  1175. else
  1176. pst_d1(d1, d2, ve);
  1177. symbolic procedure pst_partition(s1, s2, ve);
  1178. begin
  1179. scalar
  1180. elt_d, elt_apair, pst_alist;
  1181. for each elt in s1 do
  1182. <<
  1183. elt_d := pst_d(elt, s2, ve);
  1184. if (elt_apair := assoc(elt_d, pst_alist)) then
  1185. rplacd(elt_apair, elt . cdr elt_apair)
  1186. else
  1187. pst_alist := (elt_d . {elt}) . pst_alist;
  1188. >>;
  1189. % sort regrouped elts according to distance to s2
  1190. pst_alist := sort(pst_alist,
  1191. function( lambda(x,y); numlist_ordp(car x, car y)));
  1192. return for each elt in pst_alist collect reverse(cdr elt);
  1193. end;
  1194. %%%%%%%%%%%%%%%%%%%%%%%% BACKTRACKING %%%%%%%%%%%%%%%%%%%%%%%%%%
  1195. symbolic procedure dv_next_choice(sc, partial_perm, rpst, comp_info);
  1196. begin scalar
  1197. next_perm, extensions, nrpst, new_aut;
  1198. integer
  1199. npoints, len, next_img ;
  1200. npoints := upbve(car sc);
  1201. g_skip_to_level := len := upbve(partial_perm) + 1;
  1202. sc_setbase(sc, partial_perm);
  1203. extensions := pst_isolable(rpst);
  1204. repeat
  1205. <<
  1206. extensions := idsort( intersection
  1207. (extensions, candidate_extensions(sc, partial_perm)));
  1208. if extensions then
  1209. <<
  1210. next_img := car extensions;
  1211. extensions := cdr extensions;
  1212. nrpst := pst_equitable(pst_isolate(next_img, fullcopy(rpst)));
  1213. next_perm := list2vect!*(car nrpst,'symbolic);
  1214. comp_info := dv_compare(next_perm, comp_info, len, npoints);
  1215. if (car comp_info = 0) then
  1216. if (upbve(next_perm) = npoints) then
  1217. <<
  1218. new_aut := pe_mult(pe_inv(venth(cadr comp_info, 1)), next_perm);
  1219. process_new_automorphism(sc, new_aut);
  1220. >>
  1221. else
  1222. comp_info := dv_next_choice(sc, next_perm, nrpst, comp_info)
  1223. else if (car comp_info = 1) then
  1224. if (upbve(next_perm) < npoints) then
  1225. comp_info := dv_next_choice(sc, next_perm, nrpst, comp_info)
  1226. else
  1227. rplaca(comp_info, 0);
  1228. rplacd(cdr comp_info, cdr cddr comp_info);
  1229. >>
  1230. >>
  1231. until (null extensions) or (len > g_skip_to_level);
  1232. return comp_info;
  1233. end;
  1234. symbolic procedure can_rep_cell(comp_info, level);
  1235. venth(venth(cadr comp_info, 2), level);
  1236. symbolic procedure last_part_kern(comp_info);
  1237. car cddr comp_info;
  1238. symbolic procedure dv_compare(next_perm, comp_info, len, npoints);
  1239. begin
  1240. scalar
  1241. part_kern, part_rep, can_rep, curlev, res;
  1242. if car comp_info = 1 then
  1243. return
  1244. dv_fill_comp_info(next_perm, comp_info, len, npoints, nil, nil);
  1245. if len = 1 then
  1246. <<
  1247. part_kern := sc_kern(venth(next_perm, 1));
  1248. part_rep := {sc_rep(venth(next_perm,1))};
  1249. >>
  1250. else
  1251. <<
  1252. part_kern := last_part_kern(comp_info);
  1253. part_kern := pa_coinc_split(part_kern,
  1254. sc_kern(venth(next_perm, len)));
  1255. part_rep := (sc_rep(venth(next_perm, len)) . car part_kern);
  1256. part_kern := cdr part_kern;
  1257. >>;
  1258. can_rep := can_rep_cell(comp_info, len);
  1259. curlev := len;
  1260. res := 0;
  1261. repeat
  1262. <<
  1263. if equal(can_rep, part_rep) then
  1264. <<
  1265. res := 0;
  1266. if (curlev < upbve(next_perm)) then
  1267. <<
  1268. curlev := curlev + 1;
  1269. part_kern := pa_coinc_split(part_kern,
  1270. sc_kern(venth(next_perm, curlev)));
  1271. part_rep := (sc_rep(venth(next_perm,curlev)) . car part_kern);
  1272. part_kern := cdr part_kern;
  1273. can_rep := can_rep_cell(comp_info, curlev);
  1274. >>
  1275. >>
  1276. else if numlist_ordp(can_rep, part_rep) then
  1277. <<
  1278. res := 1;
  1279. rplaca(comp_info, 1);
  1280. comp_info := dv_fill_comp_info(next_perm, comp_info,
  1281. curlev, npoints, part_rep, part_kern);
  1282. >>
  1283. else
  1284. <<
  1285. res := 2;
  1286. % grow partial permutation kernel stack
  1287. rplacd(cdr comp_info, nil . (cddr comp_info));
  1288. rplaca(comp_info, 2);
  1289. >>
  1290. >>
  1291. until (res neq 0) or (curlev = upbve(next_perm));
  1292. if res = 0 then
  1293. <<
  1294. % update partial permutation stack
  1295. rplacd(cdr comp_info, part_kern . cddr comp_info);
  1296. if (curlev = npoints) and
  1297. dv_new_aut_hook(next_perm, comp_info) then
  1298. <<
  1299. g_skip_to_level := 0;
  1300. rplaca(comp_info, 2);
  1301. >>;
  1302. >>;
  1303. return comp_info;
  1304. end;
  1305. symbolic procedure dv_fill_comp_info(pe, comp_info, len, npoints,
  1306. part_rep, part_kern);
  1307. begin scalar
  1308. part_rep;
  1309. integer level;
  1310. if len = 1 then
  1311. <<
  1312. part_kern := sc_kern(venth(pe, 1));
  1313. part_rep := {sc_rep(venth(pe,1))};
  1314. >>
  1315. else if null part_kern then
  1316. <<
  1317. part_kern := last_part_kern(comp_info);
  1318. part_kern := pa_coinc_split(part_kern, sc_kern(venth(pe, len)));
  1319. part_rep := (sc_rep(venth(pe, len)) . car part_kern);
  1320. part_kern := cdr part_kern;
  1321. >>;
  1322. putve(venth(cadr comp_info, 2), len, part_rep);
  1323. level := len + 1;
  1324. while(level <= upbve(pe)) do
  1325. <<
  1326. part_kern := pa_coinc_split(part_kern, sc_kern(venth(pe, level)));
  1327. part_rep := (sc_rep(venth(pe, level)) . car part_kern);
  1328. part_kern := cdr part_kern;
  1329. putve(venth(cadr comp_info, 2), level, part_rep);
  1330. level := level + 1
  1331. >>;
  1332. rplacd(cdr comp_info, part_kern . (cddr comp_info));
  1333. if level = npoints+1 then
  1334. if null venth(cadr comp_info, 1) and
  1335. dv_null_first_kern(part_kern) then
  1336. <<
  1337. g_skip_to_level := 0;
  1338. rplaca(comp_info, 2);
  1339. >>
  1340. else
  1341. <<
  1342. putve(cadr comp_info, 1, fullcopy(pe));
  1343. putve(cadr comp_info, 3, part_kern);
  1344. >>;
  1345. return comp_info;
  1346. end;
  1347. symbolic procedure dv_null_first_kern(kern);
  1348. begin
  1349. scalar
  1350. l_kern, cell, nullexp, acell;
  1351. integer
  1352. count, count2;
  1353. nullexp := nil;
  1354. l_kern := pa_vect2list kern;
  1355. for each cell in l_kern do
  1356. if cdr cell and not nullexp then
  1357. <<
  1358. count := 0;
  1359. for count2 := 1 : upbve(g_sc_ve) do
  1360. if (car (acell := car venth(g_sc_ve, count2)) eq '!-) and
  1361. member (car cell, acell) then count := count + 1;
  1362. if oddp count then
  1363. nullexp := t;
  1364. >>;
  1365. return nullexp;
  1366. end;
  1367. symbolic procedure dv_new_aut_hook(pe, comp_info);
  1368. begin
  1369. scalar tmp1, tmp2, ve;
  1370. integer count, thesign;
  1371. thesign := st_signchange(venth(cadr comp_info,1), pe);
  1372. tmp1 := pa_part2list(venth(cadr comp_info, 3));
  1373. tmp2 := pa_part2list(caddr comp_info);
  1374. ve := mkve(length(tmp1));
  1375. count := 1;
  1376. while tmp1 do
  1377. <<
  1378. putve(ve, car tmp1, car tmp2);
  1379. tmp1 := cdr tmp1;
  1380. tmp2 := cdr tmp2;
  1381. count := count + 1;
  1382. >>;
  1383. for count := 1 : upbve(g_sc_ve) do
  1384. <<
  1385. tmp1 := car venth(g_sc_ve, count);
  1386. if car tmp1 eq '!- then
  1387. <<
  1388. tmp1 := cdr tmp1;
  1389. tmp2 := for each elt in tmp1 collect venth(ve,elt);
  1390. % tmp2 is the image of tmp1. Since all cells in g_sc_ve are
  1391. % ordered in increased numerical order
  1392. thesign := thesign * car num_signsort(tmp2);
  1393. >>
  1394. >>;
  1395. if thesign = -1 then
  1396. return t;
  1397. return nil;
  1398. end;
  1399. %%%%%%%%%%%%%%%%%%%%%%%%%% TOP LEVEL %%%%%%%%%%%%%%%%%%%%%%%%%%%
  1400. symbolic procedure dv_canon_monomial(sf);
  1401. begin
  1402. scalar
  1403. tmp, sklist, camb, skel, skprod, aut_sc, can_kern,
  1404. new_dvnames, pst, comp_info, factlst, res, fact,
  1405. sorted_factlst;
  1406. integer
  1407. count, expnt, thesign, maxind;
  1408. %% get skeleton pairs for each one of the factors
  1409. thesign := 1;
  1410. while not domainp sf do
  1411. <<
  1412. tmp := lpow(sf); sf := lc(sf);
  1413. %% suppose exponents are integers
  1414. expnt := cdr tmp; camb := car tmp;
  1415. if expnt neq 1 and flagp(dv_cambhead(camb),'anticom) then
  1416. <<
  1417. skel := nil;
  1418. sf := nil;
  1419. >>
  1420. else
  1421. skel := dv_skelsplit(camb);
  1422. if null skel then
  1423. sf := nil
  1424. else
  1425. <<
  1426. if car skel < 0 then
  1427. <<
  1428. skel := cdr skel;
  1429. if oddp(expnt) then thesign := - thesign
  1430. else rplacd(cdr skel, subst('!-, '!+, cdr skel));
  1431. >>
  1432. else
  1433. skel := cdr skel;
  1434. if (car skel > maxind) then maxind := car skel;
  1435. skel := cadr skel;
  1436. if expnt neq 1 then
  1437. rplaca(skel, {'expt, car skel, expnt});
  1438. sklist := skel . sklist;
  1439. >>;
  1440. >>;
  1441. if null sf then return nil;
  1442. sklist := reverse((sf . nil) . sklist);
  1443. %% regroup factors with identical skeletons
  1444. skprod := dv_skelprod(sklist, maxind);
  1445. if null skprod then return nil;
  1446. sklist := car skprod;
  1447. if maxind > 0 then
  1448. <<
  1449. g_sc_ve := cddr skprod;
  1450. g_init_stree := cadr skprod;
  1451. aut_sc := sc_create(upbve(g_sc_ve));
  1452. comp_info := mkve(3);
  1453. putve(comp_info, 2, mkve(upbve(g_sc_ve)));
  1454. comp_info := {1, comp_info, nil};
  1455. pst := pst_mkpst(g_init_stree);
  1456. tmp := list2vect!*(car pst,'symbolic);
  1457. g_skip_to_level := 1;
  1458. if car pst then
  1459. comp_info := dv_compare(tmp, comp_info, 1, upbve(g_sc_ve));
  1460. if cdr pst then
  1461. comp_info := dv_next_choice(aut_sc, tmp, pst, comp_info);
  1462. if g_skip_to_level = 0 then return nil;
  1463. can_kern := pa_part2list(venth(cadr comp_info, 3));
  1464. count := 0;
  1465. new_dvnames := nil;
  1466. for each elt in can_kern do
  1467. <<
  1468. count := count + 1;
  1469. if elt neq count then
  1470. new_dvnames := (elt . count) . new_dvnames;
  1471. >>;
  1472. >>;
  1473. for each cell in sklist do
  1474. <<
  1475. factlst := nil;
  1476. skel := car cell;
  1477. if cadr cell then
  1478. <<
  1479. for each stree in cdr cell do
  1480. <<
  1481. fact := dv_skel2factor( (skel . stree), new_dvnames);
  1482. if car fact = -1 then
  1483. thesign := - thesign;
  1484. factlst := (cdr fact) . factlst;
  1485. >>;
  1486. factlst := reverse factlst;
  1487. if flagp(dv_cambhead skel, 'anticom) then
  1488. <<
  1489. sorted_factlst := ad_signsort(factlst, 'idcons_ordp);
  1490. thesign := thesign * car sorted_factlst;
  1491. sorted_factlst := cdr sorted_factlst;
  1492. >>
  1493. else
  1494. sorted_factlst := sort(factlst, 'idcons_ordp);
  1495. res := append(res, sorted_factlst);
  1496. >>
  1497. else
  1498. res := append(res, {skel});
  1499. >>;
  1500. %% transform res, list of factors, into standard form
  1501. if thesign = -1 then
  1502. skprod := {'minus, 'times . res}
  1503. else if thesign = 1 then
  1504. skprod := 'times . res
  1505. else
  1506. skprod := 0;
  1507. return !*a2f skprod;
  1508. end;
  1509. symbolic procedure dv_skel2factor(skelpair, newnames);
  1510. begin
  1511. scalar stree, dvars;
  1512. if null cdr skelpair then return car skelpair;
  1513. stree := sublis(newnames, cdr skelpair);
  1514. stree := st_ad_numsorttree(stree);
  1515. dvars :=
  1516. for each elt in st_flatten(cdr stree) collect dv_ind2var elt;
  1517. return (car stree . dv_skel2factor1(car skelpair, dvars));
  1518. end;
  1519. %%%%%%%%%%%%%%%%%%%%%%% USER INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%
  1520. symbolic procedure canonical sq;
  1521. begin
  1522. scalar
  1523. sf, denom, res, !*distribute;
  1524. res := nil;
  1525. sq := simp!* car sq;
  1526. denom := denr sq;
  1527. on distribute;
  1528. sf := distri_pol numr sq;
  1529. %% process each monomial in sf
  1530. while not domainp(sf) do
  1531. <<
  1532. res := addf(res, dv_canon_monomial(lt sf .+ nil));
  1533. sf := red sf;
  1534. >>;
  1535. res := addf(res,sf);
  1536. %% simplify the whole thing, and return
  1537. return simp!*( {'!*sq, res ./ denom, nil} )
  1538. end;
  1539. put ('canonical, 'simpfn, 'canonical);
  1540. flag('(symtree),'opfn);
  1541. symbolic procedure symtree (name, s);
  1542. <<
  1543. put (name, 'symtree, alg_to_symb s);
  1544. >>;
  1545. symbolic procedure remsym u;
  1546. % ALLOWS TO ELIMINATE THE DECLARED SYMMETRIES.
  1547. for each j in u do
  1548. if flagp(j,'symmetric) then remflag(list j,'symmetric)
  1549. else
  1550. if flagp(j,'antisymmetric) then remflag(list j,'antisymmetric)
  1551. else remprop(j,'symtree);
  1552. symbolic procedure dummy_names u;
  1553. <<if g_dvbase then msgpri("The created dummy base",g_dvbase,
  1554. "must be cleared",nil,t);
  1555. g_dvnames := list2vect!*(u,'symbolic);
  1556. flag(u, 'dummy);
  1557. t>>;
  1558. rlistat '(dummy_names);
  1559. symbolic procedure show_dummy_names;
  1560. if g_dvnames then symb_to_alg vect2list g_dvnames
  1561. else symb_to_alg list('list);
  1562. symbolic procedure dummy_base u;
  1563. if g_dvnames then
  1564. msgpri("Named variables",symb_to_alg vect2list g_dvnames,
  1565. "must be eliminated",nil,t)
  1566. else g_dvbase := u;
  1567. symbolic procedure clear_dummy_base;
  1568. << g_dvbase := nil;t>>;
  1569. symbolic procedure clear_dummy_names;
  1570. << g_dvnames := nil;t>>;
  1571. flag ('(show_dummy_names clear_dummy_names dummy_base
  1572. clear_dummy_base), 'opfn);
  1573. deflist(
  1574. '((clear_dummy_base endstat) (clear_dummy_names endstat)),'stat);
  1575. symbolic procedure anticom u;
  1576. << for each x in u do
  1577. <<flag(list x, 'anticom); flag(list x, 'noncom)>>;
  1578. t>>;
  1579. symbolic procedure remanticom u;
  1580. % ALLOWS TO ELIMINATE THE DECLARED anticom flag.
  1581. % Operators becomes COMMUTATIVE operators.
  1582. <<
  1583. for each x in u do
  1584. <<remflag(x,'noncom); remflag(x,'anticom)>>;
  1585. t>>;
  1586. deflist('((anticom rlis) (remanticom rlis)),'stat);
  1587. endmodule;
  1588. end;