/****************************************************************************
**
*A setup.c ANUPQ source Eamonn O'Brien
**
*Y Copyright 1995-2001, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
*Y Copyright 1995-2001, School of Mathematical Sciences, ANU, Australia
**
*/
#include "pq_defs.h"
#include "pcp_vars.h"
#include "constants.h"
#include "pq_functions.h"
#include "setup.h"
void class_setup(int new_space, struct pcp_vars *pcp);
/* this routine moves existing structures in the array y to create
the space necessary to store the presentation to be computed for
the next class; for a description of the basic data structures,
read the header file setup.h */
void setup(struct pcp_vars *pcp)
{
register int *y = y_address;
register int e;
register int i;
register int j;
register int k;
register int s;
register int w;
register int x;
register int p1;
register int ee;
register int moccur;
register int new_space; /* new space required for next class */
register int max_gens; /* upper bound for total number of generators */
register int end_ccm2; /* last generator of class pcp->cc - 2 */
register int halfwt;
register int oldpc;
register int pcomm;
register int extra_ppower; /* extra pointers to powers */
register int extra_ppcomm; /* extra pointers to pointers to commutators */
register int extra_comm; /* extra pointers to commutators */
register int bound;
register int value;
register int ndgen = pcp->ndgen;
register int lastg = pcp->lastg;
register int class_end;
#include "access.h"
/* delete the pcp->words and subgroups entries if present */
if (pcp->subgrp != pcp->structure && pcp->cc != 0)
delete_tables(0, pcp);
if (pcp->complete != 0 && !pcp->multiplicator)
return;
++pcp->cc;
pcp->ccbeg = pcp->lastg + 1;
/* set up class 1 */
if (pcp->cc == 1) {
/* y[pcp->clend + i] is the number of the last pcp generator
in class i; set y[pcp->clend] = 0 for convenience */
pcp->clend = pcp->fronty;
for (i = 0; i <= MAXCLASS; ++i)
y[pcp->clend + i] = 0;
pcp->dgen = pcp->clend + MAXCLASS + ndgen + 1;
moccur = pcp->dgen + ndgen;
pcp->relp = moccur + ndgen;
pcp->first_pseudo = 0;
pcp->newgen = ndgen;
pcp->lastg = ndgen;
/* structure information is stored at the back of y */
pcp->structure = pcp->backy - ndgen;
pcp->words = pcp->structure;
pcp->subgrp = pcp->words;
pcp->submlg = pcp->subgrp - pcp->lastg;
pcp->nwords = 0;
pcp->nsubgp = 0;
/* pcp->lused is the last used location working from the front */
pcp->lused = pcp->relp + 2 * pcp->ndrel;
/* pcp->gspace is the index of the first garbage collectable
location in the array y */
pcp->gspace = pcp->lused + 1;
if (is_space_exhausted(0, pcp))
return;
/* mark all defining generators as irredundant */
for (i = 1; i <= ndgen; ++i) {
y[pcp->dgen + i] = i;
y[moccur + i] = 0;
}
/* read defining relations */
/*
read_relations (pcp);
pcp->gspace = pcp->lused + 1;
*/
/* set up inverse, j^(p - 1), for defining generator j;
not all inverses are required but we choose to compute these
as such information is useful for the Holt & Rees programs */
for (j = 1; j <= ndgen; ++j) {
if (is_space_exhausted(3, pcp))
return;
pcp->lused += 3;
y[pcp->dgen - j] = -(pcp->lused - 2);
y[pcp->lused - 1] = 1;
y[pcp->lused - 2] = pcp->dgen - j;
y[pcp->lused] = PACK2(pcp->pm1, j);
}
/* for generators of current class, generator eliminating
equations are pointed to by y[structure + i];
y[structure + i] is positive if generator i is not redundant;
y[structure + i] = 0 if generator i is trivial;
y[structure + i] = -ptr if generator i has value pointed to by ptr;
each positive word in y[structure + i] has 3 pieces of
information stored in it arranged as follows --
bits 25 to the (no of bits in a computer word - 1) contain
weight (class) information;
bits 0 to 24 contain the defining information for generator i;
the defining information is composed of 2 parts,
bits 0 to 8 containing a say, and bits 9 to 24 containing b say;
if b = 0 then generator i is on the image of defining generator a;
if a = 0 then generator i is on the power b^p;
if both a and b are non-zero then generator i is on the
commutator (b, a); it is possible that this version allows the
user to control the the precise breakdown of the word via
the run-time options -c and -d */
/* insert structure information to indicate that i is irredundant */
for (i = 1; i <= ndgen; ++i)
y[pcp->structure + i] = i;
return;
}
/* for class 2 we create space for --
the pointers to powers (base address pcp->ppower),
pointers to pointers to commutators (base address pcp->ppcomm),
pointers to commutators, and additional structure information;
this data is accommodated by moving the structure array forward */
if (pcp->cc == 2) {
pcp->ncomm = lastg * (lastg - 1) / 2;
/* is the next class already set up? */
if (pcp->ncset != 0) {
new_space = pcp->ncomm + ndgen;
class_setup(new_space, pcp);
return;
}
/* the following additional space is required --
for pcp->ppower = lastg; for pcp->ppower = lastg;
for pcp->ppcomm = lastg - 1; for pcomm = pcp->ncomm;
also required is pcp->ncomm + ndgen */
new_space = lastg + lastg - 1 + pcp->ncomm + pcp->ncomm + ndgen;
/* structure information is moved to accommodate the new data */
pcp->structure -= new_space;
pcp->words = pcp->structure;
pcp->subgrp = pcp->words;
pcp->submlg = pcp->subgrp - lastg;
if (is_space_exhausted(0, pcp))
return;
for (i = 1; i <= lastg; ++i)
y[pcp->structure + i] = y[pcp->structure + new_space + i];
/* pointers to powers follow structure plus any spare area */
pcp->ppower = pcp->structure + lastg + pcp->ncomm + ndgen;
for (i = 1; i <= lastg; ++i)
y[pcp->ppower + i] = 0;
/* initialise pcp->ppcomm so that y[pcp->ppcomm + 2] is the
first location after y[pcp->ppower + lastg] */
pcp->ppcomm = pcp->ppower + lastg - 1;
/* pointers to commutators follow in lexicographic order
after y[pcp->ppcomm + lastg] */
pcomm = pcp->ppcomm + lastg;
for (i = 2; i <= lastg; ++i) {
pcomm += i - 2;
y[pcp->ppcomm + i] = pcomm;
}
for (i = 1, bound = pcp->ncomm; i <= bound; ++i)
y[pcp->ppcomm + lastg + i] = 0;
return;
}
/* class 3 onwards --
check that occurrence conditions don't stop at this class */
if (pcp->nocset > 1 && pcp->cc > pcp->nocset) {
--pcp->cc;
pcp->complete = 1;
pcp->ccbeg = y[pcp->clend + pcp->cc - 1] + 1;
/*
text (5, pcp->cc, pcp->p, lastg, 0);
*/
return;
}
class_end = pcp->clend;
/* calculate an upper bound for the number of new generators */
value = y[class_end + 1];
max_gens = value * (value - 1) / 2 + (lastg - value) * value + ndgen;
/* is the next class already set up? */
if (pcp->ncset != 0) {
new_space = max_gens;
class_setup(new_space, pcp);
return;
}
/* compute the new space required */
end_ccm2 = y[class_end + pcp->cc - 2];
extra_ppower = lastg - end_ccm2;
extra_ppcomm = extra_ppower;
halfwt = (pcp->cc - 1) / 2;
/* compute the number of extra commutators to be stored */
for (i = 1, extra_comm = 0; i <= halfwt; ++i) {
extra_comm +=
(y[class_end + i] - y[class_end + i - 1]) *
(y[class_end + pcp->cc - i] - y[class_end + pcp->cc - i - 1]);
}
if (MOD(pcp->cc, 2) == 0) {
halfwt = pcp->cc / 2;
extra_comm += (y[class_end + halfwt] - y[class_end + halfwt - 1]) *
(y[class_end + halfwt] - y[class_end + halfwt - 1] - 1) / 2;
}
new_space = max_gens + extra_ppower + extra_ppcomm + extra_comm;
if (is_space_exhausted(new_space, pcp))
return;
/* move structure array forward */
pcp->structure -= new_space;
pcp->words = pcp->structure;
pcp->subgrp = pcp->words;
pcp->submlg = pcp->subgrp - lastg;
for (i = 1; i <= lastg; ++i)
y[pcp->structure + i] = y[pcp->structure + new_space + i];
/* move pointers to powers forward */
for (i = 1; i <= end_ccm2; ++i) {
y[pcp->structure + lastg + max_gens + i] = y[pcp->ppower + i];
if (y[pcp->ppower + i] < 0) {
p1 = -y[pcp->ppower + i];
y[p1] = pcp->structure + lastg + max_gens + i;
}
}
pcp->ppower = pcp->structure + lastg + max_gens;
for (i = end_ccm2 + 1; i <= lastg; ++i)
y[pcp->ppower + i] = 0;
oldpc = pcp->ppcomm + end_ccm2;
pcp->ppcomm = pcp->ppower + lastg - 1;
pcomm = pcp->ppcomm + lastg;
/* move pointers to commutators and compute pointers to these */
for (w = 3, bound = pcp->cc; w <= bound; w++) {
s = MAX(y[class_end + w - 3] + 1, 2);
e = y[class_end + w - 2];
for (i = s; i <= e; ++i) {
y[pcp->ppcomm + i] = pcomm;
value = y[class_end + pcp->cc - w + 1];
for (ee = MIN(i - 1, value); ee > 0; --ee) {
y[++pcomm] = y[++oldpc];
if (y[pcomm] < 0) {
p1 = -y[pcomm];
y[p1] = pcomm;
}
}
x = w - 2 - halfwt;
if (x > 0)
/* make room for (w - 2, pcp->cc - (w - 2)) commutators */
k = y[class_end + pcp->cc - w + 2] - value;
else {
if (x == 0 && MOD(pcp->cc, 2) == 0)
/* make room for (pcp->cc / 2, pcp->cc / 2) commutators */
k = MAX(0, i - y[class_end + halfwt - 1] - 1);
else
k = 0;
}
for (j = 1; j <= k; ++j)
y[pcomm + j] = 0;
pcomm += k;
}
}
/* append the left-normed commutators of class pcp->cc */
s = y[class_end + pcp->cc - 2] + 1;
k = y[class_end + 1];
for (i = s; i <= lastg; ++i) {
for (j = 1; j <= k; ++j)
y[pcomm + j] = 0;
y[pcp->ppcomm + i] = pcomm;
pcomm += k;
}
pcp->ncomm += extra_comm;
}
/* was the class already setup? */
void class_setup(int new_space, struct pcp_vars *pcp)
{
register int *y = y_address;
register int i;
register int bound = pcp->lastg;
new_space -= (pcp->ppower - (pcp->structure + pcp->lastg));
if (new_space > 0) {
if (is_space_exhausted(new_space, pcp))
return;
pcp->structure -= new_space;
pcp->words = pcp->structure;
pcp->subgrp = pcp->words;
pcp->submlg = pcp->subgrp - pcp->lastg;
for (i = 1; i <= bound; ++i)
y[pcp->structure + i] = y[pcp->structure + new_space + i];
}
pcp->ncset = 0;
}
¤ Dauer der Verarbeitung: 0.4 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland