Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

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

563500 views
1
2
/**************************************************************************
3
4
util0.c
5
Colin Ramsay ([email protected])
6
20 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 some utilities for Level 0 of ACE.
18
19
**************************************************************************/
20
21
#include "al0.h"
22
23
/******************************************************************
24
We seem to need sys/types.h & time.h (for the system call time()).
25
On other flavours of Unix, we might need sys/time.h.
26
******************************************************************/
27
28
#include <sys/types.h>
29
#include <time.h>
30
31
/******************************************************************
32
char *al0_date(void)
33
34
Gets the system date/time, and converts it to ASCII string. Note
35
that this includes a trailing '\n'.
36
******************************************************************/
37
38
char *al0_date(void)
39
{
40
time_t t = time(NULL);
41
return ctime(&t);
42
}
43
44
/******************************************************************
45
double al0_clock(void)
46
47
clock() returns the actual cpu time used, in seconds, since this
48
process started. It's equivalent to the `user' time in the `time'
49
system command. Type clock_t is usually defined as a (signed)
50
long, but seems to actually be a 32-bit unsigned - we try our best
51
to preserve all information over a variety of machines! Note that
52
64-bit machines may sign extend, hence the truncation.
53
CLOCKS_PER_SEC (usually 1000000, but may be 100 on a PC) converts
54
clock() to seconds. Note that, even if CLOCKS_PER_SECOND > 100,
55
resolution may only be 10mS (i.e., 100Hz system clock).
56
******************************************************************/
57
58
double al0_clock(void)
59
{
60
unsigned long ulc = 0xffffffffUL & (unsigned long)clock();
61
62
return (double)ulc/(double)CLOCKS_PER_SEC;
63
}
64
65
/******************************************************************
66
double al0_diff(double c1, double c2)
67
68
We assume that c1/c2 are values from al0_clock(). This routine
69
finds the difference between two times, by assuming that either 0
70
or 1 `overflow' has taken place. double's are used for all timing
71
to allow (long) times to be properly processed. Provided that the
72
run is `short' (w.r.t. to the normal rollover interval of 71m35s)
73
or that progress messages are output `frequently', then the
74
difference will be correct. On long runs with few messages, then
75
the difference may be incorrect.
76
******************************************************************/
77
78
79
double al0_diff(double c1, double c2)
80
{
81
double clkroll = ((double)65536*(double)65536)/(double)CLOCKS_PER_SEC;
82
83
if (c2 >= c1)
84
{ return (c2-c1); }
85
else
86
{ return (clkroll - c1 + c2); }
87
}
88
89
/******************************************************************
90
void al0_init(void)
91
92
One-off initialisation of the Level 0 stuff. Ensures a valid
93
initial state, and sets defaults (default setting is roughly
94
equivalent to the "def" option of Level 2). Does _not_ allocate /
95
free memory, so it's up to the user (in practice, usually the Level
96
1 wrapper routines) to make sure memory's allocated and to properly
97
free it to prevent memory leakage. It's not really necessary to
98
set _everything_ here, but we do anyway, since we adhere to the
99
P^3 Principle (ie, paranoia prevents problems)!
100
******************************************************************/
101
102
void al0_init(void)
103
{
104
fop = stdout;
105
fip = stdin;
106
setvbuf(stdout, NULL, _IOLBF, 0); /* line buffer o/p */
107
108
begintime = endtime = deltatime = totaltime = 0.0;
109
msgctrl = msghol = FALSE;
110
msgincr = msgnext = -1;
111
112
mendel = FALSE;
113
rfill = TRUE;
114
pcomp = FALSE;
115
116
maxrow = 0;
117
rfactor = 200;
118
cfactor = 1000;
119
comppc = 10;
120
nrinsgp = 0;
121
lahead = 1;
122
123
tlimit = -1;
124
hlimit = -1;
125
llimit = lcount = 0;
126
127
nalive = maxcos = totcos = 1;
128
129
chead = ctail = 0;
130
131
pdefn = pdsiz = 0;
132
ffactor = 0.0;
133
pdqcol = pdqrow = NULL;
134
toppd = botpd = 0;
135
136
dedsiz = 0;
137
dedrow = dedcol = NULL;
138
topded = -1;
139
dedmode = 0;
140
disded = FALSE;
141
142
edp = edpbeg = edpend = NULL;
143
144
ncol = 0;
145
colptr = NULL;
146
col1ptr = col2ptr = NULL;
147
invcol = NULL;
148
149
ndrel = 0;
150
relind = relexp = rellen = relators = NULL;
151
152
nsgpg = 0;
153
subggen = subgindex = subglength = NULL;
154
sgdone = FALSE;
155
156
knr = knh = 1;
157
nextdf = 2;
158
}
159
160
/******************************************************************
161
Logic al0_compact(void)
162
163
Remove unused rows from the coset table, by closing up all used
164
rows to the front. (This is _not_ the same as putting the table
165
into its canonic form!) To maintain data-structure consistency,
166
the pdq is cleared & any stored deductions/coincidences should be
167
discarded. The pdq entries don't matter, but throwing away
168
unprocessed deductions or coincidences is _not_ a good thing. It
169
is the _caller's_ responsibility to ensure that this routine isn't
170
called when there are outstanding deductions/coincidences or, if
171
it is, that `appropriate' action is taken. We return TRUE if we
172
actually did any compaction, else FALSE.
173
174
In fact, we fully process all coincidences immediately. So,
175
outside of the coincidence processing routine, the coinc queue is
176
always empty. Since al0_compact isn't called during coincidence
177
handling, we're ok there. As for deductions, we _could_ work thro
178
the queue repeatedly as we compact, resetting the stored coset
179
numbers to their adjusted values, but we don't (v. expensive). We
180
just throw any outstanding deductions away, noting this in disded.
181
We worry later (if we get a finite result) about whether or not we
182
have to do any extra work to check whether this cavalier attitude
183
was `justified'.
184
185
Note that this routine is called `on-the-fly' by some of the Level
186
2 options. It can also be called directly by the rec[over] option.
187
******************************************************************/
188
189
Logic al0_compact(void)
190
{
191
int i, j, irow, col;
192
int knra, knha;
193
194
/* Table is already compact, do nothing. */
195
if (nalive == nextdf-1)
196
{ return(FALSE); }
197
198
/* Clear any preferred definitions on their queue. */
199
toppd = botpd = 0;
200
201
/* Throw away (after logging) any outstanding deductions. */
202
if (topded >= 0)
203
{
204
disded = TRUE;
205
topded = -1;
206
}
207
208
/* Zero the counters for knr/knh adjustment. Note that we can't adjust
209
these as we go, since it's their _original_ values which are relevant. */
210
211
knra = knha = 0;
212
213
/* Set irow to the lowest redundant coset (which is _never_ #1). */
214
215
for (irow = 2; irow < nextdf; irow++)
216
{
217
if (COL1(irow) < 0)
218
{ break; }
219
}
220
221
/* Compact the coset table. */
222
223
for (i = irow; i < nextdf; i++)
224
{
225
if (COL1(i) < 0)
226
{
227
if (i <= knr)
228
{ knra++; }
229
if (i <= knh)
230
{ knha++; }
231
}
232
else
233
{ /* Convert row i to row irow. */
234
for (col = 1; col <= ncol; col++)
235
{
236
if ((j = CT(i, col)) != 0)
237
{
238
if (j == i)
239
{ j = irow; }
240
else
241
{ CT(j, invcol[col]) = irow; }
242
}
243
CT(irow, col) = j;
244
}
245
irow++;
246
}
247
}
248
249
knr -= knra; /* Adjust counters */
250
knh -= knha;
251
252
nextdf = irow; /* 1st unused row */
253
254
return(TRUE);
255
}
256
257
/******************************************************************
258
Logic al0_stdct(void)
259
260
This companion programme to _compact() puts the table into standard
261
form. This form is based on the order of the generators in the
262
table, but is otherwise fixed for a given group/subgroup; it's
263
independant of the details of an enumeration. It allows canonic
264
rep'ves to be picked off by back-tracing (see al1_bldrep()). We
265
chose _not_ to combine _stdct() & _compact() into one routine,
266
since the core enumerator may compact (more than once) & we don't
267
want to impact it's speed with `unnecessary' work. After an
268
enumeration completes, a single call of _compact() & then of
269
_stdct() gives a hole-free, standardised table. We can standardise
270
holey-tables, but the result is only unique up to the set of coset
271
labels in use.
272
273
Similar remarks to those in _compact() regarding pdefns, dedns,
274
coincs, etc., etc. apply here. We return true if we actually
275
change anything, else false. We do the work in two stages, since
276
we want to avoid (possibly) throwing away dedns if we can avoid it.
277
Note that we have to do some work even if the table is already
278
standardised, since there is no quick way to check this. However,
279
the termination condition is next=nextdf, and this occurs generally
280
before we scan up to row=nextdf,
281
******************************************************************/
282
283
Logic al0_stdct(void)
284
{
285
int row, col, cos, next, icol, iicol, c1, c2, c3, c4;
286
287
/* Init next to 1st non-redundant coset > 1 */
288
289
next = 1;
290
do
291
{ next++; }
292
while (next < nextdf && COL1(next) < 0);
293
294
if (next == nextdf)
295
{ return(FALSE); } /* table is in standard form */
296
297
/* Find 1st non-std entry, if it exists */
298
299
for (row = 1; row < nextdf; row++)
300
{
301
if (COL1(row) >= 0)
302
{
303
for (col = 1; col <= ncol; col++)
304
{
305
if ((cos = CT(row,col)) > 0)
306
{
307
if (cos < next)
308
{ ; } /* ok */
309
else if (cos == next)
310
{ /* new next value; maybe finish */
311
do
312
{ next++; }
313
while (next < nextdf && COL1(next) < 0);
314
if (next == nextdf)
315
{ return(FALSE); }
316
}
317
else
318
{ goto non_std; } /* table is non-std */
319
}
320
}
321
}
322
}
323
324
return(FALSE); /* Table is standard. Never get here ?! */
325
326
non_std:
327
328
/* Table is non-std, so we'll be changing it. Clear the preferred
329
definition queue, and throw away (after logging) any outstanding
330
deductions. */
331
332
toppd = botpd = 0;
333
334
if (topded >= 0)
335
{
336
disded = TRUE;
337
topded = -1;
338
}
339
340
/* Now work through the table, standardising it. For simplicity, we
341
`continue' the loops used above, restarting the inner (column) loop. */
342
343
for ( ; row < nextdf; row++)
344
{
345
if (COL1(row) >= 0)
346
{
347
for (col = 1; col <= ncol; col++)
348
{
349
if ((cos = CT(row,col)) > 0)
350
{
351
if (cos < next)
352
{ ; }
353
else if (cos == next)
354
{
355
do
356
{ next++; }
357
while (next < nextdf && COL1(next) < 0);
358
if (next == nextdf)
359
{ return(TRUE); }
360
}
361
else
362
{
363
/* At this point, cos > next and we have to swap these rows.
364
Note that all entries in rows <row are <next, and will not be
365
effected. We process x/X pairs in one hit (to prevent any
366
nasties), so we skip over any 2nd (in order) occurrence of a
367
generator. Warning: trying to understand this code can cause
368
wetware malfunction! */
369
370
for (icol = 1; icol <= ncol; icol++)
371
{
372
iicol = invcol[icol];
373
374
if (icol < iicol)
375
{
376
c1 = CT(next,icol);
377
if (c1 == next)
378
{ c1 = cos; }
379
else if (c1 == cos)
380
{ c1 = next; }
381
382
c2 = CT(cos,icol);
383
if (c2 == next)
384
{ c2 = cos; }
385
else if (c2 == cos)
386
{ c2 = next; }
387
388
c3 = CT(next,iicol);
389
if (c3 == next)
390
{ c3 = cos; }
391
else if (c3 == cos)
392
{ c3 = next; }
393
394
c4 = CT(cos,iicol);
395
if (c4 == next)
396
{ c4 = cos; }
397
else if (c4 == cos)
398
{ c4 = next; }
399
400
CT(next,icol) = c2;
401
if (c2 != 0)
402
{ CT(c2,iicol) = next; }
403
404
CT(cos,icol) = c1;
405
if (c1 != 0)
406
{ CT(c1,iicol) = cos; }
407
408
CT(next,iicol) = c4;
409
if (c4 != 0)
410
{ CT(c4,icol) = next; }
411
412
CT(cos,iicol) = c3;
413
if (c3 != 0)
414
{ CT(c3,icol) = cos; }
415
}
416
else if (icol == iicol)
417
{
418
c1 = CT(next,icol);
419
if (c1 == next)
420
{ c1 = cos; }
421
else if (c1 == cos)
422
{ c1 = next; }
423
424
c2 = CT(cos,icol);
425
if (c2 == next)
426
{ c2 = cos; }
427
else if (c2 == cos)
428
{ c2 = next; }
429
430
CT(next,icol) = c2;
431
if (c2 != 0)
432
{ CT(c2,icol) = next; }
433
434
CT(cos,icol) = c1;
435
if (c1 != 0)
436
{ CT(c1,icol) = cos; }
437
}
438
}
439
440
do
441
{ next++; }
442
while (next < nextdf && COL1(next) < 0);
443
if (next == nextdf)
444
{ return(TRUE); }
445
}
446
}
447
}
448
}
449
}
450
451
return(TRUE);
452
}
453
454
/******************************************************************
455
double al0_nholes(void)
456
457
On flute, this processes `active' rows at ~ 5.10^6 entries/sec.
458
Note the use of knh to cut down the amount of work as much as
459
possible. Can be called by the TBA option of Level 2? Worst-case
460
complexity, in terms of the number of table accesses, is r(c+1);
461
where r/c are the number of rows/cols in the table.
462
463
Warning: possible int overflow of k for large tables.
464
******************************************************************/
465
466
double al0_nholes(void)
467
{
468
int i,j,k;
469
470
k = 0;
471
for (i = knh; i < nextdf; i++)
472
{
473
if (COL1(i) >= 0)
474
{
475
for (j = 1; j <= ncol; j++)
476
{
477
if (CT(i,j) == 0)
478
{ k++; }
479
}
480
}
481
}
482
483
return( (100.0*(double)k) / ((double)ncol*(double)nalive) );
484
}
485
486
/******************************************************************
487
void al0_upknh(void)
488
489
Counts knh up to the next incomplete row, skipping redundants. We
490
either bail out at an empty table slot, or reach nextdf. During an
491
enumeration knh is maintained by C-style, due to its overloaded
492
meaning (ie, knh & knc). If we can't guarantee that the table is
493
hole-free in an R-style finite result, we have to run this check to
494
make sure. Worst-case complexity is r(c+1).
495
496
Note: this should not be called carelessly during an enumeration,
497
since it is important that knh-based C-style hole filling &
498
deduction stacking / processing are done together, due to the
499
overloading of knh's meaning & the fact that it triggers a finite
500
result if it hits nextdf. This should really only be called when
501
we _know_ we have a finite result (to check whether the table is
502
hole-free), or when we _know_ that all definitions have been
503
applied (perhaps in a C-style lookahead).
504
******************************************************************/
505
506
void al0_upknh(void)
507
{
508
int col;
509
510
for ( ; knh < nextdf; knh++)
511
{
512
if (COL1(knh) >= 0)
513
{
514
for (col = 1; col <= ncol; col++)
515
{
516
if (CT(knh,col) == 0)
517
{ return; }
518
}
519
}
520
}
521
}
522
523
/******************************************************************
524
void al0_dedn(int cos, int gen)
525
526
Handling the deduction stack is a pain. The best option, in many
527
cases, seems to be to throw deductions away if we get too many at
528
any one time (where `too many' can be quite `small', eg, <1000),
529
and run an "RA:" or a "CL:" check. However, dedmode #4 (which is
530
the default) allows a special stack-handling function to be called
531
if we try to stack a deduction & can't.
532
533
Currently, in this mode our aim is _never_ to lose any deductions,
534
so we expand the stack space to accomodate the new element. We
535
take the opportunity to eliminate redundancies from the stack. The
536
code is essentially that used in dedmod #2 in _coinc() (which
537
emulates ACE2).
538
539
Note the messaging code, since we're interested in what the stack
540
actually `looks' like when it overflows! Some ad hoc tests show
541
that redundancies are common (in collapses). Duplicates (incl.
542
`inverted' duplicates) are not, and it's expensive to process
543
these, so we don't bother trying to track them.
544
545
Warning: this is the _only_ place in the core enumerator where we
546
make a system call (apart from o/p & date calls; if these fail
547
we've got real problems), and it's one which could fail. There is
548
_no_ mechanism in ACE Level 0 for handling these sorts of errors,
549
so we do the best we can to recover. Note also that there is no
550
cap on the amount of space which we'll (try to) allocate; so this
551
could all come crashing down in a heap!
552
******************************************************************/
553
554
void al0_dedn(int cos, int gen)
555
{
556
int i,j;
557
int dead = 0;
558
559
dedsiz *= 2; /* Best way to go? */
560
if ( (dedrow = (int *)realloc(dedrow, dedsiz*sizeof(int))) == NULL ||
561
(dedcol = (int *)realloc(dedcol, dedsiz*sizeof(int))) == NULL )
562
{
563
/* Our attempt to allocate more space failed, and we lost the existing
564
stack. Print out a nasty message (if messaging is on), and tidy up.
565
Note that the enumerator works correctly with dedsiz=0, but discards
566
_all_ deductions (& does so forever, since 2*0 = 0!). */
567
568
if (dedrow != NULL)
569
{ free(dedrow); }
570
if (dedcol != NULL)
571
{ free(dedcol); }
572
dedsiz = 0;
573
topded = -1;
574
disded = TRUE;
575
576
if (msgctrl)
577
{ fprintf(fop, "DS: Unable to grow, all deductions discarded\n"); }
578
579
return;
580
}
581
582
/* Is is actually _worth_ doing this? In a big collapse, the proportion
583
of coinc dedns can be high; but these are skipped over when encountered
584
in _cdefn(), so why go to the expense of a (linear) pass & data move. It
585
might keep the stack size down and prevent one doubling, so we have a
586
time vs mempry trade-off (maybe). We could also be cleverer, and move
587
non-redundants from the top to redundant slots at the bottom, cutting the
588
number of data moves. */
589
590
j = -1;
591
i = 0;
592
while (i <= topded && COL1(dedrow[i]) >= 0)
593
{ j++; i++; }
594
for ( ; i <= topded; i++)
595
{
596
if (COL1(dedrow[i]) >= 0)
597
{
598
dedrow[++j] = dedrow[i];
599
dedcol[j] = dedcol[i];
600
}
601
else
602
{ dead++; } /* Track no. redundancies discarded. */
603
}
604
topded = j;
605
606
/* Now add the original cause of the problem. There's no need to check
607
for an overflow, since we're guaranteed to have enough space at this
608
point. Note however that we do need to take care to update sdmax
609
correctly if the stats package is on. */
610
611
dedrow[++topded] = cos;
612
dedcol[topded] = gen;
613
#ifdef AL0_STAT
614
if (topded >= sdmax)
615
{ sdmax = topded+1; }
616
#endif
617
618
if (msgctrl)
619
{
620
msgnext = msgincr;
621
ETINT;
622
fprintf(fop, "DS: a=%d r=%d h=%d n=%d;", nalive, knr, knh, nextdf);
623
MSGMID;
624
fprintf(fop, " s=%d d=%d c=%d\n", dedsiz, topded+1, dead);
625
BTINT;
626
}
627
}
628
629
/******************************************************************
630
void al0_dump(Logic allofit)
631
632
Dump out the internals of Level 0 of ACE, working through al0.h
633
more or less in order. We could do more here in terms of pretty-
634
printing the data; or we could introduce further arguments
635
controlling the level of detail; or we could incorporate checks for
636
consistency; or ensure that this is only called when there's valid
637
data; or ... These are left as exercises for the reader; the
638
output is intended for debugging, and obscurity & information
639
overload are part of the game!
640
******************************************************************/
641
642
void al0_dump(Logic allofit)
643
{
644
int i,j;
645
646
fprintf(fop, " #---- %s: Level 0 Dump ----\n", ACE_VER);
647
648
/* FILE *fop, *fip; */
649
if (allofit)
650
{
651
if (fop == NULL)
652
{ fprintf(fop, "fop=NULL"); }
653
else if (fop == stdout)
654
{ fprintf(fop, "fop=stdout"); }
655
else if (fop == stderr)
656
{ fprintf(fop, "fop=stderr"); }
657
else
658
{ fprintf(fop, "fop=(something)"); }
659
if (fip == NULL)
660
{ fprintf(fop, " fip=NULL\n"); }
661
else if (fip == stdin)
662
{ fprintf(fop, " fip=stdin\n"); }
663
else
664
{ fprintf(fop, " fop=(something)\n"); }
665
}
666
667
/* double begintime, endtime, deltatime, totaltime; */
668
if (allofit)
669
{
670
fprintf(fop,
671
"begintime=%4.2f endtime=%4.2f deltatime=%4.2f totaltime=%4.2f\n",
672
begintime, endtime, deltatime, totaltime);
673
}
674
675
/* msgctrl, msghol, msgincr, msgnext; */
676
fprintf(fop, "msgctrl=%d msghol=%d msgincr=%d msgnext=%d\n",
677
msgctrl, msghol, msgincr, msgnext);
678
679
/* Logic mendel, rfill, pcomp; */
680
fprintf(fop, "mendel=%d rfill=%d pcomp=%d\n", mendel, rfill, pcomp);
681
682
/* int maxrow, rfactor, cfactor, comppc, nrinspg, lahead; */
683
fprintf(fop, "maxrow=%d rfactor=%d cfactor=%d\n",
684
maxrow, rfactor, cfactor);
685
fprintf(fop, "comppc=%d nrinsgp=%d lahead=%d\n",
686
comppc, nrinsgp, lahead);
687
688
/* int tlimit, hlimit, llimit, lcount */
689
fprintf(fop, "tlimit=%d hlimit=%d llimit=%d lcount=%d\n",
690
tlimit, hlimit, llimit, lcount);
691
692
/* int nalive, maxcos, totcos; */
693
fprintf(fop, "nalive=%d maxcos=%d totcos=%d\n", nalive, maxcos, totcos);
694
695
/* int chead, ctail; + coincidence queue */
696
fprintf(fop, "chead=%d ctail=%d", chead, ctail);
697
if (chead == 0)
698
{ fprintf(fop, " (empty)\n"); }
699
else if (chead == ctail)
700
{ fprintf(fop, " (%d->%d (+%d))\n",
701
chead, -COL1(chead), COL2(chead)); }
702
else
703
{ fprintf(fop, " (%d->%d (+%d) ... %d->%d (+%d))\n", chead,
704
-COL1(chead), COL2(chead), ctail, -COL1(ctail), COL2(ctail)); }
705
706
/* int pdefn, ffactor, pdsiz; */
707
fprintf(fop, "pdefn=%d ffactor=%3.1f pdsiz=%d\n", pdefn, ffactor, pdsiz);
708
709
/* int toppd, botpd; + int pdqcol[], pdqrow[]; */
710
fprintf(fop, "toppd=%d botpd=%d", toppd, botpd);
711
if (toppd == botpd)
712
{ fprintf(fop, " (empty)\n"); }
713
else
714
{ fprintf(fop, " (pdqrow/col=%d.%d ...)\n",
715
pdqrow[toppd], pdqcol[toppd]); }
716
717
/* int dedsiz, topded, disded, dedmode; + int *dedrow, *dedcol; */
718
fprintf(fop, "dedmode=%d dedsiz=%d disded=%d topded=%d",
719
dedmode, dedsiz, disded, topded);
720
if (topded < 0)
721
{ fprintf(fop, " (empty)\n"); }
722
else
723
{ fprintf(fop, " (... dedrow/col=%d.%d)\n",
724
dedrow[topded], dedcol[topded]); }
725
726
/* int *edp, *edpbeg, *edpend; */
727
if (allofit)
728
{
729
if (edp == NULL)
730
{ fprintf(fop, "edp=NULL\n"); }
731
else
732
{
733
fprintf(fop, "edpbeg edpend edp[]\n");
734
for (i = 1; i <= ncol; i++)
735
{
736
if (edpbeg[i] >= 0)
737
{
738
fprintf(fop, "%5d %5d ", edpbeg[i], edpend[i]);
739
for (j = edpbeg[i]; j <= edpend[i]; j++, j++)
740
{ fprintf(fop, " %d(%d)", edp[j], edp[j+1]); }
741
}
742
else
743
{ fprintf(fop, "%5d %5d -", edpbeg[i], edpend[i]);}
744
fprintf(fop, "\n");
745
}
746
}
747
}
748
749
/* int ncol, **colptr (+ col1ptr/col2ptr ?), *invcol; */
750
if (allofit)
751
{
752
fprintf(fop, "ncol=%d\n", ncol);
753
if (colptr == NULL)
754
{ fprintf(fop, "colptr=NULL\n"); }
755
else
756
{
757
fprintf(fop, " invcol[] ");
758
for (i = 1; i <= ncol; i++)
759
{ fprintf(fop, " %4d", invcol[i]); }
760
fprintf(fop, "\n");
761
762
fprintf(fop, " colptr[][1] ");
763
for (i = 1; i <= ncol; i++)
764
{ fprintf(fop, " %4d", colptr[i][1]); }
765
fprintf(fop, "\n");
766
767
fprintf(fop, " CT(2,) ");
768
for (i = 1; i <= ncol; i++)
769
{ fprintf(fop, " %4d", CT(2,i)); }
770
fprintf(fop, "\n");
771
}
772
}
773
else
774
{ fprintf(fop, "ncol=%d", ncol); }
775
776
/* int ndrel, *relind, *relexp, *rellen, *relators; */
777
if (allofit)
778
{
779
fprintf(fop, "ndrel=%d\n", ndrel);
780
if (relators == NULL)
781
{ fprintf(fop, "relators=NULL\n"); }
782
else
783
{
784
fprintf(fop, " rellen relexp relind relators[]\n");
785
for (i = 1; i <= ndrel; i++)
786
{
787
fprintf(fop, " %5d %5d %5d ", rellen[i], relexp[i], relind[i]);
788
for (j = relind[i]; j < relind[i]+rellen[i]; j++)
789
{ fprintf(fop, " %d", relators[j]); }
790
fprintf(fop, " ");
791
for ( ; j < relind[i]+2*rellen[i]; j++)
792
{ fprintf(fop, " %d", relators[j]); }
793
fprintf(fop, "\n");
794
}
795
}
796
}
797
else
798
{ fprintf(fop, " ndrel=%d", ndrel); }
799
800
/* int nsgpg, *subggen, *subgindex, *subglength, sgdone; */
801
if (allofit)
802
{
803
fprintf(fop, "nsgpg=%d sgdone=%d\n", nsgpg, sgdone);
804
if (subggen == NULL)
805
{ fprintf(fop, "subggen=NULL\n"); }
806
else
807
{
808
fprintf(fop, " subglength subgindex subggen[]\n");
809
for (i = 1; i <= nsgpg; i++)
810
{
811
fprintf(fop, " %8d %7d ", subglength[i], subgindex[i]);
812
for (j = subgindex[i]; j < subgindex[i]+subglength[i]; j++)
813
{ fprintf(fop, " %d", subggen[j]); }
814
fprintf(fop, "\n");
815
}
816
}
817
}
818
else
819
{ fprintf(fop, " nsgpg=%d sgdone=%d\n", nsgpg, sgdone); }
820
821
/* int knr, knh, nextdf; */
822
fprintf(fop, "knr=%d knh=%d nextdf=%d\n",
823
knr, knh, nextdf);
824
825
fprintf(fop, " #---------------------------------\n");
826
}
827
828
/******************************************************************
829
void al0_rslt(int rslt)
830
831
Pretty-print the result of a run, and some gross statistics.
832
******************************************************************/
833
834
void al0_rslt(int rslt)
835
{
836
if (rslt >= 1)
837
{
838
fprintf(fop, "INDEX = %d", rslt);
839
fprintf(fop, " (a=%d r=%d h=%d n=%d; l=%d c=%4.2f; m=%d t=%d)\n",
840
nalive, knr, knh, nextdf, lcount, totaltime, maxcos, totcos);
841
}
842
else
843
{
844
switch(rslt)
845
{
846
case -4097: fprintf(fop, "BAD FINITE RESULT"); break;
847
case -4096: fprintf(fop, "BAD MACHINE STATE"); break;
848
case -514: fprintf(fop, "INVALID MODE/STYLE"); break;
849
case -513: fprintf(fop, "INVALID STYLE"); break;
850
case -512: fprintf(fop, "INVALID MODE"); break;
851
case -260: fprintf(fop, "SG PHASE OVERFLOW"); break;
852
case -259: fprintf(fop, "ITERATION LIMIT"); break;
853
case -258: fprintf(fop, "TIME LIMT"); break;
854
case -257: fprintf(fop, "HOLE LIMIT"); break;
855
case -256: fprintf(fop, "INCOMPLETE TABLE"); break;
856
case 0: fprintf(fop, "OVERFLOW"); break;
857
default: fprintf(fop, "UNKNOWN ERROR (%d)", rslt); break;
858
}
859
860
if (rslt <= -512)
861
{ fprintf(fop, "\n"); }
862
else
863
{
864
fprintf(fop, " (a=%d r=%d h=%d n=%d;", nalive, knr, knh, nextdf);
865
if (msghol)
866
{ fprintf(fop, " h=%4.2f%%", al0_nholes()); }
867
fprintf(fop, " l=%d c=%4.2f;", lcount, totaltime);
868
fprintf(fop, " m=%d t=%d)\n", maxcos, totcos);
869
}
870
}
871
}
872
873
#ifdef AL0_STAT
874
875
/******************************************************************
876
void al0_statinit(void)
877
878
Initialise the stats package for this call to al0_enum().
879
******************************************************************/
880
881
void al0_statinit(void)
882
{
883
cdcoinc = rdcoinc = apcoinc = rlcoinc = clcoinc = 0;
884
xcols12 = xcoinc = qcoinc = 0;
885
xsave12 = s12dup = s12new = 0;
886
xcrep = crepred = crepwrk = 0;
887
xcomp = compwrk = 0;
888
xsaved = sdmax = sdoflow = 0;
889
xapply = apdedn = apdefn = 0;
890
rldedn = cldedn = 0;
891
xrdefn = rddedn = rddefn = rdfill = 0;
892
xcdefn = cddproc = cdddedn = cddedn = cdgap = cdidefn = 0;
893
cdidedn = cdpdl = cdpof = cdpdead = cdpdefn = cddefn = 0;
894
}
895
896
/******************************************************************
897
void al0_statdump(void)
898
899
Dump the stats for latest call to al0_enum().
900
******************************************************************/
901
902
void al0_statdump(void)
903
{
904
fprintf(fop, " #- %s: Level 0 Statistics -\n", ACE_VER);
905
906
fprintf(fop, "cdcoinc=%d rdcoinc=%d apcoinc=%d rlcoinc=%d clcoinc=%d\n",
907
cdcoinc, rdcoinc, apcoinc, rlcoinc, clcoinc);
908
fprintf(fop, " xcoinc=%d xcols12=%d qcoinc=%d\n",
909
xcoinc, xcols12, qcoinc);
910
fprintf(fop, " xsave12=%d s12dup=%d s12new=%d\n",
911
xsave12, s12dup, s12new);
912
fprintf(fop, " xcrep=%d crepred=%d crepwrk=%d xcomp=%d compwrk=%d\n",
913
xcrep, crepred, crepwrk, xcomp, compwrk);
914
fprintf(fop, "xsaved=%d sdmax=%d sdoflow=%d\n", xsaved, sdmax, sdoflow);
915
fprintf(fop, "xapply=%d apdedn=%d apdefn=%d\n", xapply, apdedn, apdefn);
916
fprintf(fop, "rldedn=%d cldedn=%d\n", rldedn, cldedn);
917
fprintf(fop, "xrdefn=%d rddedn=%d rddefn=%d rdfill=%d\n",
918
xrdefn, rddedn, rddefn, rdfill);
919
fprintf(fop, "xcdefn=%d cddproc=%d cdddedn=%d cddedn=%d\n",
920
xcdefn, cddproc, cdddedn, cddedn);
921
fprintf(fop, " cdgap=%d cdidefn=%d cdidedn=%d cdpdl=%d cdpof=%d\n",
922
cdgap, cdidefn, cdidedn, cdpdl, cdpof);
923
fprintf(fop, " cdpdead=%d cdpdefn=%d cddefn=%d\n",
924
cdpdead, cdpdefn, cddefn);
925
926
fprintf(fop, " #---------------------------------\n");
927
}
928
929
#endif
930
931
932