/* ** If the current class reaches the weight of the engel condition, ** then we want to speed up the evaluation of the engel relations by ** evaluating each commutator only with the required precision. The ** last commutator of an Engel-n commutator has to be evaluated in ** class (Class+1) quotient (i.e. the full group), the second last in ** the class Class quotient, etc. The first commutator has to be ** evaluated in the class (Class+1-(n-1)) quotient. See also the ** function SetupCommuteList() in addgen.c
*/
n = 1; Class = Class - (engel - 1);
if ((v = Commutator(v, w)) == (word)0) return (word)0;
n++; while (n <= engel) { Class++;
if ((v1 = Commutator(v, w)) == (word)0) return (word)0;
Free(v);
v = v1;
n++;
} return v;
}
static void evalEngelRel(word v, word w) {
word comm; long needed;
static void buildPairs(word u, long i, gen g, word v, long wt, long which) { long save_wt;
/* First we check if the Engel condition is trivially satisfied for weight reasons. The commutator
[u, n v] is 1 if w(u) + n*w(v) > Class+1. */ if (which == 1 && i == 1 &&
Wt(abs(u[0].g)) + Engel * Wt(abs(v[0].g)) > Class + 1) return;
if (wt == 0 && which == 1 && i > 0) {
evalEngelRel(u, v); return;
}
/* Keep u and start to build v. */ if (i > 0 && which == 2) buildPairs(v, 0, 1, u, wt, 1);
if (g > NrPcGens) return;
save_wt = wt; while (!EarlyStop &&
g <= NrPcGens && Wt(g) <= Class + 1 - Engel && Wt(g) <= wt) {
u[i].g = g;
u[i].e = (expo)0;
u[i + 1].g = EOW; while (!EarlyStop && Wt(g) <= wt) {
u[i].e++; if (Exponent[g] > (expo)0 && Exponent[g] == u[i].e) break;
wt -= Wt(g);
buildPairs(u, i + 1, g + 1, v, wt, which); /* now build the same word with negative exponent */ if (!EarlyStop && !SemigroupOnly && Exponent[g] == (expo)0) {
u[i].g *= -1;
buildPairs(u, i + 1, g + 1, v, wt, which);
u[i].g *= -1;
}
}
wt = save_wt;
g++;
}
u[i].g = EOW;
u[i].e = (expo)0; if (EarlyStop || SemigroupOnly || !SemigroupFirst) return;
while (!EarlyStop &&
g <= NrPcGens && Wt(g) <= Class + 1 - Engel && Wt(g) <= wt) {
u[i].g = -g;
u[i].e = (expo)0;
u[i + 1].g = EOW; while (!EarlyStop && Wt(g) <= wt) {
u[i].e++; if (Exponent[g] > (expo)0 && Exponent[g] == u[i].e) break;
wt -= Wt(g);
buildPairs(u, i + 1, g + 1, v, wt, which); if (EarlyStop) return; /* now build the same word with negative exponent */ if (!EarlyStop && !SemigroupOnly && Exponent[g] == (expo)0) {
u[i].g *= -1;
buildPairs(u, i + 1, g + 1, v, wt, which);
u[i].g *= -1;
}
}
wt = save_wt;
g++;
}
u[i].g = EOW;
u[i].e = (expo)0;
}
static void evalEngel(void) {
word u, v; long c;
u = (word)Allocate((NrPcGens + NrCenGens + 1) * sizeof(gpower));
v = (word)Allocate((NrPcGens + NrCenGens + 1) * sizeof(gpower));
/* For `production purposes' I don't want to run through */ /* those classes that don't yield non-trivial instances of the */ /* Engel law. Therefore, we stop as soon as we ran through a */ /* class that didn't yield any non-trivial instances. This is */ /* done through the static variable Needed which is set by */ /* evalEngelRel() as soon as a non-trivial instance has been */ /* found if the flag CheckFewInstances (option -c) is set. */ if (ReverseOrder) for (c = Class + 1; !EarlyStop && c >= 2; c--) {
u[0].g = EOW;
u[0].e = (expo)0;
v[0].g = EOW;
v[0].e = (expo)0;
NrWords = 0; if (Verbose)
printf("# Checking pairs of words of weight %ld\n", c);
buildPairs(u, 0, 1, v, c, 2); if (Verbose) printf("# Checked %d words.\n", NrWords);
} else {
Needed = 1; for (c = 2; !EarlyStop && Needed && c <= Class + 1; c++) {
Needed = 0;
u[0].g = EOW;
u[0].e = (expo)0;
v[0].g = EOW;
v[0].e = (expo)0;
NrWords = 0; if (Verbose)
printf("# Checking pairs of words of weight %ld\n", c);
buildPairs(u, 0, 1, v, c, 2); if (Verbose) printf("# Checked %d words.\n", NrWords);
} for (; !EarlyStop && c <= Class + 1; c++)
printf("# NOT checking pairs of words of weight %ld\n", c);
}
free(u);
free(v);
}
static void evalRightEngelRel(word w) {
word comm; long n, needed;
/* printf( "evalRightEngelRel() called with : " );*/ /* printWord( w, 'A' );*/ /* putchar( '\n' );*/
NrWords++; /* Calculate [ a, w, .., w ] */ if ((comm = EngelCommutator(A, w, RightEngel)) == (word)0) {
Error(A, w, 'r'); return;
}
needed = addRow(ExpVecWord(comm)); if (needed) {
printf("# [ ");
printWord(A, 'a'); for (n = RightEngel - 1; n >= 0; n--) {
printf(", ");
printWord(w, 'a');
}
printf(" ]\n");
} if (CheckFewInstances) Needed |= needed; else Needed = 1;
Free(comm);
}
static void evalLeftEngelRel(word w) {
word comm; long n, needed;
/* printf( "evalLeftEngelRel() called with : " );*/ /* printWord( w, 'A' );*/ /* putchar( '\n' );*/
NrWords++; /* Calculate [ w, a, .., a ] */
if ((comm = EngelCommutator(w, A, LeftEngel)) == (word)0) {
Error(w, A, 'l'); return;
}
needed = addRow(ExpVecWord(comm)); if (needed) {
printf("# [ ");
printWord(w, 'a'); for (n = LeftEngel - 1; n >= 0; n--) {
printf(", ");
printWord(A, 'a');
}
printf(" ]\n");
} if (CheckFewInstances) Needed |= needed; else Needed = 1;
Free(comm);
}
static void buildWord(word u, long i, gen g, long wt) { long save_wt;
if (wt == 0 && i > 0) { if (RightEngel) evalRightEngelRel(u); if (LeftEngel) evalLeftEngelRel(u); return;
}
if (g > NrPcGens) return;
save_wt = wt; while (!EarlyStop && g <= NrPcGens && Wt(g) <= wt) {
u[i].g = g;
u[i].e = (expo)0;
u[i + 1].g = EOW; while (!EarlyStop && Wt(g) <= wt) {
u[i].e++; if (Exponent[g] > (expo)0 && Exponent[g] == u[i].e) break;
wt -= Wt(g);
buildWord(u, i + 1, g + 1, wt); /* now build the same word with negative exponent */ if (!EarlyStop && !SemigroupOnly &&
!SemigroupFirst && Exponent[g] == (expo)0) {
u[i].g *= -1;
buildWord(u, i + 1, g + 1, wt);
u[i].g *= -1;
}
}
wt = save_wt;
g++;
}
u[i].g = EOW;
u[i].e = (expo)0; if (EarlyStop || SemigroupOnly || !SemigroupFirst) return; while (!EarlyStop && g <= NrPcGens && Wt(g) <= wt) {
u[i].g = -g;
u[i].e = (expo)0;
u[i + 1].g = EOW; while (!EarlyStop && Wt(g) <= wt) {
u[i].e++; if (Exponent[g] > (expo)0 && Exponent[g] == u[i].e) break;
wt -= Wt(g);
buildWord(u, i + 1, g + 1, wt);
}
wt = save_wt;
g++;
}
u[i].g = EOW;
u[i].e = (expo)0;
}
static void evalLREngel(void) {
word u; int n; long cl;
A = (word)Allocate(2 * sizeof(gpower));
u = (word)Allocate((NrPcGens + NrCenGens + 1) * sizeof(gpower));
for (n = 1; !EarlyStop && n <= NrEngelGens; n++) {
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.