71 #define CUDD_SWAP_MOVE 0 72 #define CUDD_LINEAR_TRANSFORM_MOVE 1 73 #define CUDD_INVERSE_TRANSFORM_MOVE 2 95 static char rcsid[]
DD_UNUSED =
"$Id: cuddLinear.c,v 1.29 2012/02/05 01:07:19 fabio Exp $";
102 extern int ddTotalNISwaps;
103 static int ddTotalNumberLinearTr;
155 int wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
158 for (i = 0; i < nvars; i++) {
159 for (j = 0; j < wordsPerRow; j++) {
160 word = table->
linear[i*wordsPerRow + j];
161 for (k = 0; k <
BPL; k++) {
162 retval = fprintf(table->
out,
"%ld",word & 1);
163 if (retval == 0)
return(0);
167 retval = fprintf(table->
out,
"\n");
168 if (retval == 0)
return(0);
192 int nvars = table->
size;
193 int wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
200 word = wordsPerRow * x + (y >>
LOGBPL);
202 result = (int) ((table->
linear[word] >> bit) & 1);
251 ddTotalNumberLinearTr = 0;
258 if (table->
linear == NULL) {
260 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
262 (void) fprintf(table->
out,
"\n");
264 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
268 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
270 (void) fprintf(table->
out,
"\n");
272 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
280 goto cuddLinearAndSiftingOutOfMem;
282 var =
ALLOC(
int,size);
285 goto cuddLinearAndSiftingOutOfMem;
288 for (i = 0; i < size; i++) {
298 x = table->
perm[var[i]];
299 if (x < lower || x > upper)
continue;
304 if (!result)
goto cuddLinearAndSiftingOutOfMem;
306 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
307 (void) fprintf(table->
out,
"-");
308 }
else if (table->
keys > (
unsigned) previousSize + table->
isolated) {
309 (void) fprintf(table->
out,
"+");
310 (void) fprintf(table->
out,
"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->
keys - table->
isolated, var[i]);
312 (void) fprintf(table->
out,
"=");
325 (void) fprintf(table->
out,
"\n#:L_LINSIFT %8d: linear trans.",
326 ddTotalNumberLinearTr);
331 cuddLinearAndSiftingOutOfMem:
334 if (var != NULL)
FREE(var);
369 int oldxkeys, oldykeys;
370 int newxkeys, newykeys;
371 int comple, newcomplement;
375 DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
398 ddTotalNumberLinearTr++;
421 isolated = - ((table->
vars[xindex]->
ref == 1) +
422 (table->
vars[yindex]->
ref == 1));
432 for (i = 0; i < xslots; i++) {
434 if (f == sentinel)
continue;
441 while ((next = f->
next) != sentinel) {
454 table->swapSteps += oldxkeys;
467 if ((
int) f1->
index == yindex) {
478 if ((
int) f0->
index == yindex) {
495 posn =
ddHash(f11, f00, yshift);
497 previousP = &(ylist[posn]);
499 while (f11 <
cuddT(newf1)) {
500 previousP = &(newf1->
next);
503 while (f11 ==
cuddT(newf1) && f00 <
cuddE(newf1)) {
504 previousP = &(newf1->
next);
507 if (
cuddT(newf1) == f11 &&
cuddE(newf1) == f00) {
512 goto cuddLinearOutOfMem;
513 newf1->
index = yindex; newf1->
ref = 1;
520 newf1->
next = *previousP;
549 posn =
ddHash(f01, f10, yshift);
551 previousP = &(ylist[posn]);
553 while (f01 <
cuddT(newf0)) {
554 previousP = &(newf0->
next);
557 while (f01 ==
cuddT(newf0) && f10 <
cuddE(newf0)) {
558 previousP = &(newf0->
next);
561 if (
cuddT(newf0) == f01 &&
cuddE(newf0) == f10) {
566 goto cuddLinearOutOfMem;
567 newf0->
index = yindex; newf0->
ref = 1;
574 newf0->
next = *previousP;
590 posn =
ddHash(newf1, newf0, xshift);
592 previousP = &(xlist[posn]);
594 while (newf1 <
cuddT(tmp)) {
595 previousP = &(tmp->
next);
598 while (newf1 ==
cuddT(tmp) && newf0 <
cuddE(tmp)) {
599 previousP = &(tmp->
next);
602 f->
next = *previousP;
610 for (i = 0; i < yslots; i++) {
611 previousP = &(ylist[i]);
613 while (f != sentinel) {
624 previousP = &(f->
next);
628 *previousP = sentinel;
633 (void) fprintf(table->
out,
"Linearly combining %d and %d\n",x,y);
637 for (i = 0; i < yslots; i++) {
639 while (f != sentinel) {
646 if (count != newykeys) {
647 fprintf(table->
err,
"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count);
650 fprintf(table->
err,
"Error in id's of ylist\twrong id's = %d\n",idcheck);
653 for (i = 0; i < xslots; i++) {
655 while (f != sentinel) {
662 if (count != newxkeys || newxkeys != oldxkeys) {
663 fprintf(table->
err,
"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count);
666 fprintf(table->
err,
"Error in id's of xlist\twrong id's = %d\n",idcheck);
669 isolated += (table->
vars[xindex]->
ref == 1) +
670 (table->
vars[yindex]->
ref == 1);
681 table->
keys += newykeys - oldykeys;
695 (void) fprintf(table->
err,
"Error: cuddLinearInPlace out of memory\n");
720 for (i = 0; i < yindex; i++) {
729 for (i = yindex+1; i < table->
size; i++) {
767 wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
768 words = wordsPerRow * nvars;
770 if (linear == NULL) {
774 table->
memused += words *
sizeof(long);
776 for (i = 0; i < words; i++) linear[i] = 0;
777 for (i = 0; i < nvars; i++) {
778 word = wordsPerRow * i + (i >>
LOGBPL);
780 linear[word] = 1 << bit;
804 int wordsPerRow,oldWordsPerRow;
809 long *linear,*oldLinear;
812 oldWordsPerRow = ((oldNvars - 1) >>
LOGBPL) + 1;
813 oldWords = oldWordsPerRow * oldNvars;
814 oldLinear = table->
linear;
817 wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
818 words = wordsPerRow * nvars;
820 if (linear == NULL) {
824 table->
memused += (words - oldWords) *
sizeof(
long);
825 for (i = 0; i < words; i++) linear[i] = 0;
828 for (i = 0; i < oldNvars; i++) {
829 for (j = 0; j < oldWordsPerRow; j++) {
830 oldWord = oldWordsPerRow * i + j;
831 word = wordsPerRow * i + j;
832 linear[word] = oldLinear[oldWord];
838 for (i = oldNvars; i < nvars; i++) {
839 word = wordsPerRow * i + (i >>
LOGBPL);
841 linear[word] = 1 << bit;
874 return((*ptrX) - (*ptrY));
920 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
922 }
else if (x == xHigh) {
928 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
930 }
else if ((x - xLow) > (xHigh - x)) {
936 assert(moveUp == NULL || moveUp->
x == x);
939 if (moveUp == (
Move *) CUDD_OUT_OF_MEM)
goto ddLinearAndSiftingAuxOutOfMem;
942 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
950 assert(moveDown == NULL || moveDown->
y == x);
953 if (moveDown == (
Move *) CUDD_OUT_OF_MEM)
goto ddLinearAndSiftingAuxOutOfMem;
956 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
959 while (moveDown != NULL) {
960 move = moveDown->
next;
964 while (moveUp != NULL) {
972 ddLinearAndSiftingAuxOutOfMem:
973 while (moveDown != NULL) {
974 move = moveDown->
next;
978 while (moveUp != NULL) {
1032 for (x = xLow + 1; x < y; x++) {
1035 isolated = table->
vars[xindex]->
ref == 1;
1039 isolated = table->
vars[yindex]->
ref == 1;
1043 while (x >= xLow && L <= limitSize) {
1047 for (z = xLow + 1; z < y; z++) {
1050 isolated = table->
vars[zindex]->
ref == 1;
1054 isolated = table->
vars[yindex]->
ref == 1;
1057 (void) fprintf(table->
out,
"checkL(%d) != L(%d)\n",checkL,L);
1061 if (size == 0)
goto ddLinearAndSiftingUpOutOfMem;
1063 if (newsize == 0)
goto ddLinearAndSiftingUpOutOfMem;
1065 if (move == NULL)
goto ddLinearAndSiftingUpOutOfMem;
1071 if (newsize >= size) {
1077 if (newsize == 0)
goto ddLinearAndSiftingUpOutOfMem;
1079 if (newsize != size) {
1080 (void) fprintf(table->
out,
"Change in size after identity transformation! From %d to %d\n",size,newsize);
1091 isolated = table->
vars[xindex]->
ref == 1;
1094 if ((
double) size > (
double) limitSize * table->
maxGrowth)
break;
1095 if (size < limitSize) limitSize = size;
1101 ddLinearAndSiftingUpOutOfMem:
1102 while (moves != NULL) {
1150 for (y = xHigh; y > x; y--) {
1153 isolated = table->
vars[yindex]->
ref == 1;
1159 while (y <= xHigh && size - R < limitSize) {
1162 for (z = xHigh; z > x; z--) {
1165 isolated = table->
vars[zindex]->
ref == 1;
1170 (void) fprintf(table->
out,
"checkR(%d) != R(%d)\n",checkR,R);
1176 isolated = table->
vars[yindex]->
ref == 1;
1180 if (size == 0)
goto ddLinearAndSiftingDownOutOfMem;
1182 if (newsize == 0)
goto ddLinearAndSiftingDownOutOfMem;
1184 if (move == NULL)
goto ddLinearAndSiftingDownOutOfMem;
1190 if (newsize >= size) {
1196 if (newsize == 0)
goto ddLinearAndSiftingDownOutOfMem;
1197 if (newsize != size) {
1198 (void) fprintf(table->
out,
"Change in size after identity transformation! From %d to %d\n",size,newsize);
1206 if ((
double) size > (
double) limitSize * table->
maxGrowth)
break;
1207 if (size < limitSize) limitSize = size;
1213 ddLinearAndSiftingDownOutOfMem:
1214 while (moves != NULL) {
1246 for (move = moves; move != NULL; move = move->
next) {
1247 if (move->
size < size) {
1252 for (move = moves; move != NULL; move = move->
next) {
1253 if (move->
size == size)
return(1);
1256 if (!res)
return(0);
1259 if (!res)
return(0);
1262 if (!res)
return(0);
1288 Move *invmoves = NULL;
1293 for (move = moves; move != NULL; move = move->
next) {
1295 if (invmove == NULL)
goto ddUndoMovesOutOfMem;
1296 invmove->
x = move->
x;
1297 invmove->
y = move->
y;
1298 invmove->
next = invmoves;
1303 if (!size)
goto ddUndoMovesOutOfMem;
1307 if (!size)
goto ddUndoMovesOutOfMem;
1309 if (!size)
goto ddUndoMovesOutOfMem;
1312 (void) fprintf(table->
err,
"Unforseen event in ddUndoMoves!\n");
1316 if (!size)
goto ddUndoMovesOutOfMem;
1318 if (!size)
goto ddUndoMovesOutOfMem;
1320 invmove->
size = size;
1325 ddUndoMovesOutOfMem:
1326 while (invmoves != NULL) {
1327 move = invmoves->
next;
1355 int nvars = table->
size;
1356 int wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
1357 int xstart = wordsPerRow * x;
1358 int ystart = wordsPerRow * y;
1359 long *linear = table->
linear;
1361 for (i = 0; i < wordsPerRow; i++) {
1362 linear[xstart+i] ^= linear[ystart+i];
static char rcsid [] DD_UNUSED
unsigned short DdHalfWord
#define cuddDeallocMove(unique, node)
int(* DD_QSFP)(const void *, const void *)
static void cuddXorLinear(DdManager *table, int x, int y)
void cuddSetInteract(DdManager *table, int x, int y)
#define Cudd_Regular(node)
int cuddNextLow(DdManager *table, int x)
#define CUDD_INVERSE_TRANSFORM_MOVE
int cuddInitLinear(DdManager *table)
static int ddLinearAndSiftingBackward(DdManager *table, int size, Move *moves)
int Cudd_ReadLinear(DdManager *table, int x, int y)
int cuddResizeLinear(DdManager *table)
int ddTotalNumberSwapping
#define Cudd_IsComplement(node)
int Cudd_PrintLinear(DdManager *table)
static Move * ddUndoMoves(DdManager *table, Move *moves)
#define CUDD_LINEAR_TRANSFORM_MOVE
int cuddLinearAndSifting(DdManager *table, int lower, int upper)
int Cudd_DebugCheck(DdManager *table)
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
int cuddLinearInPlace(DdManager *table, int x, int y)
DdNode * cuddDynamicAllocNode(DdManager *table)
#define cuddDeallocNode(unique, node)
int cuddNextHigh(DdManager *table, int x)
static Move * ddLinearAndSiftingUp(DdManager *table, int y, int xLow, Move *prevMoves)
int cuddSwapInPlace(DdManager *table, int x, int y)
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
static Move * ddLinearAndSiftingDown(DdManager *table, int x, int xHigh, Move *prevMoves)
int cuddTestInteract(DdManager *table, int x, int y)
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)