100 WORD *ll, *m, *w, *llf, *OldWork, *StartWork, *ww, *mm, *t, *OldTermBuffer = 0;
101 WORD power = 0, i, msign = 0, ll2;
103 int numdollars = 0, protosize, oldallnumrhs;
104 CBUF *C = cbuf+AM.rbufnum, *CC;
111 if ( *ll == TYPEEXPRESSION ) {
117 else if ( *ll == TYPEREPEAT ) {
121 else if ( *ll == TYPEENDREPEAT ) {
122 if ( *AN.RepPoint ) {
129 if ( AN.RepPoint < AT.RepCount ) {
131 MLOCK(ErrorMessageLock);
132 MesPrint(
"!>Internal problems with REPEAT count");
133 MUNLOCK(ErrorMessageLock);
140 else if ( *ll == TYPEOPERATION ) {
144 if ( (*(FG.OperaFind[ll[2]]))(BHEAD term,ll) )
return(-1);
150 OldWork = AT.WorkPointer;
151 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
169 if ( ( ja + 2 ) > AN.patternbuffersize ) {
170 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
171 AN.patternbuffersize = 2 * ja + 2;
172 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
175 ma = AN.patternbuffer;
181 AN.WildValue = w = m + SUBEXPSIZE;
182 protosize = IDHEAD + m[1];
190 if ( ( ll[4] & DOLLARFLAG ) != 0 ) {
191 WORD oldRepPoint = *AN.RepPoint, olddefer = AR.DeferFlag;
196 ww = AT.WorkPointer; i = m[0]; mm = m;
199 *ww++ = 1; *ww++ = 1; *ww++ = 3;
203 if (
Generator(BHEAD StartWork,AR.Cnumlhs) ) {
205 AT.WorkPointer = OldWork;
206 AR.DeferFlag = olddefer;
210 if (
EndSort(BHEAD ww,0) < 0 ) {}
211 AR.DeferFlag = olddefer;
212 if ( *ww == 0 || *(ww+*ww) != 0 ) {
213 if ( AP.lhdollarerror == 0 ) {
217 MLOCK(ErrorMessageLock);
218 MesPrint(
"&LHS must be one term");
219 MUNLOCK(ErrorMessageLock);
220 AP.lhdollarerror = 1;
222 AT.WorkPointer = OldWork;
226 if ( m[*m-1] < 0 ) { msign = 1; m[*m-1] = -m[*m-1]; }
227 if ( *ww || m[*m-1] != 3 || m[*m-2] != 1 || m[*m-3] != 1 ) {
228 MLOCK(ErrorMessageLock);
229 MesPrint(
"Dollar variable develops into an illegal pattern in id-statement");
230 MUNLOCK(ErrorMessageLock);
234 if ( ( *m + 1 + protosize ) > AN.patternbuffersize ) {
235 if ( AN.patternbuffer ) M_free(AN.patternbuffer,
"AN.patternbuffer");
236 AN.patternbuffersize = 2 * (*m) + 2 + protosize;
237 AN.patternbuffer = (WORD *)Malloc1(AN.patternbuffersize *
sizeof(WORD),
239 mm = ll; ww = AN.patternbuffer; i = protosize;
241 AN.FullProto = AN.patternbuffer + IDHEAD;
242 AN.WildValue = w = AN.FullProto + SUBEXPSIZE;
243 AN.WildStop = AN.patternbuffer + protosize;
245 mm = AN.patternbuffer + protosize;
248 m = AN.patternbuffer + protosize;
255 WORD *mmm = m + *m, *m1 = m+1, jm, noveto = 0;
257 if ( *m1 == SYMBOL ) {
258 for ( jm = 2; jm < m1[1]; jm+=2 ) {
259 if ( m1[jm+1] < MAXPOWER && m1[jm+1] > -MAXPOWER )
break;
261 if ( jm < m1[1] ) { noveto = 1;
break; }
263 else if ( *m1 == DOTPRODUCT ) {
264 for ( jm = 2; jm < m1[1]; jm+=3 ) {
265 if ( m1[jm+2] < MAXPOWER && m1[jm+2] > -MAXPOWER )
break;
267 if ( jm < m1[1] ) { noveto = 1;
break; }
269 else { noveto = 1;
break; }
273 ll2 = ll2 & ~SUBMASK;
277 AT.WorkPointer = ww = StartWork;
278 *AN.RepPoint = oldRepPoint;
286 if ( ( ll2 & SUBMASK ) == SUBALL ) {
287 WORD *t = AN.patternbuffer+IDHEAD, *tt;
288 WORD *tstop, *ttstop, ii;
289 t += t[1]; tstop = t + *t; t++;
290 while ( t < tstop ) {
291 if ( *t < FUNCTION )
break;
295 MLOCK(ErrorMessageLock);
296 MesPrint(
"Error: id,all can only be used with (products of) functions and/or tensors.");
297 MUNLOCK(ErrorMessageLock);
300 OldTermBuffer = AN.termbuffer;
301 AN.termbuffer = TermMalloc(
"id,all");
305 tt = term; ttstop = tt+*tt; ttstop -= ABS(ttstop[-1]); tt++;
307 while ( tt < ttstop ) {
308 if ( *tt >= FUNCTION && *tt != AR.PolyFun && *tt != AR.PolyFunInv ) {
309 ii = tt[1]; NCOPY(t,tt,ii);
313 *t++ = 1; *t++ = 1; *t++ = 3; AN.termbuffer[0] = t-AN.termbuffer;
321 while ( w < AN.WildStop ) {
322 if ( *w == LOADDOLLAR ) numdollars++;
326 AN.RepFunList = AT.WorkPointer;
327 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
328 if ( AT.WorkPointer >= AT.WorkTop ) {
329 MLOCK(ErrorMessageLock);
331 MUNLOCK(ErrorMessageLock);
334 AN.DisOrderFlag = ll2 & SUBDISORDER;
335 AN.nogroundlevel = 0;
336 switch ( ll2 & SUBMASK ) {
339 AN.UseFindOnly = 1; AN.ForFindOnly = 0;
340 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
341 FindOnly(BHEAD term,m) ) ) {
343 if ( msign ) term[term[0]-1] = -term[term[0]-1];
349 if ( ( power = FindRest(BHEAD term,m) ) > 0 ) {
350 if ( ( power = FindOnce(BHEAD term,m) ) > 0 ) {
353 if ( msign ) term[term[0]-1] = -term[term[0]-1];
354 Substitute(BHEAD term,m,1);
356 WildDollars(BHEAD (WORD *)0);
359 if ( ww < term+term[0] ) ww = term+term[0];
365 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
366 if ( AT.WorkPointer >= AT.WorkTop ) {
367 MLOCK(ErrorMessageLock);
369 MUNLOCK(ErrorMessageLock);
379 AN.nogroundlevel = 0;
380 }
while ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
381 FindOnce(BHEAD term,m) ) );
384 else if ( power < 0 ) {
386 if ( msign ) term[term[0]-1] = -term[term[0]-1];
387 Substitute(BHEAD term,m,1);
389 WildDollars(BHEAD (WORD *)0);
392 if ( ww < term+term[0] ) ww = term+term[0];
398 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
399 if ( AT.WorkPointer >= AT.WorkTop ) {
400 MLOCK(ErrorMessageLock);
402 MUNLOCK(ErrorMessageLock);
412 }
while ( FindRest(BHEAD term,m) );
416 else if ( power < 0 ) {
417 if ( FindOnce(BHEAD term,m) ) {
419 if ( msign ) term[term[0]-1] = -term[term[0]-1];
420 Substitute(BHEAD term,m,1);
422 WildDollars(BHEAD (WORD *)0);
425 if ( ww < term+term[0] ) ww = term+term[0];
431 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer/2);
432 if ( AT.WorkPointer >= AT.WorkTop ) {
433 MLOCK(ErrorMessageLock);
435 MUNLOCK(ErrorMessageLock);
445 }
while ( FindOnce(BHEAD term,m) );
450 if ( ( ll2 & SUBAFTER ) != 0 ) *level = AC.Labels[ll[3]];
453 if ( ( ll2 & SUBAFTERNOT ) != 0 ) *level = AC.Labels[ll[3]];
458 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnce(BHEAD term,m) ) ) {
460 if ( msign ) term[term[0]-1] = -term[term[0]-1];
465 power = FindMulti(BHEAD term,m);
466 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
469 while ( ( power = FindAll(BHEAD term,m,*level,(WORD *)0) ) != 0 ) {
470 if ( ( power & 1 ) != 0 && msign ) term[term[0]-1] = -term[term[0]-1];
475 llf = ll + IDHEAD; llf += llf[1]; llf += *llf;
476 AN.UseFindOnly = 1; AN.ForFindOnly = llf;
477 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind || FindOnly(BHEAD term,m) ) ) {
478 if ( msign ) term[term[0]-1] = -term[term[0]-1];
486 if ( *term > AN.sizeselecttermundo ) {
487 if ( AN.selecttermundo ) M_free(AN.selecttermundo,
"AN.selecttermundo");
488 AN.sizeselecttermundo = *term +10;
489 AN.selecttermundo = (WORD *)Malloc1(
490 AN.sizeselecttermundo*
sizeof(WORD),
"AN.selecttermundo");
492 t1 = term; t2 = AN.selecttermundo; i = *term;
496 Substitute(BHEAD term,m,power);
498 if ( TestSelect(term,llf) ) {
501 t1 = term; t2 = AN.selecttermundo; i = *t2;
504 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
505 *level = AC.Labels[ll[3]];
512 WildDollars(BHEAD (WORD *)0);
516 if ( ( ll2 & SUBAFTER ) != 0 ) {
517 *level = AC.Labels[ll[3]];
521 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
522 *level = AC.Labels[ll[3]];
529 CC = cbuf+AT.allbufnum;
530 oldallnumrhs = CC->numrhs;
531 t =
AddRHS(AT.allbufnum,1);
534 AT.idallmaxnum = ll[5];
536 if ( FindRest(BHEAD AN.termbuffer,m) || AT.idallflag > 1 ) {
537 WORD *t, *tstop, *tt, first = 1, ii;
540 if ( msign ) term[term[0]-1] = -term[term[0]-1];
552 t = term; tstop = t + *t; ii = ABS(tstop[-1]); tstop -= ii;
553 tt = AT.WorkPointer+1;
555 while ( t < tstop ) {
556 if ( *t >= FUNCTION && *t != AR.PolyFun && *t != AR.PolyFunInv ) {
558 *tt++ = SUBEXPRESSION;
562 *tt++ = AT.allbufnum;
569 i = t[1]; NCOPY(tt,t,i);
572 if ( ( ll[4] & NORMALIZEFLAG ) != 0 ) {
579 for ( i = 0; i < ii; i++ ) tt[i] = t[i];
580 Divvy(BHEAD (UWORD *)tt,&na,(UWORD *)(&(AT.idallnum)),1);
589 ii = tt-AT.WorkPointer;
590 *(AT.WorkPointer) = ii;
591 tt = AT.WorkPointer; t = term;
594 if ( ( ll2 & SUBAFTER ) != 0 ) {
595 *level = AC.Labels[ll[3]];
597 TermFree(AN.termbuffer,
"id,all");
598 AN.termbuffer = OldTermBuffer;
599 AT.WorkPointer = AN.RepFunList;
602 TransferBuffer(AT.aebufnum,AT.ebufnum,AT.allbufnum);
607 CC->numrhs = oldallnumrhs;
608 TermFree(AN.termbuffer,
"id,all");
609 AN.termbuffer = OldTermBuffer;
615 Substitute(BHEAD term,m,power);
617 WildDollars(BHEAD (WORD *)0);
621 if ( ( ll2 & SUBAFTER ) != 0 ) {
622 *level = AC.Labels[ll[3]];
626 AT.WorkPointer = AN.RepFunList;
627 if ( ( ll2 & SUBAFTERNOT ) != 0 ) {
628 *level = AC.Labels[ll[3]];
632 }
while ( (*level)++ < AR.Cnumlhs && C->
lhs[*level][0] == TYPEIDOLD );
634 AT.WorkPointer = AN.RepFunList;
643void Substitute(PHEAD WORD *term, WORD *pattern, WORD power)
650 WORD nt, *fill, nq, mt;
651 WORD *q, *subterm, *tcoef, oldval1 = 0, newval3, i = 0;
652 WORD PutExpr = 0, sign = 0;
653 TemTerm = AT.WorkPointer;
654 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
655 MLOCK(ErrorMessageLock);
657 MUNLOCK(ErrorMessageLock);
666 tstop = t - ABS(*t) + 1;
671 if ( m < mstop ) {
do {
675 if ( *m == SYMBOL ) {
678 while ( *t != SYMBOL && t < tstop ) {
682 if ( t >= tstop )
goto SubCoef;
689 if ( *m == *t && t < xstop ) {
692 if ( mt >= 2*MAXPOWER ) {
693 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
698 else if ( mt <= -2*MAXPOWER ) {
699 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
713 else if ( *m >= 2*MAXPOWER ) {
714 while ( t < xstop ) { *fill++ = *t++; *fill++ = *t++; }
715 nq = WORDDIF(fill,subterm);
718 if ( !CheckWild(BHEAD *m-2*MAXPOWER,SYMTOSYM,*fill,&newval3) ) {
720 if ( mt >= 2*MAXPOWER ) {
721 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
722 if ( fill[1] -= AN.oldvalue )
goto SubsL2;
725 else if ( mt <= -2*MAXPOWER ) {
726 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
727 if ( fill[1] += AN.oldvalue )
goto SubsL2;
731 if ( fill[1] -= mt * power ) {
744 while ( --nq >= 0 ) *fill++ = *q++;
748 else if ( *m < *t || t >= xstop ) { m += 2; }
749 else { *fill++ = *t++; *fill++ = *t++; }
750 }
while ( m < ystop );
751 while ( t < xstop ) *fill++ = *t++;
752 nq = WORDDIF(fill,subterm);
757 else { fill = subterm; fill -= 2; }
763 else if ( *m == DOTPRODUCT ) {
766 while ( *t > DOTPRODUCT && t < tstop ) {
770 if ( t >= tstop )
goto SubCoef;
771 if ( *t != DOTPRODUCT ) {
775 *fill++ = DOTPRODUCT;
781 if ( *m == *t && m[1] == t[1] && t < xstop ) {
784 if ( mt >= 2*MAXPOWER ) {
785 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
790 else if ( mt <= -2*MAXPOWER ) {
791 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
808 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
809 while ( t < xstop ) {
810 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
815 else if ( m[1] >= (AM.OffsetVector+WILDOFFSET) ) {
816 while ( *m >= *t && t < xstop ) {
817 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
820SubsL4: nq = WORDDIF(fill,subterm);
823 if ( ( oldval1 && ( (
824 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3)
825 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
827 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
828 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,fill[1],&newval3)
829 ) ) ) || ( !oldval1 && ( (
831 && !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,fill[1],&newval3)
833 !CheckWild(BHEAD m[1]-WILDOFFSET,VECTOVEC,*fill,&newval3)
834 && *m == fill[1] ) ) ) ) {
836 if ( mt >= 2*MAXPOWER ) {
837 if ( CheckWild(BHEAD mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
838 if ( fill[2] -= AN.oldvalue )
842 else if ( mt <= -2*MAXPOWER ) {
843 if ( CheckWild(BHEAD -mt-2*MAXPOWER,SYMTONUM,-MAXPOWER,&newval3) ) {
844 if ( fill[2] += AN.oldvalue )
849 if ( fill[2] -= mt * power ) {
862 while ( --nq >= 0 ) *fill++ = *q++;
865 else if ( t >= xstop || *m < *t || ( *m == *t && m[1] < t[1] ) )
868 *fill++ = *t++; *fill++ = *t++; *fill++ = *t++;
870 }
while ( m < ystop );
871 while ( t < xstop ) *fill++ = *t++;
872 nq = WORDDIF(fill,subterm);
877 else { fill = subterm; fill -= 2; }
883 else if ( *m >= FUNCTION ) {
884 while ( *t >= FUNCTION || *t == SUBEXPRESSION ) {
885 nt = WORDDIF(t,term);
886 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
887 if ( nt == AN.RepFunList[mt] )
break;
889 if ( mt >= AN.RepFunNum ) {
895 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
897 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
899 *fill++ = i + FUNHEAD+1;
907 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
908 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
909 ) sign += AN.RepFunList[mt+1];
910 else if ( *m >= FUNCTION+WILDOFFSET
911 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
912 ) sign += AN.RepFunList[mt+1];
923 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
924 i = oldt[1] - m[1] - i;
927 *fill++ = i + FUNHEAD+1;
929 *fill++ = oldt[FUNHEAD];
943 else if ( *m == VECTOR ) {
944 while ( *t > VECTOR ) {
956 if ( *m == *t && m[1] == t[1] ) {
959 else if ( *m >= (AM.OffsetVector+WILDOFFSET) ) {
960 while ( t < xstop ) *fill++ = *t++;
961 nq = WORDDIF(fill,subterm);
963 if ( m[1] < (AM.OffsetIndex+WILDOFFSET) ) {
965 if ( m[1] == fill[1] &&
966 !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
974 if ( !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
975 && !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*fill,&newval3) )
977 if ( *fill == oldval1 && fill[1] == AN.oldvalue )
break;
984 if ( nq > 0 ) { NCOPY(fill,q,nq); }
987 else if ( *m <= *t &&
988 m[1] >= (AM.OffsetIndex + WILDOFFSET) ) {
989 while ( *m == *t && t < xstop )
990 { *fill++ = *t++; *fill++ = *t++; }
991 nq = WORDDIF(fill,subterm);
995 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3) )
1002 if ( nq > 0 ) { NCOPY(fill,q,nq); }
1005 else { *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; }
1021 else if ( *m == INDEX ) {
1022 while ( *t > INDEX ) {
1037 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
1038 while ( t < xstop ) *fill++ = *t++;
1039 nq = WORDDIF(fill, subterm);
1042 if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3) ) {
1058 }
while ( m < ystop );
1059 while ( t < xstop ) *fill++ = *t++;
1060 nq = WORDDIF(fill,subterm);
1065 else { fill = subterm; fill -= 2; }
1071 else if ( *m == DELTA ) {
1072 while ( *t > DELTA ) {
1084 if ( *t == *m && t[1] == m[1] ) { m += 2; t += 2; }
1085 else if ( *m >= (AM.OffsetIndex+WILDOFFSET) ) {
1086 while ( t < xstop ) *fill++ = *t++;
1091 else if ( m[1] >= (AM.OffsetIndex+WILDOFFSET) ) {
1092 while ( (*m == *t || *m == t[1] ) && ( t < xstop ) ) {
1093 *fill++ = *t++; *fill++ = *t++;
1096SubsL6: nq = WORDDIF(fill,subterm);
1099 if ( ( oldval1 && ( (
1100 !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*fill,&newval3)
1101 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
1103 !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1104 && !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,fill[1],&newval3)
1105 ) ) ) || ( !oldval1 && ( (
1107 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,fill[1],&newval3)
1110 && !CheckWild(BHEAD m[1]-WILDOFFSET,INDTOIND,*fill,&newval3)
1123 *fill++ = *t++; *fill++ = *t++;
1125 }
while ( m < ystop );
1126 while ( t < xstop ) *fill++ = *t++;
1127 nq = WORDDIF(fill,subterm);
1132 else { fill = subterm; fill -= 2; }
1138 }
while ( m < mstop ); }
1139 while ( t < tstop ) *fill++ = *t++;
1151 nq = WORDDIF(fill,TemTerm);
1158 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
1160 if ( AT.WorkPointer < fill ) AT.WorkPointer = fill;
1199int FindAll(PHEAD WORD *term, WORD *pattern, WORD level, WORD *par)
1202 WORD *t, *m, *r, *mm, rnum;
1203 WORD *tstop, *mstop, *TwoProto, *vwhere = 0, oldv, oldvv, vv, level2;
1204 WORD v, nq, OffNum = AM.OffsetVector + WILDOFFSET, i, ii = 0, jj;
1205 WORD fromindex, *intens, notflag1 = 0, notflag2 = 0;
1207 C = cbuf+AM.rbufnum;
1219 if ( *t == VECTOR ) {
1223 while ( r < tstop ) {
1225 if ( v >= OffNum ) {
1226 vwhere = AN.FullProto + 3 + SUBEXPSIZE;
1227 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1228 WORD *afirst, *alast, j;
1230 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1231 else { notflag1 = 0; }
1232 afirst = SetElements + Sets[j].first;
1233 alast = SetElements + Sets[j].last;
1235 if ( notflag1 == 0 ) {
1237 if ( *afirst == *r ) {
1238 if ( vwhere[1] == SETTONUM ) {
1239 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1240 AN.FullProto[11+SUBEXPSIZE] = ii;
1242 else if ( vwhere[4] >= 0 ) {
1243 oldv = *(afirst - Sets[j].first
1244 + Sets[vwhere[4]].first);
1249 }
while ( ++afirst < alast );
1253 if ( *afirst == *r )
break;
1254 }
while ( ++afirst < alast );
1255 if ( afirst >= alast )
goto DoVect;
1260 else if ( v == *r ) {
1261DoVect: m = AT.WorkPointer;
1265 do { *m++ = *t++; }
while ( t < tstop );
1272 if ( fromindex == 1 ) m[-1] = FUNNYVEC;
1274 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1275 if ( vwhere[1] > 12+SUBEXPSIZE ) {
1276 vwhere[11+SUBEXPSIZE] = ii;
1277 vwhere[8+SUBEXPSIZE] = SYMTONUM;
1279 if ( t[1] > fromindex+2 ) {
1281 *m++ = *t++ - fromindex;
1282 while ( t < r ) *m++ = *t++;
1286 do { *m++ = *t++; }
while ( t < mstop );
1287 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1301 else if ( *t == DOTPRODUCT ) {
1305 if ( ( i = r[2] ) < 0 )
goto NextDot;
1309TwoVec: m = AT.WorkPointer;
1313 do { *m++ = *t++; }
while ( t < tstop );
1320 m[-1] = ++AR.CurDum;
1321 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1322 }
while ( --i > 0 );
1327 while ( t < r ) *m++ = *t++;
1331 do { *m++ = *t++; }
while ( t < mstop );
1332 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1339 else if ( v >= OffNum ) {
1340 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1341 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1342 WORD *afirst, *alast, j;
1344 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1345 else { notflag1 = 0; }
1346 afirst = SetElements + Sets[j].first;
1347 alast = SetElements + Sets[j].last;
1349 if ( notflag1 == 0 ) {
1351 if ( *afirst == *r ) {
1352 if ( vwhere[1] == SETTONUM ) {
1353 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1354 AN.FullProto[11+SUBEXPSIZE] = ii;
1356 else if ( vwhere[4] >= 0 ) {
1357 oldv = *(afirst - Sets[j].first
1358 + Sets[vwhere[4]].first);
1363 }
while ( ++afirst < alast );
1367 if ( *afirst == *r )
break;
1368 }
while ( ++afirst < alast );
1369 if ( afirst >= alast )
goto TwoVec;
1376 if ( v == r[1] ) { r[1] = *r; *r = v; }
1380 if ( !par ) {
while ( ++level <= AR.Cnumlhs
1381 && C->
lhs[level][0] == TYPEIDOLD ) {
1384 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1385 if ( ( vv = m[m[1]+3] ) == r[1] ) {
1386OnePV: TwoProto = AN.FullProto;
1387TwoPV: m = AT.WorkPointer;
1391 do { *m++ = *t++; }
while ( t < tstop );
1394 vwhere = m + 3 +SUBEXPSIZE;
1398 m[-1] = ++AR.CurDum;
1399 if ( v >= OffNum ) *vwhere = oldv;
1400 if ( vwhere[-2-SUBEXPSIZE] > 12+SUBEXPSIZE ) {
1402 vwhere[5] = SYMTONUM;
1405 vwhere = m + 3+SUBEXPSIZE;
1414 mm[2] = C->
lhs[level][IDHEAD+2];
1415 mm[4] = C->
lhs[level][IDHEAD+4];
1417 if ( vv >= OffNum ) *vwhere = oldvv;
1418 }
while ( --i > 0 );
1421 else if ( vv > OffNum ) {
1422 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1423 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1424 WORD *afirst, *alast, j;
1426 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1427 else { notflag1 = 0; }
1428 afirst = SetElements + Sets[j].first;
1429 alast = SetElements + Sets[j].last;
1430 if ( notflag1 == 0 ) {
1433 if ( *afirst == r[1] ) {
1434 if ( vwhere[1] == SETTONUM ) {
1435 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1436 AN.FullProto[11+SUBEXPSIZE] = ii;
1438 else if ( vwhere[4] >= 0 ) {
1439 oldvv = *(afirst - Sets[j].first
1440 + Sets[vwhere[4]].first);
1445 }
while ( ++afirst < alast );
1449 if ( *afirst == *r )
break;
1450 }
while ( ++afirst < alast );
1451 if ( afirst >= alast )
goto OnePV;
1464OneOnly: m = AT.WorkPointer;
1468 do { *m++ = *t++; }
while ( t < tstop );
1476 if ( v >= OffNum ) vwhere[3+SUBEXPSIZE] = oldv;
1479 else if ( v >= OffNum ) {
1480 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1481 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1482 WORD *afirst, *alast, *bfirst, *blast, j;
1484 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1485 else { notflag1 = 0; }
1486 afirst = SetElements + Sets[j].first;
1487 alast = SetElements + Sets[j].last;
1489 if ( notflag1 == 0 ) {
1491 if ( *afirst == *r ) {
1492 if ( vwhere[1] == SETTONUM ) {
1493 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1494 AN.FullProto[11+SUBEXPSIZE] = ii;
1496 else if ( vwhere[4] >= 0 ) {
1497 oldv = *(afirst - Sets[j].first
1498 + Sets[vwhere[4]].first);
1500Hitlevel1: level2 = level;
1502 if ( !par ) m = C->
lhs[level2];
1505 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1506 if ( ( vv = m[m[1]+3] ) == r[1] )
1508 else if ( vv >= OffNum ) {
1509 if ( m[SUBEXPSIZE+4] != FROMSET &&
1510 m[SUBEXPSIZE+4] != SETTONUM )
goto OnePV;
1511 j = m[SUBEXPSIZE+6];
1512 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag2 = 1; }
1513 else { notflag2 = 0; }
1514 bfirst = SetElements + Sets[j].first;
1515 blast = SetElements + Sets[j].last;
1517 if ( notflag2 == 0 ) {
1519 if ( *bfirst == r[1] ) {
1520 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1521 m[SUBEXPSIZE+8] = SYMTONUM;
1522 m[SUBEXPSIZE+11] = jj;
1524 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1525 oldvv = *(bfirst - Sets[j].first
1526 + Sets[m[SUBEXPSIZE+7]].first);
1531 }
while ( ++bfirst < blast );
1535 if ( *bfirst == r[1] )
break;
1536 }
while ( ++bfirst < blast );
1537 if ( bfirst >= blast )
goto OnePV;
1541 }
while ( ++level2 < AR.Cnumlhs &&
1542 C->
lhs[level2][0] == TYPEIDOLD );
1546 else if ( *afirst == r[1] ) {
1547 if ( vwhere[1] == SETTONUM ) {
1548 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1549 AN.FullProto[11+SUBEXPSIZE] = ii;
1551 else if ( vwhere[4] >= 0 ) {
1552 oldv = *(afirst - Sets[j].first
1553 + Sets[vwhere[4]].first);
1555Hitlevel2: level2 = level;
1556 while ( ++level2 < AR.Cnumlhs &&
1557 C->
lhs[level2][0] == TYPEIDOLD ) {
1558 if ( !par ) m = C->
lhs[level2];
1561 if ( m[-IDHEAD+2] == SUBVECTOR ) {
1562 if ( ( vv = m[6] ) == *r )
1564 else if ( vv >= OffNum ) {
1565 if ( m[SUBEXPSIZE+4] != FROMSET && m[SUBEXPSIZE+4]
1572 j = m[SUBEXPSIZE+6];
1573 bfirst = SetElements + Sets[j].first;
1574 blast = SetElements + Sets[j].last;
1577 if ( *bfirst == *r ) {
1578 if ( m[SUBEXPSIZE+4] == SETTONUM ) {
1579 m[SUBEXPSIZE+8] = SYMTONUM;
1580 m[SUBEXPSIZE+11] = jj;
1582 else if ( m[SUBEXPSIZE+7] >= 0 ) {
1583 oldvv = *(bfirst - Sets[j].first
1584 + Sets[m[SUBEXPSIZE+7]].first);
1589 j = oldv; oldv = oldvv; oldvv = j;
1593 }
while ( ++bfirst < blast );
1597 jj = *r; *r = r[1]; r[1] = jj;
1598 jj = oldv; oldv = oldvv; oldvv = j;
1603 }
while ( ++afirst < alast );
1607 if ( *afirst == *r )
break;
1608 }
while ( ++afirst < alast );
1609 if ( afirst >= alast )
goto Hitlevel1;
1611 if ( *afirst == r[1] )
break;
1612 }
while ( ++afirst < alast );
1613 if ( afirst >= alast )
goto Hitlevel2;
1618 TwoProto = AN.FullProto;
1624 }
while ( r < tstop );
1630 else if ( *t == LEVICIVITA ) {
1635 while ( r < tstop ) {
1637 if ( v >= OffNum && *r < -10 ) {
1638 vwhere = AN.FullProto + 3+SUBEXPSIZE;
1639 if ( vwhere[1] == FROMSET || vwhere[1] == SETTONUM ) {
1640 WORD *afirst, *alast, j;
1642 if ( j > WILDOFFSET ) { j -= 2*WILDOFFSET; notflag1 = 1; }
1643 else { notflag1 = 0; }
1644 afirst = SetElements + Sets[j].first;
1645 alast = SetElements + Sets[j].last;
1647 if ( notflag1 == 0 ) {
1649 if ( *afirst == *r ) {
1650 if ( vwhere[1] == SETTONUM ) {
1651 AN.FullProto[8+SUBEXPSIZE] = SYMTONUM;
1652 AN.FullProto[11+SUBEXPSIZE] = ii;
1654 else if ( vwhere[4] >= 0 ) {
1655 oldv = *(afirst - Sets[j].first
1656 + Sets[vwhere[4]].first);
1661 }
while ( ++afirst < alast );
1665 if ( *afirst == *r )
break;
1666 }
while ( ++afirst < alast );
1667 if ( afirst >= alast )
goto DoVect;
1672 else if ( v == *r ) {
1673LeVect: m = AT.WorkPointer;
1674 mstop = term + *term;
1677 if ( intens ) *intens = DIRTYSYMFLAG;
1678 do { *m++ = *t++; }
while ( t < tstop );
1682 if ( v >= OffNum ) *vwhere = oldv;
1686 do { *m++ = *t++; }
while ( t < mstop );
1687 *AT.WorkPointer = nq = WORDDIF(m,AT.WorkPointer);
1701 else if ( *t == GAMMA ) {
1705 if ( r < tstop )
goto OneVect;
1711 else if ( *t == INDEX ) {
1721 else if ( *t >= FUNCTION ) {
1723 && functions[*t-FUNCTION].spec >= TENSORFUNCTION
1724 && t[1] > FUNHEAD ) {
1750int TestSelect(WORD *term, WORD *setp)
1752 WORD *tstop, *t, *s, *el, *elstop, *termstop, *tt, n, ns;
1753 GETSTOP(term,tstop);
1755 while ( term < tstop ) {
1763 while ( --ns >= 0 ) {
1764 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1765 el = SetElements + Sets[*s].first;
1766 elstop = SetElements + Sets[*s].last;
1767 while ( el < elstop ) {
1768 if ( *el++ == *t )
return(1);
1782 while ( --ns >= 0 ) {
1783 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1784 el = SetElements + Sets[*s].first;
1785 elstop = SetElements + Sets[*s].last;
1786 while ( el < elstop ) {
1787 if ( *el++ == *t )
return(1);
1794 while ( --ns >= 0 ) {
1795 if ( Sets[*s].type != CINDEX
1796 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1797 el = SetElements + Sets[*s].first;
1798 elstop = SetElements + Sets[*s].last;
1799 while ( el < elstop ) {
1800 if ( *el++ == *t )
return(1);
1818 while ( --ns >= 0 ) {
1819 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1820 el = SetElements + Sets[*s].first;
1821 elstop = SetElements + Sets[*s].last;
1822 while ( el < elstop ) {
1823 if ( *el++ == *t )
return(1);
1830 while ( --ns >= 0 ) {
1831 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1832 el = SetElements + Sets[*s].first;
1833 elstop = SetElements + Sets[*s].last;
1834 while ( el < elstop ) {
1835 if ( *el++ == *t )
return(1);
1848 if ( *term < FUNCTION )
break;
1851 while ( --ns >= 0 ) {
1852 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1853 el = SetElements + Sets[*s].first;
1854 elstop = SetElements + Sets[*s].last;
1855 while ( el < elstop ) {
1856 if ( *el++ == *term )
return(1);
1860 if ( functions[*term-FUNCTION].spec > 0 ) {
1861 n = term[1] - FUNHEAD;
1867 while ( --ns >= 0 ) {
1868 if ( *t < MINSPEC ) {
1869 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1871 else if ( *t >= 0 ) {
1872 if ( Sets[*s].type != CINDEX
1873 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1875 else { s++;
continue; }
1876 el = SetElements + Sets[*s].first;
1877 elstop = SetElements + Sets[*s].last;
1878 while ( el < elstop ) {
1879 if ( *el++ == *t )
return(1);
1888 termstop = term + term[1];
1889 tt = term + FUNHEAD;
1890 while ( tt < termstop ) {
1892 if ( *tt == -SYMBOL ) {
1895 while ( --ns >= 0 ) {
1896 if ( Sets[*s].type != CSYMBOL ) { s++;
continue; }
1897 el = SetElements + Sets[*s].first;
1898 elstop = SetElements + Sets[*s].last;
1899 while ( el < elstop ) {
1900 if ( *el++ == tt[1] )
return(1);
1906 else if ( *tt == -VECTOR || *tt == -MINVECTOR ) {
1909 while ( --ns >= 0 ) {
1910 if ( Sets[*s].type != CVECTOR ) { s++;
continue; }
1911 el = SetElements + Sets[*s].first;
1912 elstop = SetElements + Sets[*s].last;
1913 while ( el < elstop ) {
1914 if ( *el++ == tt[1] )
return(1);
1920 else if ( *tt == -INDEX ) {
1923 while ( --ns >= 0 ) {
1924 if ( Sets[*s].type != CINDEX
1925 && Sets[*s].type != CNUMBER ) { s++;
continue; }
1926 el = SetElements + Sets[*s].first;
1927 elstop = SetElements + Sets[*s].last;
1928 while ( el < elstop ) {
1929 if ( *el++ == tt[1] )
return(1);
1935 else if ( *tt <= -FUNCTION ) {
1938 while ( --ns >= 0 ) {
1939 if ( Sets[*s].type != CFUNCTION ) { s++;
continue; }
1940 el = SetElements + Sets[*s].first;
1941 elstop = SetElements + Sets[*s].last;
1942 while ( el < elstop ) {
1943 if ( *el++ == -(*tt) )
return(1);
1955 if ( TestSelect(t,setp) )
return(1);
1984void SubsInAll(PHEAD0)
1989 WORD *tstop, *mstop, *xstop;
1990 WORD nt, *fill, nq, mt;
1992 WORD PutExpr = 0, sign = 0;
1999 TemTerm = AT.WorkPointer;
2000 if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer*2) ) > AT.WorkTop ) {
2001 MLOCK(ErrorMessageLock);
2003 MUNLOCK(ErrorMessageLock);
2006 m = AN.patternbuffer + IDHEAD; m += m[1];
2009 term = AN.termbuffer;
2010 tstop = term + *term; tcoef = tstop-1; tstop -= ABS(tstop[-1]);
2015 while ( m < mstop ) {
2016 while ( t < tstop ) {
2017 nt = WORDDIF(t,term);
2018 for ( mt = 0; mt < AN.RepFunNum; mt += 2 ) {
2019 if ( nt == AN.RepFunList[mt] )
break;
2021 if ( mt >= AN.RepFunNum ) {
2027 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
2029 if ( ( i = AN.RepFunList[mt+1] ) > 0 ) {
2031 *fill++ = i + FUNHEAD+1;
2039 else if ( ( *t == LEVICIVITA ) || ( *t >= FUNCTION
2040 && (functions[*t-FUNCTION].symmetric & ~REVERSEORDER) == ANTISYMMETRIC )
2041 ) sign += AN.RepFunList[mt+1];
2042 else if ( *m >= FUNCTION+WILDOFFSET
2043 && (functions[*m-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER) == ANTISYMMETRIC
2044 ) sign += AN.RepFunList[mt+1];
2046 WORD *pstart = fill, *p, *w, *ww;
2062 p = pstart + SUBEXPSIZE;
2063 while ( p < fill ) {
2070 w = cbuf[AT.ebufnum].rhs[p[3]];
2071 ww = cbuf[AT.ebufnum].rhs[p[3]+1];
2079 AddNtoC(AT.aebufnum,ww-w,w,11);
2080 p[3] = cbuf[AT.aebufnum].numrhs;
2081 cbuf[AT.aebufnum].rhs[p[3]+1] = cbuf[AT.aebufnum].Pointer;
2097 if ( *m == GAMMA && m[1] != FUNHEAD+1 ) {
2098 i = oldt[1] - m[1] - i;
2101 *fill++ = i + FUNHEAD+1;
2103 *fill++ = oldt[FUNHEAD];
2113 while ( t < tstop ) *fill++ = *t++;
2125 if ( ( sign & 1 ) != 0 ) fill[-1] = -fill[-1];
2127 *TemTerm = fill-TemTerm;
2131 AddNtoC(AT.allbufnum,TemTerm[0],TemTerm,12);
2132 cbuf[AT.allbufnum].Pointer[0] = 0;
2145void TransferBuffer(
int from,
int to,
int spectator)
2147 CBUF *C = cbuf + spectator;
2148 CBUF *Cf = cbuf + from;
2149 CBUF *Ct = cbuf + to;
2150 int offset = Ct->numrhs;
2152 WORD *t, *tt, *ttt, *tstop, size;
2153 for ( i = 1; i <= Cf->numrhs; i++ ) {
2154 size = Cf->
rhs[i+1]-Cf->
rhs[i];
2163 t = C->
rhs[C->numrhs];
2166 tstop = t-ABS(t[-1]);
2167 while ( tt < tstop ) {
2168 if ( *tt == SUBEXPRESSION ) {
2169 ttt = tt+SUBEXPSIZE; tt += tt[1];
2170 while ( ttt < tt ) {
2195#define PutInBuffers(pow) \
2196 AddRHS(AT.ebufnum,1); \
2197 *out++ = SUBEXPRESSION; \
2198 *out++ = SUBEXPSIZE; \
2199 *out++ = C->numrhs; \
2201 *out++ = AT.ebufnum; \
2203 r = AT.pWorkSpace[rhs+i]; \
2205 oldinr = r[*r]; r[*r] = 0; \
2206 AddNtoC(AT.ebufnum,(*r+1-ARGHEAD),(r+ARGHEAD),14); \
2210 ToGeneral(r,buffer,1); \
2211 buffer[buffer[0]] = 0; \
2212 AddNtoC(AT.ebufnum,buffer[0]+1,buffer,15); \
2215int TakeIDfunction(PHEAD WORD *term)
2217 WORD *tstop, *t, *r, *m, *f, *nextf, *funstop, *left, *l, *newterm;
2218 WORD *out, oldinr, pow;
2220 int i, ii, j, numsub, numfound = 0, first;
2223 GETSTOP(term,tstop);
2224 for ( t = term+1; t < tstop; t += t[1] ) {
if ( *t == IDFUNCTION )
break; }
2225 if ( t >= tstop )
return(0);
2229 funstop = t + t[1]; f = t + FUNHEAD;
2230 left = term + *term;
2231 l = left+1; numsub = 0;
2232 while ( f < funstop ) {
2233 nextf = f; NEXTARG(nextf)
2234 if ( nextf >= funstop ) {
return(0); }
2235 if ( *f == -SYMBOL ) { *l++ = SYMBOL; *l++ = 4; *l++ = f[1]; *l++ = 1; }
2236 else if ( *f < -FUNCTION ) { *l++ = *f; *l++ = FUNHEAD; FILLFUN(l) }
2237 else if ( *f > 0 ) {
2238 if ( *f != f[ARGHEAD]+ARGHEAD )
goto noaction;
2239 if ( nextf[-1] != 3 || nextf[-2] != 1 || nextf[-3] != 1 )
goto noaction;
2240 if ( f[ARGHEAD] <= 4 )
goto noaction;
2241 if ( f[ARGHEAD] != f[ARGHEAD+2]+4 )
goto noaction;
2242 if ( f[ARGHEAD] == 8 && f[ARGHEAD+1] == SYMBOL ) {
2243 for ( i = 0; i < 4; i++ ) *l++ = f[ARGHEAD+1+i];
2245 else if ( f[ARGHEAD] == 9 && f[ARGHEAD+1] == DOTPRODUCT ) {
2246 for ( i = 0; i < 5; i++ ) *l++ = f[ARGHEAD+1+i];
2248 else if ( f[ARGHEAD+1] >= FUNCTION ) {
2249 for ( i = 0; i < f[ARGHEAD+1]-4; i++ ) *l++ = f[ARGHEAD+1+i];
2258 C = cbuf+AT.ebufnum;
2264 WantAddPointers(2*numsub);
2265 lhs = AT.pWorkPointer;
2267 AT.pWorkPointer = rhs+numsub;
2268 f = t + FUNHEAD; l = left+1;
2269 for ( i = 0; i < numsub; i++ ) {
2270 AT.pWorkSpace[lhs+i] = l; l += l[1];
2272 AT.pWorkSpace[rhs+i] = f;
2281 t = term+1; newterm = AT.WorkPointer; out = newterm+1;
2282 while ( t < tstop ) {
2283 if ( *t == IDFUNCTION && first ) { first = 0; t += t[1];
continue; }
2284 if ( *t >= FUNCTION ) {
2285 for ( i = 0; i < numsub; i++ ) {
2286 m = AT.pWorkSpace[lhs+i];
2287 if ( *m != *t )
continue;
2288 for ( j = 1; j < t[1]; j++ ) {
2289 if ( m[j] != t[j] )
break;
2291 if ( j != t[1] )
continue;
2300 if ( i == numsub ) {
2301 j = t[1]; NCOPY(out,t,j)
2304 else if ( *t == SYMBOL ) {
2305 for ( i = 0; i < numsub; i++ ) {
2306 m = AT.pWorkSpace[lhs+i];
2307 if ( *m != SYMBOL )
continue;
2308 for ( ii = 2; ii < t[1]; ii += 2 ) {
2309 if ( m[2] != t[ii] )
continue;
2311 if ( pow <= 0 )
continue;
2312 t[ii+1] = t[ii+1]%m[3];
2324 m = out; *out++ = t[0]; *out++ = t[1];
2325 for ( ii = 2; ii < t[1]; ii += 2 ) {
2326 if ( t[ii+1] ) { *out++ = t[ii]; *out++ = t[ii+1]; }
2329 if ( m[1] == 2 ) out = m;
2332 else if ( *t == DOTPRODUCT ) {
2333 for ( i = 0; i < numsub; i++ ) {
2334 m = AT.pWorkSpace[lhs+i];
2335 if ( *m != DOTPRODUCT )
continue;
2336 for ( ii = 2; ii < t[1]; ii += 3 ) {
2337 if ( m[2] != t[ii] || m[3] != t[ii+1] )
continue;
2339 if ( pow <= 0 )
continue;
2340 t[ii+2] = t[ii+2]%m[4];
2352 m = out; *out++ = t[0]; *out++ = t[1];
2353 for ( ii = 2; ii < t[1]; ii += 3 ) {
2354 if ( t[ii+2] ) { *out++ = t[ii]; *out++ = t[ii+1]; *out++ = t[ii+2]; }
2357 if ( m[1] == 2 ) out = m;
2361 j = t[1]; NCOPY(out,t,j)
2367 t = tstop; r = term+*term;
while ( t < r ) *out++ = *t++;
2368 *newterm = out-newterm;
2373 t = term; r = newterm; NCOPY(t,r,i)
2378 AT.pWorkPointer = lhs;
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int TestMatch(PHEAD WORD *term, WORD *level)