58int EpfFind(PHEAD WORD *term, WORD *params)
61 WORD *t, *m, *r, n1 = 0, n2, min = -1, count, fac;
62 WORD *c1 = 0, *c2 = 0, sgn = 1;
64 UWORD *facto = (UWORD *)AT.WorkPointer;
67 if ( ( AT.WorkPointer = (WORD *)(facto + AM.MaxTal) ) > AT.WorkTop ) {
68 MLOCK(ErrorMessageLock);
70 MUNLOCK(ErrorMessageLock);
79 while ( *t != LEVICIVITA && t < tstop ) t += t[1];
80 if ( t >= tstop )
return(0);
82 while ( *m == LEVICIVITA && m < tstop ) { n1++; m += m[1]; }
84 if ( n1 <= (number+1) || n1 <= 1 )
return(0);
88 while ( m[1] == t[1] ) {
91 count = fac = n1 = n2 = t[1] - FUNHEAD;
100 if ( *m >= AM.OffsetIndex &&
101 ( ( *m >= AM.IndDum && AC.lDefDim == fac ) ||
103 indices[*m-AM.OffsetIndex].dimension == fac ) ) ) {
106 r++; m++; n1--; n2--;
110 if ( min < 0 || count < min ) {
112 c2 = m - fac - FUNHEAD;
115 if ( m >= mstop )
break;
118 }
while ( ( m = t + t[1] ) < mstop );
121 fac = type + FUNHEAD;
122 while ( *t != LEVICIVITA && t < tstop ) t += t[1];
123 while ( *t == LEVICIVITA && t < tstop && t[1] != fac ) t += t[1];
124 if ( t >= tstop )
return(0);
126 while ( *m == LEVICIVITA && m < tstop && m[1] == fac ) { n1++; m += m[1]; }
134 if ( min < 0 )
return(0);
137 fac = t[1] - FUNHEAD;
141 if ( number < 0 ) *m++ = 1;
143 n1 = n2 = t[1] - FUNHEAD;
149 if ( *m > *r ) { *c1++ = *r++; n2--; }
150 else if ( *m < *r ) { *c2++ = *m++; n1--; }
152 if ( *m < AM.OffsetIndex || ( *m < AM.IndDum &&
153 ( indices[*m-AM.OffsetIndex].dimension != fac ) ) ||
154 ( *m >= AM.IndDum && AC.lDefDim != fac ) ) {
155 *c1++ = *r++; *c2++ = *m++;
157 else {
if ( ( n1 ^ n2 ) & 1 ) sgn = -sgn; r++; m++; }
161 if ( n1 ) { NCOPY(c2,m,n1); }
162 else if ( n2 ) { NCOPY(c1,r,n2); }
165 while ( m < mstop ) *t++ = *m++;
167 while ( m < tstop ) *t++ = *m++;
168 *t++ = SUBEXPRESSION;
179 while ( m < mstop ) *t++ = *m++;
180 if ( Factorial(BHEAD fac,facto,&nfac) || Mully(BHEAD (UWORD *)tstop,&ncoef,facto,nfac) ) {
181 MLOCK(ErrorMessageLock);
183 MUNLOCK(ErrorMessageLock);
186 tstop += (ABS(ncoef))*2;
187 if ( sgn < 0 ) ncoef = -ncoef;
189 *tstop++ = (ncoef<0)?(ncoef-1):(ncoef+1);
190 *term = WORDDIF(tstop,term);
212int EpfCon(PHEAD WORD *term, WORD *params, WORD num, WORD level)
215 WORD *kron, *perm, *termout, *tstop, size2;
216 WORD *m, *t, sizes, sgn = 0, i;
218 kron = AT.WorkPointer;
219 perm = (AT.WorkPointer += sizes);
220 termout = (AT.WorkPointer += sizes);
221 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
222 if ( AT.WorkPointer > AT.WorkTop ) {
223 MLOCK(ErrorMessageLock);
225 MUNLOCK(ErrorMessageLock);
229 if ( !(*params++) ) level--;
231 if ( !size2 )
goto DoOnce;
232 while ( ( sgn = EpfGen(size2,params,kron,perm,sgn) ) != 0 ) {
238 while ( t < tstop ) *m++ = *t++;
239 if ( t[2] != num || *t != SUBEXPRESSION ) {
240 MLOCK(ErrorMessageLock);
241 MesPrint(
"Serious error in EpfCon");
242 MUNLOCK(ErrorMessageLock);
251 if ( i ) { NCOPY(m,t,i); }
254 tstop = term + *term;
255 while ( t < tstop ) *m++ = *t++;
256 *termout = WORDDIF(m,termout);
258 if ( sgn < 0 ) *m = - *m;
262 AT.WorkPointer = termout + *termout;
263 if (
Generator(BHEAD termout,level) < 0 )
goto EpfCall;
266 AT.WorkPointer = kron;
269 if ( AM.tracebackflag ) {
270 MLOCK(ErrorMessageLock);
272 MUNLOCK(ErrorMessageLock);
282WORD EpfGen(WORD number, WORD *inlist, WORD *kron, WORD *perm, WORD sgn)
286 in2 = inlist + number;
288 for ( i = 1; i < number; i += 2 ) {
294 if ( number <= 0 )
return(0);
299 while ( ( i -= 2 ) >= 0 ) {
300 if ( ( k = perm[i] ) != i ) {
306 if ( ( k = ( perm[i] += 2 ) ) < number ) {
311 for ( k = i + 2; k < number; k += 2 ) perm[k] = k;
331WORD Trick(WORD *in,
TRACES *t)
336 switch ( t->eers[n] ) {
339 p = t->pepf + t->mepf[n];
352 p = t->pdel + t->mdel[n];
357 *in = *(t->pepf + t->mepf[n] + 2);
363 t->sign1 = - t->sign1;
364 *(t->pdel + t->mdel[n] + 1) = in[2];
369 t->sign1 = - t->sign1;
371 *(t->pdel + t->mdel[n]) = in[1];
375 in[2] = *(t->pdel + t->mdel[n] + 1);
383 return(--(t->eers[n]));
418int Trace4no(WORD number, WORD *kron,
TRACES *t)
425 if ( ( number < 0 ) || ( number & 1 ) )
return(0);
427 if ( t->gamma5 == GAMMA5 )
return(0);
429 *kron++ = *t->inlist;
430 *kron++ = t->inlist[1];
436 WORD nhalf = number >> 1;
437 WORD ndouble = number * 2;
439 t->eers = p; p += nhalf;
440 t->mepf = p; p += nhalf;
441 t->mdel = p; p += nhalf;
442 t->pdel = p; p += number + nhalf;
443 t->pepf = p; p += ndouble;
444 t->e4 = p; p += number;
445 t->e3 = p; p += ndouble;
446 t->nt3 = p; p += nhalf;
447 t->nt4 = p; p += nhalf;
448 t->j3 = p; p += ndouble;
453 t->mdum = AM.mTraceDum;
462 t->stap = (t->step1)++;
464 t->eers[t->stap] = 0;
465 t->mepf[t->step1] = t->mepf[t->stap];
466 t->mdel[t->step1] = t->mdel[t->stap];
467CallTrick:
while ( !Trick(t->inlist+t->kstep,t) ) {
469 t->step1 = (t->stap)--;
474 }
while ( t->kstep < (number-4) );
481 if ( ( t->gamma5 == GAMMA7 ) && ( t->gamm == -1 ) ) {
482 t->sign2 = - t->sign2;
484 else if ( ( t->gamma5 == GAMMA5 ) && ( t->gamm == 1 ) ) {
487 else if ( ( t->gamma5 == GAMMA1 ) && ( t->gamm == -1 ) ) {
490 p = t->pdel + t->mdel[t->step1];
491 *p++ = t->inlist[t->kstep+2];
492 *p++ = t->inlist[t->kstep+3];
506 ae = t->mepf[t->step1];
507 t->ad = t->mdel[t->step1]+2;
510 while ( ( ae -= 4 ) >= 0 ) {
511 if ( t->pepf[ae] > AM.mTraceDum && t->pepf[ae] <= t->mdum ) {
514 for ( i = 0; i < 3; i++ ) {
524 for ( i = 0; i < 4; i++ ) *p++ = *m++;
538 while ( t->a3 > 0 ) {
539 t->nt3[++(t->lc3)] = 0;
540 while ( ( t->nt3[t->lc3] = EpfGen(3,t->e3+t->a3-6,
541 t->pdel+t->ad,t->j3+6*t->lc3,oldsign = t->nt3[t->lc3]) ) == 0 ) {
542 if ( oldsign < 0 ) t->sign2 = - t->sign2;
544NextE3:
if ( t->lc3 < 0 )
goto CallTrick;
549 if ( oldsign != t->nt3[t->lc3] ) t->sign2 = - t->sign2;
551 else if ( t->nt3[t->lc3] < 0 ) t->sign2 = - t->sign2;
558 while ( t->a4 > 4 ) {
559 t->nt4[++(t->lc4)] = 0;
560 while ( ( t->nt4[t->lc4] = EpfGen(4,t->e4+t->a4-8,
561 t->pdel+t->ad,t->j4+8*t->lc4,oldsign = t->nt4[t->lc4]) ) == 0 ) {
562 if ( oldsign < 0 ) t->sign2 = - t->sign2;
564NextE4:
if ( t->lc4 < 0 )
goto NextE3;
569 if ( oldsign != t->nt4[t->lc4] ) t->sign2 = - t->sign2;
571 else if ( t->nt4[t->lc4] < 0 ) t->sign2 = - t->sign2;
585 *m++ = *p++; *m++ = *p++; *m++ = *p++; *m++ = *p++;
589 if ( t->sign2 < 0 ) retval = - retval;
591 for ( i = 0; i < t->ad; i++ ) *m++ = *p++;
597 stop = p + t->ad + 4;
599 while ( *p >= AM.mTraceDum && *p <= t->mdum ) {
608 else if ( m[1] == *p ) {
615 }
while ( m < stop );
619 else stop = p + t->ad;
620 while ( p < (stop-2) ) {
621 while ( *p >= AM.mTraceDum && *p <= t->mdum ) {
630 else if ( m[1] == *p ) {
637 }
while ( m < stop );
640 while ( *p >= AM.mTraceDum && *p <= t->mdum ) {
649 else if ( m[1] == *p ) {
656 }
while ( m < stop );
662 if ( number <= 2 )
return(0);
663 else {
goto NextE4; }
695int Trace4(PHEAD WORD *term, WORD *params, WORD num, WORD level)
699 WORD *p, *m, number, i;
701 WORD j, minimum, minimum2, *min, *stopper;
703 OldW = AT.WorkPointer;
704 if ( AN.numtracesctack >= AN.intracestack ) {
705 number = AN.intracestack + 2;
706 t = (
TRACES *)Malloc1(number*
sizeof(
TRACES),
"TRACES-struct");
707 if ( AN.tracestack ) {
708 for ( i = 0; i < AN.intracestack; i++ ) { t[i] = AN.tracestack[i]; }
709 M_free(AN.tracestack,
"TRACES-struct");
712 AN.intracestack = number;
715 number = *params - 6;
716 if ( number < 0 || ( number & 1 ) || !params[5] )
return(0);
718 t = AN.tracestack + AN.numtracesctack;
721 t->finalstep = ( params[2] & 16 ) ? 1 : 0;
722 t->gamma5 = params[3];
723 if ( t->finalstep && t->gamma5 != GAMMA1 ) {
724 MLOCK(ErrorMessageLock);
725 MesPrint(
"Gamma5 not allowed in this option of the trace command");
726 MUNLOCK(ErrorMessageLock);
730 t->inlist = AT.WorkPointer;
731 t->accup = t->accu = t->inlist + number;
732 t->perm = t->accu + (number*2);
733 t->eers = t->perm + number;
734 if ( ( AT.WorkPointer += 19 * number ) >= AT.WorkTop ) {
735 MLOCK(ErrorMessageLock);
737 MUNLOCK(ErrorMessageLock);
744 for ( i = 0; i < number; i++ ) *p++ = *m++;
746 t->factor = params[4];
747 t->allsign = params[5];
748 if ( number >= 10 || ( t->gamma5 != GAMMA1 && number > 4 ) ) {
754 minimum = 0; min = t->inlist;
755 stopper = min + number;
756 for ( i = 1; i < number; i++ ) {
759 for ( j = 0; j < number; j++ ) {
760 if ( *p < *m )
break;
767 if ( m >= stopper ) m = t->inlist;
768 if ( p >= stopper ) p = t->inlist;
772 min = m = AT.WorkPointer;
776 if ( p >= stopper ) p = t->inlist;
781 while ( --i >= 0 ) *p++ = *m++;
785 i = *p; *p++ = *--m; *m = i;
788 for ( i = 0; i < number; i++ ) {
791 for ( j = 0; j < number; j++ ) {
792 if ( *p < *m )
break;
799 if ( m >= stopper ) m = t->inlist;
805 if ( m >= stopper ) m = t->inlist;
809 if ( ( minimum & 1 ) != 0 ) {
810 if ( t->gamma5 == GAMMA5 ) t->allsign = - t->allsign;
811 else if ( t->gamma5 != GAMMA1 )
812 t->gamma5 = GAMMA6 + GAMMA7 - t->gamma5;
814 p = min; m = t->inlist; i = number;
815 while ( --i >= 0 ) *m++ = *p++;
820 ret = Trace4Gen(BHEAD t,number);
821 AT.WorkPointer = OldW;
858int Trace4Gen(PHEAD
TRACES *t, WORD number)
861 WORD *termout, *stop;
863 WORD *pold, *mold, diff, *oldstring, cp;
868 if ( t->gamma5 == GAMMA5 )
return(0);
869 termout = AT.WorkPointer;
875 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
878 do { *m++ = *p++; }
while ( p < oldstring );
880 *m++ = AC.lUniTrace[0];
881 *m++ = AC.lUniTrace[1];
882 *m++ = AC.lUniTrace[2];
883 *m++ = AC.lUniTrace[3];
884 if ( number == 2 || t->accup > t->accu ) {
892 if ( t->accup > t->accu ) {
895 while ( p < t->accup ) *m++ = *p++;
896 oldstring[1] = WORDDIF(m,oldstring);
906 do { *m++ = *p++; }
while ( p < stop );
907 *termout = WORDDIF(m,termout);
908 if ( t->allsign < 0 ) m[-1] = -m[-1];
909 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
910 MLOCK(ErrorMessageLock);
912 MUNLOCK(ErrorMessageLock);
920 if (
Generator(BHEAD termout,t->level) )
goto TracCall;
922 AT.WorkPointer= termout;
926 }
while ( p < stop );
934 stop = p + number - 1;
940 while ( m < stop ) *p++ = *m++;
941 if ( t->gamma5 != GAMMA1 ) {
942 if ( t->gamma5 == GAMMA5 ) t->allsign = - t->allsign;
943 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
944 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
946 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
947 t = AN.tracestack + AN.numtracesctack - 1;
948 if ( t->gamma5 != GAMMA1 ) {
949 if ( t->gamma5 == GAMMA5 ) t->allsign = - t->allsign;
950 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
951 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
953 while ( p > t->inlist ) *--m = *--p;
965 while ( m <= stop ) *p++ = *m++;
966 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
967 t = AN.tracestack + AN.numtracesctack - 1;
968 while ( p > pold ) *--m = *--p;
975 }
while ( p < stop );
983 if ( *p >= AM.OffsetIndex && (
984 ( *p < WILDOFFSET + AM.OffsetIndex &&
985 indices[*p-AM.OffsetIndex].dimension == 4 )
986 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim == 4 ) ) ) {
994 t->allsign = - t->allsign;
997 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1000 while ( m < stop ) *p++ = *m++;
1001 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
1002 t = AN.tracestack + AN.numtracesctack - 1;
1004 while ( m > mold ) *m-- = *--p;
1009 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1010 t->allsign = - t->allsign;
1018 }
while ( p < stop );
1027 if ( *p >= AM.OffsetIndex && (
1028 ( *p < WILDOFFSET + AM.OffsetIndex &&
1029 indices[*p-AM.OffsetIndex].dimension == 4 )
1030 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim == 4 ) ) ) {
1032 if ( m >= stop ) m -= number;
1034 WORD oldfactor, old5;
1035 oldstring = AT.WorkPointer;
1036 AT.WorkPointer += number;
1037 oldfactor = t->allsign;
1039 if ( m < p ) cp = (WORDDIF(m,t->inlist) + 1 ) & 1;
1041 if ( cp && ( t->gamma5 != GAMMA1 ) ) {
1042 if ( t->gamma5 == GAMMA5 ) t->allsign = -t->allsign;
1043 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
1044 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
1049 while ( m < stop ) *p++ = *m++;
1055 while ( m < stop ) *p++ = *m++;
1057 if ( !cp && ((WORDDIF(stop,p))&1) != 0 && ( t->gamma5 != GAMMA1 ) ) {
1058 if ( t->gamma5 == GAMMA5 ) t->allsign = -t->allsign;
1059 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
1060 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
1062 while ( p < stop ) *p++ = *m++;
1066 oldval = number - 4;
1067 while ( oldval > 0 ) {
1068 if ( *p >= AM.OffsetIndex && (
1069 ( *p < WILDOFFSET + AM.OffsetIndex &&
1070 indices[*p-AM.OffsetIndex].dimension )
1071 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim ) ) ) {
1076 else if ( *p == m[1] ) {
1083 if ( oldval <= 0 ) {
1084 *(t->accup)++ = *m++;
1085 *(t->accup)++ = *m++;
1087 if ( Trace4Gen(BHEAD t,number-4) )
goto TracCall;
1088 t = AN.tracestack + AN.numtracesctack - 1;
1090 if ( oldval <= 0 ) t->accup -= 2;
1092 t->allsign = oldfactor;
1093 AT.WorkPointer = p = oldstring;
1095 while ( m < stop ) *m++ = *p++;
1100 }
while ( p < stop );
1107 if ( *p >= AM.OffsetIndex && (
1108 ( *p < WILDOFFSET + AM.OffsetIndex &&
1109 indices[*p-AM.OffsetIndex].dimension == 4 )
1110 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim == 4 ) ) ) {
1112 while ( m < stop ) {
1131 while ( m < stop ) *p++ = *m++;
1132 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
1133 t = AN.tracestack + AN.numtracesctack - 1;
1137 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1142 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
1143 t = AN.tracestack + AN.numtracesctack - 1;
1146 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1150 while ( m > mold ) *m-- = *--p;
1163 }
while ( p < stop );
1169 stop = p + number - 1;
1173 while ( p <= stop ) {
1175 if ( m > stop ) m -= number;
1177 WORD oldfactor, c, old5;
1178 oldfactor = t->allsign;
1180 cp = (WORDDIF(m,t->inlist)) & 1;
1181 if ( !cp && ( t->gamma5 != GAMMA1 ) ) {
1182 if ( t->gamma5 == GAMMA5 ) t->allsign = -t->allsign;
1183 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
1184 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
1186 oldstring = AT.WorkPointer;
1187 AT.WorkPointer += number;
1192 while ( m <= stop ) *p++ = *m++;
1198 while ( m <= stop ) *p++ = *m++;
1200 while ( p <= stop ) *p++ = *m++;
1204 *(t->accup) = oldval;
1211 if ( Trace4Gen(BHEAD t,number-2) )
goto Trac4Call;
1212 t = AN.tracestack + AN.numtracesctack - 1;
1214 t->allsign = - t->allsign;
1220 if ( Trace4Gen(BHEAD t,number-2) )
goto Trac4Call;
1221 t = AN.tracestack + AN.numtracesctack - 1;
1223 t->allsign = oldfactor;
1224 AT.WorkPointer = p = oldstring;
1226 while ( m <= stop ) *m++ = *p++;
1232 }
while ( ++diff <= (number>>1) );
1241 termout = AT.WorkPointer;
1243 if ( t->finalstep == 0 ) diff = Trace4no(number,t->accup,t);
1244 else diff = TraceNno(number,t->accup,t);
1246 if ( diff == 0 )
break;
1251 if ( p < stop )
do {
1252 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
1255 do { *m++ = *p++; }
while ( p < oldstring );
1258 *m++ = AC.lUniTrace[0];
1259 *m++ = AC.lUniTrace[1];
1260 *m++ = AC.lUniTrace[2];
1261 *m++ = AC.lUniTrace[3];
1268 if ( diff == 2 || diff == -2 ) {
1273 *m++ = *p++; *m++ = *p++; *m++ = *p++; *m++ = *p++;
1276 if ( oldval > 0 || t->accup > t->accu ) {
1280 if ( oldval > 0 ) NCOPY(m,p,oldval);
1281 if ( t->accup > t->accu ) {
1283 while ( p < t->accup ) *m++ = *p++;
1284 oldstring[1] = WORDDIF(m,oldstring);
1288 do { *m++ = *p++; }
while ( p < stop );
1289 *termout = WORDDIF(m,termout);
1290 if ( ( diff ^ t->allsign ) < 0 ) m[-1] = - m[-1];
1291 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
1292 MLOCK(ErrorMessageLock);
1294 MUNLOCK(ErrorMessageLock);
1300 if (
Generator(BHEAD termout,t->level) ) {
1301 AT.WorkPointer = termout;
1304 t = AN.tracestack + AN.numtracesctack - 1;
1309 }
while ( p < stop );
1311 AT.WorkPointer = termout;
1318 AT.WorkPointer = oldstring;
1320 if ( AM.tracebackflag ) {
1321 MLOCK(ErrorMessageLock);
1322 MesCall(
"Trace4Gen");
1323 MUNLOCK(ErrorMessageLock);
1343WORD TraceNno(WORD number, WORD *kron,
TRACES *t)
1347 if ( !number || ( number & 1 ) )
return(0);
1349 for ( i = 0; i < number; i++ ) {
1361 for ( j = i + 1; j <= *p; j++ ) kron[j-1] = kron[j];
1363 if ( *p < number ) {
1366 while ( j >= (i+1) ) { kron[j] = kron[j-1]; j--; }
1369 for ( j = i+2; j < number; j += 2 ) t->perm[j] = j;
1384int TraceN(PHEAD WORD *term, WORD *params, WORD num, WORD level)
1388 WORD *p, *m, number, i;
1391 if ( params[3] != GAMMA1 ) {
1392 MLOCK(ErrorMessageLock);
1393 MesPrint(
"Gamma5 not allowed in n-trace");
1394 MUNLOCK(ErrorMessageLock);
1397 OldW = AT.WorkPointer;
1398 if ( AN.numtracesctack >= AN.intracestack ) {
1399 number = AN.intracestack + 2;
1400 t = (
TRACES *)Malloc1(number*
sizeof(
TRACES),
"TRACES-struct");
1401 if ( AN.tracestack ) {
1402 for ( i = 0; i < AN.intracestack; i++ ) { t[i] = AN.tracestack[i]; }
1403 M_free(AN.tracestack,
"TRACES-struct");
1406 AN.intracestack = number;
1408 number = *params - 6;
1409 if ( number < 0 || ( number & 1 ) || !params[5] )
return(0);
1411 t = AN.tracestack + AN.numtracesctack;
1412 AN.numtracesctack++;
1414 t->inlist = AT.WorkPointer;
1415 t->accup = t->accu = t->inlist + number;
1416 t->perm = t->accu + number;
1417 if ( ( AT.WorkPointer += 3 * number ) >= AT.WorkTop ) {
1418 AN.numtracesctack--;
1419 MLOCK(ErrorMessageLock);
1421 MUNLOCK(ErrorMessageLock);
1428 for ( i = 0; i < number; i++ ) *p++ = *m++;
1430 t->factor = params[4];
1431 t->allsign = params[5];
1432 ret = TraceNgen(BHEAD t,number);
1433 AT.WorkPointer = OldW;
1434 AN.numtracesctack--;
1449int TraceNgen(PHEAD
TRACES *t, WORD number)
1452 WORD *termout, *stop;
1453 WORD *p, *m, oldval;
1454 WORD *pold, *mold, diff, *oldstring;
1458 if ( number <= 2 ) {
1459 termout = AT.WorkPointer;
1464 if ( p < stop )
do {
1465 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
1468 do { *m++ = *p++; }
while ( p < oldstring );
1470 *m++ = AC.lUniTrace[0];
1471 *m++ = AC.lUniTrace[1];
1472 *m++ = AC.lUniTrace[2];
1473 *m++ = AC.lUniTrace[3];
1474 if ( number == 2 || t->accup > t->accu ) {
1478 if ( number == 2 ) {
1479 *m++ = t->inlist[0];
1480 *m++ = t->inlist[1];
1482 if ( t->accup > t->accu ) {
1485 while ( p < t->accup ) *m++ = *p++;
1486 oldstring[1] = WORDDIF(m,oldstring);
1496 do { *m++ = *p++; }
while ( p < stop );
1497 *termout = WORDDIF(m,termout);
1498 if ( t->allsign < 0 ) m[-1] = -m[-1];
1499 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
1500 MLOCK(ErrorMessageLock);
1502 MUNLOCK(ErrorMessageLock);
1508 if (
Generator(BHEAD termout,t->level) )
goto TracCall;
1510 AT.WorkPointer= termout;
1514 }
while ( p < stop );
1522 stop = p + number - 1;
1523 if ( *p == *stop ) {
1528 while ( m < stop ) *p++ = *m++;
1529 if ( TraceNgen(BHEAD t,number-2) )
goto TracCall;
1530 t = AN.tracestack + AN.numtracesctack - 1;
1531 while ( p > t->inlist ) *--m = *--p;
1532 *p = *stop = oldval;
1543 while ( m <= stop ) *p++ = *m++;
1544 if ( TraceNgen(BHEAD t,number-2) )
goto TracCall;
1545 t = AN.tracestack + AN.numtracesctack - 1;
1546 while ( p > pold ) *--m = *--p;
1553 }
while ( p < stop );
1559 stop = p + number - 1;
1563 while ( p <= stop ) {
1565 if ( m > stop ) m -= number;
1568 oldstring = AT.WorkPointer;
1569 AT.WorkPointer += number;
1574 while ( m <= stop ) *p++ = *m++;
1581 while ( m <= stop ) *p++ = *m++;
1583 while ( p <= stop ) *p++ = *m++;
1585 oldfactor = t->allsign;
1589 if ( oldval >= ( AM.OffsetIndex + WILDOFFSET ) ||
1590 ( oldval >= AM.OffsetIndex
1591 && indices[oldval-AM.OffsetIndex].dimension ) ) {
1601 while ( m > (p+3) ) {
1605 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1606 t = AN.tracestack + AN.numtracesctack - 1;
1608 t->allsign = - t->allsign;
1610 switch ( WORDDIF(m,p) ) {
1615 if ( oldval < ( AM.OffsetIndex + WILDOFFSET )
1616 && indices[oldval-AM.OffsetIndex].nmin4
1618 t->allsign = - t->allsign;
1619 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1620 t = AN.tracestack + AN.numtracesctack - 1;
1622 *(t->accup)++ = SUMMEDIND;
1624 indices[oldval-AM.OffsetIndex].nmin4;
1628 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1629 t = AN.tracestack + AN.numtracesctack - 1;
1630 t->allsign = - t->allsign;
1632 *(t->accup)++ = oldval;
1633 *(t->accup)++ = oldval;
1635 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1636 t = AN.tracestack + AN.numtracesctack - 1;
1646 if ( TraceNgen(BHEAD t,number-4) )
goto TracnCall;
1647 t = AN.tracestack + AN.numtracesctack - 1;
1648 *p = one; p[1] = two;
1650 if ( oldval < ( AM.OffsetIndex + WILDOFFSET )
1651 && indices[oldval-AM.OffsetIndex].nmin4
1654 *(t->accup)++ = SUMMEDIND;
1656 indices[oldval-AM.OffsetIndex].nmin4;
1659 t->allsign = - t->allsign;
1660 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1661 t = AN.tracestack + AN.numtracesctack - 1;
1662 t->allsign = - t->allsign;
1664 *(t->accup)++ = oldval;
1665 *(t->accup)++ = oldval;
1667 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1668 t = AN.tracestack + AN.numtracesctack - 1;
1676 c = m[-1]; m[-1] = m[-2]; m[-2] = c;
1677 t->allsign = - t->allsign;
1678 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1679 t = AN.tracestack + AN.numtracesctack - 1;
1685 if ( oldval < ( AM.OffsetIndex + WILDOFFSET )
1686 && indices[oldval-AM.OffsetIndex].nmin4
1688 *(t->accup)++ = SUMMEDIND;
1690 indices[oldval-AM.OffsetIndex].nmin4;
1691 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1692 t = AN.tracestack + AN.numtracesctack - 1;
1694 t->allsign = - t->allsign;
1698 *(t->accup)++ = oldval;
1699 *(t->accup)++ = oldval;
1700 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1701 t = AN.tracestack + AN.numtracesctack - 1;
1703 t->allsign = - t->allsign;
1705 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1706 t = AN.tracestack + AN.numtracesctack - 1;
1713 *(t->accup) = oldval;
1720 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1721 t = AN.tracestack + AN.numtracesctack - 1;
1723 t->allsign = - t->allsign;
1729 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1730 t = AN.tracestack + AN.numtracesctack - 1;
1733 t->allsign = oldfactor;
1736 while ( m <= stop ) *m++ = *p++;
1737 AT.WorkPointer = oldstring;
1743 }
while ( diff <= (number>>1) );
1752 termout = AT.WorkPointer;
1753 while ( ( diff = TraceNno(number,t->accup,t) ) != 0 ) {
1758 if ( p < stop )
do {
1759 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
1762 do { *m++ = *p++; }
while ( p < oldstring );
1765 *m++ = AC.lUniTrace[0];
1766 *m++ = AC.lUniTrace[1];
1767 *m++ = AC.lUniTrace[2];
1768 *m++ = AC.lUniTrace[3];
1779 if ( t->accup > t->accu ) {
1781 while ( p < t->accup ) *m++ = *p++;
1782 oldstring[1] = WORDDIF(m,oldstring);
1785 do { *m++ = *p++; }
while ( p < stop );
1786 *termout = WORDDIF(m,termout);
1787 if ( ( diff ^ t->allsign ) < 0 ) m[-1] = - m[-1];
1788 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
1789 MLOCK(ErrorMessageLock);
1791 MUNLOCK(ErrorMessageLock);
1797 if (
Generator(BHEAD termout,t->level) ) {
1798 AT.WorkPointer = termout;
1801 t = AN.tracestack + AN.numtracesctack - 1;
1806 }
while ( p < stop );
1808 AT.WorkPointer = termout;
1815 AT.WorkPointer = oldstring;
1817 if ( AM.tracebackflag ) {
1818 MLOCK(ErrorMessageLock);
1819 MesCall(
"TraceNGen");
1820 MUNLOCK(ErrorMessageLock);
1834int Traces(PHEAD WORD *term, WORD *params, WORD num, WORD level)
1837 switch ( AT.TMout[2] ) {
1839 return(TraceN(BHEAD term,params,num,level));
1841 return(Trace4(BHEAD term,params,num,level));
1843 return(Trace4(BHEAD term,params,num,level));
1845 return(Trace4(BHEAD term,params,num,level));
1856int TraceFind(PHEAD WORD *term, WORD *params)
1860 WORD *termout, *stop, *stop2, number = 0;
1862 WORD type, spinline, sp;
1864 spinline = params[4];
1865 if ( spinline < 0 ) {
1866 sp = DolToIndex(BHEAD -spinline);
1867 if ( AN.ErrorInDollar || sp < 0 ) {
1868 MLOCK(ErrorMessageLock);
1869 MesPrint(
"$%s does not have an index value in trace statement in module %l",
1870 DOLLARNAME(Dollars,-spinline),AC.CModule);
1871 MUNLOCK(ErrorMessageLock);
1886 termout = m = AT.WorkPointer;
1889 while ( p < stop ) {
1891 if ( *p == GAMMA && p[FUNHEAD] == spinline ) {
1893 *m++ = SUBEXPRESSION;
1902 while ( p < stop2 ) {
1903 if ( *p == GAMMA5 ) {
1904 if ( AT.TMout[3] == GAMMA5 ) AT.TMout[3] = GAMMA1;
1905 else if ( AT.TMout[3] == GAMMA1 ) AT.TMout[3] = GAMMA5;
1906 else if ( AT.TMout[3] == GAMMA7 ) AT.TMout[5] = -AT.TMout[5];
1907 if ( number & 1 ) AT.TMout[5] = - AT.TMout[5];
1910 else if ( *p == GAMMA6 ) {
1911 if ( number & 1 )
goto F7;
1912F6:
if ( AT.TMout[3] == GAMMA6 ) (AT.TMout[4])++;
1913 else if ( AT.TMout[3] == GAMMA1 ) AT.TMout[3] = GAMMA6;
1914 else if ( AT.TMout[3] == GAMMA5 ) AT.TMout[3] = GAMMA6;
1915 else if ( AT.TMout[3] == GAMMA7 ) AT.TMout[5] = 0;
1918 else if ( *p == GAMMA7 ) {
1919 if ( number & 1 )
goto F6;
1920F7:
if ( AT.TMout[3] == GAMMA7 ) (AT.TMout[4])++;
1921 else if ( AT.TMout[3] == GAMMA1 ) AT.TMout[3] = GAMMA7;
1922 else if ( AT.TMout[3] == GAMMA5 ) {
1923 AT.TMout[3] = GAMMA7;
1924 AT.TMout[5] = -AT.TMout[5];
1926 else if ( AT.TMout[3] == GAMMA6 ) AT.TMout[5] = 0;
1936 while ( p < stop2 ) *m++ = *p++;
1939 if ( first )
return(0);
1940 AT.TMout[0] = WORDDIF(to,AT.TMout);
1943 while ( p < to ) *m++ = *p++;
1944 *termout = WORDDIF(m,termout);
1947 do { *to++ = *p++; }
while ( p < m );
1948 AT.WorkPointer = term + *term;
1966int Chisholm(PHEAD WORD *term, WORD level)
1969 WORD *t, *r, *m, *s, *tt, *rr;
1970 WORD *mat, *matpoint, *termout, *rdo;
1971 CBUF *C = cbuf+AM.rbufnum;
1972 WORD i, j, num = C->
lhs[level][2], gam5;
1973 WORD norm = 0, k, *matp;
1977 mat = matpoint = AT.WorkPointer;
1979 r = t + *t - 1; r -= ABS(*r);
1984 if ( *t == GAMMA && t[FUNHEAD] == num ) {
1988 if ( *t >= 0 || *t < MINSPEC ) i++;
1990 if ( gam5 == GAMMA1 ) gam5 = *t;
1991 else if ( gam5 == GAMMA5 ) {
1992 if ( *t == GAMMA5 ) gam5 = GAMMA1;
1993 else if ( *t != GAMMA1 ) gam5 = *t;
2001 if ( ( i & 1 ) != 0 )
return(0);
2017 while ( s < matpoint ) {
2022 if ( *s < AM.OffsetIndex || ( *s < ( AM.OffsetIndex + WILDOFFSET ) &&
2023 indices[*s-AM.OffsetIndex].dimension != 4 )
2024 || ( ( AC.lDefDim != 4 ) && ( *s >= ( AM.OffsetIndex + WILDOFFSET ) ) ) ) {
2029 if ( *t == GAMMA && t[FUNHEAD] != num ) {
2043 if ( norm == 0 )
return(
Generator(BHEAD term,level));
2063 if ( C->
lhs[level][3] == 0 ) norm = 1;
2066 for ( k = 0; k < norm; k++ ) {
2069 while ( s < matpoint ) {
2074 if ( *s < AM.OffsetIndex || ( *s < ( AM.OffsetIndex + WILDOFFSET ) &&
2075 indices[*s-AM.OffsetIndex].dimension != 4 ) ) {
2080 if ( *t == GAMMA && t[FUNHEAD] != num ) {
2088 while ( m <= s ) *matpoint++ = *m++;
2090 while ( m < matpoint ) *t++ = *m++;
2095 if ( *t != GAMMA || t[FUNHEAD] != num ) {
2105 while ( --j >= 0 ) *m++ = *t++;
2108 while ( s < termout ) *m++ = *s++;
2111 while ( t < tt ) *m++ = *t++;
2112 rdo[1] = WORDDIF(m,rdo);
2114 *m++ = AC.lUniTrace[0];
2115 *m++ = AC.lUniTrace[1];
2116 *m++ = AC.lUniTrace[2];
2117 *m++ = AC.lUniTrace[3];
2124 if ( *t != GAMMA || t[FUNHEAD] != num ) {
2131 while ( t < rr ) *m++ = *t++;
2133 *termout = WORDDIF(m,termout);
2139 if (
Generator(BHEAD t,level) )
goto ChisCall;
2141 j = WORDDIF(termout,mat)-1;
2144 AT.WorkPointer = rr;
2146 i = *--m; *m = *t; *t++ = i;
2149 if (
Generator(BHEAD termout,level) )
goto ChisCall;
2150 AT.WorkPointer = mat;
2168 if ( AM.tracebackflag ) {
2169 MLOCK(ErrorMessageLock);
2170 MesCall(
"Chisholm");
2171 MUNLOCK(ErrorMessageLock);
2181int TenVecFind(PHEAD WORD *term, WORD *params)
2184 WORD *t, *w, *m, *tstop;
2185 WORD i, mode, thevector, thetensor, spectator;
2186 thetensor = params[3];
2187 thevector = params[4];
2189 if ( thetensor < 0 ) {
2190 thetensor = DolToTensor(BHEAD -thetensor);
2191 if ( thetensor < FUNCTION ) {
2192 if ( thevector > 0 ) {
2193 thetensor = DolToTensor(BHEAD thevector);
2194 if ( thetensor < FUNCTION ) {
2195 MLOCK(ErrorMessageLock);
2196 MesPrint(
"$%s should have been a tensor in module %l"
2197 ,DOLLARNAME(Dollars,params[4]),AC.CModule);
2198 MUNLOCK(ErrorMessageLock);
2201 thevector = DolToVector(BHEAD -params[3]);
2202 if ( thevector >= 0 ) {
2203 MLOCK(ErrorMessageLock);
2204 MesPrint(
"$%s should have been a vector in module %l"
2205 ,DOLLARNAME(Dollars,-params[3]),AC.CModule);
2206 MUNLOCK(ErrorMessageLock);
2211 MLOCK(ErrorMessageLock);
2212 MesPrint(
"$%s should have been a tensor in module %l"
2213 ,DOLLARNAME(Dollars,-params[3]),AC.CModule);
2214 MUNLOCK(ErrorMessageLock);
2219 if ( thevector > 0 ) {
2220 thevector = DolToVector(BHEAD thevector);
2221 if ( thevector >= 0 ) {
2222 MLOCK(ErrorMessageLock);
2223 MesPrint(
"$%s should have been a vector in module %l"
2224 ,DOLLARNAME(Dollars,params[4]),AC.CModule);
2225 MUNLOCK(ErrorMessageLock);
2229 if ( ( mode & 1 ) != 0 ) {
2230 GETSTOP(term,tstop);
2232 while ( t < tstop ) {
2233 if ( *t == DOTPRODUCT ) {
2234 i = t[1] - 2; t += 2;
2238 else if ( *t == thevector && t[1] == thevector ) {
2239 if ( ( mode & 2 ) == 0 ) spectator = thevector;
2241 else if ( *t == thevector ) spectator = t[1];
2242 else if ( t[1] == thevector ) spectator = *t;
2244 if ( ( mode & 8 ) == 0 )
goto match;
2245 w = SetElements + Sets[params[6]].first;
2246 m = SetElements + Sets[params[6]].last;
2248 if ( *w == spectator )
break;
2251 if ( w >= m )
goto match;
2257 else if ( *t == VECTOR ) {
2258 i = t[1] - 2; t += 2;
2260 if ( *t == thevector )
goto match;
2265 else if ( *t == thetensor ) t += t[1];
2266 else if ( *t >= FUNCTION ) {
2267 if ( functions[*t-FUNCTION].spec > 0 ) {
2271 if ( *t == thevector )
goto match;
2275 else if ( ( mode & 4 ) != 0 ) {
2279 if ( *t == -VECTOR && t[1] == thevector )
goto match;
2280 else if ( *t > 0 ) t += *t;
2281 else if ( *t <= -FUNCTION ) t++;
2291 GETSTOP(term,tstop);
2293 while ( t < tstop ) {
2294 if ( *t == thetensor )
goto match;
2301 AT.TMout[1] = TENVEC;
2302 AT.TMout[2] = thetensor;
2303 AT.TMout[3] = thevector;
2305 if ( ( mode & 8 ) != 0 ) { AT.TMout[0] = 6; AT.TMout[5] = params[6]; }
2315int TenVec(PHEAD WORD *term, WORD *params, WORD num, WORD level)
2318 WORD *t, *m, *w, *termout, *tstop, *outlist, *ou, *ww, *mm;
2319 WORD i, j, k, x, mode, thevector, thetensor, DumNow, spectator;
2321 thetensor = params[2];
2322 thevector = params[3];
2324 termout = AT.WorkPointer;
2325 DumNow = AR.CurDum = DetCurDum(BHEAD term);
2326 if ( ( mode & 1 ) != 0 ) {
2327 AT.WorkPointer += *term;
2328 ou = outlist = AT.WorkPointer;
2329 GETSTOP(term,tstop);
2332 while ( t < tstop ) {
2333 if ( *t == DOTPRODUCT ) {
2336 *m++ = *t++; *m++ = *t++;
2340 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2342 else if ( *t == thevector && t[1] == thevector ) {
2343 if ( ( mode & 2 ) == 0 ) spectator = thevector;
2345 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2348 else if ( *t == thevector ) spectator = t[1];
2349 else if ( t[1] == thevector ) spectator = *t;
2351 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2354 if ( ( mode & 8 ) == 0 )
goto noveto;
2355 ww = SetElements + Sets[params[5]].first;
2356 mm = SetElements + Sets[params[5]].last;
2358 if ( *ww == spectator )
break;
2362 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2365noveto:
if ( spectator == thevector ) {
2366 for ( j = 0; j < t[2]; j++ ) {
2367 *ou++ = ++AR.CurDum;
2373 for ( j = 0; j < t[2]; j++ ) *ou++ = spectator;
2379 w[1] = WORDDIF(m,w);
2380 if ( w[1] == 2 ) m = w;
2382 else if ( *t == VECTOR ) {
2383 i = t[1] - 2; w = m;
2384 *m++ = *t++; *m++ = *t++;
2386 if ( *t == thevector ) {
2390 else { *m++ = *t++; *m++ = *t++; }
2393 w[1] = WORDDIF(m,w);
2394 if ( w[1] == 2 ) m = w;
2396 else if ( *t == thetensor ) {
2401 else if ( *t >= FUNCTION ) {
2402 if ( functions[*t-FUNCTION].spec > 0 ) {
2407 if ( *t == thevector ) {
2415 else if ( ( mode & 4 ) != 0 ) {
2420 if ( *t == -VECTOR && t[1] == thevector ) {
2426 else if ( *t > 0 ) {
2430 else if ( *t <= -FUNCTION ) *m++ = *t++;
2431 else { *m++ = *t++; *m++ = *t++; }
2442 i = WORDDIF(ou,outlist);
2444 for ( j = 1; j < i; j++ ) {
2445 if ( outlist[j-1] > outlist[j] ) {
2446 x = outlist[j-1]; outlist[j-1] = outlist[j]; outlist[j] = x;
2447 for ( k = j-1; k > 0; k-- ) {
2448 if ( outlist[k-1] <= outlist[k] )
break;
2449 x = outlist[k-1]; outlist[k-1] = outlist[k]; outlist[k] = x;
2456 *m++ = DIRTYSYMFLAG;
2462 while ( t < w ) *m++ = *t++;
2465 GETSTOP(term,tstop);
2468 while ( t < tstop ) {
2469 if ( *t != thetensor ) {
2478 while ( --i >= 0 ) {
2483 w[1] = WORDDIF(m,w);
2488 while ( t < w ) *m++ = *t++;
2490 *termout = WORDDIF(m,termout);
2493 if (
Generator(BHEAD termout,level) )
goto fromTenVec;
2495 AT.WorkPointer = termout;
2498 if ( AM.tracebackflag ) {
2499 MLOCK(ErrorMessageLock);
2501 MUNLOCK(ErrorMessageLock);
int Generator(PHEAD WORD *, WORD)