57int Lus(WORD *term, WORD funnum, WORD loopsize, WORD numargs, WORD outfun, WORD mode)
60 WORD *w, *t, *tt, *m, *r, **loc, *tstop, minloopsize;
61 int nfun, i, j, jj, k, n, sign = 0, action = 0, L, ten, ten2, totnum,
62 sign2, *alist, *wi, mini, maxi, medi = 0;
63 if ( numargs <= 1 )
return(0);
69 if ( ( ten = functions[funnum-FUNCTION].spec ) >= TENSORFUNCTION ) {
71 if ( *t == funnum && t[1] == FUNHEAD+numargs ) { nfun++; }
78 i = 0; m = t+FUNHEAD; t += t[1];
79 while ( m < t ) { i++; NEXTARG(m) }
80 if ( i == numargs ) nfun++;
85 if ( loopsize < 0 ) minloopsize = 2;
86 else minloopsize = loopsize;
87 if ( funnum < minloopsize )
return(0);
88 if ( ((functions[funnum-FUNCTION].symmetric) & ~REVERSEORDER) == ANTISYMMETRIC ) sign = 1;
89 if ( mode == 1 || mode < 0 ) {
90 ten2 = functions[outfun-FUNCTION].spec >= TENSORFUNCTION;
96 if ( AN.numflocs < funnum ) {
97 if ( AN.funlocs ) M_free(AN.funlocs,
"Lus: AN.funlocs");
99 AN.funlocs = (WORD **)Malloc1(
sizeof(WORD *)*AN.numflocs,
"Lus: AN.funlocs");
101 if ( AN.numfargs < funnum*numargs ) {
102 if ( AN.funargs ) M_free(AN.funargs,
"Lus: AN.funargs");
103 AN.numfargs = funnum*numargs;
104 AN.funargs = (
int *)Malloc1(
sizeof(
int *)*AN.numfargs,
"Lus: AN.funargs");
109 alist = AN.funargs; loc = AN.funlocs;
111 if ( ten >= TENSORFUNCTION ) {
112 while ( t < tstop ) {
113 if ( *t == funnum && t[1] == FUNHEAD+numargs ) {
116 j = i = numargs;
while ( --i >= 0 ) {
117 if ( *t >= AM.OffsetIndex &&
118 ( *t >= AM.OffsetIndex+WILDOFFSET ||
119 indices[*t-AM.OffsetIndex].dimension != 0 ) ) {
120 *alist++ = *t++; j--;
124 while ( --j >= 0 ) *alist++ = -1;
131 while ( t < tstop ) {
132 if ( *t == funnum ) {
134 i = 0; m = t+FUNHEAD; t += t[1];
135 while ( m < t ) { i++; NEXTARG(m) }
136 if ( i == numargs ) {
139 if ( *m == -INDEX && m[1] >= AM.OffsetIndex &&
140 ( m[1] >= AM.OffsetIndex+WILDOFFSET ||
141 indices[m[1]-AM.OffsetIndex].dimension != 0 ) ) {
142 *alist++ = m[1]; m += 2; i--;
144 else if ( ten2 >= TENSORFUNCTION && *m != -INDEX
145 && *m != -VECTOR && *m != -MINVECTOR &&
146 ( *m != -SNUMBER || *m < 0 || *m >= AM.OffsetIndex ) ) {
154 while ( --i >= 0 ) *alist++ = -1;
160 if ( nfun < minloopsize )
return(0);
169 alist = AN.funargs; totnum = numargs*nfun;
171 if ( AN.funisize < totnum ) {
172 if ( AN.funinds ) M_free(AN.funinds,
"AN.funinds");
173 AN.funisize = (totnum*3)/2;
174 AN.funinds = (
int *)Malloc1(AN.funisize*2*
sizeof(
int),
"AN.funinds");
176 i = totnum; n = 0; wi = AN.funinds;
178 if ( *alist >= 0 ) { n++; *wi++ = *alist; *wi++ = 1; }
181 n = SortTheList(AN.funinds,n);
184 for ( i = 0; i < nfun; i++ ) {
185 alist = AN.funargs + i*numargs;
187 for ( j = 0; j < jj; j++ ) {
188 if ( alist[j] < 0 )
break;
189 mini = 0; maxi = n-1;
190 while ( mini <= maxi ) {
191 medi = (mini + maxi) / 2; k = AN.funinds[2*medi];
192 if ( alist[j] > k ) mini = medi + 1;
193 else if ( alist[j] < k ) maxi = medi - 1;
196 if ( AN.funinds[2*medi+1] <= 1 ) {
197 (AN.funinds[2*medi+1])--;
198 jj--; k = j;
while ( k < jj ) { alist[k] = alist[k+1]; k++; }
204 mini = 0; maxi = n-1;
205 while ( mini <= maxi ) {
206 medi = (mini + maxi) / 2; k = AN.funinds[2*medi];
207 if ( alist[0] > k ) mini = medi + 1;
208 else if ( alist[0] < k ) maxi = medi - 1;
211 (AN.funinds[2*medi+1])--;
212 if ( AN.funinds[2*medi+1] == 1 ) action++;
214 nfun--; totnum -= numargs; AN.funlocs[i] = AN.funlocs[nfun];
215 wi = AN.funargs + nfun*numargs;
216 for ( j = 0; j < numargs; j++ ) alist[j] = *wi++;
223 for ( i = 0; i < totnum; i++ ) {
224 if ( alist[i] == -1 )
continue;
225 for ( j = 0; j < totnum; j++ ) {
226 if ( alist[j] == alist[i] && j != i )
break;
228 if ( j >= totnum ) alist[i] = -1;
232 for ( i = 0; i < nfun; i++ ) {
233 alist = AN.funargs + i*numargs;
235 for ( k = 0; k < n; k++ ) {
236 if ( alist[k] < 0 ) { alist[k--] = alist[--n]; alist[n] = -1; }
239 if ( n == 1 ) { j = alist[0]; }
241 nfun--; totnum -= numargs; AN.funlocs[i] = AN.funlocs[nfun];
242 wi = AN.funargs + nfun * numargs;
243 for ( k = 0; k < numargs; k++ ) alist[k] = wi[k];
246 for ( k = 0, jj = 0, wi = AN.funargs; k < totnum; k++, wi++ ) {
247 if ( *wi == j ) { jj++;
if ( jj > 1 )
break; }
250 for ( k = 0, wi = AN.funargs; k < totnum; k++, wi++ ) {
251 if ( *wi == j ) { *wi = -1; action = 1; }
259 if ( nfun < minloopsize )
return(0);
264 if ( mode != 0 && mode != 1 ) {
265 if ( mode > 0 ) AN.tohunt = mode - 5;
266 else AN.tohunt = -mode - 5;
267 AN.nargs = numargs; AN.numoffuns = nfun;
269 if ( loopsize < 0 ) {
270 if ( loopsize == -1 ) k = nfun;
271 else { k = -loopsize-1;
if ( k > nfun ) k = nfun; }
272 for ( L = 2; L <= k; L++ ) {
273 if ( FindLus(0,L,AN.tohunt) )
goto Success;
276 else if ( FindLus(0,loopsize,AN.tohunt) ) { L = loopsize;
goto Success; }
279 AN.nargs = numargs; AN.numoffuns = nfun;
280 if ( loopsize < 0 ) {
282 if ( loopsize < -1 ) { k = -loopsize-1;
if ( k > nfun ) k = nfun; }
284 else { jj = k = loopsize; }
285 for ( L = jj; L <= k; L++ ) {
286 for ( i = 0; i <= nfun-L; i++ ) {
287 alist = AN.funargs + i * numargs;
288 for ( jj = 0; jj < numargs; jj++ ) {
289 if ( alist[jj] < 0 )
continue;
290 AN.tohunt = alist[jj];
291 for ( j = jj+1; j < numargs; j++ ) {
292 if ( alist[j] < 0 )
continue;
293 if ( FindLus(i+1,L-1,alist[j]) ) {
294 alist[0] = alist[jj];
305 if ( mode == 0 || mode > 1 )
return(1);
310 wi = AN.funargs + i*numargs; loc = AN.funlocs + i;
311 for ( k = 0; k < L; k++ ) *(loc[k]) = -1;
312 if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
313 w = AT.WorkPointer + 1;
315 while ( t < tstop ) {
316 if ( *t == -1 )
break;
319 while ( m < t ) *w++ = *m++;
325 if ( functions[outfun-FUNCTION].spec >= TENSORFUNCTION ) {
326 if ( ten >= TENSORFUNCTION ) {
327 for ( i = 0; i < L; i++ ) {
328 alist = wi + i*numargs;
329 m = loc[i] + FUNHEAD;
330 for ( k = 0; k < numargs; k++ ) {
331 if ( m[k] == alist[0] ) {
333 jj = m[k]; m[k] = m[0]; m[0] = jj;
339 for ( k = 1; k < numargs; k++ ) {
340 if ( m[k] == alist[1] ) {
342 jj = m[k]; m[k] = m[1]; m[1] = jj;
349 for ( k = 2; k < numargs; k++ ) *w++ = *m++;
354 for ( i = 0; i < L; i++ ) {
355 alist = wi + i*numargs;
358 for ( k = 0; k < numargs; k++ ) {
359 if ( *m == -INDEX && m[1] == alist[0] ) {
361 if ( ( k & 1 ) != 0 ) sign = -sign;
365 t2 = m+2; t1 = m; t3 = tt+FUNHEAD;
366 while ( t1 > t3 ) { *--t2 = *--t1; }
367 t3[0] = -INDEX; t3[1] = alist[0];
373 m = tt + FUNHEAD + 2;
374 for ( k = 1; k < numargs; k++ ) {
375 if ( *m == -INDEX && m[1] == alist[1] ) {
377 if ( ( k & 1 ) == 0 ) sign = -sign;
381 t2 = m+2; t1 = m; t3 = tt+FUNHEAD+2;
382 while ( t1 > t3 ) { *--t2 = *--t1; }
383 t3[0] = -INDEX; t3[1] = alist[1];
393 t1 = tt + FUNHEAD + 4;
396 if ( *t1 == -INDEX || *t1 == -VECTOR ) {
397 *w++ = t1[1]; t1 += 2;
399 else if ( *t1 == -MINVECTOR ) {
400 *w++ = t1[1]; t1 += 2; sign2 = -sign2;
402 else if ( ( *t1 == -SNUMBER ) && ( t1[1] >= 0 ) && ( t1[1] < AM.OffsetIndex ) ) {
403 *w++ = t1[1]; t1 += 2; sign2 = -sign2;
406 MLOCK(ErrorMessageLock);
407 MesPrint(
"Illegal attempt to use a non-index-like argument in a tensor in ReplaceLoop statement");
408 MUNLOCK(ErrorMessageLock);
416 if ( ten >= TENSORFUNCTION ) {
417 for ( i = 0; i < L; i++ ) {
418 alist = wi + i*numargs;
419 m = loc[i] + FUNHEAD;
420 for ( k = 0; k < numargs; k++ ) {
421 if ( m[k] == alist[0] ) {
423 jj = m[k]; m[k] = m[0]; m[0] = jj;
429 for ( k = 1; k < numargs; k++ ) {
430 if ( m[k] == alist[1] ) {
432 jj = m[k]; m[k] = m[1]; m[1] = jj;
439 for ( k = 2; k < numargs; k++ ) {
440 if ( *m >= AM.OffsetIndex ) { *w++ = -INDEX; }
441 else if ( *m < 0 ) { *w++ = -VECTOR; }
442 else { *w = -SNUMBER; }
449 for ( i = 0; i < L; i++ ) {
450 alist = wi + i*numargs;
453 for ( k = 0; k < numargs; k++ ) {
454 if ( *m == -INDEX && m[1] == alist[0] ) {
456 if ( ( k & 1 ) != 0 ) sign = -sign;
460 t2 = m+2; t1 = m; t3 = tt+FUNHEAD;
461 while ( t1 > t3 ) { *--t2 = *--t1; }
462 t3[0] = -INDEX; t3[1] = alist[0];
468 m = tt + FUNHEAD + 2;
469 for ( k = 1; k < numargs; k++ ) {
470 if ( *m == -INDEX && m[1] == alist[1] ) {
472 if ( ( k & 1 ) == 0 ) sign = -sign;
476 t2 = m+2; t1 = m; t3 = tt+FUNHEAD+2;
477 while ( t1 > t3 ) { *--t2 = *--t1; }
478 t3[0] = -INDEX; t3[1] = alist[1];
487 t1 = tt + FUNHEAD + 4;
489 while ( t1 < t2 ) *w++ = *t1++;
494 while ( t < tstop ) {
495 if ( *t == -1 ) { t += t[1];
continue; }
499 tstop = term + *term;
500 while ( t < tstop ) *w++ = *t++;
501 if ( sign < 0 ) w[-1] = -w[-1];
502 i = w - AT.WorkPointer;
504 t = term; w = AT.WorkPointer;
515int FindLus(
int from,
int level,
int openindex)
518 int i, j, k, jj, *alist, *blist, *w, *m, partner;
519 WORD **loc = AN.funlocs, *wor;
521 for ( i = from; i < AN.numoffuns; i++ ) {
522 alist = AN.funargs + i*AN.nargs;
523 for ( j = 0; j < AN.nargs; j++ ) {
524 if ( alist[j] == openindex ) {
525 for ( k = 0; k < AN.nargs; k++ ) {
526 if ( k == j )
continue;
527 if ( alist[k] == AN.tohunt ) {
529 alist = AN.funargs + from*AN.nargs;
530 alist[0] = openindex; alist[1] = AN.tohunt;
539 for ( i = from; i < AN.numoffuns; i++ ) {
540 alist = AN.funargs + i*AN.nargs;
541 for ( j = 0; j < AN.nargs; j++ ) {
542 if ( alist[j] == openindex ) {
544 wor = loc[i]; loc[i] = loc[from]; loc[from] = wor;
545 blist = w = AN.funargs + from*AN.nargs;
548 while ( --k >= 0 ) { jj = *m; *m++ = *w; *w++ = jj; }
551 for ( k = 0; k < AN.nargs; k++ ) {
552 if ( k == j || blist[k] < 0 )
continue;
554 if ( FindLus(from+1,level-1,partner) ) {
555 blist[0] = openindex; blist[1] = partner;
560 wor = loc[i]; loc[i] = loc[from]; loc[from] = wor;
561 w = AN.funargs + from*AN.nargs;
564 while ( --k >= 0 ) { jj = *m; *m++ = *w; *w++ = jj; }
578int SortTheList(
int *slist,
int num)
581 int i, nleft, nright, *t1, *t2, *t3, *rlist;
583 if ( num <= 1 )
return(num);
584 if ( slist[0] < slist[2] )
return(2);
585 if ( slist[0] > slist[2] ) {
586 i = slist[0]; slist[0] = slist[2]; slist[2] = i;
587 i = slist[1]; slist[1] = slist[3]; slist[3] = i;
590 slist[1] += slist[3];
594 nleft = num/2; rlist = slist + 2*nleft;
595 nright = SortTheList(rlist,num-nleft);
596 nleft = SortTheList(slist,nleft);
597 if ( AN.tlistsize < nleft ) {
598 if ( AN.tlistbuf ) M_free(AN.tlistbuf,
"AN.tlistbuf");
599 AN.tlistsize = (nleft*3)/2;
600 AN.tlistbuf = (
int *)Malloc1(AN.tlistsize*2*
sizeof(
int),
"AN.tlistbuf");
602 i = nleft; t1 = slist; t2 = AN.tlistbuf;
603 while ( --i >= 0 ) { *t2++ = *t1++; *t2++ = *t1++; }
604 i = nleft+nright; t1 = AN.tlistbuf; t2 = rlist; t3 = slist;
605 while ( nleft > 0 && nright > 0 ) {
607 *t3++ = *t1++; *t3++ = *t1++; nleft--;
609 else if ( *t1 > *t2 ) {
610 *t3++ = *t2++; *t3++ = *t2++; nright--;
613 *t3++ = *t1++; t2++; *t3++ = (*t1++) + (*t2++); i--;
617 while ( --nleft >= 0 ) { *t3++ = *t1++; *t3++ = *t1++; }
618 while ( --nright >= 0 ) { *t3++ = *t2++; *t3++ = *t2++; }
650int AllLoops(PHEAD WORD *term,WORD level)
652 CBUF *C = cbuf+AM.rbufnum;
653 WORD vcode = C->
lhs[level][2];
654 WORD option1 = C->
lhs[level][4];
655 WORD option2 = C->
lhs[level][5];
656 WORD *tstop, *t, *tend, *tstart, *tfrom;
658 WORD *arglist, nargs, *loop, nloop;
659 WORD *oldworkpointer = AT.WorkPointer;
660 LONG oldpworkpointer = AT.pWorkPointer;
661 LONG numgenerated = 0, vert;
662 WORD *a, *a1, *a2, *a3, *v, *vv, nvert, *to, *from, *tos, action;
666 tstop = term+*term; tstop -= ABS(tstop[-1]);
668 while ( t < tstop && *t != vcode ) t += t[1];
670 if ( option2 == 0 )
return(0);
671 else return(
Generator(BHEAD term,level));
677 }
while ( t < tstop && *t == vcode );
682 WantAddPointers(2*nvert);
683 vert = AT.pWorkPointer;
684 AT.pWorkPointer += 2*nvert;
693 if ( functions[vcode-FUNCTION].spec == TENSORFUNCTION ) {
695 while ( from < tend ) {
697 tfrom = from+from[1];
699 while ( from < tfrom ) {
700 if ( option1 == -INDEX && *from >= 0 ) {
703 else if ( option1 == -VECTOR && *from < 0 ) {
704 *to++ = *from++ - AM.OffsetVector;
711 if ( *tos < 3 ) to = tos;
712 else AT.pWorkSpace[vert+nvert++] = tos;
715 else if ( functions[vcode-FUNCTION].spec == 0 ) {
717 while ( from < tend ) {
719 tfrom = from + from[1];
721 while ( from < tfrom ) {
722 if ( option1 == -VECTOR
723 && ( from[0] == -INDEX || from[0] == -VECTOR )
726 *to++ = *from++ - AM.OffsetVector;
728 else if ( option1 == *from ) {
729 from++; *to++ = *from++;
736 if ( *tos < 3 ) to = tos;
737 else AT.pWorkSpace[vert+nvert++] = tos;
741 AT.WorkPointer = oldworkpointer;
742 AT.pWorkPointer = oldpworkpointer;
743 if ( option2 == 0 )
return(0);
750 a = arglist = AT.WorkPointer;
751 for ( i = 0; i < nvert; i++ ) {
752 v = AT.pWorkSpace[vert+i];
761 a1 = arglist; a2 = a1+1;
764 while ( a3 > a1 && a3[-1] > a3[0] ) {
773 a1 = arglist; a2 = a1; a3 = a1+nargs;
775 if ( a2+1 == a3 ) {
break; }
776 else if ( a2+2 == a3 ) {
777 if ( a2[0] == a2[1] ) { *a1++ = a2[0]; }
781 if ( a2[0] != a2[1] ) { a2++; }
782 else if ( a2[0] != a2[2] ) {
783 *a1++ = a2[0]; a2 += 2;
786 a2++;
while ( a2 < a3 && a2[-1] == a2[0] ) a2++;
797 for ( i = 0; i < nvert; i++ ) {
798 vv = v = AT.pWorkSpace[vert+i];
800 for ( j = 1; j < vv[0]; j++ ) {
801 for ( jj = 0; jj < nargs; jj++ ) {
802 if ( *v == arglist[jj] )
break;
806 for ( jj = j; jj < vv[0]; jj++ ) vv[jj] = vv[jj+1];
816 for ( i = 0; i < nvert; i++ ) {
817 vv = AT.pWorkSpace[vert+i];
819 AT.pWorkSpace[vert+i] = AT.pWorkSpace[vert+nvert-1];
820 nvert--; i--;
continue;
822 else if ( vv[0] == 2 ) {
823 for ( j = 0; j < nargs; j++ ) {
824 if ( arglist[j] == vv[1] )
break;
826 while ( j < nargs-1 ) arglist[j] = arglist[j+1];
828 AT.pWorkSpace[vert+i] = AT.pWorkSpace[vert+nvert-1];
846 loop = AT.WorkPointer;
847 AT.WorkPointer += nargs;
849 numgenerated += StartLoops(BHEAD term,level,vert,nvert,arglist,nargs,loop,nloop);
850 AT.WorkPointer = oldworkpointer;
851 AT.pWorkPointer = oldpworkpointer;
853 if ( numgenerated == 0 && option2 != 0 )
return(
Generator(BHEAD term,level));
894LONG StartLoops(PHEAD WORD *term,WORD level,LONG vert,WORD nvert,
895 WORD *arglist,WORD nargs,WORD *loop,WORD nloop)
897 LONG numgenerated = 0;
898 WORD *v, *vv, *vstart, istart, *vpartner, ipartner, j;
899 while ( nargs > 1 ) {
905 loop[nloop++] = arglist[0];
906 for ( istart = 0; istart < nvert; istart++ ) {
907 vstart = AT.pWorkSpace[vert+istart];
908 v = vstart+1; vv = vstart + *vstart;
910 if ( *v == arglist[0] )
goto havestart;
917 MesPrint(
"Internal error in StartLoops. Object not found.");
921 AT.pWorkSpace[vert+nvert] = vstart;
927 if ( *v == arglist[0] ) {
928 LoopOutput(BHEAD term,level,loop,nloop);
937 for ( ipartner = istart+1; ipartner < nvert; ipartner++ ) {
938 vpartner = AT.pWorkSpace[vert+ipartner];
939 vv = vpartner+*vpartner; v = vpartner+1;
941 if ( *v == arglist[0] )
goto havepartner;
945 return(numgenerated);
947 AT.pWorkSpace[vert+nvert+1] = vpartner;
954 if ( *v != arglist[0] ) {
955 for ( j = 1; j < nargs; j++ ) {
956 if ( *v == arglist[j] ) {
958 numgenerated += GenLoops(BHEAD term,level,vert,nvert,
959 arglist,nargs,loop,nloop);
970 return(numgenerated);
980LONG GenLoops(PHEAD WORD *term,WORD level,LONG vert,WORD nvert,
981 WORD *arglist,WORD nargs,WORD *loop,WORD nloop)
983 LONG numgenerated = 0;
984 WORD *vstart, *v, *vv, i, j, *vpartner;
988 vstart = AT.pWorkSpace[nvert];
989 vv = vstart + *vstart; v = vstart+1;
991 if ( *v == loop[nloop-1] ) {
996 LoopOutput(BHEAD term,level,loop,nloop);
998 return(numgenerated);
1005 for ( i = 0; i < nvert; i++ ) {
1006 vpartner = AT.pWorkSpace[vert+i];
1007 if ( vpartner == vstart )
continue;
1008 for ( j = 0; j < nloop; j++ ) {
1009 if ( vpartner == AT.pWorkSpace[vert+nvert+j] )
break;
1011 if ( j < nloop )
continue;
1012 v = vpartner+1; vv = vpartner + *vpartner;
1014 if ( *v == loop[nloop-1] ) {
1024 for ( j = 0; j < nargs; j++ ) {
1025 if ( *v == arglist[j] )
break;
1027 if ( j >= nargs ) { v++;
continue; }
1031 for ( j = 0; j < nloop; j++ ) {
1032 if ( *v == loop[j] )
break;
1035 AT.pWorkSpace[vert+nvert+nloop] = vpartner;
1037 numgenerated += GenLoops(BHEAD term,level,vert,nvert,
1038 arglist,nargs,loop,nloop);
1043 return(numgenerated);
1051 return(numgenerated);
1059void LoopOutput(PHEAD WORD *term, WORD level, WORD *loop, WORD nloop)
1061 CBUF *C = cbuf+AM.rbufnum;
1062 WORD loopfun = C->
lhs[level][3];
1063 WORD option1 = C->
lhs[level][4];
1064 WORD *tstop, *tstop1, *t, *tt;
1065 WORD *outterm, *loop1;
1067 tstop1 = term+*term; tstop = tstop1 - ABS(tstop1[-1]);
1072 loop1 = AT.WorkPointer;
1074 for ( i = 1; i < nloop; i++ ) { loop1[i] = loop[nloop-i]; }
1075 if ( loop1[1] < loop[1] ) {
1076 AT.WorkPointer += nloop;
1080 outterm = AT.WorkPointer;
1081 tt = outterm; t = term;
1082 while ( t < tstop ) *tt++ = *t++;
1084 if ( functions[loopfun-FUNCTION].spec == TENSORFUNCTION ) {
1085 *tt++ = FUNHEAD+nloop;
1087 if ( option1 == -VECTOR ) {
1088 for ( i = 0; i < nloop; i++ ) *tt++ = loop[i]+AM.OffsetVector;
1091 for ( i = 0; i < nloop; i++ ) *tt++ = loop[i];
1095 *tt++ = FUNHEAD+nloop*2;
1097 for ( i = 0; i< nloop; i++ ) {
1099 if ( option1 == -VECTOR ) *tt++ = loop[i] + AM.OffsetVector;
1100 else *tt++ = loop[i];
1103 while ( t < tstop1 ) *tt++ = *t++;
1104 *outterm = tt - outterm;
1105 AT.WorkPointer = tt;
1107 MesCall(
"LoopOutput");
1110 AT.WorkPointer = outterm;
1123int AllPaths(PHEAD WORD *term,WORD level)
1125 CBUF *C = cbuf+AM.rbufnum;
1126 WORD endcode = C->
lhs[level][2];
1127 WORD vcode = C->
lhs[level][3];
1128 WORD option1 = C->
lhs[level][5];
1129 WORD option2 = C->
lhs[level][6];
1130 WORD *t, *tstop, *tend1, *tend2, *tstart, *tend, numend, nvert, npass;
1131 WORD *tfrom, *to, *tos, *from;
1132 WORD *arglist, nargs, *path, npath, *a, *a1, *a2, *a3;
1133 WORD i, j, jj, *v, *vv, action;
1135 WORD numgenerated = 0;
1136 WORD *oldworkpointer = AT.WorkPointer;
1137 LONG oldpworkpointer = AT.pWorkPointer;
1141 tstop = term+*term; tstop -= ABS(tstop[-1]);
1143 while ( t < tstop && *t != endcode ) t += t[1];
1145 if ( option2 == 0 )
return(0);
1146 else return(
Generator(BHEAD term,level));
1150 while ( t < tstop && *t == endcode ) { tend2 = t; t += t[1]; numend++; }
1151 if ( numend != 2 ) {
1152 if ( option2 == 0 )
return(0);
1153 else return(
Generator(BHEAD term,level));
1160 while ( t < tstop && *t != vcode ) t += t[1];
1162 while ( t < tstop && *t == vcode ) {
1171 WantAddPointers((2*nvert+8));
1172 vert = AT.pWorkPointer+2;
1173 vert1 = AT.pWorkPointer;
1175 AT.pWorkPointer += 2*nvert+8;
1180 to = AT.WorkPointer;
1182 if ( functions[endcode-FUNCTION].spec == TENSORFUNCTION ) {
1183 from = tend1; npass = 0;
1186 tfrom = from+from[1];
1188 while ( from < tfrom ) {
1189 if ( option1 == -INDEX && *from >= 0 ) {
1192 else if ( option1 == -VECTOR && *from < 0 ) {
1193 *to++ = *from++ - AM.OffsetVector;
1200 if ( *tos < 2 ) to = tos;
1201 else AT.pWorkSpace[vert1+npass] = tos;
1203 if ( from == tend2 )
goto redo1;
1205 else if ( functions[endcode-FUNCTION].spec == 0 ) {
1210 tfrom = from + from[1];
1212 while ( from < tfrom ) {
1213 if ( option1 == -VECTOR
1214 && ( from[0] == -INDEX || from[0] == -VECTOR )
1217 *to++ = *from++ - AM.OffsetVector;
1219 else if ( option1 == *from ) {
1220 from++; *to++ = *from++;
1227 if ( *tos < 2 ) to = tos;
1228 else AT.pWorkSpace[vert1+npass] = tos;
1230 if ( from == tend2 )
goto redo2;
1233 AT.WorkPointer = oldworkpointer;
1234 AT.pWorkPointer = oldpworkpointer;
1235 if ( option2 == 0 )
return(0);
1242 if ( functions[vcode-FUNCTION].spec == TENSORFUNCTION ) {
1244 while ( from < tend ) {
1246 tfrom = from+from[1];
1248 while ( from < tfrom ) {
1249 if ( option1 == -INDEX && *from >= 0 ) {
1252 else if ( option1 == -VECTOR && *from < 0 ) {
1253 *to++ = *from++ - AM.OffsetVector;
1260 if ( *tos < 3 ) to = tos;
1261 else AT.pWorkSpace[vert+nvert++] = tos;
1264 else if ( functions[vcode-FUNCTION].spec == 0 ) {
1266 while ( from < tend ) {
1268 tfrom = from + from[1];
1270 while ( from < tfrom ) {
1271 if ( option1 == -VECTOR
1272 && ( from[0] == -INDEX || from[0] == -VECTOR )
1275 *to++ = *from++ - AM.OffsetVector;
1277 else if ( option1 == *from ) {
1278 from++; *to++ = *from++;
1285 if ( *tos < 3 ) to = tos;
1286 else AT.pWorkSpace[vert+nvert++] = tos;
1290 AT.WorkPointer = oldworkpointer;
1291 AT.pWorkPointer = oldpworkpointer;
1292 if ( option2 == 0 )
return(0);
1295 AT.WorkPointer = to;
1299 a = arglist = AT.WorkPointer;
1300 for ( i = -2; i < nvert; i++ ) {
1301 v = AT.pWorkSpace[vert+i];
1310 a1 = arglist; a2 = a1+1;
1313 while ( a3 > a1 && a3[-1] > a3[0] ) {
1322 a1 = arglist; a2 = a1; a3 = a1+nargs;
1324 if ( a2+1 == a3 ) {
break; }
1325 else if ( a2+2 == a3 ) {
1326 if ( a2[0] == a2[1] ) { *a1++ = a2[0]; }
1330 if ( a2[0] != a2[1] ) { a2++; }
1331 else if ( a2[0] != a2[2] ) {
1332 *a1++ = a2[0]; a2 += 2;
1335 a2++;
while ( a2 < a3 && a2[-1] == a2[0] ) a2++;
1346 for ( i = -2; i < nvert; i++ ) {
1347 vv = v = AT.pWorkSpace[vert+i];
1349 for ( j = 1; j < vv[0]; j++ ) {
1350 for ( jj = 0; jj < nargs; jj++ ) {
1351 if ( *v == arglist[jj] )
break;
1353 if ( jj >= nargs ) {
1355 for ( jj = j; jj < vv[0]; jj++ ) vv[jj] = vv[jj+1];
1365 for ( i = -2; i < nvert; i++ ) {
1366 vv = AT.pWorkSpace[vert+i];
1368 AT.pWorkSpace[vert+i] = AT.pWorkSpace[vert+nvert-1];
1369 nvert--; i--;
continue;
1371 else if ( vv[0] == 2 && i >= 0 ) {
1372 for ( j = 0; j < nargs; j++ ) {
1373 if ( arglist[j] == vv[1] )
break;
1375 while ( j < nargs-1 ) arglist[j] = arglist[j+1];
1377 AT.pWorkSpace[vert+i] = AT.pWorkSpace[vert+nvert-1];
1387 path = AT.WorkPointer; npath = 0;
1388 AT.WorkPointer += nvert+8;
1390 t = AT.pWorkSpace[vert1];
1392 for ( i = 1; i < *t; i++ ) {
1393 AT.pWorkSpace[vert+nvert] = t;
1394 path[npath++] = t[i];
1395 numgenerated += GenPaths(BHEAD term,level,vert,nvert,arglist,nargs,path,npath);
1399 AT.WorkPointer = oldworkpointer;
1400 AT.pWorkPointer = oldpworkpointer;
1401 if ( numgenerated == 0 && option2 != 0 )
return(
Generator(BHEAD term,level));
1413LONG GenPaths(PHEAD WORD *term, WORD level, LONG vert, WORD nvert,
1414 WORD *arglist, WORD nargs, WORD *path, WORD npath)
1416 LONG numgenerated = 0;
1417 WORD *t, *vpartner, *v, *vv;
1422 t = AT.pWorkSpace[vert-1];
1423 for ( i = 1; i < *t; i++ ) {
1424 if ( t[i] == path[npath-1] ) {
1425 PathOutput(BHEAD term,level,path,npath);
1427 return(numgenerated);
1433 for ( i = 0; i < nvert; i++ ) {
1434 vpartner = AT.pWorkSpace[vert+i];
1435 for ( j = 0; j < npath; j++ ) {
1436 if ( vpartner == AT.pWorkSpace[vert+nvert+j] )
break;
1438 if ( j < npath )
continue;
1439 v = vpartner+1; vv = vpartner + *vpartner;
1441 if ( *v == path[npath-1] ) {
1451 for ( j = 0; j < nargs; j++ ) {
1452 if ( *v == arglist[j] )
break;
1454 if ( j >= nargs ) { v++;
continue; }
1458 for ( j = 0; j < npath; j++ ) {
1459 if ( *v == path[j] )
break;
1462 AT.pWorkSpace[vert+nvert+npath] = vpartner;
1464 numgenerated += GenPaths(BHEAD term,level,vert,nvert,
1465 arglist,nargs,path,npath);
1470 return(numgenerated);
1478 return(numgenerated);
1486void PathOutput(PHEAD WORD *term, WORD level, WORD *path, WORD npath)
1488 CBUF *C = cbuf+AM.rbufnum;
1489 WORD pathfun = C->
lhs[level][4];
1490 WORD option1 = C->
lhs[level][5];
1491 WORD *tstop, *tstop1, *t, *tt;
1494 tstop1 = term+*term; tstop = tstop1 - ABS(tstop1[-1]);
1495 outterm = AT.WorkPointer;
1496 tt = outterm; t = term;
1497 while ( t < tstop ) *tt++ = *t++;
1499 if ( functions[pathfun-FUNCTION].spec == TENSORFUNCTION ) {
1500 *tt++ = FUNHEAD+npath;
1502 if ( option1 == -VECTOR ) {
1503 for ( i = 0; i < npath; i++ ) *tt++ = path[i]+AM.OffsetVector;
1506 for ( i = 0; i < npath; i++ ) *tt++ = path[i];
1510 *tt++ = FUNHEAD+npath*2;
1512 for ( i = 0; i< npath; i++ ) {
1514 if ( option1 == -VECTOR ) *tt++ = path[i] + AM.OffsetVector;
1515 else *tt++ = path[i];
1518 while ( t < tstop1 ) *tt++ = *t++;
1519 *outterm = tt - outterm;
1520 AT.WorkPointer = tt;
1522 MesCall(
"PathOutput");
1525 AT.WorkPointer = outterm;
1566WORD AllOnePI(WORD *term,WORD level)
1568 CBUF *C = cbuf+AM.rbufnum;
1569 WORD vcode = C->
lhs[level][2];
1570 WORD option1 = C->
lhs[level][4];
1586int RemoveBridges(
void)
1596int TakeOneLine(WORD*term,WORD level)
1608int OutputOnePI(PHEAD WORD *term,WORD level)
int Generator(PHEAD WORD *, WORD)