53int NormPolyTerm(PHEAD WORD *term)
55 WORD *tcoef, ncoef, *tstop, *tfill, *t, *tt;
57 WORD *r1, *r2, *r3, *r4, *r5, *rfirst, rv;
64 tstop = tcoef - ABS(tcoef[-1]);
67 if ( t >= tstop ) {
return(*term); }
77 r2 = rfirst+4; tt = r3 = t + t[1]; equal = 0;
80 if ( *r2 > *r1 ) { r2 += 2;
continue; }
81 if ( *r2 == *r1 ) { r2 += 2; equal = 1;
continue; }
82 rv = *r1; *r1 = *r2; *r2 = rv;
83 r1 -= 2; r2 -= 2; r4 = r2 + 2;
85 if ( *r2 >= *r1 ) { r2 = r4;
break; }
86 rv = *r1; *r1 = *r2; *r2 = rv;
100 while ( r4 < r3 ) *r2++ = *r4++;
102 r2 = r1 + 2; r3 -= 2;
111 r1 = t + 2; tt = r3 = t + t[1];
113 r2 = rfirst+2; r4 = rfirst + rfirst[1];
119 else if ( *r2 > *r1 ) {
121 while ( r5 > r2 ) { r5[1] = r5[-1]; r5[0] = r5[-2]; r5 -= 2; }
123 *r2 = *r1; r2[1] = r1[1];
130 *r2++ = *r1++; *r2++ = *r1++;
143 if ( t[3] & 1 ) ncoef = -ncoef;
145 else if ( t[2] == 0 ) {
146 if ( t[3] < 0 )
goto NormInf;
149 lnum = TermMalloc(
"lnum");
152 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
153 ncoef = REDLENG(ncoef);
155 if ( Divvy(BHEAD (UWORD *)tstop,&ncoef,(UWORD *)lnum,nnum) )
158 else if ( t[3] > 0 ) {
159 if ( Mully(BHEAD (UWORD *)tstop,&ncoef,(UWORD *)lnum,nnum) )
162 ncoef = INCLENG(ncoef);
164 TermFree(lnum,
"lnum");
167 ncoef = REDLENG(ncoef);
168 if ( Mully(BHEAD (UWORD *)tstop,&ncoef,(UWORD *)(t+3),t[2]) )
goto FromNorm;
169 ncoef = INCLENG(ncoef);
174 MLOCK(ErrorMessageLock);
175 MesPrint(
"!>Illegal code in NormPolyTerm");
176 MUNLOCK(ErrorMessageLock);
187 r3 = rfirst + rfirst[1];
191 while ( r1 < r3 ) { r1[-2] = r1[0]; r1[-1] = r1[1]; r1 += 2; }
197 if ( rfirst[1] < 4 ) rfirst = 0;
204 NCOPY(tfill,rfirst,i)
209 *term = tfill - term;
215 MLOCK(ErrorMessageLock);
216 MesPrint(
"0^0 in NormPolyTerm");
217 MUNLOCK(ErrorMessageLock);
221 MLOCK(ErrorMessageLock);
222 MesCall(
"NormPolyTerm");
223 MUNLOCK(ErrorMessageLock);
253#ifdef WITHCOMPAREPOLY
255WORD ComparePoly(WORD *term1, WORD *term2, WORD level)
257 WORD *t1, *t2, *t3, *t4, *tstop1, *tstop2;
258 tstop1 = term1 + *term1;
259 tstop1 -= ABS(tstop1[-1]);
260 tstop2 = term2 + *term2;
261 tstop2 -= ABS(tstop2[-1]);
264 while ( t1 < tstop1 && t2 < tstop2 ) {
266 if ( *t1 == HAAKJE ) {
267 if ( t1[2] != t2[2] )
return(t2[2]-t1[2]);
268 t1 += t1[1]; t2 += t2[1];
271 t3 = t1 + t1[1]; t4 = t2 + t2[1];
273 while ( t1 < t3 && t2 < t4 ) {
274 if ( *t1 != *t2 )
return(*t2-*t1);
275 if ( t1[1] != t2[1] )
return(t2[1]-t1[1]);
278 if ( t1 < t3 )
return(-1);
279 if ( t2 < t4 )
return(1);
282 else return(*t2-*t1);
284 if ( t1 < tstop1 )
return(-1);
285 if ( t2 < tstop2 )
return(1);
307static int FirstWarnConvertToPoly = 1;
309int ConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD *comlist, WORD par)
311 WORD *tout, *tstop, ncoef, *t, *r, *tt, *ttwo = 0;
318 if ( comlist[2] == DOALL ) {
319 while ( t < tstop ) {
320 if ( *t == SYMBOL ) {
335 i = FindSubterm(tout+1);
338 *tout++ = MAXVARIABLES-i;
345 else if ( *t == DOTPRODUCT ) {
349 tout[1] = DOTPRODUCT;
359 i = FindSubterm(tout+1);
362 *tout++ = MAXVARIABLES-i;
368 else if ( *t == VECTOR ) {
376 i = FindSubterm(tout+1);
379 *tout++ = MAXVARIABLES-i;
385 else if ( *t == INDEX ) {
392 i = FindSubterm(tout+1);
395 *tout++ = MAXVARIABLES-i;
401 else if ( *t == HAAKJE) {
403 tout[0] = 1; tout[1] = 1; tout[2] = 3;
404 *outterm = (tout+3)-outterm;
405 if ( NormPolyTerm(BHEAD outterm) < 0 )
return(-1);
406 tout = outterm + *outterm;
408 i = t[1]; NCOPY(tout,t,i);
413 else if ( *t >= FUNCTION ) {
418 *tout++ = MAXVARIABLES-i;
423 if ( FirstWarnConvertToPoly ) {
424 MLOCK(ErrorMessageLock);
425 MesPrint(
"Illegal object in conversion to polynomial notation");
426 MUNLOCK(ErrorMessageLock);
427 FirstWarnConvertToPoly = 0;
432 NCOPY(tout,tstop,ncoef)
436 if ( ( i = NormPolyTerm(BHEAD ttwo) ) >= 0 ) i = action;
439 *outterm = tout - outterm;
442 *outterm = tout-outterm;
443 if ( ( i = NormPolyTerm(BHEAD outterm) ) >= 0 ) i = action;
446 else if ( comlist[2] == ONLYFUNCTIONS ) {
447 while ( t < tstop ) {
448 if ( *t >= FUNCTION ) {
449 if ( comlist[1] == 3 ) {
454 *tout++ = MAXVARIABLES-i;
459 for ( i = 3; i < comlist[1]; i++ ) {
460 if ( *t == comlist[i] )
break;
462 if ( i < comlist[1] ) {
467 *tout++ = MAXVARIABLES-i;
472 i = t[1]; NCOPY(tout,t,i);
477 i = t[1]; NCOPY(tout,t,i);
480 NCOPY(tout,tstop,ncoef)
481 *outterm = tout-outterm;
482 Normalize(BHEAD outterm);
487 MLOCK(ErrorMessageLock);
488 MesPrint(
"!>Illegal internal code in conversion to polynomial notation");
489 MUNLOCK(ErrorMessageLock);
516 WORD *tout, *tstop, ncoef, *t, *r, *tt, *ttwo = 0;
523 while ( t < tstop ) {
524 if ( *t == SYMBOL ) {
539 i = FindLocalSubterm(BHEAD tout+1,startebuf);
542 *tout++ = MAXVARIABLES-i;
549 else if ( *t == DOTPRODUCT ) {
553 tout[1] = DOTPRODUCT;
563 i = FindLocalSubterm(BHEAD tout+1,startebuf);
566 *tout++ = MAXVARIABLES-i;
572 else if ( *t == VECTOR ) {
580 i = FindLocalSubterm(BHEAD tout+1,startebuf);
583 *tout++ = MAXVARIABLES-i;
589 else if ( *t == INDEX ) {
596 i = FindLocalSubterm(BHEAD tout+1,startebuf);
599 *tout++ = MAXVARIABLES-i;
605 else if ( *t == HAAKJE) {
607 tout[0] = 1; tout[1] = 1; tout[2] = 3;
608 *outterm = (tout+3)-outterm;
609 if ( NormPolyTerm(BHEAD outterm) < 0 )
return(-1);
610 tout = outterm + *outterm;
612 i = t[1]; NCOPY(tout,t,i);
617 else if ( *t >= FUNCTION ) {
618 i = FindLocalSubterm(BHEAD t,startebuf);
622 *tout++ = MAXVARIABLES-i;
627 if ( FirstWarnConvertToPoly ) {
628 MLOCK(ErrorMessageLock);
629 MesPrint(
"Illegal object in conversion to polynomial notation");
630 MUNLOCK(ErrorMessageLock);
631 FirstWarnConvertToPoly = 0;
636 NCOPY(tout,tstop,ncoef)
640 if ( ( i = NormPolyTerm(BHEAD ttwo) ) >= 0 ) i = action;
643 *outterm = tout - outterm;
646 *outterm = tout-outterm;
647 if ( ( i = NormPolyTerm(BHEAD outterm) ) >= 0 ) i = action;
664int ConvertFromPoly(PHEAD WORD *term, WORD *outterm, WORD from, WORD to, WORD offset, WORD par)
666 WORD *tout, *tstop, *tstop1, ncoef, *t, *r, *tt;
724 while ( t < tstop ) {
725 if ( *t == SYMBOL ) {
728 while ( tt < tstop1 ) {
729 if ( ( *tt < MAXVARIABLES - to )
730 || ( *tt >= MAXVARIABLES - from ) ) {
734 *tout++ = SUBEXPRESSION;
735 *tout++ = SUBEXPSIZE;
736 *tout++ = MAXVARIABLES - *tt++ + offset;
738 if ( par ) *tout++ = AT.ebufnum;
739 else *tout++ = AM.sbufnum;
744 *tout++ = SYMBOL; *tout++ = 0;
745 while ( t < tstop1 ) {
746 if ( ( *t < MAXVARIABLES - to )
747 || ( *t >= MAXVARIABLES - from ) ) {
754 if ( r[1] <= 2 ) tout = r;
757 i = t[1]; NCOPY(tout,t,i)
760 NCOPY(tout,tstop,ncoef)
761 *outterm = tout-outterm;
777int FindSubterm(WORD *subterm)
779 WORD old[5], *ss, *term;
781 CBUF *C = cbuf + AM.sbufnum;
784 ss = subterm+subterm[1];
788 old[0] = *term; old[1] = ss[0]; old[2] = ss[1]; old[3] = ss[2]; old[4] = ss[3];
789 ss[0] = 1; ss[1] = 1; ss[2] = 3; ss[3] = 0; *term = subterm[1]+4;
799 AddNtoC(AM.sbufnum,*term,term,8);
804 number = InsTree(AM.sbufnum,C->numrhs);
808 if ( number < (C->numrhs) ) {
814 WORD dim = DimensionSubterm(subterm);
816 if ( dim == -MAXPOSITIVE ) {
817 WORD *old = AN.currentTerm;
818 AN.currentTerm = term;
819 MLOCK(ErrorMessageLock);
820 MesPrint(
"Dimension out of range in %t");
821 MUNLOCK(ErrorMessageLock);
822 AN.currentTerm = old;
831 *term = old[0]; ss[0] = old[1]; ss[1] = old[2]; ss[2] = old[3]; ss[3] = old[4];
847int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf)
849 WORD old[5], *ss, *term, i, j, *t1, *t2;
851 CBUF *C = cbuf + AT.ebufnum;
853 ss = subterm+subterm[1];
857 old[0] = *term; old[1] = ss[0]; old[2] = ss[1]; old[3] = ss[2]; old[4] = ss[3];
858 ss[0] = 1; ss[1] = 1; ss[2] = 3; ss[3] = 0; *term = subterm[1]+4;
862 number = FindTree(AM.sbufnum,term);
863 if ( number > 0 )
goto wearehappy;
868 for ( i = startebuf+1; i <= C->numrhs; i++ ) {
869 t1 = C->
rhs[i]; t2 = term;
872 while ( *t1 == *t2 && j > 0 ) { t1++; t2++; j--; }
874 number = i-startebuf+numxsymbol;
883 AddNtoC(AT.ebufnum,*term,term,9);
885 number = C->numrhs-startebuf+numxsymbol;
887 *term = old[0]; ss[0] = old[1]; ss[1] = old[2]; ss[2] = old[3]; ss[3] = old[4];
901void PrintSubtermList(
int from,
int to)
903 UBYTE buffer[80], *out, outbuffer[300];
904 int first, i, ii, inc = 1;
906 CBUF *C = cbuf + AM.sbufnum;
917 AO.OutFill = AO.OutputLine = outbuffer;
918 AO.OutStop = AO.OutputLine+AC.LineLength;
922 if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
923 TokenToLine((UBYTE *)
" ");
926 else if ( ( AO.Optimize.debugflags & 1 ) == 1 ) {}
927 else if ( AO.OutSkip > 0 ) {
928 for ( i = 0; i < AO.OutSkip; i++ ) TokenToLine((UBYTE *)
" ");
932 if ( ( AO.Optimize.debugflags & 1 ) == 1 ) {
933 TokenToLine((UBYTE *)
"id ");
934 for ( ii = 3; ii < AO.OutSkip; ii++ ) TokenToLine((UBYTE *)
" ");
941 else if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {}
942 else { TokenToLine((UBYTE *)
" "); }
944 out = StrCopy((UBYTE *)AC.extrasym,buffer);
945 if ( AC.extrasymbols == 0 ) {
946 out = NumCopy(i,out);
947 out = StrCopy((UBYTE *)
"_",out);
949 else if ( AC.extrasymbols == 1 ) {
950 out = AddArrayIndex(i,out);
952 out = StrCopy((UBYTE *)
"=",out);
957 out = StrCopy((UBYTE *)
"0",buffer);
958 if ( AC.OutputMode != FORTRANMODE && AC.OutputMode != PFORTRANMODE ) {
959 out = StrCopy((UBYTE *)
";",out);
965 if ( WriteInnerTerm(term,first) ) Terminate(-1);
969 if ( AC.OutputMode != FORTRANMODE && AC.OutputMode != PFORTRANMODE ) {
970 out = StrCopy((UBYTE *)
";",buffer);
987 if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
1013void PrintExtraSymbol(
int num, WORD *terms,
int par)
1015 UBYTE buffer[80], *out, outbuffer[300];
1019 AO.OutFill = AO.OutputLine = outbuffer;
1020 AO.OutStop = AO.OutputLine+AC.LineLength;
1023 if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
1024 TokenToLine((UBYTE *)
" ");
1027 else if ( ( AO.Optimize.debugflags & 1 ) == 1 ) {
1028 TokenToLine((UBYTE *)
"id ");
1029 for ( i = 3; i < AO.OutSkip; i++ ) TokenToLine((UBYTE *)
" ");
1031 else if ( AO.OutSkip > 0 ) {
1032 for ( i = 0; i < AO.OutSkip; i++ ) TokenToLine((UBYTE *)
" ");
1037 if ( num >= MAXVARIABLES-cbuf[AM.sbufnum].numrhs ) {
1038 num = MAXVARIABLES-num;
1041 out = StrCopy(FindSymbol(num),out);
1047 out = StrCopy(FindExtraSymbol(num),out);
1059 case EXPRESSIONNUMBER:
1060 out = StrCopy(EXPRNAME(num),out);
1063 MesPrint(
"Illegal option in PrintExtraSymbol");
1066 out = StrCopy((UBYTE *)
"=",out);
1067 TokenToLine(buffer);
1071 out = StrCopy((UBYTE *)
"0",buffer);
1072 TokenToLine(buffer);
1076 if ( WriteInnerTerm(term,first) ) Terminate(-1);
1081 if ( AC.OutputMode != FORTRANMODE && AC.OutputMode != PFORTRANMODE ) {
1082 out = StrCopy((UBYTE *)
";",buffer);
1083 TokenToLine(buffer);
1100int FindSubexpression(WORD *subexpr)
1104 CBUF *C = cbuf + AM.sbufnum;
1108 while ( *term ) term += *term;
1109 number = term - subexpr;
1121 AddNtoC(AM.sbufnum,number,subexpr,10);
1126 number = InsTree(AM.sbufnum,C->numrhs);
1130 if ( number < (C->numrhs) ) {
1136 WORD dim = DimensionExpression(BHEAD subexpr);
1143 UNLOCK(AM.sbuflock);
1153int ExtraSymFun(PHEAD WORD *term,WORD level)
1155 WORD *oldworkpointer = AT.WorkPointer;
1156 WORD *termout, *t1, *t2, *t3, *tstop, *tend, i;
1158 tend = termout = term + *term;
1159 tstop = tend - ABS(tend[-1]);
1160 t3 = t1 = term+1; t2 = termout+1;
1164 while ( t1 < tstop ) {
1165 if ( *t1 == EXTRASYMFUN && t1[1] == FUNHEAD+2 ) {
1166 if ( t1[FUNHEAD] == -SNUMBER && t1[FUNHEAD+1] <= numxsymbol
1167 && t1[FUNHEAD+1] > 0 ) {
1170 else if ( t1[FUNHEAD] == -SYMBOL && t1[FUNHEAD+1] < MAXVARIABLES
1171 && t1[FUNHEAD+1] >= MAXVARIABLES-numxsymbol ) {
1172 i = MAXVARIABLES - t1[FUNHEAD+1];
1175 while ( t3 < t1 ) *t2++ = *t3++;
1179 *t2++ = SUBEXPRESSION;
1185 t3 = t1 = t1 + t1[1];
1187 else if ( *t1 == EXTRASYMFUN && t1[1] == FUNHEAD ) {
1188 while ( t3 < t1 ) *t2++ = *t3++;
1189 t3 = t1 = t1 + t1[1];
1196 while ( t3 < tend ) *t2++ = *t3++;
1197 *termout = t2 - termout;
1198 AT.WorkPointer = t2;
1199 if ( AT.WorkPointer >= AT.WorkTop ) {
1200 MLOCK(ErrorMessageLock);
1202 MUNLOCK(ErrorMessageLock);
1203 AT.WorkPointer = oldworkpointer;
1206 retval =
Generator(BHEAD termout,level);
1207 AT.WorkPointer = oldworkpointer;
1209 MLOCK(ErrorMessageLock);
1210 MesCall(
"ExtraSymFun");
1211 MUNLOCK(ErrorMessageLock);
1221int PruneExtraSymbols(WORD downto)
1223 CBUF *C = cbuf + AM.sbufnum;
1224 if ( downto < C->numrhs && downto >= 0 ) {
1225 ClearTree(AM.sbufnum);
1227 if ( downto == 0 ) {
1231 WORD *w = C->
rhs[downto], i;
1232 while ( *w ) w += *w;
1234 for ( i = 1; i <= downto; i++ ) {
1235 InsTree(AM.sbufnum,i);
int Generator(PHEAD WORD *, WORD)
int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par)