CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / pkg / ace-5.2 / src / util1.c
Views: 418346
1
2
/**************************************************************************
3
4
util1.c
5
Colin Ramsay ([email protected])
6
22 Dec 00
7
8
ADVANCED COSET ENUMERATOR, Version 3.001
9
10
Copyright 2000
11
Centre for Discrete Mathematics and Computing,
12
Department of Mathematics and
13
Department of Computer Science & Electrical Engineering,
14
The University of Queensland, QLD 4072.
15
(http://staff.itee.uq.edu.au/havas)
16
17
These are the utilities for Level 1 of ACE.
18
19
**************************************************************************/
20
21
#include "al1.h"
22
23
#include <ctype.h>
24
25
/******************************************************************
26
void al1_init(void)
27
28
One-off initialisation of the Level 1 stuff, and all lower levels.
29
Note that there is no need to initialise, for example, genal[].
30
******************************************************************/
31
32
void al1_init(void)
33
{
34
al0_init();
35
36
workspace = DEFWORK;
37
workmult = 1;
38
costable = NULL;
39
tabsiz = 0;
40
41
currrep = NULL;
42
repsiz = repsp = 0;
43
44
asis = FALSE;
45
46
grpname = NULL;
47
rellst = NULL;
48
trellen = 0;
49
50
ndgen = 0;
51
geninv = NULL;
52
gencol = colgen = NULL;
53
galpha = FALSE;
54
algen[0] = algen[1] = '\0'; /* &algen[1] is printable string */
55
56
subgrpname = NULL;
57
genlst = NULL;
58
tgenlen = 0;
59
60
rfactor1 = cfactor1 = 0;
61
pdsiz1 = dedsiz1 = 0;
62
maxrow1 = ffactor1 = 0;
63
nrinsgp1 = -1;
64
}
65
66
/******************************************************************
67
void al1_dump(Logic allofit)
68
69
Dump out the internals of Level 1 of ACE, working through al1.h
70
more or less in order.
71
******************************************************************/
72
73
void al1_dump(Logic allofit)
74
{
75
int i;
76
Wlelt *p;
77
78
fprintf(fop, " #---- %s: Level 1 Dump ----\n", ACE_VER);
79
80
/* workspace, workmult, costable, tabsiz; */
81
fprintf(fop, "workspace=%d workmult=%d", workspace, workmult);
82
if (costable == NULL)
83
{ fprintf(fop, " costable=NULL"); }
84
else
85
{ fprintf(fop, " costable=non-NULL"); }
86
fprintf(fop, " tabsiz=%d\n", tabsiz);
87
88
/* currrep, repsiz, repsp; */
89
if (currrep == NULL)
90
{ fprintf(fop, "currrep=NULL"); }
91
else
92
{ fprintf(fop, "currrep=non-NULL"); }
93
fprintf(fop, " repsiz=%d repsp=%d\n", repsiz, repsp);
94
95
/* LLL, asis */
96
fprintf(fop, "LLL=%d, asis=%d\n", LLL, asis);
97
98
/* group: name, generators, geninv */
99
if (grpname == NULL)
100
{ fprintf(fop, "grpname=NULL\n"); }
101
else
102
{ fprintf(fop, "grpname=%s\n", grpname); }
103
104
if (ndgen == 0)
105
{ fprintf(fop, "ndgen=%d\n", ndgen); }
106
else if (galpha)
107
{
108
fprintf(fop, "ndgen=%d galpha=%d algen[]=", ndgen, galpha);
109
for (i = 1; i <= ndgen; i++)
110
{ fprintf(fop, "%c", algen[i]); }
111
fprintf(fop, "\n");
112
113
if (allofit)
114
{
115
fprintf(fop, " genal[]=");
116
for (i = 1; i <= 26; i++)
117
{ fprintf(fop, "%d ", genal[i]); }
118
fprintf(fop, "\n");
119
}
120
}
121
else
122
{ fprintf(fop, "ndgen=%d galpha=%d\n", ndgen, galpha); }
123
124
if (geninv == NULL)
125
{ fprintf(fop, "geninv=NULL\n"); }
126
else
127
{
128
fprintf(fop, "geninv[]=");
129
for (i = 1; i <= ndgen; i++)
130
{ fprintf(fop, "%d ", geninv[i]); }
131
fprintf(fop, "\n");
132
}
133
134
/* gencol, colgen */
135
if (gencol == NULL)
136
{ fprintf(fop, "gencol=NULL\n"); }
137
else
138
{
139
fprintf(fop, "gencol[]=");
140
for (i = -ndgen; i <= -1; i++)
141
{ fprintf(fop, "%d ", gencol[ndgen+i]); }
142
fprintf(fop, "x ");
143
for (i = 1; i <= ndgen; i++)
144
{ fprintf(fop, "%d ", gencol[ndgen+i]); }
145
fprintf(fop, "\n");
146
}
147
if (colgen == NULL)
148
{ fprintf(fop, "colgen=NULL\n"); }
149
else
150
{
151
fprintf(fop, "colgen[]=");
152
for (i = 1; i <= ncol; i++)
153
{ fprintf(fop, "%d ", colgen[i]); }
154
fprintf(fop, "\n");
155
}
156
157
/* group relators + trellen */
158
if (rellst == NULL)
159
{ fprintf(fop, "rellst=NULL trellen=%d\n", trellen); }
160
else if (rellst->len == 0)
161
{ fprintf(fop, "rellst->len=0 trellen=%d\n", trellen); }
162
else
163
{
164
fprintf(fop, "rellst->len=%d trellen=%d\n", rellst->len, trellen);
165
if (allofit)
166
{
167
fprintf(fop, " len exp inv word\n");
168
for (p = rellst->first; ; p = p->next)
169
{
170
fprintf(fop, " %3d %3d %3d ", p->len, p->exp, p->invol);
171
for (i = 1; i <= p->len; i++)
172
{ fprintf(fop, "%d ", p->word[i]); }
173
fprintf(fop, "\n");
174
175
if (p == rellst->last)
176
{ break; }
177
}
178
}
179
}
180
181
/* subgroup: name */
182
if (subgrpname == NULL)
183
{ fprintf(fop, "subgrpname=NULL\n"); }
184
else
185
{ fprintf(fop, "subgrpname=%s\n", subgrpname); }
186
187
/* subgroup generators + tgenlen */
188
if (genlst == NULL)
189
{ fprintf(fop, "genlst=NULL tgenlen=%d\n", tgenlen); }
190
else if (genlst->len == 0)
191
{ fprintf(fop, "genlst->len=0 tgenlen=%d\n", tgenlen); }
192
else
193
{
194
fprintf(fop, "genlst->len=%d tgenlen=%d\n", genlst->len, tgenlen);
195
if (allofit)
196
{
197
fprintf(fop, " len exp inv word\n");
198
for (p = genlst->first; ; p = p->next)
199
{
200
fprintf(fop, " %3d %3d %3d ", p->len, p->exp, p->invol);
201
for (i = 1; i <= p->len; i++)
202
{ fprintf(fop, "%d ", p->word[i]); }
203
fprintf(fop, "\n");
204
205
if (p == genlst->last)
206
{ break; }
207
}
208
}
209
}
210
211
/* rfactor1, cfactor1 */
212
fprintf(fop, "rfactor1=%d cfactor1=%d\n", rfactor1, cfactor1);
213
214
/* pdsiz1, dedsiz1 */
215
fprintf(fop, "pdsiz1=%d dedsiz1=%d\n", pdsiz1, dedsiz1);
216
217
/* maxrow1, ffactor1, nrinsgp1 */
218
fprintf(fop, "maxrow1=%d ffactor1=%d nrinsgp1=%d\n",
219
maxrow1, ffactor1, nrinsgp1);
220
221
fprintf(fop, " #---------------------------------\n");
222
}
223
224
/******************************************************************
225
void al1_prtdetails(int bits)
226
227
This prints out details of the Level 0 & 1 settings, in a form
228
suitable for reading in by applications using the core enumerator
229
plus its wrapper (eg, ACE Level 2). If bits is 0, then enum, rel,
230
subg & gen are printed. If 1 then *all* of the presentation and
231
the enumerator control settings (this allows the run to be
232
duplicated at a later date). If bits is 2-5, then only enum, rel,
233
subg & gen, respectively, are printed. This routine is really
234
intended for the ACE Level 2 interface, where some items cannot be
235
examined by invoking them with an empty argument. However it is
236
put here (at Level 1), since it is a useful utility for any
237
application.
238
239
If messaging in on, this routine (with bits 1) is called by
240
al1_start() after all the setup & just before the call to
241
al0_enum(). So it shows what the parameters actually were. They
242
may not match what you thought they were, since the Level 1 wrapper
243
(which interfaces between applications (ie, ACE's Level 2
244
interactive interface) and the Level 0 enumerator) trys to prevent
245
errors, and may occasionally ignore or change something. If you
246
call this after changing parameters, but before calling _start(),
247
the values do *not* reflect the new values. If you want to see
248
what the Level 2 parameters are (as opposed to the current Level 0
249
parameters), use the `empty argument' form of the commands, or the
250
"sr;" Level 2 command (which invokes this function with bits
251
false.
252
253
To *exactly* duplicate a run, you may need to duplicate the entire
254
sequence of commands since ACE was started, the execution
255
environment, and use the same executable; but that's a project for
256
some rainy Sunday afternoon sometime in the future. However do
257
note that the allocation of generators to columns may have upset
258
your intended handling of involutions and/or the ordering of the
259
generators; do a (full) Level 0/1 dump to check this, if you care!
260
In particular, the value of asis is the *current* value, which may
261
not match that when the call to _start() which allocated columns &
262
determined which generators will be involutions was made.
263
******************************************************************/
264
265
void al1_prtdetails(int bits)
266
{
267
if (bits < 2)
268
{ fprintf(fop, " #--- %s: Run Parameters ---\n", ACE_VER); }
269
270
if (bits == 0 || bits == 1 || bits == 2)
271
{
272
if (grpname != NULL)
273
{ fprintf(fop, "Group Name: %s;\n", grpname); }
274
else
275
{ fprintf(fop, "Group Name: ;\n"); }
276
}
277
278
if (bits == 1)
279
{
280
if (ndgen > 0)
281
{
282
fprintf(fop, "Group Generators: ");
283
if (!galpha)
284
{ fprintf(fop, "%d", ndgen); }
285
else
286
{ fprintf(fop, "%s", &algen[1]); }
287
fprintf(fop, ";\n");
288
}
289
}
290
291
if (bits == 0 || bits == 1 || bits == 3)
292
{
293
if (rellst != NULL)
294
{
295
fprintf(fop, "Group Relators: ");
296
al1_prtwl(rellst, 16);
297
fprintf(fop, ";\n");
298
}
299
else
300
{ fprintf(fop, "Group Relators: ;\n"); }
301
}
302
303
if (bits == 0 || bits == 1 || bits == 4)
304
{
305
if (subgrpname != NULL)
306
{ fprintf(fop, "Subgroup Name: %s;\n", subgrpname); }
307
else
308
{ fprintf(fop, "Subgroup Name: ;\n"); }
309
}
310
311
if (bits == 0 || bits == 1 || bits == 5)
312
{
313
if (genlst != NULL)
314
{
315
fprintf(fop, "Subgroup Generators: ");
316
al1_prtwl(genlst, 21);
317
fprintf(fop, ";\n");
318
}
319
else
320
{ fprintf(fop, "Subgroup Generators: ;\n"); }
321
}
322
323
if (bits == 1)
324
{
325
switch (workmult)
326
{
327
case 1:
328
fprintf(fop, "Wo:%d;", workspace);
329
break;
330
case KILO:
331
fprintf(fop, "Wo:%dK;", workspace);
332
break;
333
case MEGA:
334
fprintf(fop, "Wo:%dM;", workspace);
335
break;
336
case GIGA:
337
fprintf(fop, "Wo:%dG;", workspace);
338
break;
339
}
340
fprintf(fop, " Max:%d;", maxrow);
341
if (msgctrl)
342
{
343
if (msghol)
344
{ fprintf(fop, " Mess:-%d;", msgincr); }
345
else
346
{ fprintf(fop, " Mess:%d;", msgincr); }
347
}
348
else
349
{ fprintf(fop, " Mess:0;"); }
350
fprintf(fop, " Ti:%d; Ho:%d; Loop:%d;\n", tlimit, hlimit, llimit);
351
352
if (asis)
353
{ fprintf(fop, "As:1;"); }
354
else
355
{ fprintf(fop, "As:0;"); }
356
if (pcomp)
357
{ fprintf(fop, " Path:1;"); }
358
else
359
{ fprintf(fop, " Path:0;"); }
360
if (rfill)
361
{ fprintf(fop, " Row:1;"); }
362
else
363
{ fprintf(fop, " Row:0;"); }
364
if (mendel)
365
{ fprintf(fop, " Mend:1;"); }
366
else
367
{ fprintf(fop, " Mend:0;"); }
368
fprintf(fop, " No:%d; Look:%d; Com:%d;\n", nrinsgp, lahead, comppc);
369
370
/* Note that we printout using the aliases, since we want to know (or,
371
at least, be able to deduce) what style was used. Note that, although
372
ffactor is a float, the Level 1 (& Level 2) interfaces use ffactor1,
373
which is an int. So we need to convert for printout, to maintain the
374
ability to read the output back in. */
375
376
fprintf(fop, "C:%d; R:%d; Fi:%d;", cfactor1, rfactor1, (int)ffactor);
377
fprintf(fop, " PMod:%d; PSiz:%d; DMod:%d;", pdefn, pdsiz, dedmode);
378
fprintf(fop, " DSiz:%d;\n", dedsiz);
379
}
380
381
if (bits < 2)
382
{ fprintf(fop, " #---------------------------------\n"); }
383
}
384
385
/******************************************************************
386
void al1_rslt(int rslt)
387
388
Pretty-print the result of a run of al1_start(). If there were no
389
problems at Level 1, this will just be the result of the call to
390
al0_enum(), printed via al0_rslt().
391
******************************************************************/
392
393
void al1_rslt(int rslt)
394
{
395
if (rslt > -8192)
396
{ al0_rslt(rslt); }
397
else
398
{
399
switch(rslt)
400
{
401
case -8194: fprintf(fop, "TABLE TOO SMALL\n"); break;
402
case -8193: fprintf(fop, "MEMORY PROBLEM\n"); break;
403
case -8192: fprintf(fop, "INVALID MODE\n"); break;
404
default: fprintf(fop, "UNKNOWN ERROR (%d)\n", rslt); break;
405
}
406
}
407
}
408
409
/**************************************************************************
410
These are the utilities for the simple list manipulation package used to
411
handle the group's relators & the subgroup's generators. Note that it is
412
up to the caller to catch any errors (flagged by the return values).
413
**************************************************************************/
414
415
/******************************************************************
416
Wlist *al1_newwl(void)
417
418
Creates a new (empty) word list. Returns NULL on failure.
419
******************************************************************/
420
421
Wlist *al1_newwl(void)
422
{
423
Wlist *p = (Wlist *)malloc(sizeof(Wlist));
424
425
if (p != NULL)
426
{
427
p->len = 0;
428
p->first = p->last = NULL;
429
}
430
431
return(p);
432
}
433
434
/******************************************************************
435
Wlelt *al1_newelt(void)
436
437
Creates a new (empty) word-list element. Returns NULL on failure.
438
******************************************************************/
439
440
Wlelt *al1_newelt(void)
441
{
442
Wlelt *p = (Wlelt *)malloc(sizeof(Wlelt));
443
444
if (p != NULL)
445
{
446
p->word = NULL;
447
p->len = p->exp = 0;
448
p->invol = FALSE;
449
p->next = NULL;
450
}
451
452
return(p);
453
}
454
455
/******************************************************************
456
void al1_addwl(Wlist *l, Wlelt *w)
457
458
Adds a word (if it's non-null & non-empty) to a word list. l must
459
be non-null, but may be empty.
460
******************************************************************/
461
462
void al1_addwl(Wlist *l, Wlelt *w)
463
{
464
if (w == NULL || w->len == 0) /* ignore null/empty words */
465
{ return; }
466
467
if (l->len == 0)
468
{ l->first = w; } /* add word to start of list */
469
else
470
{ l->last->next = w; } /* add word to end of list */
471
472
l->last = w;
473
l->len++;
474
}
475
476
/******************************************************************
477
void al1_concatwl(Wlist *l, Wlist *m);
478
479
Concatenate m's list to l's, and delete m's header node. Note that
480
l is guaranteed non-null, but may be empty. m may be null, empty,
481
or contain data.
482
******************************************************************/
483
484
void al1_concatwl(Wlist *l, Wlist *m)
485
{
486
if (m == NULL)
487
{ return; }
488
else if (m->len == 0)
489
{
490
free(m);
491
return;
492
}
493
494
/* If we get here, m contains data */
495
496
if (l->len == 0) /* l is empty */
497
{
498
l->len = m->len;
499
l->first = m->first;
500
l->last = m->last;
501
}
502
else /* l is non-empty */
503
{
504
l->len += m->len;
505
l->last->next = m->first;
506
l->last = m->last;
507
}
508
509
free(m);
510
}
511
512
/******************************************************************
513
void al1_emptywl(Wlist *l)
514
515
Delete the list of words in l, leaving l as an empty list. Does
516
*not* delete the storage for l.
517
******************************************************************/
518
519
void al1_emptywl(Wlist *l)
520
{
521
Wlelt *p, *q;
522
523
if (l == NULL || l->len == 0)
524
{ return; }
525
526
for (p = l->first; p != NULL; )
527
{
528
q = p->next;
529
530
if (p->word != NULL)
531
{ free(p->word); }
532
free(p);
533
534
p = q;
535
}
536
537
l->len = 0;
538
l->first = l->last = NULL;
539
}
540
541
/******************************************************************
542
void al1_prtwl(Wlist *l, int n)
543
544
Attempt to pretty-print a list of group relators or subgroup
545
generators within the allowed (i.e., LLL) number of columns. n is
546
the current output column. (Not quite sure how this would cope
547
with a really nasty presentation!) Note that this prints out words
548
in exp form. If no enumeration has yet been run, exp is at its
549
default of 1, so a printout will not be `exponentiated'. Note that
550
relators of the form xx are *always* printed out in the form (x)^2
551
*if* they were entered thus; in all other cases they are printed as
552
xx. This is to preserve the ability to specify whether or not a
553
generator should be treated as an involution when asis is true.
554
555
Warning: if the list contains any empty words superfluous commas
556
may be introduced, rendering the list `invalid' to the Level 2
557
input parser! If _start() has been called in start/redo mode, then
558
the relator & generator lists are guaranteed to be free of empty
559
word (although they may contain duplicates).
560
******************************************************************/
561
562
void al1_prtwl(Wlist *l, int n)
563
{
564
Wlelt *e;
565
int elen, eexp;
566
int i, len;
567
char c;
568
569
if (l == NULL || l->len == 0)
570
{ return; }
571
572
for (e = l->first; e != NULL; e = e->next)
573
{
574
elen = e->len; /* Alias e->len & e->exp ... */
575
eexp = e->exp;
576
577
if (elen == 2 && e->word[1] == e->word[2])
578
{ /* ... adjust them if involn */
579
if (e->invol)
580
{ eexp = 2; }
581
else
582
{ eexp = 1; }
583
}
584
585
len = elen/eexp;
586
587
if (!galpha)
588
{ /* numeric generators */
589
if (eexp == 1)
590
{
591
n += 2 + len*2; /* +2 for \ , *2 for \ n */
592
if (n > LLL)
593
{
594
fprintf(fop, "\n ");
595
n = 2+2 + len*2;
596
}
597
}
598
else
599
{
600
n += 2+4 + len*2; /* 4 for ()^e */
601
if (n > LLL)
602
{
603
fprintf(fop, "\n ");
604
n = 4+4 + len*2;
605
}
606
fprintf(fop, "(");
607
}
608
609
for (i = 1; i <= len; i++)
610
{ fprintf(fop, "%d ", e->word[i]); }
611
612
if (eexp != 1)
613
{ fprintf(fop, ")^%d", eexp); }
614
if (e->next != NULL && len != 0) /* len = 0 not poss? */
615
{ fprintf(fop, ", "); }
616
}
617
else
618
{ /* alphabetic generators */
619
if (eexp == 1)
620
{
621
n += 2 + len;
622
if (n > LLL)
623
{
624
fprintf(fop, "\n ");
625
n = 2+1 + len;
626
}
627
}
628
else
629
{
630
n += 2+4 + len; /* 4 for ()^x */
631
if (n > LLL)
632
{
633
fprintf(fop, "\n ");
634
n = 3+4 + len;
635
}
636
fprintf(fop, "(");
637
}
638
639
for (i = 1; i <= len; i++)
640
{
641
c = (e->word[i] > 0) ? algen[e->word[i]]
642
: toupper(algen[-e->word[i]]);
643
fprintf(fop, "%c", c);
644
}
645
646
if (eexp != 1)
647
{ fprintf(fop, ")^%d", eexp); }
648
if (e->next != NULL && len !=0)
649
{ fprintf(fop, ", "); }
650
}
651
}
652
}
653
654
/**************************************************************************
655
These are the utilities for handling coset representatives.
656
**************************************************************************/
657
658
/******************************************************************
659
Logic al1_addrep(int col)
660
661
Add #col to the current rep've, possibly extending its storage.
662
Fails if we can't allocate memory.
663
******************************************************************/
664
665
Logic al1_addrep(int col)
666
{
667
if (currrep == NULL)
668
{
669
repsp = 8;
670
if ((currrep = (int*)malloc(repsp*sizeof(int))) == NULL)
671
{
672
repsiz = repsp = 0;
673
return(FALSE);
674
}
675
}
676
else if (repsiz == repsp) /* current entries are 0..repsiz-1 */
677
{
678
repsp *= 2;
679
if ((currrep = (int*)realloc(currrep, repsp*sizeof(int))) == NULL)
680
{
681
repsiz = repsp = 0;
682
return(FALSE);
683
}
684
}
685
686
currrep[repsiz++] = col;
687
return(TRUE);
688
}
689
690
/******************************************************************
691
Logic al1_bldrep(int cos)
692
693
Traces back through the table, building up a rep've of #cos in
694
currrep. The rep've is in terms of column numbers, and is
695
guaranteed to be the `canonic' rep've (ie, first in `length + col
696
order' order) in terms of the *current* table. The table may or
697
may not be compact/standard. If the table is compact & standard,
698
then the rep've is guaranteed to be `really' canonic, independant
699
of the details of the enumeration. Fails if _addrep() fails.
700
701
The order of the columns is *not* constrained in any way (apart
702
from the col 1/2 stuff), so we have to be careful to pick up the
703
1st col (ie, scol) in order (*after* they have been inverted) if
704
more than one entry in a row is minimal.
705
706
Note that our ability to backtrace is predicated on the fact that
707
the first definition of a coset is always in terms of a lower-
708
numbered coset, and during coinc processing we keep the lower-
709
numbered coset & move data from the higher to the lower. So each
710
coset's row, apart from #1, *must* contain a lower-numbered entry.
711
In this routine we *assume* that this property of the table has not
712
been compromised in any way; if it has, then the behaviour is
713
undefined.
714
******************************************************************/
715
716
Logic al1_bldrep(int cos)
717
{
718
int low, slow, col, scol, i;
719
720
repsiz = 0;
721
if (cos <= 1 || cos >= nextdf || COL1(cos) < 0)
722
{ return(TRUE); }
723
724
low = slow = cos;
725
while (low > 1)
726
{
727
scol = 0;
728
for (col = 1; col <= ncol; col++)
729
{
730
if ((i = CT(low,col)) > 0)
731
{
732
if (i < slow) /* Lower row number found */
733
{
734
slow = i;
735
scol = col;
736
}
737
else if (i == slow && scol != 0) /* Same row & slow < low */
738
{ /* ... earlier column? */
739
if (invcol[col] < invcol[scol])
740
{ scol = col; }
741
}
742
}
743
}
744
745
/* Add it (increases repsiz); note the column inversion! Failure sets
746
repsiz to 0 */
747
748
if (!al1_addrep(invcol[scol]))
749
{ return(FALSE); }
750
751
low = slow;
752
}
753
754
/* Reverse representative (note: inversion already done) */
755
756
for (i = 1; i <= repsiz/2; i++)
757
{
758
col = currrep[i-1];
759
scol = currrep[repsiz-i];
760
761
currrep[i-1] = scol;
762
currrep[repsiz-i] = col;
763
}
764
765
return(TRUE);
766
}
767
768
/******************************************************************
769
int al1_trrep(int cos)
770
771
Traces currrep, starting at #cos. Returns 0 on redundant cosets,
772
on empty slot, or if there's no rep've.
773
******************************************************************/
774
775
int al1_trrep(int cos)
776
{
777
int i;
778
779
if (repsiz == 0)
780
{ return(0); }
781
782
for (i = 0; i < repsiz; i++)
783
{
784
if ((COL1(cos) < 0) || ((cos = CT(cos,currrep[i])) == 0))
785
{ return(0); }
786
}
787
788
return(cos);
789
}
790
791
/******************************************************************
792
int al1_ordrep(void)
793
794
Traces currrep repeatedly until we arrive back at #1, or an empty
795
slot. The number of times round the loop is the order; return 0 if
796
the tracing doesn't complete or the rep is empty. Note that
797
termination is guaranteed, since the table is finite!
798
******************************************************************/
799
800
int al1_ordrep(void)
801
{
802
int i,j;
803
804
if (repsiz == 0)
805
{ return(0); }
806
807
for (i = j = 1; ; j++)
808
{
809
if ((i = al1_trrep(i)) == 1)
810
{ return(j); }
811
else if (i == 0)
812
{ return(0); }
813
}
814
815
return(0); /* Can't get here; prevent compiler whinging */
816
}
817
818
/******************************************************************
819
void al1_prtct(int f, int l, int s, Logic c, Logic or)
820
821
This is a general-purpose coset table printer. It prints rows from
822
f[irst] to l[ast] inclusive, in steps of s. On a bad value, we try
823
to do the `right' thing. If c[oinc] is true then the print-out
824
includes coincident rows, else not; we skip the appropriate number
825
of rows whatever the c flag is. If or is true then the order and
826
a representative are printed. The rep've is found via a backtrace
827
of the table; if the table is in standard form, this rep will be
828
minimal & the `first' in `order' (length + *column* order). Note
829
that the table may or may not have been compacted and/or
830
standardised.
831
832
Warnings/Notes:
833
i) If you print entries >999999, then the neatly aligned columns
834
will be lost, although the entries *will* be spaced.
835
ii) _bldrep() can fail. Most probably due to a lack of memory, but
836
also if the table is `corrupt' or it is called `inappropriately'.
837
In this situation we should perhaps alert the user, but we choose
838
simply to print `?'s instead!
839
******************************************************************/
840
841
void al1_prtct(int f, int l, int s, Logic c, Logic or)
842
{
843
int i, j, row;
844
845
if (f < 1)
846
{ f = 1; }
847
if (l > nextdf-1)
848
{ l = nextdf-1; }
849
if (s < 1)
850
{ s = 1; }
851
852
fprintf(fop, " coset |"); /* above coset number */
853
if (!galpha)
854
{
855
for (i = 1; i <= ncol; i++)
856
{ fprintf(fop, " %6d", colgen[i]); }
857
}
858
else
859
{
860
for (i = 1; i <= ncol; i++)
861
{ fprintf(fop, " %c", (colgen[i] > 0)
862
? algen[colgen[i]] : toupper(algen[-colgen[i]])); }
863
}
864
if (or)
865
{ fprintf(fop," order rep've"); }
866
fprintf(fop, "\n");
867
868
fprintf(fop, "-------+");
869
for (i = 1; i <= ncol; i++)
870
{ fprintf(fop, "-------"); }
871
if (or)
872
{ fprintf(fop,"-----------------"); }
873
fprintf(fop, "\n");
874
875
row = f;
876
if (!c)
877
{
878
while (row < nextdf && COL1(row) < 0)
879
{ row++; }
880
}
881
while (row <= l)
882
{
883
fprintf(fop, "%6d |", row);
884
for (i = 1; i <= ncol; i++)
885
{ fprintf(fop, " %6d", CT(row,i)); }
886
if (or && row != 1)
887
{
888
if (COL1(row) < 0)
889
{ fprintf(fop, " - -"); }
890
else
891
{
892
if (al1_bldrep(row))
893
{
894
fprintf(fop, " %7d ", al1_ordrep());
895
for (i = 0; i < repsiz; i++)
896
{
897
j = colgen[currrep[i]]; /* generator number */
898
if (!galpha)
899
{ fprintf(fop, "%d ", j); }
900
else
901
{ fprintf(fop, "%c",
902
(j > 0) ? algen[j] : toupper(algen[-j])); }
903
}
904
}
905
else
906
{ fprintf(fop, " ? ?"); }
907
}
908
}
909
fprintf(fop, "\n");
910
911
/* If we're printing *all* rows, we can just incr row by s. If not, we
912
have to jump over non-redundant rows. */
913
914
if (c)
915
{ row += s; }
916
else
917
{
918
for (i = 1; i <= s; i++)
919
{
920
row++;
921
while (row < nextdf && COL1(row) < 0)
922
{ row++; }
923
if (row == nextdf)
924
{ break; }
925
}
926
}
927
}
928
}
929
930
931