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 / enum01.c
Views: 418346
1
2
/**************************************************************************
3
4
enum01.c
5
Colin Ramsay ([email protected])
6
18 Oct 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
This is the code for the al0_rpefn() routine; i.e., R*-style. In concept,
18
it's closest to C-style; except that the defns are done using relator
19
application, instead of via fill-factor/next hole. It could also be viewed
20
as R-style with all dedns stacked & processed. We `borrow' heavily from
21
the _cdefn()/_rdefn() routines; see the comments therein for a less terse
22
code run-through. Note that we use the _cdefn()/_rdefn() stats package
23
variables; since statistics are accumulated on a `per call to _enum()'
24
basis, there's no possibility of confusion.
25
26
Originally, termination was judged only on knr. However, for a (big)
27
collapse this required what was effectively an RA phase to count knr up
28
from the collapse point to nextdf. This is expensive if mendel is on (it's
29
switched off in a genuine RA phase). Since there is no way in advance of
30
detecting this state, we elect to keep track of knh (ie, holes) also. We
31
can terminate on either; the final check phase may invoke either an RA or
32
an UH phase (or neither), depending on circumstances. Since we have to do
33
some work anyway to terminate/check the result, this seems to be the
34
fastest way; the only `unnecessary' work is counting up knh.
35
36
The orignial version of this routine processed deductions on a row by row
37
basis. The current version processes deductions on a scan by scan basis;
38
ie, much more frequently. It is closer in spirit to Felsch mode, and tends
39
to have smaller max/tot statistics (esp. if there are any very long
40
relators).
41
42
**************************************************************************/
43
44
static int al0_rpefn(int cnt, Logic fill)
45
{
46
int icol, rcol, irow, ires, col;
47
int first, last, i, ii, j, ifront, iback, k, l, m, mi, n;
48
int *beg, *end, *fwd, *bwd;
49
50
INCR(xrdefn);
51
52
#include "enum02.c" /* `empty' deduction stack */
53
54
/* Count up knh to its `correct' value; its current value may be
55
redundant and/or we may already have a complete (hole-free) table. Ditto
56
knr; its current value may be redundant and/or we may already have
57
scanned all non-redundant cosets. */
58
59
for ( ; knh < nextdf; knh++)
60
{
61
if (COL1(knh) >= 0)
62
{
63
for (icol = 1; icol <= ncol; icol++)
64
{
65
if (CT(knh, icol) == 0)
66
{ goto hfill1; }
67
}
68
}
69
}
70
return(nalive);
71
72
hfill1:
73
74
while (knr < nextdf && COL1(knr) < 0)
75
{ knr++; }
76
if (knr == nextdf)
77
{ return(nalive); }
78
79
/* The main loop. Provided cnt is non-zero, each pass through this scans
80
and closes one row. */
81
82
while (cnt != 0)
83
{
84
/* Scan through all relators for this coset. The code here is
85
essentially the same as that in al0_apply. We inline for speed (and
86
flexibility; the code's not _exactly_ the same). */
87
88
for (ii = 1; ii <= ndrel; ii++)
89
{
90
j = (mendel ? rellen[ii]/relexp[ii] : 1);
91
for (k = 0; k < j; k++)
92
{
93
94
/* <-- cancel indent */
95
96
/* Setup start & stop positions for scan, and the coset at the current
97
scan positions. */
98
99
beg = &(relators[relind[ii]+k]);
100
end = beg-1 + rellen[ii];
101
ifront = iback = knr;
102
103
/* Forward scan, leaving ifront set to coset at left of leftmost hole in
104
relator or to the last coset in the relator if no hole. */
105
106
for (fwd = beg; fwd <= end; fwd++)
107
{
108
if ((l = CT(ifront, *fwd)) > 0)
109
{ ifront = l; }
110
else
111
{ break; }
112
}
113
114
/* If the scan completed, then l = ifront & iback = cos, and we'll fall
115
right through and check for a coincidence (i.e., has ifront cycled back
116
to cos or not?). Else, there's a hole & a backward scan is required. */
117
118
if (l == 0)
119
{
120
for (bwd = end; bwd >= fwd; bwd--)
121
{
122
m = *bwd;
123
mi = invcol[m];
124
125
if ((l = CT(iback, mi)) > 0)
126
{ iback = l; }
127
else /* Scan stalled */
128
{
129
if (bwd == fwd)
130
{
131
/* The backward scan has only one gap, so note the deduction to
132
complete the cycle & prime for coincidence check. */
133
134
CT(iback, mi) = ifront;
135
SAVED(iback, mi);
136
137
if (CT(ifront, m) > 0)
138
{ ifront = CT(ifront, m); }
139
else
140
{
141
CT(ifront, m) = iback;
142
ifront = iback;
143
}
144
145
INCR(rddedn);
146
}
147
else /* Need to define a new coset */
148
{
149
/* Note that, if m is an involution, and occurs next to itself,
150
then after the first defn, the remainder of the string of m's
151
will close. Note that if m^2 = 1 & m is _not_ being treated as
152
an involution, then `removing' it is a Tietze transformation, not
153
a free reduction! */
154
155
if (nextdf > maxrow) /* Overflow */
156
{ return(0); }
157
158
NEXTC(n); /* Making a definition ... */
159
160
CT(iback,mi) = n;
161
CT(n,m) = iback;
162
SAVED(iback,mi);
163
164
iback = n; /* Advance to next spot */
165
166
INCR(rddefn);
167
168
if (msgctrl && --msgnext == 0)
169
{
170
msgnext = msgincr;
171
ETINT;
172
fprintf(fop, "RD: a=%d r=%d h=%d n=%d;",
173
nalive, knr, knh, nextdf);
174
MSGMID;
175
fprintf(fop, " m=%d t=%d\n", maxcos, totcos);
176
BTINT;
177
}
178
}
179
}
180
}
181
}
182
183
/* If we get here, the scan has been completed. Check to see if we've
184
found a pair of coincident cosets. Recall that _coinc (if it does not
185
return >0) is guaranteed _not_ to change knc/knh, although it may render
186
them redundant. */
187
188
if (ifront != iback)
189
{
190
INCR(rdcoinc);
191
if ((l = al0_coinc(ifront,iback,TRUE)) > 0)
192
{ return(l); }
193
if (COL1(knr) < 0)
194
{ goto do_next; } /* knr now redundant */
195
}
196
197
/* --> restore indent */
198
199
#include "enum02.c" /* `empty' deduction stack */
200
201
if (COL1(knr) < 0)
202
{ goto do_next; } /* knr now redundant */
203
}
204
}
205
206
/* All relators close at this coset, any row-filling to do? Only
207
(formally) necessary if some g/G does _not_ appear in any relator,
208
but it's usually a good thing to do. Also, don't bother if the row
209
is guaranteed hole-free. */
210
211
if (fill && knr >= knh)
212
{
213
for (i = 1; i <= ncol; i++)
214
{
215
if (CT(knr,i) == 0)
216
{
217
if (nextdf > maxrow) /* Overflow */
218
{ return(0); }
219
220
NEXTC(k); /* Make definition */
221
CT(knr,i) = k;
222
CT(k,invcol[i]) = knr;
223
SAVED(knr,i);
224
225
INCR(rdfill);
226
227
if (msgctrl && --msgnext == 0)
228
{
229
msgnext = msgincr;
230
ETINT;
231
fprintf(fop, "RF: a=%d r=%d h=%d n=%d;",
232
nalive, knr, knh, nextdf);
233
MSGMID;
234
fprintf(fop, " m=%d t=%d\n", maxcos, totcos);
235
BTINT;
236
}
237
}
238
}
239
#include "enum02.c" /* `empty' deduction stack */
240
}
241
242
/* Row knr is fully scanned (or redundant), so we adjust knr up,
243
jumping over any redundancies & checking to see if we've finished. We
244
have also used up one of our allowed rows, if there's a limit. We also
245
check to see if the table if complete. */
246
247
do_next: /* from al0_coinc() or dedn processing: knr redundant */
248
249
do
250
{ knr++; }
251
while (knr < nextdf && COL1(knr) < 0);
252
253
if (knr == nextdf)
254
{ return(nalive); }
255
256
if (cnt > 0)
257
{ cnt--; }
258
259
for ( ; knh < nextdf; knh++)
260
{
261
if (COL1(knh) >= 0)
262
{
263
for (icol = 1; icol <= ncol; icol++)
264
{
265
if (CT(knh, icol) == 0)
266
{ goto hfill2; }
267
}
268
}
269
}
270
return(nalive);
271
272
hfill2:
273
;
274
} /* end of "while(cnt!=0)" */
275
276
return(-1); /* `normal' return */
277
}
278
279
280