65WORD WildFill(PHEAD WORD *to, WORD *from, WORD *sub)
68 WORD i, j, *s, *t, *m, len, dflag, odirt, adirt;
69 WORD *r, *u, *v, *w, *z, *zst, *zz, *subs, *accu, na, dirty = 0, *tstop;
70 WORD *temp = 0, *uu, *oldcpointer, sgn;
71 WORD subcount, setflag, *setlist = 0, si;
72 accu = oldcpointer = AR.CompressPointer;
77 while ( s < t && *s != FROMBRAC ) {
83 if ( dirty ) AN.WildDirt = dirty;
87 subs = sub + SUBEXPSIZE;
107 for ( si = 0; si < setflag; si += 2 ) {
108 if ( t == temp + setlist[si] )
goto sspow;
111 for ( j = 0; j < i; j++ ) {
113 if ( *s == SYMTOSYM ) {
114 *m = s[3]; dirty = 1;
117 else if ( *s == SYMTONUM ) {
125 if ( ABS(*t) >= 2*MAXPOWER) {
127 for ( j = 0; j < i; j++ ) {
128 if ( ( *s == SYMTONUM ) &&
129 ( ABS(*t) - 2*MAXPOWER ) == s[2] ) {
132 if ( *t < 0 ) *w = -*w;
135 if ( ( *s == SYMTOSYM ) &&
136 ( ABS(*t) - 2*MAXPOWER ) == s[2] ) {
139 while ( --zz >= zst ) {
140 zz[1+FUNHEAD+ARGHEAD] = *zz;
142 w += 1+FUNHEAD+ARGHEAD;
145 zst[FUNHEAD+ARGHEAD] = WORDDIF(z,zst)+4;
147 zst[FUNHEAD] = WORDDIF(z,zst)+4+ARGHEAD;
148 z += FUNHEAD+ARGHEAD+1;
169 zst[1] = WORDDIF(z,zst);
172 if ( *s == SYMTOSUB &&
173 ( ABS(*t) - 2*MAXPOWER ) == s[2] ) {
176 while ( --zz >= zst ) {
177 zz[1+FUNHEAD+ARGHEAD] = *zz;
179 w += 1+FUNHEAD+ARGHEAD;
182 zst[FUNHEAD+ARGHEAD] = WORDDIF(z,zst)+4;
184 zst[FUNHEAD] = WORDDIF(z,zst)+4+ARGHEAD;
185 z += FUNHEAD+ARGHEAD+1;
190 *z++ = 4+SUBEXPSIZE+ARGHEAD;
193 *z++ = SUBEXPRESSION;
201 *z++ = *t > 0 ? 3: -3;
202 zst[1] = WORDDIF(z,zst);
208 if ( !*w ) z = w - 3;
212 else if ( *s == SYMTOSUB ) {
215 *z++ = SUBEXPRESSION;
230 for ( si = 0; si < setflag; si += 2 ) {
231 if ( t == temp + setlist[si] ) {
236 for ( j = 0; j < i; j++ ) {
237 if ( ( ABS(*t) - 2*MAXPOWER ) == s[2] ) {
238 if ( *s == SYMTONUM ) {
241 if ( *t < 0 ) *m = -*m;
244 else if ( *s == SYMTOSYM ) {
247 if ( *t < 0 ) *z++ = FUNHEAD+ARGHEAD+10;
248 else *z++ = 4+FUNHEAD;
272 else if ( *s == SYMTOSUB ) {
293 while ( s < z ) *m++ = *s++;
310 for ( si = 0; si < setflag; si += 2 ) {
311 if ( t == temp + setlist[si] )
goto ss2;
314 for ( j = 0; j < i; j++ ) {
316 if ( *s == VECTOVEC ) {
317 *m = s[3]; dirty = 1;
break;
319 if ( *s == VECTOMIN ) {
322 if ( ( ABS(t[2]) - 2*MAXPOWER ) < 0 ) {
332 if ( *s == VECTOSUB ) {
333 *m = s[3]; dirty = 1; subcount = 1;
break;
342 for ( si = 0; si < setflag; si += 2 ) {
343 if ( t == temp + setlist[si] )
goto ss3;
345 for ( j = 0; j < i; j++ ) {
347 if ( *s == VECTOVEC ) {
348 *m = s[3]; dirty = 1;
break;
350 if ( *s == VECTOMIN ) {
353 if ( ( ABS(t[1]) - 2*MAXPOWER ) < 0 ) {
363 if ( *s == VECTOSUB ) {
364 *m = s[3]; dirty = 1; subcount += 2;
break;
371 if ( ( ABS(*t) - 2*MAXPOWER ) < 0 )
goto RegPow;
373 for ( j = 0; j < i; j++ ) {
374 if ( ( ABS(*t) - 2*MAXPOWER ) == s[2] ) {
375 if ( *s == SYMTONUM ) {
382 if ( *t < 0 ) *m = -*m;
386 if ( *s <= SYMTOSUB ) {
394 if ( subcount == 0 ) {
395 *z++ = 17+FUNHEAD+2*ARGHEAD;
410 if ( *s == SYMTOSYM ) {
421 *z++ = 4+SUBEXPSIZE+ARGHEAD;
425 *z++ = SUBEXPRESSION;
433 *z++ = ( s[2] > 0 ) ? 3: -3;
435 else if ( subcount == 3 ) {
436 *z++ = 20+2*SUBEXPSIZE+FUNHEAD+2*ARGHEAD;
439 *z++ = 12+2*SUBEXPSIZE+ARGHEAD;
441 *z++ = 12+2*SUBEXPSIZE;
442 *z++ = SUBEXPRESSION;
453 *z++ = SUBEXPRESSION;
463 *z++ = 1; *z++ = 1; *z++ = 3;
466 if ( subcount == 2 ) {
467 j = *m; *m = m[1]; m[1] = j;
469 *z++ = 16+SUBEXPSIZE+FUNHEAD+2*ARGHEAD;
472 *z++ = 8+SUBEXPSIZE+ARGHEAD;
475 *z++ = SUBEXPRESSION;
485 *z++ = 1; *z++ = 1; *z++ = 3;
487 if ( *s == SYMTOSYM ) {
504 *z++ = 4+SUBEXPSIZE+ARGHEAD;
507 *z++ = SUBEXPRESSION;
515 *z++ = ( s[2] > 0 ) ? 3: -3;
523RegPow:
if ( *m ) m++;
524 else { m -= 2; subcount = 0; }
528 if ( subcount == 3 ) {
530 j = (-m[2]) * (2*SUBEXPSIZE+8);
532 *z++ = j + 8 + FUNHEAD + ARGHEAD;
535 *z++ = j + 8 + ARGHEAD;
540 *z++ = SUBEXPRESSION;
550 *z++ = SUBEXPRESSION;
565 *z++ = 1; *z++ = 1; *z++ = 3;
570 *z++ = SUBEXPRESSION;
580 *z++ = SUBEXPRESSION;
594 if ( subcount == 2 ) {
595 j = *m; *m = m[1]; m[1] = j;
599 *z++ = 8+SUBEXPSIZE+FUNHEAD+ARGHEAD;
602 *z++ = 8+SUBEXPSIZE+ARGHEAD;
606 *z++ = SUBEXPRESSION;
617 *z++ = 1; *z++ = 1; *z++ = 3;
623 if ( m <= v ) m = v - 2;
624 else v[-1] = WORDDIF(m,v) + 2;
638 temp = accu + (((AR.ComprTop - accu)>>1)&(-2));
639 if ( ResolveSet(BHEAD t,temp,sub) ) {
642 setlist = t + 2 + t[3];
643 setflag = t[1] - 2 - t[3];
644 t = temp; u = t + t[1];
659 for ( si = 0; si < setflag; si += 2 ) {
660 if ( t == temp + setlist[si] )
goto ss4;
663 for ( j = 0; j < i; j++ ) {
665 if ( *s == INDTOIND || *s == VECTOVEC ) {
666 *m = s[3]; dirty = 1;
break;
668 if ( *s == VECTOMIN ) {
669 *m = s[3]; dirty = 1; sgn++;
break;
671 else if ( *s == VECTOSUB ) {
672 *z++ = SUBEXPRESSION;
684 for ( j = 0; j < i; j++ ) {
685 if ( z[-1] == s[2] ) {
686 if ( *s == INDTOIND || *s == VECTOVEC ) {
690 if ( *s == INDTOSUB || *s == VECTOSUB ) {
692 *z++ = SUBEXPRESSION;
698 if ( *s == INDTOSUB ) *z++ = INDTOIND;
699 else *z++ = VECTOSUB;
711 else if ( *s == INDTOSUB ) {
712 *z++ = SUBEXPRESSION;
732 if ( m <= v ) m = v-2;
733 else v[-1] = WORDDIF(m,v)+2;
735 j = WORDDIF(z,accu); z = accu;
752 for ( si = 0; si < setflag; si += 2 ) {
753 if ( t == temp + setlist[si] )
goto ss5;
756 for ( j = 0; j < i; j++ ) {
758 if ( *s == INDTOIND || *s == VECTOVEC )
759 { *m = s[3]; dirty = 1;
break; }
760 if ( *s == VECTOMIN )
761 { *m = s[3]; dirty = 1; sgn++;
break; }
762 else if ( *s == VECTOSUB || *s == INDTOSUB ) {
763 *z++ = SUBEXPRESSION;
778 if ( m <= v ) m = v-2;
779 else v[-1] = WORDDIF(m,v)+2;
781 j = WORDDIF(z,accu); z = accu;
798 if ( t[-2] != DELTA ) *m++ = *t++;
805 for ( si = 0; si < setflag; si += 2 ) {
806 if ( t == temp + setlist[si] )
goto ss6;
809 if ( *m == FUNNYWILD ) {
810 CBUF *C = cbuf+AT.ebufnum;
812 for ( j = 0; j < i; j++ ) {
813 if ( *s == ARGTOARG && *t == s[2] ) {
819DEBUG(MesPrint(
"Thread %w(a): s[3] = %d, w=(%d,%d,%d,%d)",s[3],w[0],w[1],w[2],w[3]);)
826 if ( *w == -INDEX || *w == -VECTOR
828 || ( *w == -SNUMBER && w[1] >= 0
829 && w[1] < AM.OffsetIndex ) ) {
830 if ( *w == -MINVECTOR ) sgn++;
835 MLOCK(ErrorMessageLock);
836DEBUG(MesPrint(
"Thread %w(aa): *w = %d",*w);)
837 MesPrint(
"Illegal substitution of argument field in tensor");
838 MUNLOCK(ErrorMessageLock);
850 for ( j = 0; j < i; j++ ) {
852 if ( *s == INDTOIND || *s == VECTOVEC )
853 { *m = s[3]; dirty = 1;
break; }
854 if ( *s == VECTOMIN )
855 { *m = s[3]; dirty = 1; sgn++;
break; }
856 else if ( *s == VECTOSUB || *s == INDTOSUB ) {
858 *z++ = SUBEXPRESSION;
874 if ( j < i && *v != DELTA ) v[2] |= DIRTYFLAG;
880 j = WORDDIF(z,accu); z = accu;
897 if ( t[-1] >= 2*MAXPOWER || t[-1] <= -2*MAXPOWER ) {
899 for ( j = 0; j < i; j++ ) {
900 if ( *s == SYMTONUM &&
901 ( ABS(t[-1]) - 2*MAXPOWER ) == s[2] ) {
903 if ( t[-1] < 0 ) m[-1] = -m[-1];
911 while ( t < tstop ) {
912 for ( si = 0; si < setflag; si += 2 ) {
913 if ( t == temp + setlist[si] - 2 )
goto ss7;
916 for ( j = 0; j < i; j++ ) {
917 if ( s[2] == t[2] ) {
918 if ( ( *s <= SYMTOSUB && *t <= SYMTOSUB )
919 || ( *s == *t && *s < FROMBRAC )
920 || ( *s == VECTOVEC && ( *t == VECTOSUB || *t == VECTOMIN ) )
921 || ( *s == VECTOSUB && ( *t == VECTOVEC || *t == VECTOMIN ) )
922 || ( *s == VECTOMIN && ( *t == VECTOSUB || *t == VECTOVEC ) )
923 || ( *s == INDTOIND && *t == INDTOSUB )
924 || ( *s == INDTOSUB && *t == INDTOIND ) ) {
956 for ( j = 0; j < i; j++ ) {
957 if ( ( ABS(t[-1]) - 2*MAXPOWER ) == s[2] ) {
958 if ( *s == SYMTONUM ) {
960 if ( t[-1] < 0 ) m[-1] = -m[-1];
963 else if ( *s <= SYMTOSUB ) {
964 MLOCK(ErrorMessageLock);
965 MesPrint(
"Wildcard power of expression should be a number");
966 MUNLOCK(ErrorMessageLock);
974 while ( t < tstop && *t != WILDCARDS ) {
978 if ( t < tstop && *t == WILDCARDS ) {
986 if ( t < tstop && *t == FROMBRAC ) {
990 if ( WildFill(BHEAD m,t+2,sub) < 0 ) {
991 MLOCK(ErrorMessageLock);
993 MUNLOCK(ErrorMessageLock);
1000 while ( t < tstop ) {
1013 if ( *t >= FUNCTION ) {
1017 for ( si = 0; si < setflag; si += 2 ) {
1018 if ( t == temp + setlist[si] ) {
1019 dflag = DIRTYFLAG;
goto ss8;
1023 for ( j = 0; j < i; j++ ) {
1024 if ( *s == FUNTOFUN && *t == s[2] )
1025 { *m = s[3]; dirty = 1; dflag = DIRTYFLAG;
break; }
1029 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
1030 >= TENSORFUNCTION ) {
1031 if ( *m < FUNCTION || functions[*m-FUNCTION].spec
1032 < TENSORFUNCTION ) {
1033 MLOCK(ErrorMessageLock);
1034 MesPrint(
"Illegal wildcarding of regular function to tensorfunction");
1035 MUNLOCK(ErrorMessageLock);
1040 *m++ = *t++ | dflag;
1045 *m++ = *t++ | dflag;
1053 CBUF *C = cbuf+AT.ebufnum;
1054 for ( si = 0; si < setflag; si += 2 ) {
1055 if ( *t <= -FUNCTION ) {
1056 if ( t == temp + setlist[si] ) {
1057 v[2] |= DIRTYFLAG;
goto ss10; }
1060 if ( t == temp + setlist[si]-1 ) {
1061 v[2] |= DIRTYFLAG;
goto ss9; }
1064 if ( *t == -ARGWILD ) {
1066 for ( j = 0; j < i; j++ ) {
1067 if ( *s == ARGTOARG && s[2] == t[1] )
break;
1072DEBUG(MesPrint(
"Thread %w(b): s[3] = %d, w=(%d,%d,%d,%d)",s[3],w[0],w[1],w[2],w[3]);)
1076 if ( *w > 0 ) j = *w;
1077 else if ( *w <= -FUNCTION ) j = 1;
1084 while ( --j >= 0 ) {
1085 if ( *w < MINSPEC ) *m++ = -VECTOR;
1086 else if ( *w >= 0 && *w < AM.OffsetIndex )
1094 if ( ( *v == NUMARGSFUN || *v == NUMTERMSFUN )
1095 && t >= u && m == v + FUNHEAD ) {
1097 *m++ = SNUMBER; *m++ = 3; *m++ = 0;
1101 else if ( *t <= -FUNCTION ) {
1104 for ( j = 0; j < i; j++ ) {
1105 if ( -*t == s[2] ) {
1106 if ( *s == FUNTOFUN )
1107 { *m = -s[3]; dirty = 1; v[2] |= DIRTYFLAG;
break; }
1113 else if ( *t == -SYMBOL ) {
1117 for ( j = 0; j < i; j++ ) {
1118 if ( *t == s[2] && *s <= SYMTOSUB ) {
1119 dirty = 1; v[2] |= DIRTYFLAG;
1120 if ( AR.PolyFunType == 2 && v[0] == AR.PolyFun )
1121 v[2] |= MUSTCLEANPRF;
1122 if ( *s == SYMTOSYM ) *m = s[3];
1123 else if ( *s == SYMTONUM ) {
1127 else if ( *s == SYMTOSUB ) {
1130DEBUG(MesPrint(
"Thread %w(c): s[3] = %d, w=(%d,%d,%d,%d)",s[3],w[0],w[1],w[2],w[3]);)
1140 if ( t[-1] == -MINVECTOR ) {
1147 if ( ToFast(s,s) ) {
1148 if ( *s <= -FUNCTION ) m = s;
1159 else if ( *t == -INDEX ) {
1163 for ( j = 0; j < i; j++ ) {
1165 if ( *s == INDTOIND || *s == VECTOVEC ) {
1167 if ( *m < MINSPEC ) m[-1] = -VECTOR;
1168 else if ( *m >= 0 && *m < AM.OffsetIndex )
1170 else m[-1] = -INDEX;
1172 else if ( *s == VECTOSUB || *s == INDTOSUB ) {
1175 *z++ = SUBEXPRESSION;
1176 *z++ = 4+SUBEXPSIZE;
1186 v[2] |= DIRTYFLAG; dirty = 1;
1193 else if ( *t == -VECTOR || *t == -MINVECTOR ) {
1197 for ( j = 0; j < i; j++ ) {
1199 if ( *s == VECTOVEC ) *m = s[3];
1200 else if ( *s == VECTOMIN ) {
1202 if ( t[-1] == -VECTOR )
1207 else if ( *s == VECTOSUB )
goto ToSub;
1208 dirty = 1; v[2] |= DIRTYFLAG;
1215 else if ( *t == -SNUMBER ) {
1219 for ( j = 0; j < i; j++ ) {
1220 if ( *t == s[2] && *s >= NUMTONUM && *s <= NUMTOSUB ) {
1221 dirty = 1; v[2] |= DIRTYFLAG;
1222 if ( *s == NUMTONUM ) *m = s[3];
1223 else if ( *s == NUMTOSYM ) {
1227 else if ( *s == NUMTOIND ) {
1231 else if ( *s == NUMTOSUB )
goto ToSub;
1242 na = WORDDIF(z,accu);
1251 odirt = AN.WildDirt; AN.WildDirt = 0;
1252 AR.CompressPointer = accu + na;
1253 for ( j = 0; j < ARGHEAD; j++ ) *m++ = *t++;
1257 if ( ( len = WildFill(BHEAD m,t,sub) ) < 0 ) {
1258 MLOCK(ErrorMessageLock);
1259 MesCall(
"WildFill");
1260 MUNLOCK(ErrorMessageLock);
1263 if ( AN.WildDirt ) {
1264 adirt = AN.WildDirt;
1272 dirty = w[1] = 1; v[2] |= DIRTYFLAG;
1273 if ( AR.PolyFunType == 2 && v[0] == AR.PolyFun )
1274 v[2] |= MUSTCLEANPRF;
1275 AN.WildDirt = adirt;
1278 AN.WildDirt = odirt;
1280 if ( ToFast(w,w) ) {
1281 if ( *w <= -FUNCTION ) {
1282 if ( *w == NUMARGSFUN || *w == NUMTERMSFUN ) {
1283 *w = -SNUMBER; w[1] = 0; m = w + 2;
1289 AR.CompressPointer = oldcpointer;
1292 v[1] = WORDDIF(m,v);
1298 if ( v[0] == EXPONENT ) {
1299 if ( v[1] == FUNHEAD+4 && v[FUNHEAD] == -SYMBOL &&
1300 v[FUNHEAD+2] == -SNUMBER && v[FUNHEAD+3] < MAXPOWER
1301 && v[FUNHEAD+3] > -MAXPOWER ) {
1304 v[2] = v[FUNHEAD+1];
1305 v[3] = v[FUNHEAD+3];
1308 else if ( v[1] == FUNHEAD+ARGHEAD+11
1309 && v[FUNHEAD] == ARGHEAD+9
1310 && v[FUNHEAD+ARGHEAD] == 9
1311 && v[FUNHEAD+ARGHEAD+1] == DOTPRODUCT
1312 && v[FUNHEAD+ARGHEAD+8] == 3
1313 && v[FUNHEAD+ARGHEAD+7] == 1
1314 && v[FUNHEAD+ARGHEAD+6] == 1
1315 && v[FUNHEAD+ARGHEAD+5] == 1
1316 && v[FUNHEAD+ARGHEAD+9] == -SNUMBER
1317 && v[FUNHEAD+ARGHEAD+10] < MAXPOWER
1318 && v[FUNHEAD+ARGHEAD+10] > -MAXPOWER ) {
1321 v[2] = v[FUNHEAD+ARGHEAD+3];
1322 v[3] = v[FUNHEAD+ARGHEAD+4];
1323 v[4] = v[FUNHEAD+ARGHEAD+10];
1328 else {
while ( t < u ) *m++ = *t++; }
1337 if ( r < t )
do { *m++ = *r++; }
while ( r < t );
1338 if ( ( sgn & 1 ) != 0 ) m[-1] = -m[-1];
1339 *to = WORDDIF(m,to);
1340 if ( dirty ) AN.WildDirt = dirty;
1361int ResolveSet(PHEAD WORD *from, WORD *to, WORD *subs)
1364 WORD *m, *s, *w, j, i, ii, i3, flag, num;
1367 int nummodopt, dtype = -1;
1372 while ( s < w ) *m++ = *s++;
1373 j = (from[1] - WORDDIF(w,from) ) >> 1;
1378 while ( s < m ) { i++; s += s[1]; }
1380 if ( *m >= FUNCTION && functions[*m-FUNCTION].spec
1381 >= TENSORFUNCTION ) flag = 0;
1383 while ( --j >= 0 ) {
1386 for ( ii = 0; ii < i; ii++ ) {
1387 if ( *s == SYMTONUM && s[2] == w[1] ) { num = s[3];
goto GotOne; }
1390 MLOCK(ErrorMessageLock);
1391 MesPrint(
" Unresolved setelement during substitution");
1392 MUNLOCK(ErrorMessageLock);
1398 if ( AS.MultiThreaded ) {
1399 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1400 if ( -w[1] == ModOptdollars[nummodopt].number )
break;
1402 if ( nummodopt < NumModOptdollars ) {
1403 dtype = ModOptdollars[nummodopt].type;
1404 if ( dtype == MODLOCAL ) {
1405 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1408 LOCK(d->pthreadslock);
1413 if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
1414 if ( d->where[0] == 4 && d->where[3] == 3 && d->where[2] == 1
1415 && d->where[1] > 0 && d->where[4] == 0 ) {
1416 num = d->where[1];
goto GotOne;
1419 else if ( d->type == DOLINDEX ) {
1420 if ( d->index > 0 && d->index < AM.OffsetIndex ) {
1421 num = d->index;
goto GotOne;
1424 else if ( d->type == DOLARGUMENT ) {
1425 if ( d->where[0] == -SNUMBER && d->where[1] > 0 ) {
1426 num = d->where[1];
goto GotOne;
1429 else if ( d->type == DOLWILDARGS ) {
1430 if ( d->where[0] == 1 &&
1431 d->where[1] > 0 && d->where[1] < AM.OffsetIndex ) {
1432 num = d->where[1];
goto GotOne;
1434 if ( d->where[0] == 0 && d->where[1] < 0 && d->where[3] == 0 ) {
1435 if ( ( d->where[1] == -SNUMBER && d->where[2] > 0 )
1436 || ( d->where[1] == -INDEX && d->where[2] > 0
1437 && d->where[2] < AM.OffsetIndex ) ) {
1438 num = d->where[2];
goto GotOne;
1443 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1445 MLOCK(ErrorMessageLock);
1446 MesPrint(
"Unusable type of variable $%s in set substitution",
1447 AC.dollarnames->namebuffer+d->name);
1448 MUNLOCK(ErrorMessageLock);
1453 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
1456 if ( ii >= 2*MAXPOWER ) i3 = ii - 2*MAXPOWER;
1457 else if ( ii <= -2*MAXPOWER ) i3 = -ii - 2*MAXPOWER;
1458 else i3 = ( ii >= 0 ) ? ii: -ii - 1;
1460 if ( num > ( Sets[i3].last - Sets[i3].first ) || num <= 0 ) {
1461 MLOCK(ErrorMessageLock);
1462 MesPrint(
"Array bound check during set substitution");
1463 MesPrint(
" value is %d",num);
1464 MUNLOCK(ErrorMessageLock);
1467 m[*w] = (SetElements+Sets[i3].first)[num-1];
1468 if ( Sets[i3].type == CSYMBOL && m[*w] > MAXPOWER ) {
1469 if ( ii >= 2*MAXPOWER ) m[*w] -= 2*MAXPOWER;
1470 else if ( ii <= -2*MAXPOWER ) m[*w] = -(m[*w] - 2*MAXPOWER);
1473 if ( m[*w] < MAXPOWER ) m[*w] -= 2*MAXPOWER;
1474 if ( flag ) MakeDirty(m,m+*w,1);
1477 else if ( Sets[i3].type == CSYMBOL ) {
1478 if ( ii >= 2*MAXPOWER ) m[*w] += 2*MAXPOWER;
1479 else if ( ii <= -2*MAXPOWER ) m[*w] = -m[*w] - 2*MAXPOWER;
1480 else if ( ii < 0 ) m[*w] = - m[*w];
1482 else if ( ii < 0 ) m[*w] = - m[*w];
1486 if ( *m >= FUNCTION && functions[*m-FUNCTION].spec
1487 >= TENSORFUNCTION ) {
1488 w = from + 2 + from[3];
1490 m = from + 2 + FUNHEAD; s = to + FUNHEAD;
1492 if ( *m == -INDEX || *m == -VECTOR ) {}
1493 else if ( *m == -ARGWILD ) { *s++ = FUNNYWILD; }
1495 MLOCK(ErrorMessageLock);
1496 MesPrint(
"Illegal argument in tensor after set substitution");
1497 MUNLOCK(ErrorMessageLock);
1503 to[1] = WORDDIF(s,to);
1518void ClearWild(PHEAD0)
1522 n = (AN.WildValue[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
1523 AN.NumWild = nn = n;
1526 do { *w++ = 0; }
while ( --n > 0 );
1529 if ( *w == SYMTONUM ) *w = SYMTOSYM;
1531 }
while ( --nn > 0 );
1544int AddWild(PHEAD WORD oldnumber, WORD type, WORD newnumber)
1547 WORD *w, *m, n, k, i = -1;
1548 CBUF *C = cbuf+AT.ebufnum;
1549 WORD eattensor = type & EATTENSOR;
1550 type = type & ~EATTENSOR;
1556 if ( n <= 0 ) {
return(-1); }
1557 if ( type <= SYMTOSUB ) {
1559 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1560 if ( n > 1 && w[4] == SETTONUM ) i = w[7];
1562 if ( *m != 2 ) *m = 1;
1563 if ( type != SYMTOSUB ) {
1564 if ( type == SYMTONUM ) AN.MaskPointer = m;
1568 m =
AddRHS(AT.ebufnum,1);
1575 while ( --n >= 0 ) *m++ = *w++;
1577 C->
rhs[C->numrhs+1] = m;
1578DEBUG(MesPrint(
"Thread %w(d): m=(%d,%d,%d,%d)(%d)",mm[0],mm[1],mm[2],mm[3],C->numrhs);)
1583 }
while ( --n > 0 );
1585 else if ( type == ARGTOARG ) {
1587 if ( w[2] == oldnumber && *w == ARGTOARG ) {
1589 m =
AddRHS(AT.ebufnum,1);
1599 while ( --newnumber >= 0 ) { NEXTARG(w) }
1600 n = WORDDIF(w,AN.argaddress);
1605DEBUG(
if ( mm != m-1 ) MesPrint(
"Thread %w(e): Alarm!"); mm = m-1;)
1606 while ( --n >= 0 ) *m++ = *w++;
1608 C->
rhs[C->numrhs+1] = m;
1610DEBUG(MesPrint(
"Thread %w(e): w=(%d,%d,%d,%d)(%d)",mm[0],mm[1],mm[2],mm[3],C->numrhs);)
1614 }
while ( --n > 0 );
1616 else if ( type == ARLTOARL ) {
1618 if ( w[2] == oldnumber && *w == ARGTOARG ) {
1621 m =
AddRHS(AT.ebufnum,1);
1624 a = (WORD **)(AN.argaddress); n = 0; k = newnumber;
1625 while ( --newnumber >= 0 ) {
1627 if ( *w > 0 ) n += *w;
1628 else if ( *w <= -FUNCTION ) n++;
1633DEBUG(
if ( mm != m-1 ) MesPrint(
"Thread %w(f): Alarm!"); mm = m-1;)
1634 a = (WORD **)(AN.argaddress);
1635 while ( --k >= 0 ) {
1637 if ( *w > 0 ) { n = *w; NCOPY(m,w,n); }
1638 else if ( *w <= -FUNCTION ) *m++ = *w++;
1639 else { *m++ = *w++; *m++ = *w++; }
1642 C->
rhs[C->numrhs+1] = m;
1643DEBUG(MesPrint(
"Thread %w(f): w=(%d,%d,%d,%d)(%d)",mm[0],mm[1],mm[2],mm[3],C->numrhs);)
1648 }
while ( --n > 0 );
1650 else if ( type == VECTOSUB || type == INDTOSUB ) {
1651 WORD *ss, *sstop, *tt, *ttstop, j, *v1, *v2 = 0;
1653 if ( w[2] == oldnumber && ( *w == type ||
1654 ( type == VECTOSUB && ( *w == VECTOVEC || *w == VECTOMIN ) )
1655 || ( type == INDTOSUB && *w == INDTOIND ) ) ) {
1656 if ( n > 1 && w[4] == SETTONUM ) i = w[7];
1659 m =
AddRHS(AT.ebufnum,1);
1665 while ( --n >= 0 ) *m++ = *w++;
1667 C->
rhs[C->numrhs+1] = m;
1669 m =
AddRHS(AT.ebufnum,1);
1675 while ( w < sstop ) {
1676 tt = w + *w; ttstop = tt - ABS(tt[-1]);
1678 while ( w < ttstop ) {
1679 if ( *w != INDEX ) {
1688 while ( --j >= 0 ) {
1689 if ( *w >= MINSPEC ) *m++ = *w++;
1694 if ( j <= 2 ) m -= 2;
1703 while ( w < tt ) *m++ = *w++;
1704 *ss = WORDDIF(m,ss);
1707 C->
rhs[C->numrhs+1] = m;
1710 MLOCK(ErrorMessageLock);
1711 MesPrint(
"Internal problems with extra compiler buffer");
1712 MUNLOCK(ErrorMessageLock);
1718 }
while ( --n > 0 );
1722 if ( w[2] == oldnumber && ( *w == type || ( type == VECTOVEC
1723 && ( *w == VECTOMIN || *w == VECTOSUB ) ) || ( type == VECTOMIN
1724 && ( *w == VECTOVEC || *w == VECTOSUB ) )
1725 || ( type == INDTOIND && *w == INDTOSUB ) ) ) {
1726 if ( n > 1 && w[4] == SETTONUM ) i = w[7];
1733 }
while ( --n > 0 );
1735 MLOCK(ErrorMessageLock);
1736 MesPrint(
"Bug in AddWild.");
1737 MUNLOCK(ErrorMessageLock);
1744 while ( --n >= 0 ) {
1745 if ( w[2] == i && *w == SYMTONUM ) {
1751 MLOCK(ErrorMessageLock);
1752 MesPrint(
" Bug in AddWild with passing set[i]");
1753 MUNLOCK(ErrorMessageLock);
1791int CheckWild(PHEAD WORD oldnumber, WORD type, WORD newnumber, WORD *newval)
1794 WORD *w, *m, *s, n, old2, inset;
1795 WORD n2, oldval, dirty, i, j;
1796 int notflag = 0, retblock = 0;
1797 CBUF *C = cbuf+AT.ebufnum;
1798 WORD eattensor = type & EATTENSOR;
1799 type = type & ~EATTENSOR;
1803 if ( n <= 0 ) { AN.oldtype = -1; AN.WildReserve = 0;
return(-1); }
1806 *newval = newnumber;
1808 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1810 if ( !*m )
goto TestSet;
1812 if ( *w == SYMTONUM && w[3] == newnumber ) {
1815 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
1818 }
while ( --n > 0 );
1821 *newval = newnumber;
1823 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1825 if ( *w == SYMTOSYM ) {
1826 if ( !*m )
goto TestSet;
1827 if ( newnumber >= 0 && (w+4) < AN.WildStop
1828 && ( w[4] == FROMSET || w[4] == SETTONUM )
1829 && w[7] >= 0 )
goto TestSet;
1830 if ( w[3] == newnumber )
return(0);
1833 if ( !*m )
goto TestSet;
1838 }
while ( --n > 0 );
1848 WORD *ss, *sstop, *tt, *ttstop;
1852 while ( ss < sstop ) {
1854 ttstop = tt - ABS(tt[-1]);
1856 while ( ss < ttstop ) {
1857 if ( *ss == INDEX )
goto NoMatch;
1864 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1866 if ( *w == SYMTONUM || *w == SYMTOSYM ) {
1869 if ( s >= AN.WildStop || *s != SETTONUM )
1873 else if ( *w == SYMTOSUB ) {
1876 if ( s >= AN.WildStop || *s != SETTONUM )
1882 if ( (C->
rhs[w[3]+1] - m - 1) == n ) {
1884 if ( *m != *newval ) {
1885 m++; newval++;
break;
1890 if ( n <= 0 )
return(0);
1893 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
1896 }
while ( --n > 0 );
1900 if ( w[2] == oldnumber && *w == ARGTOARG ) {
1901 if ( !*m )
return(0);
1908 while ( --n >= 0 ) {
1909 if ( *m != *newval ) {
1910 m++; newval++;
break;
1914 if ( n < 0 )
return(0);
1919 while ( --n >= 0 ) {
1920 if ( *newval != m[1] || ( *m != -INDEX
1921 && *m != -VECTOR && *m != -SNUMBER ) )
break;
1925 if ( n < 0 && *m == 0 )
return(0);
1933 while ( --i >= 0 ) {
1934 if ( *m != newval[1]
1935 || ( *newval != -VECTOR
1936 && *newval != -INDEX
1937 && *newval != -SNUMBER ) )
break;
1941 if ( i < 0 )
return(0);
1947 while ( --i >= 0 ) { NEXTARG(s) }
1948 n = WORDDIF(s,newval);
1949 while ( --n >= 0 ) {
1950 if ( *m != *newval ) {
1951 m++; newval++;
break;
1955 if ( n < 0 && *m == 0 )
return(0);
1958 AN.oldtype = *w; AN.oldvalue = w[3];
goto NoMatch;
1961 }
while ( --n > 0 );
1965 if ( w[2] == oldnumber && *w == ARGTOARG ) {
1967 if ( !*m )
return(0);
1970 a = (WORD **)newval;
1974 while ( --i >= 0 ) {
1979 && *s != -SNUMBER ) )
break;
1982 if ( i < 0 )
return(0);
1987 while ( --i >= 0 ) {
1991 while ( --n >= 0 ) {
1997 if ( n >= 0 )
break;
1999 else if ( *s <= -FUNCTION ) {
2016 if ( i < 0 && *m == 0 )
return(0);
2018 AN.oldtype = *w; AN.oldvalue = w[3];
goto NoMatch;
2021 }
while ( --n > 0 );
2032 WORD *ss, *sstop, *tt, *ttstop, count, jt;
2036 while ( ss < sstop ) {
2038 ttstop = tt - ABS(tt[-1]);
2041 while ( ss < ttstop ) {
2042 if ( *ss == INDEX ) {
2043 jt = ss[1] - 2; ss += 2;
2044 while ( --jt >= 0 ) {
2045 if ( *ss < MINSPEC ) count++;
2051 if ( count != 1 )
goto NoMatch;
2056 if ( w[2] == oldnumber ) {
2058 if ( ( type == VECTOSUB && ( *w == VECTOVEC || *w == VECTOMIN ) )
2059 || ( type == INDTOSUB && *w == INDTOIND ) ) {
2060 if ( !*m )
goto TestSet;
2061 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2063 else if ( *w == type ) {
2064 if ( !*m )
goto TestSet;
2065 if ( type != INDTOIND && type != INDTOSUB ) {
2069 if ( (C->
rhs[w[3]+1] - m - 1) == n ) {
2071 if ( *m != *newval ) {
2072 m++; newval++;
break;
2077 if ( n <= 0 )
return(0);
2080 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2084 }
while ( --n > 0 );
2087 *newval = newnumber;
2089 if ( w[2] == oldnumber ) {
2092 if ( !*m )
goto TestSet;
2093 if ( newnumber >= 0 && (w+4) < AN.WildStop &&
2094 ( w[4] == FROMSET || w[4] == SETTONUM )
2095 && w[7] >= 0 )
goto TestSet;
2096 if ( newnumber < 0 && *w == VECTOVEC
2097 && (w+4) < AN.WildStop && ( w[4] == FROMSET
2098 || w[4] == SETTONUM ) && w[7] >= 0 )
goto TestSet;
2102 if ( *w == INDTOIND && w[3] < 0 )
goto NoMatch;
2103 if ( w[3] == newnumber ) {
2104 if ( *w != FUNTOFUN || newnumber < FUNCTION
2105 || functions[newnumber-FUNCTION].spec ==
2106 functions[oldnumber-FUNCTION].spec )
2109 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2111 else if ( ( type == VECTOVEC &&
2112 ( *w == VECTOSUB || *w == VECTOMIN ) )
2113 || ( type == INDTOIND && *w == INDTOSUB ) ) {
2114 if ( *m )
goto NoMatch;
2118 else if ( type == VECTOMIN &&
2119 ( *w == VECTOSUB || *w == VECTOVEC ) ) {
2120 if ( *m )
goto NoMatch;
2126 if ( n > 1 && ( *w == FROMSET
2127 || *w == SETTONUM ) ) { n--; m++; w += w[1]; }
2128 }
while ( --n > 0 );
2134 MLOCK(ErrorMessageLock);
2135 MesPrint(
"Inconsistency in Wildcard prototype.");
2136 MUNLOCK(ErrorMessageLock);
2148 if ( w < AN.WildStop && ( *w == FROMSET || *w == SETTONUM ) ) {
2151 j = w[2]; n2 = w[3];
2156 if ( j > WILDOFFSET ) {
2165 if ( j < AM.NumFixedSets ) {
2169 if ( type != SYMTONUM ||
2170 newnumber <= 0 )
goto NoMnot;
2173 if ( type != SYMTONUM ||
2174 newnumber < 0 )
goto NoMnot;
2177 if ( type != SYMTONUM ||
2178 newnumber >= 0 )
goto NoMnot;
2181 if ( type != SYMTONUM ||
2182 newnumber > 0 )
goto NoMnot;
2185 if ( type != SYMTONUM ||
2186 ( newnumber & 1 ) != 0 )
goto NoMnot;
2189 if ( type != SYMTONUM ||
2190 ( newnumber & 1 ) == 0 )
goto NoMnot;
2193 if ( type != SYMTONUM )
goto NoMnot;
2196 if ( type != SYMTOSYM )
goto NoMnot;
2199 if ( type != INDTOIND ||
2200 newnumber >= AM.OffsetIndex ||
2201 newnumber < 0 )
goto NoMnot;
2204 if ( type != INDTOIND ||
2205 newnumber < 0 )
goto NoMnot;
2208 if ( type == SYMTONUM )
break;
2209 if ( type == SYMTOSUB ) {
2214 if ( ss >= sstop )
break;
2215 if ( ss + *ss < sstop )
goto NoMnot;
2216 if ( ABS(sstop[-1]) == ss[0]-1 )
break;
2220 if ( type != INDTOIND ||
2221 newnumber < AM.IndDum || newnumber >= AM.IndDum+MAXDUMMIES )
goto NoMnot;
2224 if ( type != VECTOVEC )
goto NoMnot;
2230 if ( notflag )
goto NoM;
2233 if ( !notflag )
goto NoM;
2236 else if ( Sets[j].type == CRANGE ) {
2237 if ( ( type == SYMTONUM )
2238 || ( type == INDTOIND && ( newnumber > 0
2239 && newnumber <= AM.OffsetIndex ) ) ) {
2240 if ( Sets[j].first < MAXPOWER ) {
2241 if ( newnumber >= Sets[j].first )
goto NoMnot;
2243 else if ( Sets[j].first < 3*MAXPOWER ) {
2244 if ( newnumber+2*MAXPOWER > Sets[j].first )
goto NoMnot;
2246 if ( Sets[j].last > -MAXPOWER ) {
2247 if ( newnumber <= Sets[j].last )
goto NoMnot;
2249 else if ( Sets[j].last > -3*MAXPOWER ) {
2250 if ( newnumber-2*MAXPOWER < Sets[j].last )
goto NoMnot;
2259 w = SetElements + Sets[j].first;
2260 m = SetElements + Sets[j].last;
2266 if ( notflag )
return 0;
2268 AN.oldvalue = oldval;
2272 if ( ( Sets[j].flags & ORDEREDSET ) == ORDEREDSET ) {
2276 i = BinarySearch(w,Sets[j].last-Sets[j].first,newnumber);
2286 w = m = SetElements + i;
2288 if ( Sets[j].type == -1 || Sets[j].type == CNUMBER ) {
2297 if ( Sets[j].type == -1 || Sets[j].type == CNUMBER ) {
2303 if ( Sets[j].type == CNUMBER ) {}
2305 if ( *w == newnumber )
goto NoMatch;
2310 if ( *w == newnumber )
goto NoMatch;
2316 else if ( type != SYMTONUM && type != INDTOIND
2317 && type != SYMTOSYM )
goto NoMatch;
2318 else if ( type == SYMTOSYM && Sets[j].type == CNUMBER )
goto NoMatch;
2319 else if ( *w == newnumber ) {
2320 if ( *s == SETTONUM ) {
2321 if ( n2 == oldnumber && type
2322 <= SYMTOSUB )
goto NoMatch;
2326 while ( --n >= 0 ) {
2327 if ( w[2] == n2 && *w <= SYMTOSUB ) {
2334 if ( *w != SYMTONUM )
2336 if ( w[3] == i )
return(0);
2338 j = (SetElements + Sets[j].first)[i];
2339 if ( j == n2 )
return(0);
2345 else if ( n2 >= 0 ) {
2346 *newval = *(w - Sets[j].first + Sets[n2].first);
2347 if ( *newval > MAXPOWER ) *newval -= 2*MAXPOWER;
2348 if ( dirty && *newval != oldval ) {
2349 *newval = oldval;
goto NoMatch;
2355 }
while ( ++w < m );
2365 if ( ( type == SYMTOSYM && *w == newnumber )
2366 || ( type == SYMTONUM && *w-2*MAXPOWER == newnumber ) ) {
2372 WORD *mm = AT.WildMask, *mmm, *part;
2373 WORD *ww = AN.WildValue;
2374 WORD nn = AN.NumWild;
2376 while ( --nn >= 0 ) {
2377 if ( *mm && ww[2] == k && ww[0] == type ) {
2378 if ( type != SYMTOSUB ) {
2379 if ( ww[3] == newnumber )
goto NoMatch;
2382 mmm = C->
rhs[ww[3]];
2385 if ( (C->
rhs[ww[3]+1]-mmm-1) == nn ) {
2386 while ( --nn >= 0 ) {
2387 if ( *mmm != *part ) {
2388 mmm++; part++;
break;
2392 if ( nn < 0 )
goto NoMatch;
2402 if ( type == VECTOMIN ) {
2403 if ( inset >= AM.OffsetVector ) { i++;
continue; }
2408 if ( inset == newnumber )
goto NoMatch;
2411 if ( inset - WILDOFFSET >= AM.OffsetVector ) {
2412 WORD *mm = AT.WildMask, *mmm, *part;
2413 WORD *ww = AN.WildValue;
2414 WORD nn = AN.NumWild;
2415 k = inset - WILDOFFSET;
2416 while ( --nn >= 0 ) {
2417 if ( *mm && ww[2] == k && ww[0] == type ) {
2418 if ( type == VECTOVEC ) {
2419 if ( ww[3] == newnumber )
goto NoMatch;
2422 mmm = C->
rhs[ww[3]];
2425 if ( (C->
rhs[ww[3]+1]-mmm-1) == nn ) {
2426 while ( --nn >= 0 ) {
2427 if ( *mmm != *part ) {
2428 mmm++; part++;
break;
2432 if ( nn < 0 )
goto NoMatch;
2442 if ( *w == newnumber )
goto NoMatch;
2445 if ( *w - (WORD)WILDMASK >= AM.OffsetIndex ) {
2446 WORD *mm = AT.WildMask, *mmm, *part;
2447 WORD *ww = AN.WildValue;
2448 WORD nn = AN.NumWild;
2450 while ( --nn >= 0 ) {
2451 if ( *mm && ww[2] == k && ww[0] == type ) {
2452 if ( type == INDTOIND ) {
2453 if ( ww[3] == newnumber )
goto NoMatch;
2456 mmm = C->
rhs[ww[3]];
2459 if ( (C->
rhs[ww[3]+1]-mmm-1) == nn ) {
2460 while ( --nn >= 0 ) {
2461 if ( *mmm != *part ) {
2462 mmm++; part++;
break;
2466 if ( nn < 0 )
goto NoMatch;
2476 if ( *w == newnumber )
goto NoMatch;
2477 if ( ( type == FUNTOFUN &&
2478 ( k = *w - WILDMASK ) > FUNCTION ) ) {
2479 WORD *mm = AT.WildMask;
2480 WORD *ww = AN.WildValue;
2481 WORD nn = AN.NumWild;
2482 while ( --nn >= 0 ) {
2483 if ( *mm && ww[2] == k && ww[0] == type ) {
2484 if ( ww[3] == newnumber )
goto NoMatch;
2495 if ( type == VECTOMIN ) {
2496 if ( inset >= AM.OffsetVector ) { i++;
continue; }
2499 if ( ( inset == newnumber && type != SYMTONUM ) ||
2500 ( type == SYMTONUM && inset-2*MAXPOWER == newnumber ) ) {
2501 if ( *s == SETTONUM ) {
2502 if ( n2 == oldnumber && type
2503 <= SYMTOSUB )
goto NoMatch;
2507 while ( --n >= 0 ) {
2508 if ( w[2] == n2 && *w <= SYMTOSUB ) {
2515 if ( *w != SYMTONUM )
2517 if ( w[3] == i )
return(0);
2519 j = (SetElements + Sets[j].first)[i];
2520 if ( j == n2 )
return(0);
2526 else if ( n2 >= 0 ) {
2527 *newval = *(w - Sets[j].first + Sets[n2].first);
2528 if ( *newval > MAXPOWER ) *newval -= 2*MAXPOWER;
2529 if ( dirty && *newval != oldval ) {
2530 *newval = oldval;
goto NoMatch;
2537 }
while ( ++w < m );
2539 if ( notflag )
return(0);
2540 AN.oldtype = old2; AN.oldvalue = oldval;
goto NoMatch;
2545 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2557int DenToFunction(WORD *term, WORD numfun)
2560 WORD *t, *tstop, *tnext, *arg, *argstop, *targ;
2562 tstop = term + *term; tstop -= ABS(tstop[-1]);
2563 while ( t < tstop ) {
2564 if ( *t == DENOMINATOR ) {
2565 *t = numfun; t[2] |= DIRTYFLAG; action = 1;
2568 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec <= 0 ) {
2570 while ( arg < tnext ) {
2572 targ = arg + ARGHEAD; argstop = arg + *arg;
2573 while ( targ < argstop ) {
2574 if ( DenToFunction(targ,numfun) ) {
2575 arg[1] |= DIRTYFLAG; t[2] |= DIRTYFLAG; action = 1;
2581 else if ( *arg <= -FUNCTION ) arg++;