100 WORD *ll, *m, *w, *llf, *OldWork, *StartWork, *ww, *mm;
101 WORD power = 0, match = 0, i, msign = 0;
102 int numdollars = 0, protosize;
103 CBUF *C = cbuf+AM.rbufnum;
109 if ( *ll == TYPEEXPRESSION ) {
115 else if ( *ll == TYPEREPEAT ) {
119 else if ( *ll == TYPEENDREPEAT ) {
120 if ( *AN.RepPoint ) {
127 if ( AN.RepPoint < AT.RepCount ) {
128 MLOCK(ErrorMessageLock);
129 MesPrint(
"Internal problems with REPEAT count");
130 MUNLOCK(ErrorMessageLock);
136 else if ( *ll == TYPEOPERATION ) {
140 if ( (*(FG.OperaFind[ll[2]]))(BHEAD term,ll) )
return(-1);
146 OldWork = AT.WorkPointer;
147 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
166 if ( ( ja + 2 ) > AN.patternbuffersize ) {
167 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
168 AN.patternbuffersize = 2 * ja + 2;
169 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
172 ma = AN.patternbuffer;
195 AN.WildValue = w = m + SUBEXPSIZE;
196 protosize = IDHEAD + m[1];
203 if ( ( ll[4] & 1 ) != 0 ) {
204 WORD oldRepPoint = *AN.RepPoint, olddefer = AR.DeferFlag;
209 ww = AT.WorkPointer; i = m[0]; mm = m;
212 *ww++ = 1; *ww++ = 1; *ww++ = 3;
216 if (
Generator(BHEAD StartWork,AR.Cnumlhs) ) {
218 AT.WorkPointer = OldWork;
219 AR.DeferFlag = olddefer;
223 if (
EndSort(BHEAD ww,0) < 0 ) {}
224 AR.DeferFlag = olddefer;
225 if ( *ww == 0 || *(ww+*ww) != 0 ) {
226 if ( AP.lhdollarerror == 0 ) {
230 MLOCK(ErrorMessageLock);
231 MesPrint(
"&LHS must be one term");
232 MUNLOCK(ErrorMessageLock);
233 AP.lhdollarerror = 1;
235 AT.WorkPointer = OldWork;
239 if ( m[*m-1] < 0 ) { msign = 1; m[*m-1] = -m[*m-1]; }
240 if ( *ww || m[*m-1] != 3 || m[*m-2] != 1 || m[*m-3] != 1 ) {
241 MLOCK(ErrorMessageLock);
242 MesPrint(
"Dollar variable develops into an illegal pattern in id-statement");
243 MUNLOCK(ErrorMessageLock);
247 if ( ( *m + 1 + protosize ) > AN.patternbuffersize ) {
248 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
249 AN.patternbuffersize = 2 * (*m) + 2 + protosize;
250 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
252 mm = ll; ww = AN.patternbuffer; i = protosize;
254 AN.FullProto = AN.patternbuffer + IDHEAD;
255 AN.WildValue = w = AN.FullProto + SUBEXPSIZE;
256 AN.WildStop = AN.patternbuffer + protosize;
258 mm = AN.patternbuffer + protosize;
261 m = AN.patternbuffer + protosize;
265 AT.WorkPointer = ww = StartWork;
266 *AN.RepPoint = oldRepPoint;
274 while ( w < AN.WildStop ) {
275 if ( *w == LOADDOLLAR ) numdollars++;
279 AN.RepFunList = AT.WorkPointer;
280 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
281 if ( AT.WorkPointer >= AT.WorkTop ) {
282 MLOCK(ErrorMessageLock);
284 MUNLOCK(ErrorMessageLock);
287 AN.DisOrderFlag = ll[2] & SUBDISORDER;
288 AN.nogroundlevel = 0;
289 switch ( ll[2] & SUBMASK ) {
292 AN.UseFindOnly = 1; AN.ForFindOnly = 0;
293 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
294 FindOnly(BHEAD term,m) ) ) {
296 if ( msign ) term[term[0]-1] = -term[term[0]-1];
302 if ( ( power = FindRest(BHEAD term,m) ) > 0 ) {
303 if ( ( power = FindOnce(BHEAD term,m) ) > 0 ) {
306 if ( msign ) term[term[0]-1] = -term[term[0]-1];
307 Substitute(BHEAD term,m,1);
312 if ( ww < term+term[0] ) ww = term+term[0];
318 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
319 if ( AT.WorkPointer >= AT.WorkTop ) {
320 MLOCK(ErrorMessageLock);
322 MUNLOCK(ErrorMessageLock);
332 AN.nogroundlevel = 0;
333 }
while ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
334 FindOnce(BHEAD term,m) ) );
337 else if ( power < 0 ) {
339 if ( msign ) term[term[0]-1] = -term[term[0]-1];
340 Substitute(BHEAD term,m,1);
345 if ( ww < term+term[0] ) ww = term+term[0];
351 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
352 if ( AT.WorkPointer >= AT.WorkTop ) {
353 MLOCK(ErrorMessageLock);
355 MUNLOCK(ErrorMessageLock);
365 }
while ( FindRest(BHEAD term,m) );
369 else if ( power < 0 ) {
370 if ( FindOnce(BHEAD term,m) ) {
372 if ( msign ) term[term[0]-1] = -term[term[0]-1];
373 Substitute(BHEAD term,m,1);
378 if ( ww < term+term[0] ) ww = term+term[0];
384 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
385 if ( AT.WorkPointer >= AT.WorkTop ) {
386 MLOCK(ErrorMessageLock);
388 MUNLOCK(ErrorMessageLock);
398 }
while ( FindOnce(BHEAD term,m) );
404 if ( ( ll[2] & SUBAFTER ) != 0 ) *level = AC.Labels[ll[3]];
407 if ( ( ll[2] & SUBAFTERNOT ) != 0 ) *level = AC.Labels[ll[3]];
415 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnce(BHEAD term,m) ) ) {
417 if ( msign ) term[term[0]-1] = -term[term[0]-1];
422 power = FindMulti(BHEAD term,m);
423 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
426 while ( ( power = FindAll(BHEAD term,m,*level,(WORD *)0) ) != 0 ) {
427 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
432 llf = ll + IDHEAD; llf += llf[1]; llf += *llf;
433 AN.UseFindOnly = 1; AN.ForFindOnly = llf;
434 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnly(BHEAD term,m) ) ) {
435 if ( msign ) term[term[0]-1] = -term[term[0]-1];
443 if ( *term > AN.sizeselecttermundo ) {
444 if ( AN.selecttermundo ) M_free(AN.selecttermundo,
"AN.selecttermundo");
445 AN.sizeselecttermundo = *term +10;
446 AN.selecttermundo = (WORD *)Malloc1(
447 AN.sizeselecttermundo*
sizeof(WORD),
"AN.selecttermundo");
449 t1 = term; t2 = AN.selecttermundo; i = *term;
453 Substitute(BHEAD term,m,power);
455 if ( TestSelect(term,llf) ) {
458 t1 = term; t2 = AN.selecttermundo; i = *t2;
461 if ( ( ll[2] & SUBAFTERNOT ) != 0 ) {
462 *level = AC.Labels[ll[3]];
474 if ( ( ll[2] & SUBAFTER ) != 0 ) {
475 *level = AC.Labels[ll[3]];
481 if ( ( ll[2] & SUBAFTERNOT ) != 0 ) {
482 *level = AC.Labels[ll[3]];
492 Substitute(BHEAD term,m,power);
499 if ( ( ll[2] & SUBAFTER ) != 0 ) {
500 *level = AC.Labels[ll[3]];
505 AT.WorkPointer = AN.RepFunList;
507 if ( ( ll[2] & SUBAFTERNOT ) != 0 ) {
508 *level = AC.Labels[ll[3]];
513 }
while ( (*level)++ < AR.Cnumlhs && C->
lhs[*level][0] == TYPEIDOLD );
515 AT.WorkPointer = AN.RepFunList;
524 VOID Substitute(
PHEAD WORD *term, WORD *pattern, WORD power)
531 WORD nt, *fill, nq, mt;
532 WORD *q, *subterm, *tcoef, oldval1 = 0, newval3, i = 0;
533 WORD PutExpr = 0, sign = 0;
534 TemTerm = AT.WorkPointer;
535 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
536 MLOCK(ErrorMessageLock);
538 MUNLOCK(ErrorMessageLock);
547 tstop = t - ABS(*t) + 1;
552 if ( m < mstop ) {
do {
556 if ( *m == SYMBOL ) {
559 while ( *t != SYMBOL && t < tstop ) {
563 if ( t >= tstop )
goto SubCoef;
570 if ( *m == *t && t < xstop ) {
573 if ( mt >= 2*MAXPOWER ) {
574 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
579 else if ( mt <= -2*MAXPOWER ) {
580 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
594 else if ( *m >= 2*MAXPOWER ) {
595 while ( t < xstop ) { *fill++ = *t++; *fill++ = *t++; }
596 nq = WORDDIF(fill,subterm);
599 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*fill,&newval3) ) {
601 if ( mt >= 2*MAXPOWER ) {
602 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
603 if ( fill[1] -= AN.oldvalue )
goto SubsL2;
606 else if ( mt <= -2*MAXPOWER ) {
607 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
608 if ( fill[1] += AN.oldvalue )
goto SubsL2;
612 if ( fill[1] -= mt * power ) {
625 while ( --nq >= 0 ) *fill++ = *q++;
629 else if ( *m < *t || t >= xstop ) { m += 2; }
630 else { *fill++ = *t++; *fill++ = *t++; }
631 }
while ( m < ystop );
632 while ( t < xstop ) *fill++ = *t++;
633 nq = WORDDIF(fill,subterm);
638 else { fill = subterm; fill -= 2; }
644 else if ( *m == DOTPRODUCT ) {
647 while ( *t > DOTPRODUCT && t < tstop ) {
651 if ( t >= tstop )
goto SubCoef;
652 if ( *t != DOTPRODUCT ) {
656 *fill++ = DOTPRODUCT;
662 if ( *m == *t && m[1] == t[1] && t < xstop ) {
665 if ( mt >= 2*MAXPOWER ) {
666 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
671 else if ( mt <= -2*MAXPOWER ) {
672 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
689 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
690 while ( t < xstop ) {
691 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
696 else if ( m[1] >= (AM.OffsetVector+WILDOFFSET) ) {
697 while ( *m >= *t && t < xstop ) {
698 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
701 SubsL4: nq = WORDDIF(fill,subterm);
704 if ( ( oldval1 && ( (
705 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3)
706 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
708 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
709 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,fill[1],&newval3)
710 ) ) ) || ( !oldval1 && ( (
712 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
714 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
715 && *m == fill[1] ) ) ) ) {
717 if ( mt >= 2*MAXPOWER ) {
718 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
719 if ( fill[2] -= AN.oldvalue )
723 else if ( mt <= -2*MAXPOWER ) {
724 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
725 if ( fill[2] += AN.oldvalue )
730 if ( fill[2] -= mt * power ) {
743 while ( --nq >= 0 ) *fill++ = *q++;
746 else if ( t >= xstop || *m < *t || ( *m == *t && m[1] < t[1] ) )
749 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
751 }
while ( m < ystop );
752 while ( t < xstop ) *fill++ = *t++;
753 nq = WORDDIF(fill,subterm);
758 else { fill = subterm; fill -= 2; }
764 else if ( *m >= FUNCTION ) {
765 while ( *t >= FUNCTION || *t == SUBEXPRESSION ) {
766 nt = WORDDIF(t,term);
767 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
768 if ( nt == AN.RepFunList[mt] )
break;
770 if ( mt >= AN.RepFunNum ) {
776 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
778 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
780 *fill++ = i + FUNHEAD+1;
788 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
789 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
790 ) sign += AN.RepFunList[mt+1];
791 else if ( *m >= FUNCTION+WILDOFFSET
792 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
793 ) sign += AN.RepFunList[mt+1];
804 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
805 i = oldt[1] - m[1] - i;
808 *fill++ = i + FUNHEAD+1;
810 *fill++ = oldt[FUNHEAD];
824 else if ( *m == VECTOR ) {
825 while ( *t > VECTOR ) {
837 if ( *m == *t && m[1] == t[1] ) {
840 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
841 while ( t < xstop ) *fill++ = *t++;
842 nq = WORDDIF(fill,subterm);
844 if ( m[1] < (AM.OffsetIndex+WILDOFFSET) ) {
846 if ( m[1] == fill[1] &&
847 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
855 if ( !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
856 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
858 if ( *fill == oldval1 && fill[1] == AN.oldvalue )
break;
865 if ( nq > 0 ) { NCOPY(fill,q,nq); }
868 else if ( *m <= *t &&
869 m[1] >= (AM.OffsetIndex + WILDOFFSET) ) {
870 while ( *m == *t && t < xstop )
871 { *fill++ = *t++; *fill++ = *t++; }
872 nq = WORDDIF(fill,subterm);
876 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3) )
883 if ( nq > 0 ) { NCOPY(fill,q,nq); }
886 else { *fill++ = *t++; *fill++ = *t++; }
887 }
while ( m < ystop );
888 while ( t < xstop ) *fill++ = *t++;
889 nq = WORDDIF(fill,subterm);
894 else { fill = subterm; fill -= 2; }
902 else if ( *m == INDEX ) {
903 while ( *t > INDEX ) {
918 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
919 while ( t < xstop ) *fill++ = *t++;
920 nq = WORDDIF(fill, subterm);
923 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3) ) {
939 }
while ( m < ystop );
940 while ( t < xstop ) *fill++ = *t++;
941 nq = WORDDIF(fill,subterm);
946 else { fill = subterm; fill -= 2; }
952 else if ( *m == DELTA ) {
953 while ( *t > DELTA ) {
965 if ( *t == *m && t[1] == m[1] ) { m += 2; t += 2; }
966 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
967 while ( t < xstop ) *fill++ = *t++;
972 else if ( m[1] >= (AM.OffsetIndex+WILDOFFSET) ) {
973 while ( (*m == *t || *m == t[1] ) && ( t < xstop ) ) {
974 *fill++ = *t++; *fill++ = *t++;
977 SubsL6: nq = WORDDIF(fill,subterm);
980 if ( ( oldval1 && ( (
981 !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3)
982 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
984 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
985 && !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,fill[1],&newval3)
986 ) ) ) || ( !oldval1 && ( (
988 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
991 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1004 *fill++ = *t++; *fill++ = *t++;
1006 }
while ( m < ystop );
1007 while ( t < xstop ) *fill++ = *t++;
1008 nq = WORDDIF(fill,subterm);
1013 else { fill = subterm; fill -= 2; }
1019 }
while ( m < mstop ); }
1020 while ( t < tstop ) *fill++ = *t++;
1032 nq = WORDDIF(fill,TemTerm);
1039 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
1041 if ( AT.WorkPointer < fill ) AT.WorkPointer = fill;
1081 WORD FindAll(
PHEAD WORD *term, WORD *pattern, WORD level, WORD *par)
1084 WORD *t, *m, *r, *mm, rnum;
1085 WORD *tstop, *mstop, *TwoProto, *vwhere = 0, oldv, oldvv, vv, level2;
1086 WORD v, nq, OffNum = AM.OffsetVector + WILDOFFSET, i, ii = 0, jj;
1087 WORD fromindex, *intens, notflag1 = 0, notflag2 = 0;
1089 C = cbuf+AM.rbufnum;
1101 if ( *t == VECTOR ) {
1105 while ( r < tstop ) {
1107 if ( v >= OffNum ) {
1108 vwhere = AN.FullProto + 3 + SUBEXPSIZE;
1109 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1110 WORD *afirst, *alast, j;
1112 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1113 else { notflag1 = 0; }
1114 afirst = SetElements + Sets[j].first;
1115 alast = SetElements + Sets[j].last;
1117 if ( notflag1 == 0 ) {
1119 if ( *afirst == *r ) {
1120 if ( vwhere[1] == SETTONUM ) {
1121 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1122 AN.FullProto[11+SUBEXPSIZE] = ii;
1124 else if ( vwhere[4] >= 0 ) {
1125 oldv = *(afirst - Sets[j].first
1126 + Sets[vwhere[4]].first);
1131 }
while ( ++afirst < alast );
1135 if ( *afirst == *r )
break;
1136 }
while ( ++afirst < alast );
1137 if ( afirst >= alast )
goto DoVect;
1142 else if ( v == *r ) {
1143 DoVect: m = AT.WorkPointer;
1147 do { *m++ = *t++; }
while ( t < tstop );
1154 if ( fromindex == 1 ) m[-1] = FUNNYVEC;
1156 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1157 if ( vwhere[1] > 12+SUBEXPSIZE ) {
1158 vwhere[11+SUBEXPSIZE] = ii;
1159 vwhere[8+SUBEXPSIZE] = SYMTONUM;
1161 if ( t[1] > fromindex+2 ) {
1163 *m++ = *t++ - fromindex;
1164 while ( t < r ) *m++ = *t++;
1168 do { *m++ = *t++; }
while ( t < mstop );
1169 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1183 else if ( *t == DOTPRODUCT ) {
1187 if ( ( i = r[2] ) < 0 )
goto NextDot;
1191 TwoVec: m = AT.WorkPointer;
1195 do { *m++ = *t++; }
while ( t < tstop );
1202 m[-1] = ++AR.CurDum;
1203 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1204 }
while ( --i > 0 );
1209 while ( t < r ) *m++ = *t++;
1213 do { *m++ = *t++; }
while ( t < mstop );
1214 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1221 else if ( v >= OffNum ) {
1222 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1223 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1224 WORD *afirst, *alast, j;
1226 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1227 else { notflag1 = 0; }
1228 afirst = SetElements + Sets[j].first;
1229 alast = SetElements + Sets[j].last;
1231 if ( notflag1 == 0 ) {
1233 if ( *afirst == *r ) {
1234 if ( vwhere[1] == SETTONUM ) {
1235 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1236 AN.FullProto[11+SUBEXPSIZE] = ii;
1238 else if ( vwhere[4] >= 0 ) {
1239 oldv = *(afirst - Sets[j].first
1240 + Sets[vwhere[4]].first);
1245 }
while ( ++afirst < alast );
1249 if ( *afirst == *r )
break;
1250 }
while ( ++afirst < alast );
1251 if ( afirst >= alast )
goto TwoVec;
1258 if ( v == r[1] ) { r[1] = *r; *r = v; }
1262 if ( !par ) {
while ( ++level <= AR.Cnumlhs
1263 && C->
lhs[level][0] == TYPEIDOLD ) {
1266 if ( m[-IDHEAD+2] == SUBALL ) {
1267 if ( ( vv = m[m[1]+3] ) == r[1] ) {
1268 OnePV: TwoProto = AN.FullProto;
1269 TwoPV: m = AT.WorkPointer;
1273 do { *m++ = *t++; }
while ( t < tstop );
1276 vwhere = m + 3 +SUBEXPSIZE;
1280 m[-1] = ++AR.CurDum;
1281 if ( v >= OffNum ) *vwhere = oldv;
1282 if ( vwhere[-2-SUBEXPSIZE] > 12+SUBEXPSIZE ) {
1284 vwhere[5] = SYMTONUM;
1287 vwhere = m + 3+SUBEXPSIZE;
1296 mm[2] = C->
lhs[level][IDHEAD+2];
1297 mm[4] = C->
lhs[level][IDHEAD+4];
1299 if ( vv >= OffNum ) *vwhere = oldvv;
1300 }
while ( --i > 0 );
1303 else if ( vv > OffNum ) {
1304 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1305 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1306 WORD *afirst, *alast, j;
1308 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1309 else { notflag1 = 0; }
1310 afirst = SetElements + Sets[j].first;
1311 alast = SetElements + Sets[j].last;
1312 if ( notflag1 == 0 ) {
1315 if ( *afirst == r[1] ) {
1316 if ( vwhere[1] == SETTONUM ) {
1317 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1318 AN.FullProto[11+SUBEXPSIZE] = ii;
1320 else if ( vwhere[4] >= 0 ) {
1321 oldvv = *(afirst - Sets[j].first
1322 + Sets[vwhere[4]].first);
1327 }
while ( ++afirst < alast );
1331 if ( *afirst == *r )
break;
1332 }
while ( ++afirst < alast );
1333 if ( afirst >= alast )
goto OnePV;
1346 OneOnly: m = AT.WorkPointer;
1350 do { *m++ = *t++; }
while ( t < tstop );
1358 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1361 else if ( v >= OffNum ) {
1362 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1363 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1364 WORD *afirst, *alast, *bfirst, *blast, j;
1366 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1367 else { notflag1 = 0; }
1368 afirst = SetElements + Sets[j].first;
1369 alast = SetElements + Sets[j].last;
1371 if ( notflag1 == 0 ) {
1373 if ( *afirst == *r ) {
1374 if ( vwhere[1] == SETTONUM ) {
1375 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1376 AN.FullProto[11+SUBEXPSIZE] = ii;
1378 else if ( vwhere[4] >= 0 ) {
1379 oldv = *(afirst - Sets[j].first
1380 + Sets[vwhere[4]].first);
1382 Hitlevel1: level2 = level;
1384 if ( !par ) m = C->
lhs[level2];
1387 if ( m[-IDHEAD+2] == SUBALL ) {
1388 if ( ( vv = m[m[1]+3] ) == r[1] )
1390 else if ( vv >= OffNum ) {
1391 if ( m[SUBEXPSIZE+4] != FROMSET &&
1392 m[SUBEXPSIZE+4] != SETTONUM )
goto OnePV;
1393 j = m[SUBEXPSIZE+6];
1394 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag2 = 1; }
1395 else { notflag2 = 0; }
1396 bfirst = SetElements + Sets[j].first;
1397 blast = SetElements + Sets[j].last;
1399 if ( notflag2 == 0 ) {
1401 if ( *bfirst == r[1] ) {
1402 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1403 m[SUBEXPSIZE+8] = SYMTONUM;
1404 m[SUBEXPSIZE+11] = jj;
1406 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1407 oldvv = *(bfirst - Sets[j].first
1408 + Sets[m[SUBEXPSIZE+7]].first);
1413 }
while ( ++bfirst < blast );
1417 if ( *bfirst == r[1] )
break;
1418 }
while ( ++bfirst < blast );
1419 if ( bfirst >= blast )
goto OnePV;
1423 }
while ( ++level2 < AR.Cnumlhs &&
1424 C->
lhs[level2][0] == TYPEIDOLD );
1428 else if ( *afirst == r[1] ) {
1429 if ( vwhere[1] == SETTONUM ) {
1430 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1431 AN.FullProto[11+SUBEXPSIZE] = ii;
1433 else if ( vwhere[4] >= 0 ) {
1434 oldv = *(afirst - Sets[j].first
1435 + Sets[vwhere[4]].first);
1437 Hitlevel2: level2 = level;
1438 while ( ++level2 < AR.Cnumlhs &&
1439 C->
lhs[level2][0] == TYPEIDOLD ) {
1440 if ( !par ) m = C->
lhs[level2];
1443 if ( m[-IDHEAD+2] == SUBALL ) {
1444 if ( ( vv = m[6] ) == *r )
1446 else if ( vv >= OffNum ) {
1447 if ( m[SUBEXPSIZE+4] != FROMSET && m[SUBEXPSIZE+4]
1454 j = m[SUBEXPSIZE+6];
1455 bfirst = SetElements + Sets[j].first;
1456 blast = SetElements + Sets[j].last;
1459 if ( *bfirst == *r ) {
1460 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1461 m[SUBEXPSIZE+8] = SYMTONUM;
1462 m[SUBEXPSIZE+11] = jj;
1464 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1465 oldvv = *(bfirst - Sets[j].first
1466 + Sets[m[SUBEXPSIZE+7]].first);
1471 j = oldv; oldv = oldvv; oldvv = j;
1475 }
while ( ++bfirst < blast );
1479 jj = *r; *r = r[1]; r[1] = jj;
1480 jj = oldv; oldv = oldvv; oldvv = j;
1485 }
while ( ++afirst < alast );
1489 if ( *afirst == *r )
break;
1490 }
while ( ++afirst < alast );
1491 if ( afirst >= alast )
goto Hitlevel1;
1493 if ( *afirst == r[1] )
break;
1494 }
while ( ++afirst < alast );
1495 if ( afirst >= alast )
goto Hitlevel2;
1500 TwoProto = AN.FullProto;
1506 }
while ( r < tstop );
1512 else if ( *t == LEVICIVITA ) {
1517 while ( r < tstop ) {
1519 if ( v >= OffNum && *r < -10 ) {
1520 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1521 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1522 WORD *afirst, *alast, j;
1524 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1525 else { notflag1 = 0; }
1526 afirst = SetElements + Sets[j].first;
1527 alast = SetElements + Sets[j].last;
1529 if ( notflag1 == 0 ) {
1531 if ( *afirst == *r ) {
1532 if ( vwhere[1] == SETTONUM ) {
1533 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1534 AN.FullProto[11+SUBEXPSIZE] = ii;
1536 else if ( vwhere[4] >= 0 ) {
1537 oldv = *(afirst - Sets[j].first
1538 + Sets[vwhere[4]].first);
1543 }
while ( ++afirst < alast );
1547 if ( *afirst == *r )
break;
1548 }
while ( ++afirst < alast );
1549 if ( afirst >= alast )
goto DoVect;
1554 else if ( v == *r ) {
1555 LeVect: m = AT.WorkPointer;
1556 mstop = term + *term;
1559 if ( intens ) *intens = DIRTYSYMFLAG;
1560 do { *m++ = *t++; }
while ( t < tstop );
1564 if ( v >= OffNum ) *vwhere = oldv;
1568 do { *m++ = *t++; }
while ( t < mstop );
1569 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1583 else if ( *t == GAMMA ) {
1587 if ( r < tstop )
goto OneVect;
1593 else if ( *t == INDEX ) {
1603 else if ( *t >= FUNCTION ) {
1605 && functions[*t-FUNCTION].spec >= TENSORFUNCTION
1606 && t[1] > FUNHEAD ) {
1632 int TestSelect(WORD *term, WORD *setp)
1634 WORD *tstop, *t, *s, *el, *elstop, *termstop, *tt, n, ns;
1635 GETSTOP(term,tstop);
1637 while ( term < tstop ) {
1645 while ( --ns >= 0 ) {
1646 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1647 el = SetElements + Sets[*s].first;
1648 elstop = SetElements + Sets[*s].last;
1649 while ( el < elstop ) {
1650 if ( *el++ == *t )
return(1);
1664 while ( --ns >= 0 ) {
1665 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1666 el = SetElements + Sets[*s].first;
1667 elstop = SetElements + Sets[*s].last;
1668 while ( el < elstop ) {
1669 if ( *el++ == *t )
return(1);
1676 while ( --ns >= 0 ) {
1677 if ( Sets[*s].type != CINDEX
1678 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1679 el = SetElements + Sets[*s].first;
1680 elstop = SetElements + Sets[*s].last;
1681 while ( el < elstop ) {
1682 if ( *el++ == *t )
return(1);
1700 while ( --ns >= 0 ) {
1701 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1702 el = SetElements + Sets[*s].first;
1703 elstop = SetElements + Sets[*s].last;
1704 while ( el < elstop ) {
1705 if ( *el++ == *t )
return(1);
1712 while ( --ns >= 0 ) {
1713 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1714 el = SetElements + Sets[*s].first;
1715 elstop = SetElements + Sets[*s].last;
1716 while ( el < elstop ) {
1717 if ( *el++ == *t )
return(1);
1730 if ( *term < FUNCTION )
break;
1733 while ( --ns >= 0 ) {
1734 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1735 el = SetElements + Sets[*s].first;
1736 elstop = SetElements + Sets[*s].last;
1737 while ( el < elstop ) {
1738 if ( *el++ == *term )
return(1);
1742 if ( functions[*term-FUNCTION].spec ) {
1743 n = term[1] - FUNHEAD;
1749 while ( --ns >= 0 ) {
1750 if ( *t < MINSPEC ) {
1751 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1753 else if ( *t >= 0 ) {
1754 if ( Sets[*s].type != CINDEX
1755 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1757 else { s++;
continue; }
1758 el = SetElements + Sets[*s].first;
1759 elstop = SetElements + Sets[*s].last;
1760 while ( el < elstop ) {
1761 if ( *el++ == *t )
return(1);
1770 termstop = term + term[1];
1771 tt = term + FUNHEAD;
1772 while ( tt < termstop ) {
1774 if ( *tt == -SYMBOL ) {
1777 while ( --ns >= 0 ) {
1778 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1779 el = SetElements + Sets[*s].first;
1780 elstop = SetElements + Sets[*s].last;
1781 while ( el < elstop ) {
1782 if ( *el++ == tt[1] )
return(1);
1788 else if ( *tt == -VECTOR || *tt == -MINVECTOR ) {
1791 while ( --ns >= 0 ) {
1792 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1793 el = SetElements + Sets[*s].first;
1794 elstop = SetElements + Sets[*s].last;
1795 while ( el < elstop ) {
1796 if ( *el++ == tt[1] )
return(1);
1802 else if ( *tt == -INDEX ) {
1805 while ( --ns >= 0 ) {
1806 if ( Sets[*s].type != CINDEX
1807 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1808 el = SetElements + Sets[*s].first;
1809 elstop = SetElements + Sets[*s].last;
1810 while ( el < elstop ) {
1811 if ( *el++ == tt[1] )
return(1);
1817 else if ( *tt <= -FUNCTION ) {
1820 while ( --ns >= 0 ) {
1821 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1822 el = SetElements + Sets[*s].first;
1823 elstop = SetElements + Sets[*s].last;
1824 while ( el < elstop ) {
1825 if ( *el++ == -(*tt) )
return(1);
1837 if ( TestSelect(t,setp) )
return(1);
WORD Generator(PHEAD WORD *, WORD)
WORD TestMatch(PHEAD WORD *term, WORD *level)
LONG EndSort(PHEAD WORD *, int)