1 /****************************************************************************
2 **
3 **    trmetab.c                       NQ                       Werner Nickel
4 **                                         nickel@mathematik.tu-darmstadt.de
5 */
6 
7 #include "nq.h"
8 #include "engel.h"
9 #include "glimt.h"
10 
11 static int NrWords = 0;
12 static int TrMetAb = 0;
13 
Error(word v,word w)14 static void Error(word v, word w) {
15 	printf("Overflow in collector computing [ ");
16 	printWord(v, 'a');
17 	printWord(w, 'a');
18 	printf(" ]\n");
19 }
20 
eval8Power(word u)21 static void eval8Power(word u) {
22 	word  uu;
23 	int   needed;
24 
25 	/*    printf( "eval8Power() called with : " );
26 	    printWord( u, 'A' );
27 	    putchar( '\n' );
28 	*/
29 	uu = Exponentiate(u, 8);
30 	needed = addRow(ExpVecWord(uu));
31 
32 	if (needed) {
33 		printf("#    (");
34 		printWord(u, 'A');
35 		printf(")^8\n");
36 	}
37 	free(uu);
38 }
39 
evalTrMetAbRel(word * ul)40 static void evalTrMetAbRel(word *ul) {
41 	word    u, uu, vv;
42 	long    i, needed;
43 
44 	/*      printf( "evalTrMetAbRel() called with : " );
45 	        for( i = 0; i < 6; i++ ) {
46 	            printWord( ul[i], 'A' ); printf( "    " );
47 	        }
48 	        putchar( '\n' );
49 	*/
50 	NrWords++;
51 	/* Calculate [ [ ul[0], ul[1] ], ul[2] ] */
52 	if ((u = Commutator(ul[0], ul[1])) == (word)0) {
53 		Error(ul[0], ul[1]);
54 		return;
55 	}
56 	if ((uu = Commutator(u, ul[2])) == (word)0) {
57 		Error(u, ul[2]);
58 		return;
59 	}
60 	free(u);
61 	/* Calculate [ [ ul[3], ul[4] ], ul[5] ] */
62 	if ((u = Commutator(ul[3], ul[4])) == (word)0) {
63 		Error(ul[3], ul[4]);
64 		return;
65 	}
66 	if ((vv = Commutator(u, ul[5])) == (word)0) {
67 		Error(u, ul[5]);
68 		return;
69 	}
70 	free(u);
71 
72 	u = Commutator(uu, vv);
73 	free(uu);
74 	free(vv);
75 
76 	needed = addRow(ExpVecWord(u));
77 	if (needed) {
78 		printf("#    [ [");
79 		for (i = 0; i < 3; i++) {
80 			printWord(ul[i], 'A');
81 			if (i != 2) printf(",");
82 		}
83 		printf("], [");
84 		for (i = 3; i < 6; i++) {
85 			printWord(ul[i], 'A');
86 			if (i != 5) printf(",");
87 		}
88 		printf("] ]\n");
89 	}
90 
91 	free(u);
92 }
93 
buildTuple(word * ul,long i,gen g,long wt,long which)94 static void buildTuple(word *ul, long i, gen g, long wt, long which) {
95 	long    save_wt;
96 	word    u;
97 
98 	if (wt == 0 && which == 5 && i > 0) {
99 		eval8Power(ul[5]);
100 	}
101 
102 	if (wt == 0 && which == 0 && i > 0) {
103 		evalTrMetAbRel(ul);
104 		return;
105 	}
106 
107 	if (i > 0 && which > 0) buildTuple(ul, 0, 1, wt, which - 1);
108 
109 	if (g > NrPcGens) return;
110 
111 	save_wt = wt;
112 	u = ul[ which ];
113 	while (!EarlyStop && g <= NrPcGens && Wt(g) <= wt) {
114 		u[i].g   = g;
115 		u[i].e   = (expo)0;
116 		u[i + 1].g = EOW;
117 		while (!EarlyStop && Wt(g) <= wt) {
118 			u[i].e++;
119 			if (Exponent[g] > (expo)0 && Exponent[g] == u[i].e) break;
120 			wt -= Wt(g);
121 			buildTuple(ul, i + 1, g + 1, wt, which);
122 			/* now build the same word with negative exponent */
123 			if (!EarlyStop && !SemigroupOnly && Exponent[g] == (expo)0) {
124 				u[i].g *= -1;
125 				buildTuple(ul, i + 1, g + 1, wt, which);
126 				u[i].g *= -1;
127 			}
128 		}
129 		wt = save_wt;
130 		g++;
131 	}
132 	u[i].g = EOW;
133 	u[i].e = (expo)0;
134 	if (EarlyStop || SemigroupOnly || !SemigroupFirst) return;
135 
136 	while (!EarlyStop && g <= NrPcGens && Wt(g) <= wt) {
137 		u[i].g   = -g;
138 		u[i].e   = (expo)0;
139 		u[i + 1].g = EOW;
140 		while (!EarlyStop && Wt(g) <= wt) {
141 			u[i].e++;
142 			if (Exponent[g] > (expo)0 && Exponent[g] == u[i].e) break;
143 			wt -= Wt(g);
144 			buildTuple(ul, i + 1, g + 1, wt, which);
145 			if (EarlyStop) return;
146 			/* now build the same word with negative exponent */
147 			if (!EarlyStop && !SemigroupOnly && Exponent[g] == (expo)0) {
148 				u[i].g *= -1;
149 				buildTuple(ul, i + 1, g + 1, wt, which);
150 				u[i].g *= -1;
151 			}
152 		}
153 		wt = save_wt;
154 		g++;
155 	}
156 	u[i].g = EOW;
157 	u[i].e = (expo)0;
158 }
159 
EvalTrMetAb(void)160 void EvalTrMetAb(void) {
161 
162 	word u, ul[6];
163 	int i, c;
164 
165 	if (!TrMetAb) return;
166 
167 	for (i = 0; i < 6; i++)
168 		ul[i] = (word)Allocate((NrPcGens + NrCenGens + 1) * sizeof(gpower));
169 
170 	u = ul[0];
171 	for (i = 1; i <= NrCenGens; i++) {
172 		u[0].g = i;
173 		u[0].e = (expo)1;
174 		u[1].g = EOW;
175 		u[1].e = (expo)0;
176 		eval8Power(u);
177 	}
178 
179 	for (c = 2; !EarlyStop && c <= Class + 1; c++) {
180 		for (i = 0; i < 6; i++) {
181 			ul[i][0].g = EOW;
182 			ul[i][0].e = (expo)0;
183 		}
184 		NrWords = 0;
185 		if (Verbose)
186 			printf("#    Checking tuples of words of weight %d\n", c);
187 		buildTuple(ul, 0, 1, c, 5);
188 		if (Verbose) printf("#    Checked %d words.\n", NrWords);
189 	}
190 
191 	for (i = 0; i < 6; i++)
192 		free(ul[i]);
193 }
194 
InitTrMetAb(int t)195 void InitTrMetAb(int t) {
196 	TrMetAb = t;
197 }
198