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 ( DollarLocalCopy(dtype) ) {
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 && ! DollarLocalCopy(dtype) ) { 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 && ! DollarLocalCopy(dtype) ) { 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;
1711 MLOCK(ErrorMessageLock);
1712 MesPrint(
"!>Internal problems with extra compiler buffer");
1713 MUNLOCK(ErrorMessageLock);
1720 }
while ( --n > 0 );
1724 if ( w[2] == oldnumber && ( *w == type || ( type == VECTOVEC
1725 && ( *w == VECTOMIN || *w == VECTOSUB ) ) || ( type == VECTOMIN
1726 && ( *w == VECTOVEC || *w == VECTOSUB ) )
1727 || ( type == INDTOIND && *w == INDTOSUB ) ) ) {
1728 if ( n > 1 && w[4] == SETTONUM ) i = w[7];
1735 }
while ( --n > 0 );
1738 MLOCK(ErrorMessageLock);
1739 MesPrint(
"!>Bug in AddWild.");
1740 MUNLOCK(ErrorMessageLock);
1748 while ( --n >= 0 ) {
1749 if ( w[2] == i && *w == SYMTONUM ) {
1756 MLOCK(ErrorMessageLock);
1757 MesPrint(
"!>Bug in AddWild with passing set[i]");
1758 MUNLOCK(ErrorMessageLock);
1797int CheckWild(PHEAD WORD oldnumber, WORD type, WORD newnumber, WORD *newval)
1800 WORD *w, *m, *s, n, old2, inset;
1801 WORD n2, oldval, dirty, i, j;
1802 int notflag = 0, retblock = 0;
1803 CBUF *C = cbuf+AT.ebufnum;
1804 WORD eattensor = type & EATTENSOR;
1805 type = type & ~EATTENSOR;
1809 if ( n <= 0 ) { AN.oldtype = -1; AN.WildReserve = 0;
return(-1); }
1812 *newval = newnumber;
1814 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1816 if ( !*m )
goto TestSet;
1818 if ( *w == SYMTONUM && w[3] == newnumber ) {
1821 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
1824 }
while ( --n > 0 );
1827 *newval = newnumber;
1829 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1831 if ( *w == SYMTOSYM ) {
1832 if ( !*m )
goto TestSet;
1833 if ( newnumber >= 0 && (w+4) < AN.WildStop
1834 && ( w[4] == FROMSET || w[4] == SETTONUM )
1835 && w[7] >= 0 )
goto TestSet;
1836 if ( w[3] == newnumber )
return(0);
1839 if ( !*m )
goto TestSet;
1844 }
while ( --n > 0 );
1854 WORD *ss, *sstop, *tt, *ttstop;
1858 while ( ss < sstop ) {
1860 ttstop = tt - ABS(tt[-1]);
1862 while ( ss < ttstop ) {
1863 if ( *ss == INDEX )
goto NoMatch;
1870 if ( w[2] == oldnumber && *w <= SYMTOSUB ) {
1872 if ( *w == SYMTONUM || *w == SYMTOSYM ) {
1875 if ( s >= AN.WildStop || *s != SETTONUM )
1879 else if ( *w == SYMTOSUB ) {
1882 if ( s >= AN.WildStop || *s != SETTONUM )
1888 if ( (C->
rhs[w[3]+1] - m - 1) == n ) {
1890 if ( *m != *newval ) {
1891 m++; newval++;
break;
1896 if ( n <= 0 )
return(0);
1899 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
1902 }
while ( --n > 0 );
1906 if ( w[2] == oldnumber && *w == ARGTOARG ) {
1907 if ( !*m )
return(0);
1914 while ( --n >= 0 ) {
1915 if ( *m != *newval ) {
1916 m++; newval++;
break;
1920 if ( n < 0 )
return(0);
1925 while ( --n >= 0 ) {
1926 if ( *newval != m[1] || ( *m != -INDEX
1927 && *m != -VECTOR && *m != -SNUMBER ) )
break;
1931 if ( n < 0 && *m == 0 )
return(0);
1939 while ( --i >= 0 ) {
1940 if ( *m != newval[1]
1941 || ( *newval != -VECTOR
1942 && *newval != -INDEX
1943 && *newval != -SNUMBER ) )
break;
1947 if ( i < 0 )
return(0);
1953 while ( --i >= 0 ) { NEXTARG(s) }
1954 n = WORDDIF(s,newval);
1955 while ( --n >= 0 ) {
1956 if ( *m != *newval ) {
1957 m++; newval++;
break;
1961 if ( n < 0 && *m == 0 )
return(0);
1964 AN.oldtype = *w; AN.oldvalue = w[3];
goto NoMatch;
1967 }
while ( --n > 0 );
1971 if ( w[2] == oldnumber && *w == ARGTOARG ) {
1973 if ( !*m )
return(0);
1976 a = (WORD **)newval;
1980 while ( --i >= 0 ) {
1985 && *s != -SNUMBER ) )
break;
1988 if ( i < 0 )
return(0);
1993 while ( --i >= 0 ) {
1997 while ( --n >= 0 ) {
2003 if ( n >= 0 )
break;
2005 else if ( *s <= -FUNCTION ) {
2022 if ( i < 0 && *m == 0 )
return(0);
2024 AN.oldtype = *w; AN.oldvalue = w[3];
goto NoMatch;
2027 }
while ( --n > 0 );
2038 WORD *ss, *sstop, *tt, *ttstop, count, jt;
2042 while ( ss < sstop ) {
2044 ttstop = tt - ABS(tt[-1]);
2047 while ( ss < ttstop ) {
2048 if ( *ss == INDEX ) {
2049 jt = ss[1] - 2; ss += 2;
2050 while ( --jt >= 0 ) {
2051 if ( *ss < MINSPEC ) count++;
2057 if ( count != 1 )
goto NoMatch;
2062 if ( w[2] == oldnumber ) {
2064 if ( ( type == VECTOSUB && ( *w == VECTOVEC || *w == VECTOMIN ) )
2065 || ( type == INDTOSUB && *w == INDTOIND ) ) {
2066 if ( !*m )
goto TestSet;
2067 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2069 else if ( *w == type ) {
2070 if ( !*m )
goto TestSet;
2071 if ( type != INDTOIND && type != INDTOSUB ) {
2075 if ( (C->
rhs[w[3]+1] - m - 1) == n ) {
2077 if ( *m != *newval ) {
2078 m++; newval++;
break;
2083 if ( n <= 0 )
return(0);
2086 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2090 }
while ( --n > 0 );
2093 *newval = newnumber;
2095 if ( w[2] == oldnumber ) {
2098 if ( !*m )
goto TestSet;
2099 if ( newnumber >= 0 && (w+4) < AN.WildStop &&
2100 ( w[4] == FROMSET || w[4] == SETTONUM )
2101 && w[7] >= 0 )
goto TestSet;
2102 if ( newnumber < 0 && *w == VECTOVEC
2103 && (w+4) < AN.WildStop && ( w[4] == FROMSET
2104 || w[4] == SETTONUM ) && w[7] >= 0 )
goto TestSet;
2108 if ( *w == INDTOIND && w[3] < 0 )
goto NoMatch;
2109 if ( w[3] == newnumber ) {
2110 if ( *w != FUNTOFUN || newnumber < FUNCTION
2111 || functions[newnumber-FUNCTION].spec ==
2112 functions[oldnumber-FUNCTION].spec )
2115 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2117 else if ( ( type == VECTOVEC &&
2118 ( *w == VECTOSUB || *w == VECTOMIN ) )
2119 || ( type == INDTOIND && *w == INDTOSUB ) ) {
2120 if ( *m )
goto NoMatch;
2124 else if ( type == VECTOMIN &&
2125 ( *w == VECTOSUB || *w == VECTOVEC ) ) {
2126 if ( *m )
goto NoMatch;
2132 if ( n > 1 && ( *w == FROMSET
2133 || *w == SETTONUM ) ) { n--; m++; w += w[1]; }
2134 }
while ( --n > 0 );
2141 MLOCK(ErrorMessageLock);
2142 MesPrint(
"!>Inconsistency in Wildcard prototype.");
2143 MUNLOCK(ErrorMessageLock);
2156 if ( w < AN.WildStop && ( *w == FROMSET || *w == SETTONUM ) ) {
2159 j = w[2]; n2 = w[3];
2164 if ( j > WILDOFFSET ) {
2173 if ( j < AM.NumFixedSets ) {
2177 if ( type != SYMTONUM ||
2178 newnumber <= 0 )
goto NoMnot;
2181 if ( type != SYMTONUM ||
2182 newnumber < 0 )
goto NoMnot;
2185 if ( type != SYMTONUM ||
2186 newnumber >= 0 )
goto NoMnot;
2189 if ( type != SYMTONUM ||
2190 newnumber > 0 )
goto NoMnot;
2193 if ( type != SYMTONUM ||
2194 ( newnumber & 1 ) != 0 )
goto NoMnot;
2197 if ( type != SYMTONUM ||
2198 ( newnumber & 1 ) == 0 )
goto NoMnot;
2201 if ( type != SYMTONUM )
goto NoMnot;
2204 if ( type != SYMTOSYM )
goto NoMnot;
2207 if ( type != INDTOIND ||
2208 newnumber >= AM.OffsetIndex ||
2209 newnumber < 0 )
goto NoMnot;
2212 if ( type != INDTOIND ||
2213 newnumber < 0 )
goto NoMnot;
2216 if ( type == SYMTONUM )
break;
2217 if ( type == SYMTOSUB ) {
2222 if ( ss >= sstop )
break;
2223 if ( ss + *ss < sstop )
goto NoMnot;
2224 if ( ABS(sstop[-1]) == ss[0]-1 )
break;
2228 if ( type != INDTOIND ||
2229 newnumber < AM.IndDum || newnumber >= AM.IndDum+MAXDUMMIES )
goto NoMnot;
2232 if ( type != VECTOVEC )
goto NoMnot;
2238 if ( notflag )
goto NoM;
2241 if ( !notflag )
goto NoM;
2244 else if ( Sets[j].type == CRANGE ) {
2245 if ( ( type == SYMTONUM )
2246 || ( type == INDTOIND && ( newnumber > 0
2247 && newnumber <= AM.OffsetIndex ) ) ) {
2248 if ( Sets[j].first < MAXPOWER ) {
2249 if ( newnumber >= Sets[j].first )
goto NoMnot;
2251 else if ( Sets[j].first < 3*MAXPOWER ) {
2252 if ( newnumber+2*MAXPOWER > Sets[j].first )
goto NoMnot;
2254 if ( Sets[j].last > -MAXPOWER ) {
2255 if ( newnumber <= Sets[j].last )
goto NoMnot;
2257 else if ( Sets[j].last > -3*MAXPOWER ) {
2258 if ( newnumber-2*MAXPOWER < Sets[j].last )
goto NoMnot;
2267 w = SetElements + Sets[j].first;
2268 m = SetElements + Sets[j].last;
2274 if ( notflag )
return 0;
2276 AN.oldvalue = oldval;
2280 if ( ( Sets[j].flags & ORDEREDSET ) == ORDEREDSET ) {
2284 i = BinarySearch(w,Sets[j].last-Sets[j].first,newnumber);
2294 w = m = SetElements + i;
2296 if ( Sets[j].type == -1 || Sets[j].type == CNUMBER ) {
2305 if ( Sets[j].type == -1 || Sets[j].type == CNUMBER ) {
2311 if ( Sets[j].type == CNUMBER ) {}
2313 if ( *w == newnumber )
goto NoMatch;
2318 if ( *w == newnumber )
goto NoMatch;
2324 else if ( type != SYMTONUM && type != INDTOIND
2325 && type != SYMTOSYM )
goto NoMatch;
2326 else if ( type == SYMTOSYM && Sets[j].type == CNUMBER )
goto NoMatch;
2327 else if ( *w == newnumber ) {
2328 if ( *s == SETTONUM ) {
2329 if ( n2 == oldnumber && type
2330 <= SYMTOSUB )
goto NoMatch;
2334 while ( --n >= 0 ) {
2335 if ( w[2] == n2 && *w <= SYMTOSUB ) {
2342 if ( *w != SYMTONUM )
2344 if ( w[3] == i )
return(0);
2346 j = (SetElements + Sets[j].first)[i];
2347 if ( j == n2 )
return(0);
2353 else if ( n2 >= 0 ) {
2354 *newval = *(w - Sets[j].first + Sets[n2].first);
2355 if ( *newval > MAXPOWER ) *newval -= 2*MAXPOWER;
2356 if ( dirty && *newval != oldval ) {
2357 *newval = oldval;
goto NoMatch;
2363 }
while ( ++w < m );
2373 if ( ( type == SYMTOSYM && *w == newnumber )
2374 || ( type == SYMTONUM && *w-2*MAXPOWER == newnumber ) ) {
2380 WORD *mm = AT.WildMask, *mmm, *part;
2381 WORD *ww = AN.WildValue;
2382 WORD nn = AN.NumWild;
2384 while ( --nn >= 0 ) {
2385 if ( *mm && ww[2] == k && ww[0] == type ) {
2386 if ( type != SYMTOSUB ) {
2387 if ( ww[3] == newnumber )
goto NoMatch;
2390 mmm = C->
rhs[ww[3]];
2393 if ( (C->
rhs[ww[3]+1]-mmm-1) == nn ) {
2394 while ( --nn >= 0 ) {
2395 if ( *mmm != *part ) {
2396 mmm++; part++;
break;
2400 if ( nn < 0 )
goto NoMatch;
2410 if ( type == VECTOMIN ) {
2411 if ( inset >= AM.OffsetVector ) { i++;
continue; }
2416 if ( inset == newnumber )
goto NoMatch;
2419 if ( inset - WILDOFFSET >= AM.OffsetVector ) {
2420 WORD *mm = AT.WildMask, *mmm, *part;
2421 WORD *ww = AN.WildValue;
2422 WORD nn = AN.NumWild;
2423 k = inset - WILDOFFSET;
2424 while ( --nn >= 0 ) {
2425 if ( *mm && ww[2] == k && ww[0] == type ) {
2426 if ( type == VECTOVEC ) {
2427 if ( ww[3] == newnumber )
goto NoMatch;
2430 mmm = C->
rhs[ww[3]];
2433 if ( (C->
rhs[ww[3]+1]-mmm-1) == nn ) {
2434 while ( --nn >= 0 ) {
2435 if ( *mmm != *part ) {
2436 mmm++; part++;
break;
2440 if ( nn < 0 )
goto NoMatch;
2450 if ( *w == newnumber )
goto NoMatch;
2453 if ( *w - (WORD)WILDMASK >= AM.OffsetIndex ) {
2454 WORD *mm = AT.WildMask, *mmm, *part;
2455 WORD *ww = AN.WildValue;
2456 WORD nn = AN.NumWild;
2458 while ( --nn >= 0 ) {
2459 if ( *mm && ww[2] == k && ww[0] == type ) {
2460 if ( type == INDTOIND ) {
2461 if ( ww[3] == newnumber )
goto NoMatch;
2464 mmm = C->
rhs[ww[3]];
2467 if ( (C->
rhs[ww[3]+1]-mmm-1) == nn ) {
2468 while ( --nn >= 0 ) {
2469 if ( *mmm != *part ) {
2470 mmm++; part++;
break;
2474 if ( nn < 0 )
goto NoMatch;
2484 if ( *w == newnumber )
goto NoMatch;
2485 if ( ( type == FUNTOFUN &&
2486 ( k = *w - WILDMASK ) > FUNCTION ) ) {
2487 WORD *mm = AT.WildMask;
2488 WORD *ww = AN.WildValue;
2489 WORD nn = AN.NumWild;
2490 while ( --nn >= 0 ) {
2491 if ( *mm && ww[2] == k && ww[0] == type ) {
2492 if ( ww[3] == newnumber )
goto NoMatch;
2503 if ( type == VECTOMIN ) {
2504 if ( inset >= AM.OffsetVector ) { i++;
continue; }
2507 if ( ( inset == newnumber && type != SYMTONUM ) ||
2508 ( type == SYMTONUM && inset-2*MAXPOWER == newnumber ) ) {
2509 if ( *s == SETTONUM ) {
2510 if ( n2 == oldnumber && type
2511 <= SYMTOSUB )
goto NoMatch;
2515 while ( --n >= 0 ) {
2516 if ( w[2] == n2 && *w <= SYMTOSUB ) {
2523 if ( *w != SYMTONUM )
2525 if ( w[3] == i )
return(0);
2527 j = (SetElements + Sets[j].first)[i];
2528 if ( j == n2 )
return(0);
2534 else if ( n2 >= 0 ) {
2535 *newval = *(w - Sets[j].first + Sets[n2].first);
2536 if ( *newval > MAXPOWER ) *newval -= 2*MAXPOWER;
2537 if ( dirty && *newval != oldval ) {
2538 *newval = oldval;
goto NoMatch;
2545 }
while ( ++w < m );
2547 if ( notflag )
return(0);
2548 AN.oldtype = old2; AN.oldvalue = oldval;
goto NoMatch;
2553 AN.oldtype = old2; AN.oldvalue = w[3];
goto NoMatch;
2565int DenToFunction(WORD *term, WORD numfun)
2568 WORD *t, *tstop, *tnext, *arg, *argstop, *targ;
2570 tstop = term + *term; tstop -= ABS(tstop[-1]);
2571 while ( t < tstop ) {
2572 if ( *t == DENOMINATOR ) {
2573 *t = numfun; t[2] |= DIRTYFLAG; action = 1;
2576 if ( *t >= FUNCTION && functions[*t-FUNCTION].spec <= 0 ) {
2578 while ( arg < tnext ) {
2580 targ = arg + ARGHEAD; argstop = arg + *arg;
2581 while ( targ < argstop ) {
2582 if ( DenToFunction(targ,numfun) ) {
2583 arg[1] |= DIRTYFLAG; t[2] |= DIRTYFLAG; action = 1;
2589 else if ( *arg <= -FUNCTION ) arg++;