1 /****************************************************************************
2 **
3 *A interactive_pga.c ANUPQ source Eamonn O'Brien
4 **
5 *Y Copyright 1995-2001, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
6 *Y Copyright 1995-2001, School of Mathematical Sciences, ANU, Australia
7 **
8 */
9
10 #include "pq_defs.h"
11 #include "pcp_vars.h"
12 #include "pga_vars.h"
13 #include "constants.h"
14 #include "menus.h"
15 #include "standard.h"
16 #include "pq_functions.h"
17 #include "global.h"
18
19 #define MAX_INTERACTIVE_OPTION 18 /* maximum number of menu options */
20
21 #define COMBINATION 100
22
23 /* interactive menu for p-group generation */
24
interactive_pga(Logical group_present,FILE * StartFile,int group_nmr,int *** auts,struct pga_vars * pga,struct pcp_vars * pcp)25 void interactive_pga(Logical group_present,
26 FILE *StartFile,
27 int group_nmr,
28 int ***auts,
29 struct pga_vars *pga,
30 struct pcp_vars *pcp)
31 {
32 struct pga_vars flag;
33 int option;
34 Logical soluble_group = TRUE;
35
36 FILE *OutputFile = 0;
37 FILE *LINK_input = 0;
38
39 char *StartName = 0;
40 int t;
41
42 int **perms = 0;
43 int index;
44 int **S = 0;
45 int k;
46 int K;
47 int label;
48 int *a = 0, *b = 0;
49 char *c = 0;
50 int *orbit_length = 0;
51 int nmr_of_exponents;
52 int *subset = 0;
53 int alpha;
54 int upper_step;
55 int rep;
56 int i;
57
58 list_interactive_pga_menu();
59
60 do {
61 option = read_option(MAX_INTERACTIVE_OPTION);
62 switch (option) {
63
64 case -1:
65 list_interactive_pga_menu();
66 break;
67
68 case SUPPLY_AUTS:
69 auts = read_auts(PGA, &pga->m, &nmr_of_exponents, pcp);
70 #ifdef HAVE_GMP
71 autgp_order(pga, pcp);
72 #endif
73 pga->soluble = TRUE;
74 start_group(&StartFile, auts, pga, pcp);
75 break;
76
77 case EXTEND_AUTS:
78 extend_automorphisms(auts, pga->m, pcp);
79 print_auts(pga->m, pcp->lastg, auts, pcp);
80 break;
81
82 case RESTORE_GP:
83 StartName = GetString("Enter input file name: ");
84 StartFile = OpenFileInput(StartName);
85 if (StartFile != NULL) {
86 read_value(TRUE, "Which group? ", &group_nmr, 0);
87 auts = restore_group(TRUE, StartFile, group_nmr, pga, pcp);
88 RESET(StartFile);
89 }
90 break;
91
92 case DISPLAY_GP:
93 print_presentation(FALSE, pcp);
94 print_structure(1, pcp->lastg, pcp);
95 print_pcp_relations(pcp);
96 break;
97
98 case SINGLE_STAGE:
99 t = runTime();
100 if (group_present && pga->m == 0)
101 start_group(&StartFile, auts, pga, pcp);
102 assert(OutputFile);
103 construct(1,
104 &flag,
105 SINGLE_STAGE,
106 OutputFile,
107 StartFile,
108 0,
109 ALL,
110 group_nmr,
111 pga,
112 pcp);
113 t = runTime() - t;
114 printf("Time for intermediate stage is %.2f seconds\n", t * CLK_SCALE);
115 break;
116
117 case DEGREE:
118 read_step_size(pga, pcp);
119 read_subgroup_rank(&k);
120 query_exponent_law(pga);
121 enforce_laws(pga, pga, pcp);
122 extend_automorphisms(auts, pga->m, pcp);
123 step_range(k, &pga->s, &upper_step, auts, pga, pcp);
124
125 if (pga->s > upper_step)
126 printf("Desired step size is invalid for current group\n");
127 else {
128 if (pga->s < upper_step) {
129 printf("The permitted relative step sizes range from %d to %d\n",
130 pga->s,
131 upper_step);
132 read_value(
133 TRUE, "Input the chosen relative step size: ", &pga->s, 0);
134 }
135
136
137 store_definition_sets(pga->r, pga->s, pga->s, pga);
138 get_definition_sets(pga);
139 pga->print_degree = TRUE;
140 compute_degree(pga);
141 pga->print_degree = FALSE;
142 }
143 break;
144
145 case PERMUTATIONS:
146 if (pga->Degree != 0) {
147 t = runTime();
148
149 query_solubility(pga);
150 pga->trace = FALSE;
151 if (pga->soluble)
152 query_space_efficiency(pga);
153 else
154 pga->space_efficient = FALSE;
155 query_perm_information(pga);
156
157 strip_identities(auts, pga, pcp);
158 soluble_group =
159 (pga->soluble || pga->Degree == 1 || pga->nmr_of_perms == 0);
160 if (!soluble_group) {
161 #if defined(GAP_LINK)
162 StartGapFile(pga);
163 #else
164 #if defined(GAP_LINK_VIA_FILE)
165 start_GAP_file(&LINK_input, auts, pga, pcp);
166 #endif
167 #endif
168 }
169 perms = permute_subgroups(LINK_input, &a, &b, &c, auts, pga, pcp);
170
171 #if defined(GAP_LINK_VIA_FILE)
172 if (!soluble_group)
173 CloseFile(LINK_input);
174 #endif
175 t = runTime() - t;
176 printf("Time to compute permutations is %.2f seconds\n",
177 t * CLK_SCALE);
178 } else
179 printf("You must first select option %d\n", DEGREE);
180
181 break;
182
183 case ORBITS:
184 orbit_option(option, perms, &a, &b, &c, &orbit_length, pga);
185 break;
186
187 case STABILISERS:
188 case STABILISER:
189 assert(perms);
190 stabiliser_option(
191 option, auts, perms, a, b, c, orbit_length, pga, pcp);
192 /*
193 free_space (pga->soluble, perms, orbit_length,
194 a, b, c, pga);
195 */
196 break;
197
198 case MATRIX_TO_LABEL:
199 S = allocate_matrix(pga->s, pga->q, 0, FALSE);
200 subset = allocate_vector(pga->s, 0, FALSE);
201 printf("Input the %d x %d subgroup matrix:\n", pga->s, pga->q);
202 read_matrix(S, pga->s, pga->q);
203 K = echelonise_matrix(S, pga->s, pga->q, pga->p, subset, pga);
204 printf("The standard matrix is:\n");
205 print_matrix(S, pga->s, pga->q);
206 printf("The label is %d\n", subgroup_to_label(S, K, subset, pga));
207 free_vector(subset, 0);
208 break;
209
210 case LABEL_TO_MATRIX:
211 read_value(TRUE, "Input allowable subgroup label: ", &label, 1);
212 S = label_to_subgroup(&index, &subset, label, pga);
213 printf("The corresponding standard matrix is\n");
214 print_matrix(S, pga->s, pga->q);
215 break;
216
217 case IMAGE:
218 t = runTime();
219 /*
220 invert_automorphisms (auts, pga, pcp);
221 print_auts (pga->m, pcp->lastg, auts, pcp);
222 */
223 printf("Input the subgroup label and automorphism number: ");
224 read_value(TRUE, "", &label, 1);
225 read_value(FALSE, "", &alpha, 1);
226 printf("Image is %d\n", find_image(label, auts[alpha], pga, pcp));
227 t = runTime() - t;
228 printf("Computation time in seconds is %.2f\n", t * CLK_SCALE);
229 break;
230
231 case SUBGROUP_RANK:
232 read_subgroup_rank(&k);
233 printf("Closure of initial segment subgroup has rank %d\n",
234 close_subgroup(k, auts, pga, pcp));
235 break;
236
237 case ORBIT_REP:
238 printf("Input label for subgroup: ");
239 read_value(TRUE, "", &label, 1);
240 rep = abs(a[label]);
241 for (i = 1; i <= pga->nmr_orbits && pga->rep[i] != rep; ++i)
242 ;
243 printf("Subgroup with label %d has representative %d and is in orbit "
244 "%d\n",
245 label,
246 rep,
247 i);
248 break;
249
250
251 case COMPACT_DESCRIPTION:
252 Compact_Description = TRUE;
253 read_value(TRUE,
254 "Lower bound for order (0 for all groups generated)? ",
255 &Compact_Order,
256 0);
257 break;
258
259 case AUT_CLASSES:
260 t = runTime();
261 permute_elements();
262 t = runTime() - t;
263 printf("Time to compute orbits is %.2f seconds\n", t * CLK_SCALE);
264 break;
265
266 /*
267 printf ("Input label: ");
268 scanf ("%d", &l);
269 process_complete_orbit (a, l, pga, pcp);
270 break;
271
272 case TEMP:
273 printf ("Input label: ");
274 scanf ("%d", &l);
275 printf ("Input label: ");
276 scanf ("%d", &u);
277 for (i = l; i <= u; ++i) {
278 x = IsValidAllowableSubgroup (i, pga);
279 printf ("%d is %d\n", i, x);
280 }
281 StartName = GetString ("Enter output file name: ");
282 OutputFile = OpenFileOutput (StartName);
283 part_setup_reps (pga->rep, pga->nmr_orbits, orbit_length, perms, a, b,
284 c,
285 auts, OutputFile, OutputFile, pga, pcp);
286
287 list_word (pga, pcp);
288
289 read_value (TRUE, "Input the rank of the subgroup: ", &pga->q, 1);
290 strip_identities (auts, pga, pcp);
291 break;
292 */
293
294 case EXIT:
295 case MAX_INTERACTIVE_OPTION:
296 printf("Exiting from interactive p-group generation menu\n");
297 break;
298
299 } /* switch */
300
301 } while (option != 0 && option != MAX_INTERACTIVE_OPTION);
302
303 #if defined(GAP_LINK)
304 if (!soluble_group)
305 QuitGap();
306 #endif
307 }
308
309 /* list available menu options */
310
list_interactive_pga_menu(void)311 void list_interactive_pga_menu(void)
312 {
313 printf("\nAdvanced Menu for p-Group Generation\n");
314 printf("-------------------------------------\n");
315 printf("%d. Read automorphism information for starting group\n",
316 SUPPLY_AUTS);
317 printf("%d. Extend and display automorphisms\n", EXTEND_AUTS);
318 printf("%d. Specify input file and group number\n", RESTORE_GP);
319 printf("%d. List group presentation\n", DISPLAY_GP);
320 printf("%d. Carry out intermediate stage calculation\n", SINGLE_STAGE);
321 printf("%d. Compute definition sets & find degree\n", DEGREE);
322 printf("%d. Construct permutations of subgroups under automorphisms\n",
323 PERMUTATIONS);
324 printf("%d. Compute and list orbit information\n", ORBITS);
325 printf("%d. Process all orbit representatives\n", STABILISERS);
326 printf("%d. Process individual orbit representative\n", STABILISER);
327 printf("%d. Compute label for standard matrix of subgroup\n",
328 MATRIX_TO_LABEL);
329 printf("%d. Compute standard matrix for subgroup from label\n",
330 LABEL_TO_MATRIX);
331 printf("%d. Find image of allowable subgroup under automorphism\n", IMAGE);
332 printf("%d. Find rank of closure of initial segment subgroup\n",
333 SUBGROUP_RANK);
334 printf("%d. List representative and orbit for supplied label\n", ORBIT_REP);
335 printf("%d. Write compact descriptions of generated groups to file\n",
336 COMPACT_DESCRIPTION);
337 printf("%d. Find automorphism classes of elements of vector space\n",
338 AUT_CLASSES);
339 printf("%d. Exit to main p-group generation menu\n", MAX_INTERACTIVE_OPTION);
340 }
341
orbit_option(int option,int ** perms,int ** a,int ** b,char ** c,int ** orbit_length,struct pga_vars * pga)342 void orbit_option(int option,
343 int **perms,
344 int **a,
345 int **b,
346 char **c,
347 int **orbit_length,
348 struct pga_vars *pga)
349 {
350 int t;
351 Logical soluble_group;
352 /* FILE * file; */
353
354
355 if (option != COMBINATION && option != STANDARDISE) {
356 query_solubility(pga);
357 if (pga->soluble)
358 query_space_efficiency(pga);
359 else
360 pga->space_efficient = FALSE;
361 query_orbit_information(pga);
362 } else if (option == COMBINATION) {
363 pga->print_orbit_summary = FALSE;
364 pga->print_orbits = FALSE;
365 } else if (option == STANDARDISE) {
366 pga->print_orbit_summary = FALSE;
367 pga->print_orbits = FALSE;
368 }
369
370 soluble_group = (pga->soluble || pga->Degree == 1 || pga->nmr_of_perms == 0);
371
372 if (!pga->space_efficient) {
373 t = runTime();
374 if (soluble_group)
375 compute_orbits(a, b, c, perms, pga);
376 else
377 insoluble_compute_orbits(a, b, c, perms, pga);
378 if (option != COMBINATION && option != STANDARDISE) {
379 t = runTime() - t;
380 printf("Time to compute orbits is %.2f seconds\n", t * CLK_SCALE);
381 }
382 }
383
384 /* if in soluble portion of combination, we do not need to
385 set up representives */
386 if (option == COMBINATION && pga->soluble)
387 return;
388
389 *orbit_length = find_orbit_reps(*a, *b, pga);
390
391 if (pga->print_orbit_summary)
392 orbit_summary(*orbit_length, pga);
393 /* file = OpenFile ("COUNT", "a+");
394 fprintf (file, "%d,\n", pga->nmr_orbits);
395 */
396 }
397
stabiliser_option(int option,int *** auts,int ** perms,int * a,int * b,char * c,int * orbit_length,struct pga_vars * pga,struct pcp_vars * pcp)398 void stabiliser_option(int option,
399 int ***auts,
400 int **perms,
401 int *a,
402 int *b,
403 char *c,
404 int *orbit_length,
405 struct pga_vars *pga,
406 struct pcp_vars *pcp)
407 {
408 int t;
409 int i;
410 /*Logical soluble_group;*/
411 FILE *OutputFile;
412 char *StartName;
413 int *rep;
414 int *length;
415 rep = allocate_vector(1, 1, 0);
416 length = allocate_vector(1, 1, 0);
417
418 t = runTime();
419
420 query_solubility(pga);
421 if (pga->soluble)
422 query_space_efficiency(pga);
423 else
424 pga->space_efficient = FALSE;
425 /*soluble_group = (pga->soluble || pga->Degree == 1 || pga->nmr_of_perms == 0);*/
426
427 query_terminal(pga);
428 query_exponent_law(pga);
429 query_metabelian_law(pga);
430 query_group_information(pga->p, pga);
431 query_aut_group_information(pga);
432 StartName = GetString("Enter output file name: ");
433 OutputFile = OpenFileOutput(StartName);
434
435 pga->final_stage = (pga->q == pga->multiplicator_rank);
436 pga->nmr_of_descendants = 0;
437 pga->nmr_of_capables = 0;
438
439 if (option == STABILISER) {
440 read_value(TRUE, "Input the orbit representative: ", &rep[1], 1);
441 /* find the length of the orbit having this representative */
442 for (i = 1; i <= pga->nmr_orbits && pga->rep[i] != rep[1]; ++i)
443 ;
444 if (pga->rep[i] == rep[1])
445 length[1] = orbit_length[i];
446 else {
447 printf("%d is not an orbit representative\n", rep[1]);
448 return;
449 }
450 }
451
452 if (option == STABILISER)
453 setup_reps(rep,
454 1,
455 length,
456 perms,
457 a,
458 b,
459 c,
460 auts,
461 OutputFile,
462 OutputFile,
463 pga,
464 pcp);
465 else
466 setup_reps(pga->rep,
467 pga->nmr_orbits,
468 orbit_length,
469 perms,
470 a,
471 b,
472 c,
473 auts,
474 OutputFile,
475 OutputFile,
476 pga,
477 pcp);
478
479 /*
480 #if defined (GAP_LINK)
481 if (!soluble_group)
482 QuitGap ();
483 #endif
484 */
485
486 RESET(OutputFile);
487
488 printf("Time to process representative is %.2f seconds\n",
489 (runTime() - t) * CLK_SCALE);
490 }
491
492
493 /* list orbit representatives as words subject to the supplied map */
494
list_word(struct pga_vars * pga,struct pcp_vars * pcp)495 int list_word(struct pga_vars *pga, struct pcp_vars *pcp)
496 {
497 register int i, j;
498 int start_length;
499
500 int start[100];
501 int word[100];
502
503 int **S;
504 int index;
505 int *subset;
506 int length = 0;
507 register int k, r;
508 register int lastg = pcp->lastg;
509
510 start_length = 0;
511 /*
512 read_value (TRUE, "Input length of initial segment: ", &start_length, 0);
513 for (i = 1; i <= start_length; ++i)
514 scanf ("%d", &start[i]);
515 */
516
517 for (r = 1; r <= pga->nmr_orbits; ++r) {
518
519 S = label_to_subgroup(&index, &subset, pga->rep[r], pga);
520
521 print_matrix(S, pga->s, pga->q);
522
523 for (i = 0; i < pga->q; ++i) {
524
525 if (1 << i & pga->list[index])
526 continue;
527
528 for (j = 1; j <= lastg; ++j)
529 word[j] = 0;
530
531 for (j = 0; j < pga->s; ++j)
532 if (S[j][i] != 0)
533 word[pcp->ccbeg + subset[j]] = pga->p - S[j][i];
534
535 word[pcp->ccbeg + i] = 1;
536
537 print_array(word, pcp->ccbeg, lastg + 1);
538
539 length = 0;
540 for (k = pcp->ccbeg; k <= lastg; ++k)
541 if (word[k] != 0)
542 ++length;
543
544 printf("%d\n", length + start_length);
545 for (k = 1; k <= start_length; ++k)
546 printf("%d 1 ", start[k]);
547
548 for (k = pcp->ccbeg; k <= lastg; ++k)
549 if (word[k] != 0)
550 printf("%d %d ", k, word[k]);
551 printf("\n");
552 }
553 }
554
555 return 0;
556 }
557