100 WORD *ll, *m, *w, *llf, *OldWork, *StartWork, *ww, *mm, *t, *OldTermBuffer = 0;
101 WORD power = 0, match = 0, i, msign = 0, ll2;
102 int numdollars = 0, protosize, oldallnumrhs;
103 CBUF *C = cbuf+AM.rbufnum, *CC;
110 if ( *ll == TYPEEXPRESSION ) {
116 else if ( *ll == TYPEREPEAT ) {
120 else if ( *ll == TYPEENDREPEAT ) {
121 if ( *AN.RepPoint ) {
128 if ( AN.RepPoint < AT.RepCount ) {
129 MLOCK(ErrorMessageLock);
130 MesPrint(
"Internal problems with REPEAT count");
131 MUNLOCK(ErrorMessageLock);
137 else if ( *ll == TYPEOPERATION ) {
141 if ( (*(FG.OperaFind[ll[2]]))(BHEAD term,ll) )
return(-1);
147 OldWork = AT.WorkPointer;
148 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;
178 AN.WildValue = w = m + SUBEXPSIZE;
179 protosize = IDHEAD + m[1];
187 if ( ( ll[4] & DOLLARFLAG ) != 0 ) {
188 WORD oldRepPoint = *AN.RepPoint, olddefer = AR.DeferFlag;
193 ww = AT.WorkPointer; i = m[0]; mm = m;
196 *ww++ = 1; *ww++ = 1; *ww++ = 3;
200 if (
Generator(BHEAD StartWork,AR.Cnumlhs) ) {
202 AT.WorkPointer = OldWork;
203 AR.DeferFlag = olddefer;
207 if (
EndSort(BHEAD ww,0) < 0 ) {}
208 AR.DeferFlag = olddefer;
209 if ( *ww == 0 || *(ww+*ww) != 0 ) {
210 if ( AP.lhdollarerror == 0 ) {
214 MLOCK(ErrorMessageLock);
215 MesPrint(
"&LHS must be one term");
216 MUNLOCK(ErrorMessageLock);
217 AP.lhdollarerror = 1;
219 AT.WorkPointer = OldWork;
223 if ( m[*m-1] < 0 ) { msign = 1; m[*m-1] = -m[*m-1]; }
224 if ( *ww || m[*m-1] != 3 || m[*m-2] != 1 || m[*m-3] != 1 ) {
225 MLOCK(ErrorMessageLock);
226 MesPrint(
"Dollar variable develops into an illegal pattern in id-statement");
227 MUNLOCK(ErrorMessageLock);
231 if ( ( *m + 1 + protosize ) > AN.patternbuffersize ) {
232 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
233 AN.patternbuffersize = 2 * (*m) + 2 + protosize;
234 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
236 mm = ll; ww = AN.patternbuffer; i = protosize;
238 AN.FullProto = AN.patternbuffer + IDHEAD;
239 AN.WildValue = w = AN.FullProto + SUBEXPSIZE;
240 AN.WildStop = AN.patternbuffer + protosize;
242 mm = AN.patternbuffer + protosize;
245 m = AN.patternbuffer + protosize;
252 WORD *mmm = m + *m, *m1 = m+1, jm, noveto = 0;
254 if ( *m1 == SYMBOL ) {
255 for ( jm = 2; jm < m1[1]; jm+=2 ) {
256 if ( m1[jm+1] < MAXPOWER && m1[jm+1] > -MAXPOWER )
break;
258 if ( jm < m1[1] ) { noveto = 1;
break; }
260 else if ( *m1 == DOTPRODUCT ) {
261 for ( jm = 2; jm < m1[1]; jm+=3 ) {
262 if ( m1[jm+2] < MAXPOWER && m1[jm+2] > -MAXPOWER )
break;
264 if ( jm < m1[1] ) { noveto = 1;
break; }
266 else { noveto = 1;
break; }
270 ll2 = ll2 & ~SUBMASK;
274 AT.WorkPointer = ww = StartWork;
275 *AN.RepPoint = oldRepPoint;
283 if ( ( ll2 & SUBMASK ) == SUBALL ) {
284 WORD *t = AN.patternbuffer+IDHEAD, *tt;
285 WORD *tstop, *ttstop, ii;
286 t += t[1]; tstop = t + *t; t++;
287 while ( t < tstop ) {
288 if ( *t < FUNCTION )
break;
292 MLOCK(ErrorMessageLock);
293 MesPrint(
"Error: id,all can only be used with (products of) functions and/or tensors.");
294 MUNLOCK(ErrorMessageLock);
297 OldTermBuffer = AN.termbuffer;
298 AN.termbuffer = TermMalloc(
"id,all");
302 tt = term; ttstop = tt+*tt; ttstop -= ABS(ttstop[-1]); tt++;
304 while ( tt < ttstop ) {
305 if ( *tt >= FUNCTION && *tt != AR.PolyFun && *tt != AR.PolyFunInv ) {
306 ii = tt[1]; NCOPY(t,tt,ii);
310 *t++ = 1; *t++ = 1; *t++ = 3; AN.termbuffer[0] = t-AN.termbuffer;
318 while ( w < AN.WildStop ) {
319 if ( *w == LOADDOLLAR ) numdollars++;
323 AN.RepFunList = AT.WorkPointer;
324 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
325 if ( AT.WorkPointer >= AT.WorkTop ) {
326 MLOCK(ErrorMessageLock);
328 MUNLOCK(ErrorMessageLock);
331 AN.DisOrderFlag = ll2 & SUBDISORDER;
332 AN.nogroundlevel = 0;
333 switch ( ll2 & SUBMASK ) {
336 AN.UseFindOnly = 1; AN.ForFindOnly = 0;
337 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
338 FindOnly(BHEAD term,m) ) ) {
340 if ( msign ) term[term[0]-1] = -term[term[0]-1];
346 if ( ( power = FindRest(BHEAD term,m) ) > 0 ) {
347 if ( ( power = FindOnce(BHEAD term,m) ) > 0 ) {
350 if ( msign ) term[term[0]-1] = -term[term[0]-1];
351 Substitute(BHEAD term,m,1);
353 WildDollars(BHEAD (WORD *)0);
356 if ( ww < term+term[0] ) ww = term+term[0];
362 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
363 if ( AT.WorkPointer >= AT.WorkTop ) {
364 MLOCK(ErrorMessageLock);
366 MUNLOCK(ErrorMessageLock);
376 AN.nogroundlevel = 0;
377 }
while ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
378 FindOnce(BHEAD term,m) ) );
381 else if ( power < 0 ) {
383 if ( msign ) term[term[0]-1] = -term[term[0]-1];
384 Substitute(BHEAD term,m,1);
386 WildDollars(BHEAD (WORD *)0);
389 if ( ww < term+term[0] ) ww = term+term[0];
395 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
396 if ( AT.WorkPointer >= AT.WorkTop ) {
397 MLOCK(ErrorMessageLock);
399 MUNLOCK(ErrorMessageLock);
409 }
while ( FindRest(BHEAD term,m) );
413 else if ( power < 0 ) {
414 if ( FindOnce(BHEAD term,m) ) {
416 if ( msign ) term[term[0]-1] = -term[term[0]-1];
417 Substitute(BHEAD term,m,1);
419 WildDollars(BHEAD (WORD *)0);
422 if ( ww < term+term[0] ) ww = term+term[0];
428 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
429 if ( AT.WorkPointer >= AT.WorkTop ) {
430 MLOCK(ErrorMessageLock);
432 MUNLOCK(ErrorMessageLock);
442 }
while ( FindOnce(BHEAD term,m) );
447 if ( ( ll2 & SUBAFTER ) != 0 ) *level = AC.Labels[ll[3]];
450 if ( ( ll2 & SUBAFTERNOT ) != 0 ) *level = AC.Labels[ll[3]];
455 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnce(BHEAD term,m) ) ) {
457 if ( msign ) term[term[0]-1] = -term[term[0]-1];
462 power = FindMulti(BHEAD term,m);
463 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
466 while ( ( power = FindAll(BHEAD term,m,*level,(WORD *)0) ) != 0 ) {
467 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
472 llf = ll + IDHEAD; llf += llf[1]; llf += *llf;
473 AN.UseFindOnly = 1; AN.ForFindOnly = llf;
474 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnly(BHEAD term,m) ) ) {
475 if ( msign ) term[term[0]-1] = -term[term[0]-1];
483 if ( *term > AN.sizeselecttermundo ) {
484 if ( AN.selecttermundo ) M_free(AN.selecttermundo,
"AN.selecttermundo");
485 AN.sizeselecttermundo = *term +10;
486 AN.selecttermundo = (WORD *)Malloc1(
487 AN.sizeselecttermundo*
sizeof(WORD),
"AN.selecttermundo");
489 t1 = term; t2 = AN.selecttermundo; i = *term;
493 Substitute(BHEAD term,m,power);
495 if ( TestSelect(term,llf) ) {
498 t1 = term; t2 = AN.selecttermundo; i = *t2;
501 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
502 *level = AC.Labels[ll[3]];
509 WildDollars(BHEAD (WORD *)0);
513 if ( ( ll2 & SUBAFTER ) != 0 ) {
514 *level = AC.Labels[ll[3]];
518 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
519 *level = AC.Labels[ll[3]];
526 CC = cbuf+AT.allbufnum;
527 oldallnumrhs = CC->numrhs;
528 t =
AddRHS(AT.allbufnum,1);
531 AT.idallmaxnum = ll[5];
533 if ( FindRest(BHEAD AN.termbuffer,m) || AT.idallflag > 1 ) {
534 WORD *t, *tstop, *tt, first = 1, ii;
537 if ( msign ) term[term[0]-1] = -term[term[0]-1];
549 t = term; tstop = t + *t; ii = ABS(tstop[-1]); tstop -= ii;
550 tt = AT.WorkPointer+1;
552 while ( t < tstop ) {
553 if ( *t >= FUNCTION && *t != AR.PolyFun && *t != AR.PolyFunInv ) {
555 *tt++ = SUBEXPRESSION;
559 *tt++ = AT.allbufnum;
566 i = t[1]; NCOPY(tt,t,i);
569 if ( ( ll[4] & NORMALIZEFLAG ) != 0 ) {
576 for ( i = 0; i < ii; i++ ) tt[i] = t[i];
577 Divvy(BHEAD (UWORD *)tt,&na,(UWORD *)(&(AT.idallnum)),1);
586 ii = tt-AT.WorkPointer;
587 *(AT.WorkPointer) = ii;
588 tt = AT.WorkPointer; t = term;
591 if ( ( ll2 & SUBAFTER ) != 0 ) {
592 *level = AC.Labels[ll[3]];
594 TermFree(AN.termbuffer,
"id,all");
595 AN.termbuffer = OldTermBuffer;
596 AT.WorkPointer = AN.RepFunList;
599 TransferBuffer(AT.aebufnum,AT.ebufnum,AT.allbufnum);
604 CC->numrhs = oldallnumrhs;
605 TermFree(AN.termbuffer,
"id,all");
606 AN.termbuffer = OldTermBuffer;
612 Substitute(BHEAD term,m,power);
614 WildDollars(BHEAD (WORD *)0);
618 if ( ( ll2 & SUBAFTER ) != 0 ) {
619 *level = AC.Labels[ll[3]];
623 AT.WorkPointer = AN.RepFunList;
624 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
625 *level = AC.Labels[ll[3]];
629 }
while ( (*level)++ < AR.Cnumlhs && C->
lhs[*level][0] == TYPEIDOLD );
631 AT.WorkPointer = AN.RepFunList;
640 VOID Substitute(PHEAD WORD *term, WORD *pattern, WORD power)
647 WORD nt, *fill, nq, mt;
648 WORD *q, *subterm, *tcoef, oldval1 = 0, newval3, i = 0;
649 WORD PutExpr = 0, sign = 0;
650 TemTerm = AT.WorkPointer;
651 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
652 MLOCK(ErrorMessageLock);
654 MUNLOCK(ErrorMessageLock);
663 tstop = t - ABS(*t) + 1;
668 if ( m < mstop ) {
do {
672 if ( *m == SYMBOL ) {
675 while ( *t != SYMBOL && t < tstop ) {
679 if ( t >= tstop )
goto SubCoef;
686 if ( *m == *t && t < xstop ) {
689 if ( mt >= 2*MAXPOWER ) {
690 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
695 else if ( mt <= -2*MAXPOWER ) {
696 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
710 else if ( *m >= 2*MAXPOWER ) {
711 while ( t < xstop ) { *fill++ = *t++; *fill++ = *t++; }
712 nq = WORDDIF(fill,subterm);
715 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*fill,&newval3) ) {
717 if ( mt >= 2*MAXPOWER ) {
718 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
719 if ( fill[1] -= AN.oldvalue )
goto SubsL2;
722 else if ( mt <= -2*MAXPOWER ) {
723 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
724 if ( fill[1] += AN.oldvalue )
goto SubsL2;
728 if ( fill[1] -= mt * power ) {
741 while ( --nq >= 0 ) *fill++ = *q++;
745 else if ( *m < *t || t >= xstop ) { m += 2; }
746 else { *fill++ = *t++; *fill++ = *t++; }
747 }
while ( m < ystop );
748 while ( t < xstop ) *fill++ = *t++;
749 nq = WORDDIF(fill,subterm);
754 else { fill = subterm; fill -= 2; }
760 else if ( *m == DOTPRODUCT ) {
763 while ( *t > DOTPRODUCT && t < tstop ) {
767 if ( t >= tstop )
goto SubCoef;
768 if ( *t != DOTPRODUCT ) {
772 *fill++ = DOTPRODUCT;
778 if ( *m == *t && m[1] == t[1] && t < xstop ) {
781 if ( mt >= 2*MAXPOWER ) {
782 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
787 else if ( mt <= -2*MAXPOWER ) {
788 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
805 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
806 while ( t < xstop ) {
807 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
812 else if ( m[1] >= (AM.OffsetVector+WILDOFFSET) ) {
813 while ( *m >= *t && t < xstop ) {
814 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
817 SubsL4: nq = WORDDIF(fill,subterm);
820 if ( ( oldval1 && ( (
821 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3)
822 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
824 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
825 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,fill[1],&newval3)
826 ) ) ) || ( !oldval1 && ( (
828 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
830 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
831 && *m == fill[1] ) ) ) ) {
833 if ( mt >= 2*MAXPOWER ) {
834 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
835 if ( fill[2] -= AN.oldvalue )
839 else if ( mt <= -2*MAXPOWER ) {
840 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
841 if ( fill[2] += AN.oldvalue )
846 if ( fill[2] -= mt * power ) {
859 while ( --nq >= 0 ) *fill++ = *q++;
862 else if ( t >= xstop || *m < *t || ( *m == *t && m[1] < t[1] ) )
865 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
867 }
while ( m < ystop );
868 while ( t < xstop ) *fill++ = *t++;
869 nq = WORDDIF(fill,subterm);
874 else { fill = subterm; fill -= 2; }
880 else if ( *m >= FUNCTION ) {
881 while ( *t >= FUNCTION || *t == SUBEXPRESSION ) {
882 nt = WORDDIF(t,term);
883 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
884 if ( nt == AN.RepFunList[mt] )
break;
886 if ( mt >= AN.RepFunNum ) {
892 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
894 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
896 *fill++ = i + FUNHEAD+1;
904 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
905 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
906 ) sign += AN.RepFunList[mt+1];
907 else if ( *m >= FUNCTION+WILDOFFSET
908 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
909 ) sign += AN.RepFunList[mt+1];
920 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
921 i = oldt[1] - m[1] - i;
924 *fill++ = i + FUNHEAD+1;
926 *fill++ = oldt[FUNHEAD];
940 else if ( *m == VECTOR ) {
941 while ( *t > VECTOR ) {
953 if ( *m == *t && m[1] == t[1] ) {
956 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
957 while ( t < xstop ) *fill++ = *t++;
958 nq = WORDDIF(fill,subterm);
960 if ( m[1] < (AM.OffsetIndex+WILDOFFSET) ) {
962 if ( m[1] == fill[1] &&
963 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
971 if ( !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
972 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
974 if ( *fill == oldval1 && fill[1] == AN.oldvalue )
break;
981 if ( nq > 0 ) { NCOPY(fill,q,nq); }
984 else if ( *m <= *t &&
985 m[1] >= (AM.OffsetIndex + WILDOFFSET) ) {
986 while ( *m == *t && t < xstop )
987 { *fill++ = *t++; *fill++ = *t++; }
988 nq = WORDDIF(fill,subterm);
992 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3) )
999 if ( nq > 0 ) { NCOPY(fill,q,nq); }
1002 else { *fill++ = *t++; *fill++ = *t++; }
1003 }
while ( m < ystop );
1004 while ( t < xstop ) *fill++ = *t++;
1005 nq = WORDDIF(fill,subterm);
1010 else { fill = subterm; fill -= 2; }
1018 else if ( *m == INDEX ) {
1019 while ( *t > INDEX ) {
1034 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
1035 while ( t < xstop ) *fill++ = *t++;
1036 nq = WORDDIF(fill, subterm);
1039 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3) ) {
1055 }
while ( m < ystop );
1056 while ( t < xstop ) *fill++ = *t++;
1057 nq = WORDDIF(fill,subterm);
1062 else { fill = subterm; fill -= 2; }
1068 else if ( *m == DELTA ) {
1069 while ( *t > DELTA ) {
1081 if ( *t == *m && t[1] == m[1] ) { m += 2; t += 2; }
1082 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
1083 while ( t < xstop ) *fill++ = *t++;
1088 else if ( m[1] >= (AM.OffsetIndex+WILDOFFSET) ) {
1089 while ( (*m == *t || *m == t[1] ) && ( t < xstop ) ) {
1090 *fill++ = *t++; *fill++ = *t++;
1093 SubsL6: nq = WORDDIF(fill,subterm);
1096 if ( ( oldval1 && ( (
1097 !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3)
1098 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
1100 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1101 && !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,fill[1],&newval3)
1102 ) ) ) || ( !oldval1 && ( (
1104 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
1107 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1120 *fill++ = *t++; *fill++ = *t++;
1122 }
while ( m < ystop );
1123 while ( t < xstop ) *fill++ = *t++;
1124 nq = WORDDIF(fill,subterm);
1129 else { fill = subterm; fill -= 2; }
1135 }
while ( m < mstop ); }
1136 while ( t < tstop ) *fill++ = *t++;
1148 nq = WORDDIF(fill,TemTerm);
1155 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
1157 if ( AT.WorkPointer < fill ) AT.WorkPointer = fill;
1197 WORD FindAll(PHEAD WORD *term, WORD *pattern, WORD level, WORD *par)
1200 WORD *t, *m, *r, *mm, rnum;
1201 WORD *tstop, *mstop, *TwoProto, *vwhere = 0, oldv, oldvv, vv, level2;
1202 WORD v, nq, OffNum = AM.OffsetVector + WILDOFFSET, i, ii = 0, jj;
1203 WORD fromindex, *intens, notflag1 = 0, notflag2 = 0;
1205 C = cbuf+AM.rbufnum;
1217 if ( *t == VECTOR ) {
1221 while ( r < tstop ) {
1223 if ( v >= OffNum ) {
1224 vwhere = AN.FullProto + 3 + SUBEXPSIZE;
1225 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1226 WORD *afirst, *alast, j;
1228 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1229 else { notflag1 = 0; }
1230 afirst = SetElements + Sets[j].first;
1231 alast = SetElements + Sets[j].last;
1233 if ( notflag1 == 0 ) {
1235 if ( *afirst == *r ) {
1236 if ( vwhere[1] == SETTONUM ) {
1237 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1238 AN.FullProto[11+SUBEXPSIZE] = ii;
1240 else if ( vwhere[4] >= 0 ) {
1241 oldv = *(afirst - Sets[j].first
1242 + Sets[vwhere[4]].first);
1247 }
while ( ++afirst < alast );
1251 if ( *afirst == *r )
break;
1252 }
while ( ++afirst < alast );
1253 if ( afirst >= alast )
goto DoVect;
1258 else if ( v == *r ) {
1259 DoVect: m = AT.WorkPointer;
1263 do { *m++ = *t++; }
while ( t < tstop );
1270 if ( fromindex == 1 ) m[-1] = FUNNYVEC;
1272 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1273 if ( vwhere[1] > 12+SUBEXPSIZE ) {
1274 vwhere[11+SUBEXPSIZE] = ii;
1275 vwhere[8+SUBEXPSIZE] = SYMTONUM;
1277 if ( t[1] > fromindex+2 ) {
1279 *m++ = *t++ - fromindex;
1280 while ( t < r ) *m++ = *t++;
1284 do { *m++ = *t++; }
while ( t < mstop );
1285 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1299 else if ( *t == DOTPRODUCT ) {
1303 if ( ( i = r[2] ) < 0 )
goto NextDot;
1307 TwoVec: m = AT.WorkPointer;
1311 do { *m++ = *t++; }
while ( t < tstop );
1318 m[-1] = ++AR.CurDum;
1319 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1320 }
while ( --i > 0 );
1325 while ( t < r ) *m++ = *t++;
1329 do { *m++ = *t++; }
while ( t < mstop );
1330 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1337 else if ( v >= OffNum ) {
1338 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1339 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1340 WORD *afirst, *alast, j;
1342 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1343 else { notflag1 = 0; }
1344 afirst = SetElements + Sets[j].first;
1345 alast = SetElements + Sets[j].last;
1347 if ( notflag1 == 0 ) {
1349 if ( *afirst == *r ) {
1350 if ( vwhere[1] == SETTONUM ) {
1351 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1352 AN.FullProto[11+SUBEXPSIZE] = ii;
1354 else if ( vwhere[4] >= 0 ) {
1355 oldv = *(afirst - Sets[j].first
1356 + Sets[vwhere[4]].first);
1361 }
while ( ++afirst < alast );
1365 if ( *afirst == *r )
break;
1366 }
while ( ++afirst < alast );
1367 if ( afirst >= alast )
goto TwoVec;
1374 if ( v == r[1] ) { r[1] = *r; *r = v; }
1378 if ( !par ) {
while ( ++level <= AR.Cnumlhs
1379 && C->
lhs[level][0] == TYPEIDOLD ) {
1382 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1383 if ( ( vv = m[m[1]+3] ) == r[1] ) {
1384 OnePV: TwoProto = AN.FullProto;
1385 TwoPV: m = AT.WorkPointer;
1389 do { *m++ = *t++; }
while ( t < tstop );
1392 vwhere = m + 3 +SUBEXPSIZE;
1396 m[-1] = ++AR.CurDum;
1397 if ( v >= OffNum ) *vwhere = oldv;
1398 if ( vwhere[-2-SUBEXPSIZE] > 12+SUBEXPSIZE ) {
1400 vwhere[5] = SYMTONUM;
1403 vwhere = m + 3+SUBEXPSIZE;
1412 mm[2] = C->
lhs[level][IDHEAD+2];
1413 mm[4] = C->
lhs[level][IDHEAD+4];
1415 if ( vv >= OffNum ) *vwhere = oldvv;
1416 }
while ( --i > 0 );
1419 else if ( vv > OffNum ) {
1420 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1421 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1422 WORD *afirst, *alast, j;
1424 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1425 else { notflag1 = 0; }
1426 afirst = SetElements + Sets[j].first;
1427 alast = SetElements + Sets[j].last;
1428 if ( notflag1 == 0 ) {
1431 if ( *afirst == r[1] ) {
1432 if ( vwhere[1] == SETTONUM ) {
1433 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1434 AN.FullProto[11+SUBEXPSIZE] = ii;
1436 else if ( vwhere[4] >= 0 ) {
1437 oldvv = *(afirst - Sets[j].first
1438 + Sets[vwhere[4]].first);
1443 }
while ( ++afirst < alast );
1447 if ( *afirst == *r )
break;
1448 }
while ( ++afirst < alast );
1449 if ( afirst >= alast )
goto OnePV;
1462 OneOnly: m = AT.WorkPointer;
1466 do { *m++ = *t++; }
while ( t < tstop );
1474 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1477 else if ( v >= OffNum ) {
1478 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1479 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1480 WORD *afirst, *alast, *bfirst, *blast, j;
1482 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1483 else { notflag1 = 0; }
1484 afirst = SetElements + Sets[j].first;
1485 alast = SetElements + Sets[j].last;
1487 if ( notflag1 == 0 ) {
1489 if ( *afirst == *r ) {
1490 if ( vwhere[1] == SETTONUM ) {
1491 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1492 AN.FullProto[11+SUBEXPSIZE] = ii;
1494 else if ( vwhere[4] >= 0 ) {
1495 oldv = *(afirst - Sets[j].first
1496 + Sets[vwhere[4]].first);
1498 Hitlevel1: level2 = level;
1500 if ( !par ) m = C->
lhs[level2];
1503 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1504 if ( ( vv = m[m[1]+3] ) == r[1] )
1506 else if ( vv >= OffNum ) {
1507 if ( m[SUBEXPSIZE+4] != FROMSET &&
1508 m[SUBEXPSIZE+4] != SETTONUM )
goto OnePV;
1509 j = m[SUBEXPSIZE+6];
1510 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag2 = 1; }
1511 else { notflag2 = 0; }
1512 bfirst = SetElements + Sets[j].first;
1513 blast = SetElements + Sets[j].last;
1515 if ( notflag2 == 0 ) {
1517 if ( *bfirst == r[1] ) {
1518 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1519 m[SUBEXPSIZE+8] = SYMTONUM;
1520 m[SUBEXPSIZE+11] = jj;
1522 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1523 oldvv = *(bfirst - Sets[j].first
1524 + Sets[m[SUBEXPSIZE+7]].first);
1529 }
while ( ++bfirst < blast );
1533 if ( *bfirst == r[1] )
break;
1534 }
while ( ++bfirst < blast );
1535 if ( bfirst >= blast )
goto OnePV;
1539 }
while ( ++level2 < AR.Cnumlhs &&
1540 C->
lhs[level2][0] == TYPEIDOLD );
1544 else if ( *afirst == r[1] ) {
1545 if ( vwhere[1] == SETTONUM ) {
1546 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1547 AN.FullProto[11+SUBEXPSIZE] = ii;
1549 else if ( vwhere[4] >= 0 ) {
1550 oldv = *(afirst - Sets[j].first
1551 + Sets[vwhere[4]].first);
1553 Hitlevel2: level2 = level;
1554 while ( ++level2 < AR.Cnumlhs &&
1555 C->
lhs[level2][0] == TYPEIDOLD ) {
1556 if ( !par ) m = C->
lhs[level2];
1559 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1560 if ( ( vv = m[6] ) == *r )
1562 else if ( vv >= OffNum ) {
1563 if ( m[SUBEXPSIZE+4] != FROMSET && m[SUBEXPSIZE+4]
1570 j = m[SUBEXPSIZE+6];
1571 bfirst = SetElements + Sets[j].first;
1572 blast = SetElements + Sets[j].last;
1575 if ( *bfirst == *r ) {
1576 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1577 m[SUBEXPSIZE+8] = SYMTONUM;
1578 m[SUBEXPSIZE+11] = jj;
1580 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1581 oldvv = *(bfirst - Sets[j].first
1582 + Sets[m[SUBEXPSIZE+7]].first);
1587 j = oldv; oldv = oldvv; oldvv = j;
1591 }
while ( ++bfirst < blast );
1595 jj = *r; *r = r[1]; r[1] = jj;
1596 jj = oldv; oldv = oldvv; oldvv = j;
1601 }
while ( ++afirst < alast );
1605 if ( *afirst == *r )
break;
1606 }
while ( ++afirst < alast );
1607 if ( afirst >= alast )
goto Hitlevel1;
1609 if ( *afirst == r[1] )
break;
1610 }
while ( ++afirst < alast );
1611 if ( afirst >= alast )
goto Hitlevel2;
1616 TwoProto = AN.FullProto;
1622 }
while ( r < tstop );
1628 else if ( *t == LEVICIVITA ) {
1633 while ( r < tstop ) {
1635 if ( v >= OffNum && *r < -10 ) {
1636 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1637 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1638 WORD *afirst, *alast, j;
1640 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1641 else { notflag1 = 0; }
1642 afirst = SetElements + Sets[j].first;
1643 alast = SetElements + Sets[j].last;
1645 if ( notflag1 == 0 ) {
1647 if ( *afirst == *r ) {
1648 if ( vwhere[1] == SETTONUM ) {
1649 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1650 AN.FullProto[11+SUBEXPSIZE] = ii;
1652 else if ( vwhere[4] >= 0 ) {
1653 oldv = *(afirst - Sets[j].first
1654 + Sets[vwhere[4]].first);
1659 }
while ( ++afirst < alast );
1663 if ( *afirst == *r )
break;
1664 }
while ( ++afirst < alast );
1665 if ( afirst >= alast )
goto DoVect;
1670 else if ( v == *r ) {
1671 LeVect: m = AT.WorkPointer;
1672 mstop = term + *term;
1675 if ( intens ) *intens = DIRTYSYMFLAG;
1676 do { *m++ = *t++; }
while ( t < tstop );
1680 if ( v >= OffNum ) *vwhere = oldv;
1684 do { *m++ = *t++; }
while ( t < mstop );
1685 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1699 else if ( *t == GAMMA ) {
1703 if ( r < tstop )
goto OneVect;
1709 else if ( *t == INDEX ) {
1719 else if ( *t >= FUNCTION ) {
1721 && functions[*t-FUNCTION].spec >= TENSORFUNCTION
1722 && t[1] > FUNHEAD ) {
1748 int TestSelect(WORD *term, WORD *setp)
1750 WORD *tstop, *t, *s, *el, *elstop, *termstop, *tt, n, ns;
1751 GETSTOP(term,tstop);
1753 while ( term < tstop ) {
1761 while ( --ns >= 0 ) {
1762 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1763 el = SetElements + Sets[*s].first;
1764 elstop = SetElements + Sets[*s].last;
1765 while ( el < elstop ) {
1766 if ( *el++ == *t )
return(1);
1780 while ( --ns >= 0 ) {
1781 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1782 el = SetElements + Sets[*s].first;
1783 elstop = SetElements + Sets[*s].last;
1784 while ( el < elstop ) {
1785 if ( *el++ == *t )
return(1);
1792 while ( --ns >= 0 ) {
1793 if ( Sets[*s].type != CINDEX
1794 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1795 el = SetElements + Sets[*s].first;
1796 elstop = SetElements + Sets[*s].last;
1797 while ( el < elstop ) {
1798 if ( *el++ == *t )
return(1);
1816 while ( --ns >= 0 ) {
1817 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1818 el = SetElements + Sets[*s].first;
1819 elstop = SetElements + Sets[*s].last;
1820 while ( el < elstop ) {
1821 if ( *el++ == *t )
return(1);
1828 while ( --ns >= 0 ) {
1829 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1830 el = SetElements + Sets[*s].first;
1831 elstop = SetElements + Sets[*s].last;
1832 while ( el < elstop ) {
1833 if ( *el++ == *t )
return(1);
1846 if ( *term < FUNCTION )
break;
1849 while ( --ns >= 0 ) {
1850 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1851 el = SetElements + Sets[*s].first;
1852 elstop = SetElements + Sets[*s].last;
1853 while ( el < elstop ) {
1854 if ( *el++ == *term )
return(1);
1858 if ( functions[*term-FUNCTION].spec ) {
1859 n = term[1] - FUNHEAD;
1865 while ( --ns >= 0 ) {
1866 if ( *t < MINSPEC ) {
1867 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1869 else if ( *t >= 0 ) {
1870 if ( Sets[*s].type != CINDEX
1871 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1873 else { s++;
continue; }
1874 el = SetElements + Sets[*s].first;
1875 elstop = SetElements + Sets[*s].last;
1876 while ( el < elstop ) {
1877 if ( *el++ == *t )
return(1);
1886 termstop = term + term[1];
1887 tt = term + FUNHEAD;
1888 while ( tt < termstop ) {
1890 if ( *tt == -SYMBOL ) {
1893 while ( --ns >= 0 ) {
1894 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1895 el = SetElements + Sets[*s].first;
1896 elstop = SetElements + Sets[*s].last;
1897 while ( el < elstop ) {
1898 if ( *el++ == tt[1] )
return(1);
1904 else if ( *tt == -VECTOR || *tt == -MINVECTOR ) {
1907 while ( --ns >= 0 ) {
1908 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1909 el = SetElements + Sets[*s].first;
1910 elstop = SetElements + Sets[*s].last;
1911 while ( el < elstop ) {
1912 if ( *el++ == tt[1] )
return(1);
1918 else if ( *tt == -INDEX ) {
1921 while ( --ns >= 0 ) {
1922 if ( Sets[*s].type != CINDEX
1923 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1924 el = SetElements + Sets[*s].first;
1925 elstop = SetElements + Sets[*s].last;
1926 while ( el < elstop ) {
1927 if ( *el++ == tt[1] )
return(1);
1933 else if ( *tt <= -FUNCTION ) {
1936 while ( --ns >= 0 ) {
1937 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1938 el = SetElements + Sets[*s].first;
1939 elstop = SetElements + Sets[*s].last;
1940 while ( el < elstop ) {
1941 if ( *el++ == -(*tt) )
return(1);
1953 if ( TestSelect(t,setp) )
return(1);
1982 VOID SubsInAll(PHEAD0)
1987 WORD *tstop, *mstop, *xstop;
1988 WORD nt, *fill, nq, mt;
1990 WORD PutExpr = 0, sign = 0;
1997 TemTerm = AT.WorkPointer;
1998 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
1999 MLOCK(ErrorMessageLock);
2001 MUNLOCK(ErrorMessageLock);
2004 m = AN.patternbuffer + IDHEAD; m += m[1];
2007 term = AN.termbuffer;
2008 tstop = term + *term; tcoef = tstop-1; tstop -= ABS(tstop[-1]);
2013 while ( m < mstop ) {
2014 while ( t < tstop ) {
2015 nt = WORDDIF(t,term);
2016 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
2017 if ( nt == AN.RepFunList[mt] )
break;
2019 if ( mt >= AN.RepFunNum ) {
2025 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
2027 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
2029 *fill++ = i + FUNHEAD+1;
2037 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
2038 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
2039 ) sign += AN.RepFunList[mt+1];
2040 else if ( *m >= FUNCTION+WILDOFFSET
2041 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
2042 ) sign += AN.RepFunList[mt+1];
2044 WORD *pstart = fill, *p, *w, *ww;
2060 p = pstart + SUBEXPSIZE;
2061 while ( p < fill ) {
2068 w = cbuf[AT.ebufnum].rhs[p[3]];
2069 ww = cbuf[AT.ebufnum].rhs[p[3]+1];
2077 AddNtoC(AT.aebufnum,ww-w,w,11);
2078 p[3] = cbuf[AT.aebufnum].numrhs;
2079 cbuf[AT.aebufnum].rhs[p[3]+1] = cbuf[AT.aebufnum].Pointer;
2095 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
2096 i = oldt[1] - m[1] - i;
2099 *fill++ = i + FUNHEAD+1;
2101 *fill++ = oldt[FUNHEAD];
2111 while ( t < tstop ) *fill++ = *t++;
2123 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
2125 *TemTerm = fill-TemTerm;
2129 AddNtoC(AT.allbufnum,TemTerm[0],TemTerm,12);
2130 cbuf[AT.allbufnum].Pointer[0] = 0;
2143 VOID TransferBuffer(
int from,
int to,
int spectator)
2145 CBUF *C = cbuf + spectator;
2146 CBUF *Cf = cbuf + from;
2147 CBUF *Ct = cbuf + to;
2148 int offset = Ct->numrhs;
2150 WORD *t, *tt, *ttt, *tstop, size;
2151 for ( i = 1; i <= Cf->numrhs; i++ ) {
2152 size = Cf->
rhs[i+1]-Cf->
rhs[i];
2161 t = C->
rhs[C->numrhs];
2164 tstop = t-ABS(t[-1]);
2165 while ( tt < tstop ) {
2166 if ( *tt == SUBEXPRESSION ) {
2167 ttt = tt+SUBEXPSIZE; tt += tt[1];
2168 while ( ttt < tt ) {
2193 #define PutInBuffers(pow) \ 2194 AddRHS(AT.ebufnum,1); \ 2195 *out++ = SUBEXPRESSION; \ 2196 *out++ = SUBEXPSIZE; \ 2197 *out++ = C->numrhs; \ 2199 *out++ = AT.ebufnum; \ 2201 r = AT.pWorkSpace[rhs+i]; \ 2203 oldinr = r[*r]; r[*r] = 0; \ 2204 AddNtoC(AT.ebufnum,(*r+1-ARGHEAD),(r+ARGHEAD),14); \ 2208 ToGeneral(r,buffer,1); \ 2209 buffer[buffer[0]] = 0; \ 2210 AddNtoC(AT.ebufnum,buffer[0]+1,buffer,15); \ 2213 int TakeIDfunction(PHEAD WORD *term)
2215 WORD *tstop, *t, *r, *m, *f, *nextf, *funstop, *left, *l, *newterm;
2216 WORD *out, oldinr, pow;
2218 int i, ii, j, numsub, numfound = 0, first;
2221 GETSTOP(term,tstop);
2222 for ( t = term+1; t < tstop; t += t[1] ) {
if ( *t == IDFUNCTION )
break; }
2223 if ( t >= tstop )
return(0);
2227 funstop = t + t[1]; f = t + FUNHEAD;
2228 left = term + *term;
2229 l = left+1; numsub = 0;
2230 while ( f < funstop ) {
2231 nextf = f; NEXTARG(nextf)
2232 if ( nextf >= funstop ) {
return(0); }
2233 if ( *f == -SYMBOL ) { *l++ = SYMBOL; *l++ = 4; *l++ = f[1]; *l++ = 1; }
2234 else if ( *f < -FUNCTION ) { *l++ = *f; *l++ = FUNHEAD; FILLFUN(l) }
2235 else if ( *f > 0 ) {
2236 if ( *f != f[ARGHEAD]+ARGHEAD )
goto noaction;
2237 if ( nextf[-1] != 3 || nextf[-2] != 1 || nextf[-3] != 1 )
goto noaction;
2238 if ( f[ARGHEAD] <= 4 )
goto noaction;
2239 if ( f[ARGHEAD] != f[ARGHEAD+2]+4 )
goto noaction;
2240 if ( f[ARGHEAD] == 8 && f[ARGHEAD+1] == SYMBOL ) {
2241 for ( i = 0; i < 4; i++ ) *l++ = f[ARGHEAD+1+i];
2243 else if ( f[ARGHEAD] == 9 && f[ARGHEAD+1] == DOTPRODUCT ) {
2244 for ( i = 0; i < 5; i++ ) *l++ = f[ARGHEAD+1+i];
2246 else if ( f[ARGHEAD+1] >= FUNCTION ) {
2247 for ( i = 0; i < f[ARGHEAD+1]-4; i++ ) *l++ = f[ARGHEAD+1+i];
2256 C = cbuf+AT.ebufnum;
2262 WantAddPointers(2*numsub);
2263 lhs = AT.pWorkPointer;
2265 AT.pWorkPointer = rhs+numsub;
2266 f = t + FUNHEAD; l = left+1;
2267 for ( i = 0; i < numsub; i++ ) {
2268 AT.pWorkSpace[lhs+i] = l; l += l[1];
2270 AT.pWorkSpace[rhs+i] = f;
2279 t = term+1; newterm = AT.WorkPointer; out = newterm+1;
2280 while ( t < tstop ) {
2281 if ( *t == IDFUNCTION && first ) { first = 0; t += t[1];
continue; }
2282 if ( *t >= FUNCTION ) {
2283 for ( i = 0; i < numsub; i++ ) {
2284 m = AT.pWorkSpace[lhs+i];
2285 if ( *m != *t )
continue;
2286 for ( j = 1; j < t[1]; j++ ) {
2287 if ( m[j] != t[j] )
break;
2289 if ( j != t[1] )
continue;
2298 if ( i == numsub ) {
2299 j = t[1]; NCOPY(out,t,j)
2302 else if ( *t == SYMBOL ) {
2303 for ( i = 0; i < numsub; i++ ) {
2304 m = AT.pWorkSpace[lhs+i];
2305 if ( *m != SYMBOL )
continue;
2306 for ( ii = 2; ii < t[1]; ii += 2 ) {
2307 if ( m[2] != t[ii] )
continue;
2309 if ( pow <= 0 )
continue;
2310 t[ii+1] = t[ii+1]%m[3];
2322 m = out; *out++ = t[0]; *out++ = t[1];
2323 for ( ii = 2; ii < t[1]; ii += 2 ) {
2324 if ( t[ii+1] ) { *out++ = t[ii]; *out++ = t[ii+1]; }
2327 if ( m[1] == 2 ) out = m;
2330 else if ( *t == DOTPRODUCT ) {
2331 for ( i = 0; i < numsub; i++ ) {
2332 m = AT.pWorkSpace[lhs+i];
2333 if ( *m != DOTPRODUCT )
continue;
2334 for ( ii = 2; ii < t[1]; ii += 3 ) {
2335 if ( m[2] != t[ii] || m[3] != t[ii+1] )
continue;
2337 if ( pow <= 0 )
continue;
2338 t[ii+2] = t[ii+2]%m[4];
2350 m = out; *out++ = t[0]; *out++ = t[1];
2351 for ( ii = 2; ii < t[1]; ii += 3 ) {
2352 if ( t[ii+2] ) { *out++ = t[ii]; *out++ = t[ii+1]; *out++ = t[ii+2]; }
2355 if ( m[1] == 2 ) out = m;
2359 j = t[1]; NCOPY(out,t,j)
2365 t = tstop; r = term+*term;
while ( t < r ) *out++ = *t++;
2366 *newterm = out-newterm;
2371 t = term; r = newterm; NCOPY(t,r,i)
2376 AT.pWorkPointer = lhs;
WORD Generator(PHEAD WORD *, WORD)
WORD TestMatch(PHEAD WORD *term, WORD *level)
LONG EndSort(PHEAD WORD *, int)