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 ) {
241 MLOCK(ErrorMessageLock);
242 MesPrint(
"!>Serious error in EpfCon");
243 MUNLOCK(ErrorMessageLock);
253 if ( i ) { NCOPY(m,t,i); }
256 tstop = term + *term;
257 while ( t < tstop ) *m++ = *t++;
258 *termout = WORDDIF(m,termout);
260 if ( sgn < 0 ) *m = - *m;
264 AT.WorkPointer = termout + *termout;
265 if (
Generator(BHEAD termout,level) < 0 )
goto EpfCall;
268 AT.WorkPointer = kron;
271 if ( AM.tracebackflag ) {
272 MLOCK(ErrorMessageLock);
274 MUNLOCK(ErrorMessageLock);
284WORD EpfGen(WORD number, WORD *inlist, WORD *kron, WORD *perm, WORD sgn)
288 in2 = inlist + number;
290 for ( i = 1; i < number; i += 2 ) {
296 if ( number <= 0 )
return(0);
301 while ( ( i -= 2 ) >= 0 ) {
302 if ( ( k = perm[i] ) != i ) {
308 if ( ( k = ( perm[i] += 2 ) ) < number ) {
313 for ( k = i + 2; k < number; k += 2 ) perm[k] = k;
333WORD Trick(WORD *in,
TRACES *t)
338 switch ( t->eers[n] ) {
341 p = t->pepf + t->mepf[n];
354 p = t->pdel + t->mdel[n];
359 *in = *(t->pepf + t->mepf[n] + 2);
365 t->sign1 = - t->sign1;
366 *(t->pdel + t->mdel[n] + 1) = in[2];
371 t->sign1 = - t->sign1;
373 *(t->pdel + t->mdel[n]) = in[1];
377 in[2] = *(t->pdel + t->mdel[n] + 1);
385 return(--(t->eers[n]));
420int Trace4no(WORD number, WORD *kron,
TRACES *t)
427 if ( ( number < 0 ) || ( number & 1 ) )
return(0);
429 if ( t->gamma5 == GAMMA5 )
return(0);
431 *kron++ = *t->inlist;
432 *kron++ = t->inlist[1];
438 WORD nhalf = number >> 1;
439 WORD ndouble = number * 2;
441 t->eers = p; p += nhalf;
442 t->mepf = p; p += nhalf;
443 t->mdel = p; p += nhalf;
444 t->pdel = p; p += number + nhalf;
445 t->pepf = p; p += ndouble;
446 t->e4 = p; p += number;
447 t->e3 = p; p += ndouble;
448 t->nt3 = p; p += nhalf;
449 t->nt4 = p; p += nhalf;
450 t->j3 = p; p += ndouble;
455 t->mdum = AM.mTraceDum;
464 t->stap = (t->step1)++;
466 t->eers[t->stap] = 0;
467 t->mepf[t->step1] = t->mepf[t->stap];
468 t->mdel[t->step1] = t->mdel[t->stap];
469CallTrick:
while ( !Trick(t->inlist+t->kstep,t) ) {
471 t->step1 = (t->stap)--;
476 }
while ( t->kstep < (number-4) );
483 if ( ( t->gamma5 == GAMMA7 ) && ( t->gamm == -1 ) ) {
484 t->sign2 = - t->sign2;
486 else if ( ( t->gamma5 == GAMMA5 ) && ( t->gamm == 1 ) ) {
489 else if ( ( t->gamma5 == GAMMA1 ) && ( t->gamm == -1 ) ) {
492 p = t->pdel + t->mdel[t->step1];
493 *p++ = t->inlist[t->kstep+2];
494 *p++ = t->inlist[t->kstep+3];
508 ae = t->mepf[t->step1];
509 t->ad = t->mdel[t->step1]+2;
512 while ( ( ae -= 4 ) >= 0 ) {
513 if ( t->pepf[ae] > AM.mTraceDum && t->pepf[ae] <= t->mdum ) {
516 for ( i = 0; i < 3; i++ ) {
526 for ( i = 0; i < 4; i++ ) *p++ = *m++;
540 while ( t->a3 > 0 ) {
541 t->nt3[++(t->lc3)] = 0;
542 while ( ( t->nt3[t->lc3] = EpfGen(3,t->e3+t->a3-6,
543 t->pdel+t->ad,t->j3+6*t->lc3,oldsign = t->nt3[t->lc3]) ) == 0 ) {
544 if ( oldsign < 0 ) t->sign2 = - t->sign2;
546NextE3:
if ( t->lc3 < 0 )
goto CallTrick;
551 if ( oldsign != t->nt3[t->lc3] ) t->sign2 = - t->sign2;
553 else if ( t->nt3[t->lc3] < 0 ) t->sign2 = - t->sign2;
560 while ( t->a4 > 4 ) {
561 t->nt4[++(t->lc4)] = 0;
562 while ( ( t->nt4[t->lc4] = EpfGen(4,t->e4+t->a4-8,
563 t->pdel+t->ad,t->j4+8*t->lc4,oldsign = t->nt4[t->lc4]) ) == 0 ) {
564 if ( oldsign < 0 ) t->sign2 = - t->sign2;
566NextE4:
if ( t->lc4 < 0 )
goto NextE3;
571 if ( oldsign != t->nt4[t->lc4] ) t->sign2 = - t->sign2;
573 else if ( t->nt4[t->lc4] < 0 ) t->sign2 = - t->sign2;
587 *m++ = *p++; *m++ = *p++; *m++ = *p++; *m++ = *p++;
591 if ( t->sign2 < 0 ) retval = - retval;
593 for ( i = 0; i < t->ad; i++ ) *m++ = *p++;
599 stop = p + t->ad + 4;
601 while ( *p >= AM.mTraceDum && *p <= t->mdum ) {
610 else if ( m[1] == *p ) {
617 }
while ( m < stop );
621 else stop = p + t->ad;
622 while ( p < (stop-2) ) {
623 while ( *p >= AM.mTraceDum && *p <= t->mdum ) {
632 else if ( m[1] == *p ) {
639 }
while ( m < stop );
642 while ( *p >= AM.mTraceDum && *p <= t->mdum ) {
651 else if ( m[1] == *p ) {
658 }
while ( m < stop );
664 if ( number <= 2 )
return(0);
665 else {
goto NextE4; }
697int Trace4(PHEAD WORD *term, WORD *params, WORD num, WORD level)
701 WORD *p, *m, number, i;
703 WORD j, minimum, minimum2, *min, *stopper;
705 OldW = AT.WorkPointer;
706 if ( AN.numtracesctack >= AN.intracestack ) {
707 number = AN.intracestack + 2;
708 t = (
TRACES *)Malloc1(number*
sizeof(
TRACES),
"TRACES-struct");
709 if ( AN.tracestack ) {
710 for ( i = 0; i < AN.intracestack; i++ ) { t[i] = AN.tracestack[i]; }
711 M_free(AN.tracestack,
"TRACES-struct");
714 AN.intracestack = number;
717 number = *params - 6;
718 if ( number < 0 || ( number & 1 ) || !params[5] )
return(0);
720 t = AN.tracestack + AN.numtracesctack;
723 t->finalstep = ( params[2] & 16 ) ? 1 : 0;
724 t->gamma5 = params[3];
725 if ( t->finalstep && t->gamma5 != GAMMA1 ) {
726 MLOCK(ErrorMessageLock);
727 MesPrint(
"Gamma5 not allowed in this option of the trace command");
728 MUNLOCK(ErrorMessageLock);
732 t->inlist = AT.WorkPointer;
733 t->accup = t->accu = t->inlist + number;
734 t->perm = t->accu + (number*2);
735 t->eers = t->perm + number;
736 if ( ( AT.WorkPointer += 19 * number ) >= AT.WorkTop ) {
737 MLOCK(ErrorMessageLock);
739 MUNLOCK(ErrorMessageLock);
746 for ( i = 0; i < number; i++ ) *p++ = *m++;
748 t->factor = params[4];
749 t->allsign = params[5];
750 if ( number >= 10 || ( t->gamma5 != GAMMA1 && number > 4 ) ) {
756 minimum = 0; min = t->inlist;
757 stopper = min + number;
758 for ( i = 1; i < number; i++ ) {
761 for ( j = 0; j < number; j++ ) {
762 if ( *p < *m )
break;
769 if ( m >= stopper ) m = t->inlist;
770 if ( p >= stopper ) p = t->inlist;
774 min = m = AT.WorkPointer;
778 if ( p >= stopper ) p = t->inlist;
783 while ( --i >= 0 ) *p++ = *m++;
787 i = *p; *p++ = *--m; *m = i;
790 for ( i = 0; i < number; i++ ) {
793 for ( j = 0; j < number; j++ ) {
794 if ( *p < *m )
break;
801 if ( m >= stopper ) m = t->inlist;
807 if ( m >= stopper ) m = t->inlist;
811 if ( ( minimum & 1 ) != 0 ) {
812 if ( t->gamma5 == GAMMA5 ) t->allsign = - t->allsign;
813 else if ( t->gamma5 != GAMMA1 )
814 t->gamma5 = GAMMA6 + GAMMA7 - t->gamma5;
816 p = min; m = t->inlist; i = number;
817 while ( --i >= 0 ) *m++ = *p++;
822 ret = Trace4Gen(BHEAD t,number);
823 AT.WorkPointer = OldW;
860int Trace4Gen(PHEAD
TRACES *t, WORD number)
863 WORD *termout, *stop;
865 WORD *pold, *mold, diff, *oldstring, cp;
870 if ( t->gamma5 == GAMMA5 )
return(0);
871 termout = AT.WorkPointer;
877 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
880 do { *m++ = *p++; }
while ( p < oldstring );
882 *m++ = AC.lUniTrace[0];
883 *m++ = AC.lUniTrace[1];
884 *m++ = AC.lUniTrace[2];
885 *m++ = AC.lUniTrace[3];
886 if ( number == 2 || t->accup > t->accu ) {
894 if ( t->accup > t->accu ) {
897 while ( p < t->accup ) *m++ = *p++;
898 oldstring[1] = WORDDIF(m,oldstring);
908 do { *m++ = *p++; }
while ( p < stop );
909 *termout = WORDDIF(m,termout);
910 if ( t->allsign < 0 ) m[-1] = -m[-1];
911 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
912 MLOCK(ErrorMessageLock);
914 MUNLOCK(ErrorMessageLock);
922 if (
Generator(BHEAD termout,t->level) )
goto TracCall;
924 AT.WorkPointer= termout;
928 }
while ( p < stop );
936 stop = p + number - 1;
942 while ( m < stop ) *p++ = *m++;
943 if ( t->gamma5 != GAMMA1 ) {
944 if ( t->gamma5 == GAMMA5 ) t->allsign = - t->allsign;
945 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
946 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
948 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
949 t = AN.tracestack + AN.numtracesctack - 1;
950 if ( t->gamma5 != GAMMA1 ) {
951 if ( t->gamma5 == GAMMA5 ) t->allsign = - t->allsign;
952 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
953 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
955 while ( p > t->inlist ) *--m = *--p;
967 while ( m <= stop ) *p++ = *m++;
968 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
969 t = AN.tracestack + AN.numtracesctack - 1;
970 while ( p > pold ) *--m = *--p;
977 }
while ( p < stop );
985 if ( *p >= AM.OffsetIndex && (
986 ( *p < WILDOFFSET + AM.OffsetIndex &&
987 indices[*p-AM.OffsetIndex].dimension == 4 )
988 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim == 4 ) ) ) {
996 t->allsign = - t->allsign;
999 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1002 while ( m < stop ) *p++ = *m++;
1003 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
1004 t = AN.tracestack + AN.numtracesctack - 1;
1006 while ( m > mold ) *m-- = *--p;
1011 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1012 t->allsign = - t->allsign;
1020 }
while ( p < stop );
1029 if ( *p >= AM.OffsetIndex && (
1030 ( *p < WILDOFFSET + AM.OffsetIndex &&
1031 indices[*p-AM.OffsetIndex].dimension == 4 )
1032 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim == 4 ) ) ) {
1034 if ( m >= stop ) m -= number;
1036 WORD oldfactor, old5;
1037 oldstring = AT.WorkPointer;
1038 AT.WorkPointer += number;
1039 oldfactor = t->allsign;
1041 if ( m < p ) cp = (WORDDIF(m,t->inlist) + 1 ) & 1;
1043 if ( cp && ( t->gamma5 != GAMMA1 ) ) {
1044 if ( t->gamma5 == GAMMA5 ) t->allsign = -t->allsign;
1045 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
1046 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
1051 while ( m < stop ) *p++ = *m++;
1057 while ( m < stop ) *p++ = *m++;
1059 if ( !cp && ((WORDDIF(stop,p))&1) != 0 && ( t->gamma5 != GAMMA1 ) ) {
1060 if ( t->gamma5 == GAMMA5 ) t->allsign = -t->allsign;
1061 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
1062 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
1064 while ( p < stop ) *p++ = *m++;
1068 oldval = number - 4;
1069 while ( oldval > 0 ) {
1070 if ( *p >= AM.OffsetIndex && (
1071 ( *p < WILDOFFSET + AM.OffsetIndex &&
1072 indices[*p-AM.OffsetIndex].dimension )
1073 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim ) ) ) {
1078 else if ( *p == m[1] ) {
1085 if ( oldval <= 0 ) {
1086 *(t->accup)++ = *m++;
1087 *(t->accup)++ = *m++;
1089 if ( Trace4Gen(BHEAD t,number-4) )
goto TracCall;
1090 t = AN.tracestack + AN.numtracesctack - 1;
1092 if ( oldval <= 0 ) t->accup -= 2;
1094 t->allsign = oldfactor;
1095 AT.WorkPointer = p = oldstring;
1097 while ( m < stop ) *m++ = *p++;
1102 }
while ( p < stop );
1109 if ( *p >= AM.OffsetIndex && (
1110 ( *p < WILDOFFSET + AM.OffsetIndex &&
1111 indices[*p-AM.OffsetIndex].dimension == 4 )
1112 || ( *p >= WILDOFFSET + AM.OffsetIndex && AC.lDefDim == 4 ) ) ) {
1114 while ( m < stop ) {
1133 while ( m < stop ) *p++ = *m++;
1134 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
1135 t = AN.tracestack + AN.numtracesctack - 1;
1139 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1144 if ( Trace4Gen(BHEAD t,number-2) )
goto TracCall;
1145 t = AN.tracestack + AN.numtracesctack - 1;
1148 while ( m > p ) { diff = *p; *p++ = *m; *m-- = diff; }
1152 while ( m > mold ) *m-- = *--p;
1165 }
while ( p < stop );
1171 stop = p + number - 1;
1175 while ( p <= stop ) {
1177 if ( m > stop ) m -= number;
1179 WORD oldfactor, c, old5;
1180 oldfactor = t->allsign;
1182 cp = (WORDDIF(m,t->inlist)) & 1;
1183 if ( !cp && ( t->gamma5 != GAMMA1 ) ) {
1184 if ( t->gamma5 == GAMMA5 ) t->allsign = -t->allsign;
1185 else if ( t->gamma5 == GAMMA6 ) t->gamma5 = GAMMA7;
1186 else if ( t->gamma5 == GAMMA7 ) t->gamma5 = GAMMA6;
1188 oldstring = AT.WorkPointer;
1189 AT.WorkPointer += number;
1194 while ( m <= stop ) *p++ = *m++;
1200 while ( m <= stop ) *p++ = *m++;
1202 while ( p <= stop ) *p++ = *m++;
1206 *(t->accup) = oldval;
1213 if ( Trace4Gen(BHEAD t,number-2) )
goto Trac4Call;
1214 t = AN.tracestack + AN.numtracesctack - 1;
1216 t->allsign = - t->allsign;
1222 if ( Trace4Gen(BHEAD t,number-2) )
goto Trac4Call;
1223 t = AN.tracestack + AN.numtracesctack - 1;
1225 t->allsign = oldfactor;
1226 AT.WorkPointer = p = oldstring;
1228 while ( m <= stop ) *m++ = *p++;
1234 }
while ( ++diff <= (number>>1) );
1243 termout = AT.WorkPointer;
1245 if ( t->finalstep == 0 ) diff = Trace4no(number,t->accup,t);
1246 else diff = TraceNno(number,t->accup,t);
1248 if ( diff == 0 )
break;
1253 if ( p < stop )
do {
1254 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
1257 do { *m++ = *p++; }
while ( p < oldstring );
1260 *m++ = AC.lUniTrace[0];
1261 *m++ = AC.lUniTrace[1];
1262 *m++ = AC.lUniTrace[2];
1263 *m++ = AC.lUniTrace[3];
1270 if ( diff == 2 || diff == -2 ) {
1275 *m++ = *p++; *m++ = *p++; *m++ = *p++; *m++ = *p++;
1278 if ( oldval > 0 || t->accup > t->accu ) {
1282 if ( oldval > 0 ) NCOPY(m,p,oldval);
1283 if ( t->accup > t->accu ) {
1285 while ( p < t->accup ) *m++ = *p++;
1286 oldstring[1] = WORDDIF(m,oldstring);
1290 do { *m++ = *p++; }
while ( p < stop );
1291 *termout = WORDDIF(m,termout);
1292 if ( ( diff ^ t->allsign ) < 0 ) m[-1] = - m[-1];
1293 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
1294 MLOCK(ErrorMessageLock);
1296 MUNLOCK(ErrorMessageLock);
1302 if (
Generator(BHEAD termout,t->level) ) {
1303 AT.WorkPointer = termout;
1306 t = AN.tracestack + AN.numtracesctack - 1;
1311 }
while ( p < stop );
1313 AT.WorkPointer = termout;
1320 AT.WorkPointer = oldstring;
1322 if ( AM.tracebackflag ) {
1323 MLOCK(ErrorMessageLock);
1324 MesCall(
"Trace4Gen");
1325 MUNLOCK(ErrorMessageLock);
1345WORD TraceNno(WORD number, WORD *kron,
TRACES *t)
1349 if ( !number || ( number & 1 ) )
return(0);
1351 for ( i = 0; i < number; i++ ) {
1363 for ( j = i + 1; j <= *p; j++ ) kron[j-1] = kron[j];
1365 if ( *p < number ) {
1368 while ( j >= (i+1) ) { kron[j] = kron[j-1]; j--; }
1371 for ( j = i+2; j < number; j += 2 ) t->perm[j] = j;
1386int TraceN(PHEAD WORD *term, WORD *params, WORD num, WORD level)
1390 WORD *p, *m, number, i;
1393 if ( params[3] != GAMMA1 ) {
1394 MLOCK(ErrorMessageLock);
1395 MesPrint(
"Gamma5 not allowed in n-trace");
1396 MUNLOCK(ErrorMessageLock);
1399 OldW = AT.WorkPointer;
1400 if ( AN.numtracesctack >= AN.intracestack ) {
1401 number = AN.intracestack + 2;
1402 t = (
TRACES *)Malloc1(number*
sizeof(
TRACES),
"TRACES-struct");
1403 if ( AN.tracestack ) {
1404 for ( i = 0; i < AN.intracestack; i++ ) { t[i] = AN.tracestack[i]; }
1405 M_free(AN.tracestack,
"TRACES-struct");
1408 AN.intracestack = number;
1410 number = *params - 6;
1411 if ( number < 0 || ( number & 1 ) || !params[5] )
return(0);
1413 t = AN.tracestack + AN.numtracesctack;
1414 AN.numtracesctack++;
1416 t->inlist = AT.WorkPointer;
1417 t->accup = t->accu = t->inlist + number;
1418 t->perm = t->accu + number;
1419 if ( ( AT.WorkPointer += 3 * number ) >= AT.WorkTop ) {
1420 AN.numtracesctack--;
1421 MLOCK(ErrorMessageLock);
1423 MUNLOCK(ErrorMessageLock);
1430 for ( i = 0; i < number; i++ ) *p++ = *m++;
1432 t->factor = params[4];
1433 t->allsign = params[5];
1434 ret = TraceNgen(BHEAD t,number);
1435 AT.WorkPointer = OldW;
1436 AN.numtracesctack--;
1451int TraceNgen(PHEAD
TRACES *t, WORD number)
1454 WORD *termout, *stop;
1455 WORD *p, *m, oldval;
1456 WORD *pold, *mold, diff, *oldstring;
1460 if ( number <= 2 ) {
1461 termout = AT.WorkPointer;
1466 if ( p < stop )
do {
1467 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
1470 do { *m++ = *p++; }
while ( p < oldstring );
1472 *m++ = AC.lUniTrace[0];
1473 *m++ = AC.lUniTrace[1];
1474 *m++ = AC.lUniTrace[2];
1475 *m++ = AC.lUniTrace[3];
1476 if ( number == 2 || t->accup > t->accu ) {
1480 if ( number == 2 ) {
1481 *m++ = t->inlist[0];
1482 *m++ = t->inlist[1];
1484 if ( t->accup > t->accu ) {
1487 while ( p < t->accup ) *m++ = *p++;
1488 oldstring[1] = WORDDIF(m,oldstring);
1498 do { *m++ = *p++; }
while ( p < stop );
1499 *termout = WORDDIF(m,termout);
1500 if ( t->allsign < 0 ) m[-1] = -m[-1];
1501 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
1502 MLOCK(ErrorMessageLock);
1504 MUNLOCK(ErrorMessageLock);
1510 if (
Generator(BHEAD termout,t->level) )
goto TracCall;
1512 AT.WorkPointer= termout;
1516 }
while ( p < stop );
1524 stop = p + number - 1;
1525 if ( *p == *stop ) {
1530 while ( m < stop ) *p++ = *m++;
1531 if ( TraceNgen(BHEAD t,number-2) )
goto TracCall;
1532 t = AN.tracestack + AN.numtracesctack - 1;
1533 while ( p > t->inlist ) *--m = *--p;
1534 *p = *stop = oldval;
1545 while ( m <= stop ) *p++ = *m++;
1546 if ( TraceNgen(BHEAD t,number-2) )
goto TracCall;
1547 t = AN.tracestack + AN.numtracesctack - 1;
1548 while ( p > pold ) *--m = *--p;
1555 }
while ( p < stop );
1561 stop = p + number - 1;
1565 while ( p <= stop ) {
1567 if ( m > stop ) m -= number;
1570 oldstring = AT.WorkPointer;
1571 AT.WorkPointer += number;
1576 while ( m <= stop ) *p++ = *m++;
1583 while ( m <= stop ) *p++ = *m++;
1585 while ( p <= stop ) *p++ = *m++;
1587 oldfactor = t->allsign;
1591 if ( oldval >= ( AM.OffsetIndex + WILDOFFSET ) ||
1592 ( oldval >= AM.OffsetIndex
1593 && indices[oldval-AM.OffsetIndex].dimension ) ) {
1603 while ( m > (p+3) ) {
1607 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1608 t = AN.tracestack + AN.numtracesctack - 1;
1610 t->allsign = - t->allsign;
1612 switch ( WORDDIF(m,p) ) {
1617 if ( oldval < ( AM.OffsetIndex + WILDOFFSET )
1618 && indices[oldval-AM.OffsetIndex].nmin4
1620 t->allsign = - t->allsign;
1621 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1622 t = AN.tracestack + AN.numtracesctack - 1;
1624 *(t->accup)++ = SUMMEDIND;
1626 indices[oldval-AM.OffsetIndex].nmin4;
1630 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1631 t = AN.tracestack + AN.numtracesctack - 1;
1632 t->allsign = - t->allsign;
1634 *(t->accup)++ = oldval;
1635 *(t->accup)++ = oldval;
1637 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1638 t = AN.tracestack + AN.numtracesctack - 1;
1648 if ( TraceNgen(BHEAD t,number-4) )
goto TracnCall;
1649 t = AN.tracestack + AN.numtracesctack - 1;
1650 *p = one; p[1] = two;
1652 if ( oldval < ( AM.OffsetIndex + WILDOFFSET )
1653 && indices[oldval-AM.OffsetIndex].nmin4
1656 *(t->accup)++ = SUMMEDIND;
1658 indices[oldval-AM.OffsetIndex].nmin4;
1661 t->allsign = - t->allsign;
1662 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1663 t = AN.tracestack + AN.numtracesctack - 1;
1664 t->allsign = - t->allsign;
1666 *(t->accup)++ = oldval;
1667 *(t->accup)++ = oldval;
1669 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1670 t = AN.tracestack + AN.numtracesctack - 1;
1678 c = m[-1]; m[-1] = m[-2]; m[-2] = c;
1679 t->allsign = - t->allsign;
1680 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1681 t = AN.tracestack + AN.numtracesctack - 1;
1687 if ( oldval < ( AM.OffsetIndex + WILDOFFSET )
1688 && indices[oldval-AM.OffsetIndex].nmin4
1690 *(t->accup)++ = SUMMEDIND;
1692 indices[oldval-AM.OffsetIndex].nmin4;
1693 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1694 t = AN.tracestack + AN.numtracesctack - 1;
1696 t->allsign = - t->allsign;
1700 *(t->accup)++ = oldval;
1701 *(t->accup)++ = oldval;
1702 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1703 t = AN.tracestack + AN.numtracesctack - 1;
1705 t->allsign = - t->allsign;
1707 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1708 t = AN.tracestack + AN.numtracesctack - 1;
1715 *(t->accup) = oldval;
1722 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1723 t = AN.tracestack + AN.numtracesctack - 1;
1725 t->allsign = - t->allsign;
1731 if ( TraceNgen(BHEAD t,number-2) )
goto TracnCall;
1732 t = AN.tracestack + AN.numtracesctack - 1;
1735 t->allsign = oldfactor;
1738 while ( m <= stop ) *m++ = *p++;
1739 AT.WorkPointer = oldstring;
1745 }
while ( diff <= (number>>1) );
1754 termout = AT.WorkPointer;
1755 while ( ( diff = TraceNno(number,t->accup,t) ) != 0 ) {
1760 if ( p < stop )
do {
1761 if ( *p == SUBEXPRESSION && p[2] == t->num ) {
1764 do { *m++ = *p++; }
while ( p < oldstring );
1767 *m++ = AC.lUniTrace[0];
1768 *m++ = AC.lUniTrace[1];
1769 *m++ = AC.lUniTrace[2];
1770 *m++ = AC.lUniTrace[3];
1781 if ( t->accup > t->accu ) {
1783 while ( p < t->accup ) *m++ = *p++;
1784 oldstring[1] = WORDDIF(m,oldstring);
1787 do { *m++ = *p++; }
while ( p < stop );
1788 *termout = WORDDIF(m,termout);
1789 if ( ( diff ^ t->allsign ) < 0 ) m[-1] = - m[-1];
1790 if ( ( AT.WorkPointer = m ) > AT.WorkTop ) {
1791 MLOCK(ErrorMessageLock);
1793 MUNLOCK(ErrorMessageLock);
1799 if (
Generator(BHEAD termout,t->level) ) {
1800 AT.WorkPointer = termout;
1803 t = AN.tracestack + AN.numtracesctack - 1;
1808 }
while ( p < stop );
1810 AT.WorkPointer = termout;
1817 AT.WorkPointer = oldstring;
1819 if ( AM.tracebackflag ) {
1820 MLOCK(ErrorMessageLock);
1821 MesCall(
"TraceNGen");
1822 MUNLOCK(ErrorMessageLock);
1836int Traces(PHEAD WORD *term, WORD *params, WORD num, WORD level)
1839 switch ( AT.TMout[2] ) {
1841 return(TraceN(BHEAD term,params,num,level));
1843 return(Trace4(BHEAD term,params,num,level));
1845 return(Trace4(BHEAD term,params,num,level));
1847 return(Trace4(BHEAD term,params,num,level));
1858int TraceFind(PHEAD WORD *term, WORD *params)
1862 WORD *termout, *stop, *stop2, number = 0;
1864 WORD type, spinline, sp;
1866 spinline = params[4];
1867 if ( spinline < 0 ) {
1868 sp = DolToIndex(BHEAD -spinline);
1869 if ( AN.ErrorInDollar || sp < 0 ) {
1870 MLOCK(ErrorMessageLock);
1871 MesPrint(
"$%s does not have an index value in trace statement in module %l",
1872 DOLLARNAME(Dollars,-spinline),AC.CModule);
1873 MUNLOCK(ErrorMessageLock);
1888 termout = m = AT.WorkPointer;
1891 while ( p < stop ) {
1893 if ( *p == GAMMA && p[FUNHEAD] == spinline ) {
1895 *m++ = SUBEXPRESSION;
1904 while ( p < stop2 ) {
1905 if ( *p == GAMMA5 ) {
1906 if ( AT.TMout[3] == GAMMA5 ) AT.TMout[3] = GAMMA1;
1907 else if ( AT.TMout[3] == GAMMA1 ) AT.TMout[3] = GAMMA5;
1908 else if ( AT.TMout[3] == GAMMA7 ) AT.TMout[5] = -AT.TMout[5];
1909 if ( number & 1 ) AT.TMout[5] = - AT.TMout[5];
1912 else if ( *p == GAMMA6 ) {
1913 if ( number & 1 )
goto F7;
1914F6:
if ( AT.TMout[3] == GAMMA6 ) (AT.TMout[4])++;
1915 else if ( AT.TMout[3] == GAMMA1 ) AT.TMout[3] = GAMMA6;
1916 else if ( AT.TMout[3] == GAMMA5 ) AT.TMout[3] = GAMMA6;
1917 else if ( AT.TMout[3] == GAMMA7 ) AT.TMout[5] = 0;
1920 else if ( *p == GAMMA7 ) {
1921 if ( number & 1 )
goto F6;
1922F7:
if ( AT.TMout[3] == GAMMA7 ) (AT.TMout[4])++;
1923 else if ( AT.TMout[3] == GAMMA1 ) AT.TMout[3] = GAMMA7;
1924 else if ( AT.TMout[3] == GAMMA5 ) {
1925 AT.TMout[3] = GAMMA7;
1926 AT.TMout[5] = -AT.TMout[5];
1928 else if ( AT.TMout[3] == GAMMA6 ) AT.TMout[5] = 0;
1938 while ( p < stop2 ) *m++ = *p++;
1941 if ( first )
return(0);
1942 AT.TMout[0] = WORDDIF(to,AT.TMout);
1945 while ( p < to ) *m++ = *p++;
1946 *termout = WORDDIF(m,termout);
1949 do { *to++ = *p++; }
while ( p < m );
1950 AT.WorkPointer = term + *term;
1968int Chisholm(PHEAD WORD *term, WORD level)
1971 WORD *t, *r, *m, *s, *tt, *rr;
1972 WORD *mat, *matpoint, *termout, *rdo;
1973 CBUF *C = cbuf+AM.rbufnum;
1974 WORD i, j, num = C->
lhs[level][2], gam5;
1975 WORD norm = 0, k, *matp;
1979 mat = matpoint = AT.WorkPointer;
1981 r = t + *t - 1; r -= ABS(*r);
1986 if ( *t == GAMMA && t[FUNHEAD] == num ) {
1990 if ( *t >= 0 || *t < MINSPEC ) i++;
1992 if ( gam5 == GAMMA1 ) gam5 = *t;
1993 else if ( gam5 == GAMMA5 ) {
1994 if ( *t == GAMMA5 ) gam5 = GAMMA1;
1995 else if ( *t != GAMMA1 ) gam5 = *t;
2003 if ( ( i & 1 ) != 0 )
return(0);
2019 while ( s < matpoint ) {
2024 if ( *s < AM.OffsetIndex || ( *s < ( AM.OffsetIndex + WILDOFFSET ) &&
2025 indices[*s-AM.OffsetIndex].dimension != 4 )
2026 || ( ( AC.lDefDim != 4 ) && ( *s >= ( AM.OffsetIndex + WILDOFFSET ) ) ) ) {
2031 if ( *t == GAMMA && t[FUNHEAD] != num ) {
2045 if ( norm == 0 )
return(
Generator(BHEAD term,level));
2065 if ( C->
lhs[level][3] == 0 ) norm = 1;
2068 for ( k = 0; k < norm; k++ ) {
2071 while ( s < matpoint ) {
2076 if ( *s < AM.OffsetIndex || ( *s < ( AM.OffsetIndex + WILDOFFSET ) &&
2077 indices[*s-AM.OffsetIndex].dimension != 4 ) ) {
2082 if ( *t == GAMMA && t[FUNHEAD] != num ) {
2090 while ( m <= s ) *matpoint++ = *m++;
2092 while ( m < matpoint ) *t++ = *m++;
2097 if ( *t != GAMMA || t[FUNHEAD] != num ) {
2107 while ( --j >= 0 ) *m++ = *t++;
2110 while ( s < termout ) *m++ = *s++;
2113 while ( t < tt ) *m++ = *t++;
2114 rdo[1] = WORDDIF(m,rdo);
2116 *m++ = AC.lUniTrace[0];
2117 *m++ = AC.lUniTrace[1];
2118 *m++ = AC.lUniTrace[2];
2119 *m++ = AC.lUniTrace[3];
2126 if ( *t != GAMMA || t[FUNHEAD] != num ) {
2133 while ( t < rr ) *m++ = *t++;
2135 *termout = WORDDIF(m,termout);
2141 if (
Generator(BHEAD t,level) )
goto ChisCall;
2143 j = WORDDIF(termout,mat)-1;
2146 AT.WorkPointer = rr;
2148 i = *--m; *m = *t; *t++ = i;
2151 if (
Generator(BHEAD termout,level) )
goto ChisCall;
2152 AT.WorkPointer = mat;
2170 if ( AM.tracebackflag ) {
2171 MLOCK(ErrorMessageLock);
2172 MesCall(
"Chisholm");
2173 MUNLOCK(ErrorMessageLock);
2183int TenVecFind(PHEAD WORD *term, WORD *params)
2186 WORD *t, *w, *m, *tstop;
2187 WORD i, mode, thevector, thetensor, spectator;
2188 thetensor = params[3];
2189 thevector = params[4];
2191 if ( thetensor < 0 ) {
2192 thetensor = DolToTensor(BHEAD -thetensor);
2193 if ( thetensor < FUNCTION ) {
2194 if ( thevector > 0 ) {
2195 thetensor = DolToTensor(BHEAD thevector);
2196 if ( thetensor < FUNCTION ) {
2197 MLOCK(ErrorMessageLock);
2198 MesPrint(
"$%s should have been a tensor in module %l"
2199 ,DOLLARNAME(Dollars,params[4]),AC.CModule);
2200 MUNLOCK(ErrorMessageLock);
2203 thevector = DolToVector(BHEAD -params[3]);
2204 if ( thevector >= 0 ) {
2205 MLOCK(ErrorMessageLock);
2206 MesPrint(
"$%s should have been a vector in module %l"
2207 ,DOLLARNAME(Dollars,-params[3]),AC.CModule);
2208 MUNLOCK(ErrorMessageLock);
2213 MLOCK(ErrorMessageLock);
2214 MesPrint(
"$%s should have been a tensor in module %l"
2215 ,DOLLARNAME(Dollars,-params[3]),AC.CModule);
2216 MUNLOCK(ErrorMessageLock);
2221 if ( thevector > 0 ) {
2222 thevector = DolToVector(BHEAD thevector);
2223 if ( thevector >= 0 ) {
2224 MLOCK(ErrorMessageLock);
2225 MesPrint(
"$%s should have been a vector in module %l"
2226 ,DOLLARNAME(Dollars,params[4]),AC.CModule);
2227 MUNLOCK(ErrorMessageLock);
2231 if ( ( mode & 1 ) != 0 ) {
2232 GETSTOP(term,tstop);
2234 while ( t < tstop ) {
2235 if ( *t == DOTPRODUCT ) {
2236 i = t[1] - 2; t += 2;
2240 else if ( *t == thevector && t[1] == thevector ) {
2241 if ( ( mode & 2 ) == 0 ) spectator = thevector;
2243 else if ( *t == thevector ) spectator = t[1];
2244 else if ( t[1] == thevector ) spectator = *t;
2246 if ( ( mode & 8 ) == 0 )
goto match;
2247 w = SetElements + Sets[params[6]].first;
2248 m = SetElements + Sets[params[6]].last;
2250 if ( *w == spectator )
break;
2253 if ( w >= m )
goto match;
2259 else if ( *t == VECTOR ) {
2260 i = t[1] - 2; t += 2;
2262 if ( *t == thevector )
goto match;
2267 else if ( *t == thetensor ) t += t[1];
2268 else if ( *t >= FUNCTION ) {
2269 if ( functions[*t-FUNCTION].spec > 0 ) {
2273 if ( *t == thevector )
goto match;
2277 else if ( ( mode & 4 ) != 0 ) {
2281 if ( *t == -VECTOR && t[1] == thevector )
goto match;
2282 else if ( *t > 0 ) t += *t;
2283 else if ( *t <= -FUNCTION ) t++;
2293 GETSTOP(term,tstop);
2295 while ( t < tstop ) {
2296 if ( *t == thetensor )
goto match;
2303 AT.TMout[1] = TENVEC;
2304 AT.TMout[2] = thetensor;
2305 AT.TMout[3] = thevector;
2307 if ( ( mode & 8 ) != 0 ) { AT.TMout[0] = 6; AT.TMout[5] = params[6]; }
2317int TenVec(PHEAD WORD *term, WORD *params, WORD num, WORD level)
2320 WORD *t, *m, *w, *termout, *tstop, *outlist, *ou, *ww, *mm;
2321 WORD i, j, k, x, mode, thevector, thetensor, DumNow, spectator;
2323 thetensor = params[2];
2324 thevector = params[3];
2326 termout = AT.WorkPointer;
2327 DumNow = AR.CurDum = DetCurDum(BHEAD term);
2328 if ( ( mode & 1 ) != 0 ) {
2329 AT.WorkPointer += *term;
2330 ou = outlist = AT.WorkPointer;
2331 GETSTOP(term,tstop);
2334 while ( t < tstop ) {
2335 if ( *t == DOTPRODUCT ) {
2338 *m++ = *t++; *m++ = *t++;
2342 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2344 else if ( *t == thevector && t[1] == thevector ) {
2345 if ( ( mode & 2 ) == 0 ) spectator = thevector;
2347 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2350 else if ( *t == thevector ) spectator = t[1];
2351 else if ( t[1] == thevector ) spectator = *t;
2353 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2356 if ( ( mode & 8 ) == 0 )
goto noveto;
2357 ww = SetElements + Sets[params[5]].first;
2358 mm = SetElements + Sets[params[5]].last;
2360 if ( *ww == spectator )
break;
2364 *m++ = *t++; *m++ = *t++; *m++ = *t++;
2367noveto:
if ( spectator == thevector ) {
2368 for ( j = 0; j < t[2]; j++ ) {
2369 *ou++ = ++AR.CurDum;
2375 for ( j = 0; j < t[2]; j++ ) *ou++ = spectator;
2381 w[1] = WORDDIF(m,w);
2382 if ( w[1] == 2 ) m = w;
2384 else if ( *t == VECTOR ) {
2385 i = t[1] - 2; w = m;
2386 *m++ = *t++; *m++ = *t++;
2388 if ( *t == thevector ) {
2392 else { *m++ = *t++; *m++ = *t++; }
2395 w[1] = WORDDIF(m,w);
2396 if ( w[1] == 2 ) m = w;
2398 else if ( *t == thetensor ) {
2403 else if ( *t >= FUNCTION ) {
2404 if ( functions[*t-FUNCTION].spec > 0 ) {
2409 if ( *t == thevector ) {
2417 else if ( ( mode & 4 ) != 0 ) {
2422 if ( *t == -VECTOR && t[1] == thevector ) {
2428 else if ( *t > 0 ) {
2432 else if ( *t <= -FUNCTION ) *m++ = *t++;
2433 else { *m++ = *t++; *m++ = *t++; }
2444 i = WORDDIF(ou,outlist);
2446 for ( j = 1; j < i; j++ ) {
2447 if ( outlist[j-1] > outlist[j] ) {
2448 x = outlist[j-1]; outlist[j-1] = outlist[j]; outlist[j] = x;
2449 for ( k = j-1; k > 0; k-- ) {
2450 if ( outlist[k-1] <= outlist[k] )
break;
2451 x = outlist[k-1]; outlist[k-1] = outlist[k]; outlist[k] = x;
2458 *m++ = DIRTYSYMFLAG;
2464 while ( t < w ) *m++ = *t++;
2467 GETSTOP(term,tstop);
2470 while ( t < tstop ) {
2471 if ( *t != thetensor ) {
2480 while ( --i >= 0 ) {
2485 w[1] = WORDDIF(m,w);
2490 while ( t < w ) *m++ = *t++;
2492 *termout = WORDDIF(m,termout);
2495 if (
Generator(BHEAD termout,level) )
goto fromTenVec;
2497 AT.WorkPointer = termout;
2500 if ( AM.tracebackflag ) {
2501 MLOCK(ErrorMessageLock);
2503 MUNLOCK(ErrorMessageLock);
int Generator(PHEAD WORD *, WORD)