perms.red 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. module perms;
  2. % returns product of two permutations
  3. symbolic procedure pe_mult(p1, p2);
  4. begin scalar prod;
  5. integer count;
  6. prod := mkve(upbve(p1));
  7. for count := 1:upbve(p1) do
  8. putve(prod, count, venth(p2, venth(p1, count)));
  9. return prod;
  10. end;
  11. % returns inverse of permutation
  12. symbolic procedure pe_inv(pe);
  13. begin
  14. scalar inv;
  15. integer count;
  16. inv := mkve(upbve(pe));
  17. for count := 1:upbve(pe) do
  18. putve(inv, venth(pe, count), count);
  19. return inv;
  20. end;
  21. % returns image of elt by permutation pe
  22. symbolic smacro procedure pe_apply(pe, elt);
  23. venth(pe, elt);
  24. %%% Stabilizer chain routines
  25. %% Access macros
  26. symbolic smacro procedure sc_orbits(sc, k);
  27. venth(venth(cdr sc, k), 1);
  28. symbolic smacro procedure sc_transversal(sc,k);
  29. venth(venth(cdr sc, k), 2);
  30. symbolic smacro procedure sc_generators(sc,k);
  31. venth(venth(cdr sc, k), 3);
  32. symbolic smacro procedure sc_inv_generators(sc,k);
  33. venth(venth(cdr sc, k),4);
  34. symbolic smacro procedure sc_stabdesc(sc, k);
  35. venth(cdr sc, k);
  36. symbolic smacro procedure sd_orbrep(sd, elt);
  37. venth(venth(sd,1),elt);
  38. symbolic smacro procedure sd_orbreps(sd);
  39. venth(sd,5);
  40. %% Building routines
  41. symbolic procedure copy_vect(v1, v2);
  42. begin
  43. integer count, top;
  44. top := upbv v2;
  45. for count := 0 : top do
  46. putv(v1, count, getv(v2, count));
  47. end;
  48. symbolic procedure sd_addgen(sd, pe, inv);
  49. begin scalar
  50. t1, t2, orbits, orbreps, transversal, generators, inv_generators,
  51. new_elems, next_elem;
  52. integer
  53. count, img;
  54. %% initialize local variables
  55. orbits := venth(sd, 1);
  56. transversal := venth(sd, 2);
  57. %% add generator and inverse
  58. generators := vectappend1(venth(sd,3), pe);
  59. inv_generators := vectappend1(venth(sd,4), inv);
  60. %% Join elements from the orbits.
  61. for count := 1 : upbve(orbits) do
  62. <<
  63. t1 := venth(orbits, count);
  64. while (t1 neq venth(orbits, t1)) do t1 := venth(orbits, t1);
  65. t2 := venth(orbits, pe_apply(pe, count));
  66. while (t2 neq venth(orbits, t2)) do t2 := venth(orbits, t2);
  67. if (t1 < t2) then
  68. putve(orbits, t2, t1)
  69. else
  70. putve(orbits, t1, t2)
  71. >>;
  72. for count := 1 : upbve(orbits) do
  73. <<
  74. putve(orbits, count, venth(orbits, venth(orbits, count)));
  75. if venth(orbits, count) = count then
  76. orbreps := count . orbreps
  77. >>;
  78. %% extend transversal
  79. % add images of elements of basic orbit by pe to new_elems
  80. for count := 1 : upbve(transversal) do
  81. <<
  82. if venth(transversal, count) then
  83. <<
  84. img := pe_apply(pe, count);
  85. if null(venth(transversal, img)) then
  86. <<
  87. putve(transversal, img, inv);
  88. new_elems := img . new_elems
  89. >>
  90. >>
  91. >>;
  92. % add all possible images of each new_elems to the transversal
  93. while new_elems do
  94. <<
  95. next_elem := car new_elems;
  96. new_elems := cdr new_elems;
  97. for count := 1 : upbve(generators) do
  98. <<
  99. img := pe_apply(venth(generators, count), next_elem);
  100. if null(venth(transversal, img)) then
  101. <<
  102. putve(transversal, img, venth(inv_generators, count));
  103. new_elems := img . new_elems;
  104. >>
  105. >>
  106. >>;
  107. %% update sd
  108. putve(sd, 1, orbits);
  109. putve(sd, 2, transversal);
  110. putve(sd, 3, generators);
  111. putve(sd, 4, inv_generators);
  112. putve(sd, 5, orbreps);
  113. return sd;
  114. end;
  115. symbolic procedure sd_create(n, beta);
  116. begin
  117. scalar sd, orbits, transversal;
  118. integer count;
  119. sd := mkve(5);
  120. orbits := mkve(n);
  121. for count := 1:n do
  122. putve(orbits, count, count);
  123. transversal := mkve(n);
  124. putve(transversal, beta, 0);
  125. putve(sd, 1, orbits);
  126. putve(sd, 2, transversal);
  127. putve(sd, 3, mkve(0));
  128. putve(sd, 4, mkve(0));
  129. putve(sd, 5, for count := 1:n collect count);
  130. return sd
  131. end;
  132. symbolic procedure sc_create(n);
  133. begin
  134. scalar base;
  135. integer count;
  136. for count := n step -1 until 1 do
  137. base := count . base;
  138. return ((list2vect!*(base,'symbolic)) . mkve(n));
  139. end;
  140. symbolic procedure sd_recomp_transversal(sd, beta);
  141. begin
  142. scalar
  143. new_trans,
  144. new_elems, next_elem,
  145. generators, inv_generators,
  146. img;
  147. integer count;
  148. new_trans := mkve(upbve(venth(sd,1)));
  149. new_elems := beta . nil;
  150. putve(new_trans, beta, 0);
  151. generators := venth(sd,3);
  152. inv_generators := venth(sd,4);
  153. while new_elems do
  154. <<
  155. next_elem := car new_elems;
  156. new_elems := cdr new_elems;
  157. for count := 1 : upbve(generators) do
  158. <<
  159. img := pe_apply(venth(generators, count), next_elem);
  160. if null(venth(new_trans, img)) then
  161. <<
  162. putve(new_trans, img, venth(inv_generators, count));
  163. new_elems := img . new_elems;
  164. >>
  165. >>
  166. >>;
  167. putve(sd, 2, new_trans);
  168. return sd;
  169. end;
  170. symbolic procedure sc_swapbase(sc, k);
  171. begin scalar
  172. sd, % stab desc being constructed
  173. pe, inv_pe,
  174. nu_1, nu_2,
  175. sd_reps_orb1, % O_k \cap orbit reps of sd \ beta_k
  176. b_orb2; % O_k+1
  177. integer
  178. b_1, b_2, % reps of basic orbits of G_k and G_k+1
  179. img,
  180. sigma, swap,
  181. count,
  182. ngens,
  183. elt;
  184. %% take care of nil stabilizer descriptions
  185. % if k'th sd is null, then the base may be changed with no other modif
  186. if null sc_stabdesc(sc,k) then
  187. <<
  188. swap := venth(car sc, k);
  189. putve(car sc, k , venth(car sc, k+1));
  190. putve(car sc, k+1, swap);
  191. return sc
  192. >>;
  193. % if k+1'th sd is null, then one must create a trivial
  194. % stabilizer desc
  195. if null sc_stabdesc(sc,k+1) then
  196. putve(cdr sc, k+1, sd_create(upbve(car sc), venth(car sc, k+1)));
  197. %% initialize sd to copy of stabdesc(k+2), changing the basic rep
  198. if (k+2 > upbve(car sc)) or null sc_stabdesc(sc, k+2) then
  199. sd := sd_create(upbve(car sc), venth(car sc, k))
  200. else
  201. <<
  202. sd := mkve(5);
  203. putve(sd, 1, fullcopy(sc_orbits(sc, k+2)));
  204. % make copy of generators, but not total copy
  205. ngens := upbve(sc_generators(sc, k+2));
  206. putve(sd, 3, mkve(ngens));
  207. putve(sd, 4, mkve(ngens));
  208. for count := 1 : ngens do
  209. <<
  210. putve(venth(sd, 3), count, venth(sc_generators(sc, k+2), count));
  211. putve(venth(sd,4), count, venth(sc_inv_generators(sc,k+2),count))
  212. >>;
  213. putve(sd, 5, venth(venth(cdr sc, k+2),5));
  214. sd_recomp_transversal(sd, venth(car sc, k));
  215. >>;
  216. %% initialize sd_reps_orb1 and b_orb2
  217. for count := 1:upbve(car sc) do
  218. <<
  219. if venth(sc_transversal(sc, k+1), count) then
  220. b_orb2 := count . b_orb2;
  221. if venth(sc_transversal(sc, k), count) then
  222. sd_reps_orb1 := count . sd_reps_orb1
  223. >>;
  224. sd_reps_orb1 :=
  225. intersection(sd_reps_orb1, venth(sd, 5));
  226. b_1 := venth(car sc, k);
  227. b_2 := venth(car sc, k+1);
  228. sd_reps_orb1 := delete(venth(car sc, k), sd_reps_orb1);
  229. %% join orbits of sd by joining elts of sd_reps_orb1
  230. while sd_reps_orb1 do
  231. <<
  232. elt := car sd_reps_orb1;
  233. sd_reps_orb1 := cdr sd_reps_orb1;
  234. nu_1 := nu_2 := nil;
  235. img := elt;
  236. while (img neq b_1) do
  237. <<
  238. nu_1 :=
  239. if nu_1 then
  240. pe_mult(nu_1, venth(sc_transversal(sc,k),img))
  241. else
  242. venth(sc_transversal(sc,k),img);
  243. img := pe_apply(nu_1, elt);
  244. >>;
  245. sigma := pe_apply(nu_1, b_2);
  246. if member(sigma, b_orb2) then
  247. <<
  248. img := sigma;
  249. while (img neq b_2) do
  250. <<
  251. nu_2 :=
  252. if nu_2 then
  253. pe_mult(nu_1, venth(sc_transversal(sc,k+1),img))
  254. else
  255. venth(sc_transversal(sc,k+1),img);
  256. img := pe_apply(nu_2, sigma);
  257. >>;
  258. if nu_2 then
  259. pe := pe_mult(nu_1, nu_2)
  260. else
  261. pe := nu_1;
  262. inv_pe := pe_inv(pe);
  263. sd_addgen(sd, pe, inv_pe);
  264. %% update sd_reps_orb1
  265. %% nu_1 taken as temp storage
  266. nu_1 := nil;
  267. for each img in sd_reps_orb1 do
  268. if sd_orbrep(sd, img)= img then
  269. nu_1 := img . nu_1;
  270. sd_reps_orb1 := nu_1;
  271. >>
  272. >>;
  273. %% update base specifications
  274. swap := venth(car sc, k);
  275. putve(car sc, k, venth(car sc, k+1));
  276. putve(car sc, k+1, swap);
  277. %% sd is new description of stabilizer at level k+1 of sc
  278. putve(cdr sc, k+1, sd);
  279. %% update transversal for sd(k), as base element has changed
  280. sd_recomp_transversal(sc_stabdesc(sc, k), venth(car sc, k));
  281. return sc;
  282. end;
  283. symbolic procedure sc_setbase(sc, base_vect);
  284. begin integer count, k;
  285. for count := 1:upbve(base_vect) do
  286. <<
  287. if venth(base_vect, count) neq venth(car sc, count) then
  288. for k := index_elt(venth(base_vect, count), car sc)-1
  289. step -1 until count do sc_swapbase(sc, k)
  290. >>;
  291. end;
  292. endmodule;
  293. end;