106 WORD GetIfDollarNum(WORD *ifp, WORD *ifstop)
110 if ( ifp[2] < 0 ) {
return(-ifp[2]-1); }
112 if ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) {
113 if ( d->nfactors == 0 ) {
114 MLOCK(ErrorMessageLock);
115 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
116 MUNLOCK(ErrorMessageLock);
119 num = GetIfDollarNum(ifp+3,ifstop);
120 if ( num > d->nfactors ) {
121 MLOCK(ErrorMessageLock);
122 MesPrint(
"Dollar factor number %s out of range",num);
123 MUNLOCK(ErrorMessageLock);
129 w = d->factors[num-1].where;
130 if ( w == 0 )
return(d->factors[num].value);
132 if ( *w == 0 )
return(0);
133 if ( *w == 4 && w[3] == 3 && w[2] == 1 && w[1] < MAXPOSITIVE && w[4] == 0 ) {
136 if ( ( w[w[0]] != 0 ) || ( ABS(w[w[0]-1]) != w[0]-1 ) ) {
137 MLOCK(ErrorMessageLock);
138 MesPrint(
"Dollar factor number expected but found expression");
139 MUNLOCK(ErrorMessageLock);
143 MLOCK(ErrorMessageLock);
144 MesPrint(
"Dollar factor number out of range");
145 MUNLOCK(ErrorMessageLock);
153 if ( d->type == DOLZERO ) {
156 else if ( d->type == DOLNUMBER || d->type == DOLTERMS ) {
157 w = d->where;
goto getnumber;
160 MLOCK(ErrorMessageLock);
161 MesPrint(
"Dollar factor number is wrong type");
162 MUNLOCK(ErrorMessageLock);
173 int FindVar(WORD *v, WORD *term)
175 WORD *t, *tstop, *m, *mstop, *f, *fstop, *a, *astop;
178 while ( t < tstop ) {
179 if ( *v == *t && *v < FUNCTION ) {
182 m = t+2; mstop = t+t[1];
183 while ( m < mstop ) {
184 if ( *m == v[1] )
return(1);
191 m = t+2; mstop = t+t[1];
192 while ( m < mstop ) {
193 if ( *m == v[1] )
return(1);
198 m = t+2; mstop = t+t[1];
199 while ( m < mstop ) {
200 if ( *m == v[1] && m[1] == v[2] )
return(1);
201 if ( *m == v[2] && m[1] == v[1] )
return(1);
207 else if ( *v == VECTOR && *t == INDEX )
goto InVe;
208 else if ( *v == INDEX && *t == VECTOR )
goto InVe;
209 else if ( ( *v == VECTOR || *v == INDEX ) && *t == DOTPRODUCT ) {
210 m = t+2; mstop = t+t[1];
211 while ( m < mstop ) {
212 if ( v[1] == m[0] || v[1] == m[1] )
return(1);
216 else if ( *t >= FUNCTION ) {
217 if ( *v == FUNCTION && v[1] == *t )
return(1);
218 if ( functions[*t-FUNCTION].spec > 0 ) {
219 if ( *v == VECTOR || *v == INDEX ) {
221 for ( i = FUNHEAD; i < t[1]; i++ ) {
222 if ( v[1] == t[i] )
return(1);
227 fstop = t + t[1]; f = t + FUNHEAD;
228 while ( f < fstop ) {
232 if ( *v == SYMBOL && v[1] == f[1] )
return(1);
238 if ( ( *v == VECTOR || *v == INDEX )
239 && ( v[1] == f[1] ) )
return(1);
246 if ( *v == FUNCTION && v[1] == -*f && *f <= -FUNCTION )
return(1);
247 if ( *f <= -FUNCTION ) f++;
253 a = f + ARGHEAD; astop = f + *f;
254 while ( a < astop ) {
255 if ( FindVar(v,a) == 1 )
return(1);
280 WORD DoIfStatement(
PHEAD WORD *ifcode, WORD *term)
284 UWORD *coef1 = 0, *coef2, *coef3, *cc;
285 WORD ncoef1, ncoef2, ncoef3, i = 0, first, *r, acoef, ismul1, ismul2, j;
286 UWORD *Spac1, *Spac2;
287 ifstop = ifcode + ifcode[1];
289 if ( ifp >= ifstop )
return(1);
290 if ( ( ifp + ifp[1] ) >= ifstop ) {
293 if ( ifp[2] )
return(1);
297 if ( HowMany(BHEAD ifp,term) )
return(1);
300 if ( Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]) )
return(1);
303 if ( CountDo(term,ifp) )
return(1);
312 int nummodopt, dtype = -1;
313 if ( AS.MultiThreaded ) {
314 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
315 if ( ifp[2] == ModOptdollars[nummodopt].number )
break;
317 if ( nummodopt < NumModOptdollars ) {
318 dtype = ModOptdollars[nummodopt].type;
319 if ( dtype == MODLOCAL ) {
320 d = ModOptdollars[nummodopt].dstruct+AT.identity;
328 if ( dtype == DOLZERO )
return(0);
329 if ( dtype == DOLUNDEFINED ) {
330 if ( AC.UnsureDollarMode == 0 ) {
331 MesPrint(
"$%s is undefined",AC.dollarnames->namebuffer+d->name);
338 r = ifp+2; j = ifp[1] - 2;
340 if ( *r == AR.CurExpr )
return(1);
345 r = ifp+2; j = ifp[1] - 2;
347 if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 )
353 if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 )
return(0);
359 WORD *OccStop = ifp + ifp[1];
361 while ( ifp < OccStop ) {
362 if ( FindVar(ifp,term) == 1 )
return(1);
363 if ( *ifp == DOTPRODUCT ) ifp += 3;
372 if ( ifp[3] == ( ifp[1] + 3 ) )
return(DoIfStatement(BHEAD ifp,term));
373 ifstop = ifp + ifp[1];
381 coef3 = NumberMalloc(
"DoIfStatement");
382 Spac1 = NumberMalloc(
"DoIfStatement");
383 Spac2 = (UWORD *)(TermMalloc(
"DoIfStatement"));
384 ncoef1 = 0; first = 1; ismul1 = 0;
388 if ( ifp[-2] == ORCOND && ncoef1 ) {
390 ncoef1 = 1; coef1[0] = coef1[1] = 1;
393 if ( ifp[-2] == ANDCOND && !ncoef1 )
goto SkipCond;
402 cc = (UWORD *)(ifp + 3);
403 for ( i = 0; i < j; i++ ) coef2[i] = cc[i];
407 coef2[0] = HowMany(BHEAD ifp,term);
409 if ( coef2[0] == 0 ) ncoef2 = 0;
412 acoef = CountDo(term,ifp);
413 coef2[0] = ABS(acoef);
415 if ( acoef == 0 ) ncoef2 = 0;
416 else if ( acoef < 0 ) ncoef2 = -1;
419 acoef = Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]);
420 coef2[0] = ABS(acoef);
422 if ( acoef == 0 ) ncoef2 = 0;
423 else if ( acoef < 0 ) ncoef2 = -1;
429 cc = (UWORD *)(r - i);
430 if ( ncoef2 < 0 ) ncoef2 = (ncoef2+1)>>1;
431 else ncoef2 = (ncoef2-1)>>1;
432 i--;
for ( j = 0; j < i; j++ ) coef2[j] = cc[j];
435 ncoef2 = coef2[0] = DoIfStatement(BHEAD ifp,term);
454 int nummodopt, dtype = -1;
455 if ( AS.MultiThreaded ) {
456 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
457 if ( ifp[2] == ModOptdollars[nummodopt].number )
break;
459 if ( nummodopt < NumModOptdollars ) {
460 dtype = ModOptdollars[nummodopt].type;
461 if ( dtype == MODLOCAL ) {
462 d = ModOptdollars[nummodopt].dstruct+AT.identity;
465 LOCK(d->pthreadslockread);
473 if ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) {
474 if ( d->nfactors == 0 ) {
475 MLOCK(ErrorMessageLock);
476 MesPrint(
"Attempt to use a factor of an unfactored $-variable");
477 MUNLOCK(ErrorMessageLock);
480 WORD num = GetIfDollarNum(ifp+3,ifstop);
482 while ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) ifp += 3;
483 if ( num > d->nfactors ) {
484 MLOCK(ErrorMessageLock);
485 MesPrint(
"Dollar factor number %s out of range",num);
486 MUNLOCK(ErrorMessageLock);
490 ncoef2 = 1; coef2[0] = d->nfactors; coef2[1] = 1;
493 w = d->factors[num-1].where;
495 if ( d->factors[num-1].value < 0 ) {
496 ncoef2 = -1; coef2[0] = -d->factors[num-1].value; coef2[1] = 1;
499 ncoef2 = 1; coef2[0] = d->factors[num-1].value; coef2[1] = 1;
506 if ( i == ( *w-1 ) ) {
508 if ( *r < 0 ) ncoef2 = -ncoef2;
509 i--; cc = coef2; r = w + 1;
510 while ( --i >= 0 ) *cc++ = (UWORD)(*r++);
520 if ( AC.UnsureDollarMode == 0 ) {
522 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
524 MLOCK(ErrorMessageLock);
525 MesPrint(
"$%s is undefined",AC.dollarnames->namebuffer+d->name);
526 MUNLOCK(ErrorMessageLock);
529 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
532 ncoef2 = coef2[0] = 0; coef2[1] = 1;
535 if ( d->where[0] != INDEX || d->where[1] != 3
536 || d->where[2] < 0 || d->where[2] >= AM.OffsetIndex ) {
537 if ( AC.UnsureDollarMode == 0 ) {
539 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
541 MLOCK(ErrorMessageLock);
542 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
543 MUNLOCK(ErrorMessageLock);
546 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
549 d->index = d->where[2];
551 if ( d->index == 0 ) {
552 ncoef2 = coef2[0] = 0; coef2[1] = 1;
554 else if ( d->index > 0 && d->index < AM.OffsetIndex ) {
555 ncoef2 = 1; coef2[0] = d->index; coef2[1] = 1;
557 else if ( AC.UnsureDollarMode == 0 ) {
559 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
561 MLOCK(ErrorMessageLock);
562 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
563 MUNLOCK(ErrorMessageLock);
566 ncoef2 = coef2[0] = 0; coef2[1] = 1;
569 if ( d->where[0] <= -FUNCTION ||
570 ( d->where[0] < 0 && d->where[2] != 0 )
571 || ( d->where[0] > 0 && d->where[d->where[0]] != 0 )
573 if ( AC.UnsureDollarMode == 0 ) {
575 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
577 MLOCK(ErrorMessageLock);
578 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
579 MUNLOCK(ErrorMessageLock);
582 ncoef2 = coef2[0] = 0; coef2[1] = 1;
586 if ( d->where[0] == -SNUMBER ) {
587 if ( d->where[1] == 0 ) {
588 ncoef2 = coef2[0] = 0;
590 else if ( d->where[1] < 0 ) {
592 coef2[0] = -d->where[1];
596 coef2[0] = d->where[1];
600 else if ( d->where[0] == -INDEX
601 && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) {
602 if ( d->where[1] == 0 ) {
603 ncoef2 = coef2[0] = 0; coef2[1] = 1;
606 ncoef2 = 1; coef2[0] = d->where[1];
610 else if ( d->where[0] > 0
611 && d->where[ARGHEAD] == (d->where[0]-ARGHEAD)
612 && ABS(d->where[d->where[0]-1]) ==
613 (d->where[0] - ARGHEAD-1) ) {
614 i = d->where[d->where[0]-1];
615 ncoef2 = (ABS(i)-1)/2;
616 if ( i < 0 ) { ncoef2 = -ncoef2; i = -i; }
617 i--; cc = coef2; r = d->where + ARGHEAD+1;
618 while ( --i >= 0 ) *cc++ = (UWORD)(*r++);
621 if ( AC.UnsureDollarMode == 0 ) {
623 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
625 MLOCK(ErrorMessageLock);
626 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
627 MUNLOCK(ErrorMessageLock);
630 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
635 if ( d->where[d->where[0]] == 0 ) {
636 r = d->where + d->where[0]-1;
638 if ( i == ( d->where[0]-1 ) ) {
640 if ( *r < 0 ) ncoef2 = -ncoef2;
641 i--; cc = coef2; r = d->where + 1;
642 while ( --i >= 0 ) *cc++ = (UWORD)(*r++);
647 if ( AC.UnsureDollarMode == 0 ) {
649 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
651 MLOCK(ErrorMessageLock);
652 MesPrint(
"$%s is of wrong type",AC.dollarnames->namebuffer+d->name);
653 MUNLOCK(ErrorMessageLock);
656 ncoef2 = 0; coef2[0] = 0; coef2[1] = 1;
661 if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
666 r = ifp+2; j = ifp[1] - 2; ncoef2 = 0;
668 if ( *r == AR.CurExpr ) { ncoef2 = 1;
break; }
675 r = ifp+2; j = ifp[1] - 2;
678 if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 ) {
685 if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 ) {
697 WORD *OccStop = ifp + ifp[1], *ifpp = ifp+2;
699 while ( ifpp < OccStop ) {
700 if ( FindVar(ifpp,term) == 1 ) {
703 if ( *ifpp == DOTPRODUCT ) ifp += 3;
714 if ( ifp[-2] != ORCOND && ifp[-2] != ANDCOND ) {
715 if ( ( ifp[-2] == EQUAL || ifp[-2] == NOTEQUAL ) &&
716 ( ismul2 || ismul1 ) ) {
717 if ( ismul1 && ismul2 ) {
718 if ( coef1[0] == coef2[0] ) i = 1;
724 Divvy(BHEAD coef2,&ncoef2,coef1,ncoef1);
725 cc = coef2; ncoef3 = ncoef2;
729 Divvy(BHEAD coef1,&ncoef1,coef2,ncoef2);
730 cc = coef1; ncoef3 = ncoef1;
732 if ( ncoef3 < 0 ) ncoef3 = -ncoef3;
734 if ( ifp[-2] == EQUAL ) i = 1;
737 else if ( cc[ncoef3] != 1 ) {
738 if ( ifp[-2] == EQUAL ) i = 0;
742 for ( j = 1; j < ncoef3; j++ ) {
743 if ( cc[ncoef3+j] != 0 )
break;
746 if ( ifp[-2] == EQUAL ) i = 0;
749 else if ( ifp[-2] == EQUAL ) i = 1;
755 else if ( AddRat(BHEAD coef1,ncoef1,coef2,-ncoef2,coef3,&ncoef3) ) {
756 NumberFree(coef3,
"DoIfStatement"); NumberFree(Spac1,
"DoIfStatement"); TermFree(Spac2,
"DoIfStatement");
757 MesCall(
"DoIfStatement");
return(-1);
761 if ( ncoef3 > 0 ) i = 1;
765 if ( ncoef3 >= 0 ) i = 1;
769 if ( ncoef3 < 0 ) i = 1;
773 if ( ncoef3 <= 0 ) i = 1;
777 if ( ncoef3 == 0 ) i = 1;
781 if ( ncoef3 != 0 ) i = 1;
785 donemul:
if ( i ) { ncoef2 = 1; coef2 = Spac2; coef2[0] = coef2[1] = 1; }
795 for ( j = 0; j < i; j++ ) coef1[j] = coef2[j];
799 }
while ( ifp < ifstop );
801 NumberFree(coef3,
"DoIfStatement"); NumberFree(Spac1,
"DoIfStatement"); TermFree(Spac2,
"DoIfStatement");
802 if ( ncoef1 )
return(1);
816 WORD HowMany(
PHEAD WORD *ifcode, WORD *term)
819 WORD *m, *t, *r, *w, power, RetVal, i, topje, *newterm;
820 WORD *OldWork, *ww, *mm;
825 AN.WildValue = w = m + SUBEXPSIZE;
828 OldWork = AT.WorkPointer;
829 if ( ( ifcode[4] & 1 ) != 0 ) {
831 ww = AT.WorkPointer; i = m[0]; mm = m;
834 *ww++ = 1; *ww++ = 1; *ww++ = 3;
836 RepSto = AN.RepPoint;
839 if (
Generator(BHEAD OldWork,AR.Cnumlhs) ) {
842 AN.RepPoint = RepSto;
843 AT.WorkPointer = OldWork;
847 if (
EndSort(BHEAD ww,0) < 0 ) {}
849 AN.RepPoint = RepSto;
850 if ( *ww == 0 || *(ww+*ww) != 0 ) {
851 if ( AP.lhdollarerror == 0 ) {
852 MLOCK(ErrorMessageLock);
853 MesPrint(
"&LHS must be one term");
854 MUNLOCK(ErrorMessageLock);
855 AP.lhdollarerror = 1;
857 AT.WorkPointer = OldWork;
860 m = ww; AT.WorkPointer = ww = m + *m;
861 if ( m[*m-1] < 0 ) { m[*m-1] = -m[*m-1]; }
867 if ( AT.WorkPointer < ww ) AT.WorkPointer = ww;
870 while ( w < AN.WildStop ) {
871 if ( *w == LOADDOLLAR ) numdollars++;
875 AN.RepFunList = AT.WorkPointer;
876 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
877 topje = cbuf[AT.ebufnum].numrhs;
878 if ( AT.WorkPointer >= AT.WorkTop ) {
879 MLOCK(ErrorMessageLock);
881 MUNLOCK(ErrorMessageLock);
884 AN.DisOrderFlag = ifcode[2] & SUBDISORDER;
885 switch ( ifcode[2] & (~SUBDISORDER) ) {
888 AN.UseFindOnly = 1; AN.ForFindOnly = 0;
894 t = term; newterm = r = AT.WorkPointer;
895 NCOPY(r,t,i); AT.WorkPointer = r;
897 if ( FindRest(BHEAD newterm,m) && ( AN.UsedOtherFind ||
898 FindOnly(BHEAD newterm,m) ) ) {
899 Substitute(BHEAD newterm,m,1);
901 WildDollars(BHEAD (WORD *)0);
915 t = term; newterm = r = AT.WorkPointer;
916 NCOPY(r,t,i); AT.WorkPointer = r;
919 if ( ( power = FindRest(BHEAD newterm,m) ) > 0 ) {
920 if ( ( power = FindOnce(BHEAD newterm,m) ) > 0 ) {
923 Substitute(BHEAD newterm,m,1);
925 WildDollars(BHEAD (WORD *)0);
930 }
while ( FindRest(BHEAD newterm,m) && (
931 AN.UsedOtherFind || FindOnce(BHEAD newterm,m) ) );
933 else if ( power < 0 ) {
935 Substitute(BHEAD newterm,m,1);
937 WildDollars(BHEAD (WORD *)0);
942 }
while ( FindRest(BHEAD newterm,m) );
945 else if ( power < 0 ) {
946 if ( FindOnce(BHEAD newterm,m) ) {
948 Substitute(BHEAD newterm,m,1);
950 WildDollars(BHEAD (WORD *)0);
954 }
while ( FindOnce(BHEAD newterm,m) );
965 t = term; newterm = r = AT.WorkPointer;
966 NCOPY(r,t,i); AT.WorkPointer = r;
969 if ( FindRest(BHEAD newterm,m) && ( AN.UsedOtherFind || FindOnce(BHEAD newterm,m) ) ) {
970 Substitute(BHEAD newterm,m,1);
972 WildDollars(BHEAD (WORD *)0);
981 RetVal = FindMulti(BHEAD term,m);
985 for ( i = 0; i < *term; i++ ) ww[i] = term[i];
986 while ( ( power = FindAll(BHEAD ww,m,AR.Cnumlhs,ifcode) ) != 0 ) { RetVal += power; }
989 ifcode += IDHEAD; ifcode += ifcode[1]; ifcode += *ifcode;
990 AN.UseFindOnly = 1; AN.ForFindOnly = ifcode;
991 if ( FindRest(BHEAD term,m) && ( AN.UsedOtherFind ||
992 FindOnly(BHEAD term,m) ) ) RetVal = 1;
999 AT.WorkPointer = AN.RepFunList;
1000 cbuf[AT.ebufnum].numrhs = topje;
1009 VOID DoubleIfBuffers()
1013 LONG *newheap, *newifcount;
1014 if ( AC.MaxIf == 0 ) newmax = 10;
1015 else newmax = 2*AC.MaxIf;
1016 newheap = (LONG *)Malloc1(
sizeof(LONG)*(newmax+1),
"IfHeap");
1017 newsumcheck = (WORD *)Malloc1(
sizeof(WORD)*(newmax+1),
"IfSumCheck");
1018 newifcount = (LONG *)Malloc1(
sizeof(LONG)*(newmax+1),
"IfCount");
1020 for ( i = 0; i < AC.MaxIf; i++ ) {
1021 newheap[i] = AC.IfHeap[i];
1022 newsumcheck[i] = AC.IfSumCheck[i];
1023 newifcount[i] = AC.IfCount[i];
1025 AC.IfStack = (AC.IfStack-AC.IfHeap) + newheap;
1026 M_free(AC.IfHeap,
"AC.IfHeap");
1027 M_free(AC.IfCount,
"AC.IfCount");
1028 M_free(AC.IfSumCheck,
"AC.IfSumCheck");
1031 AC.IfStack = newheap;
1033 AC.IfHeap = newheap;
1034 AC.IfSumCheck = newsumcheck;
1035 AC.IfCount = newifcount;
WORD Generator(PHEAD WORD *, WORD)
LONG EndSort(PHEAD WORD *, int)