75 #define CUDD_SWAP_MOVE 0
76 #define CUDD_LINEAR_TRANSFORM_MOVE 1
77 #define CUDD_INVERSE_TRANSFORM_MOVE 2
99 static char rcsid[]
DD_UNUSED =
"$Id: cuddLinear.c,v 1.28 2009/02/19 16:21:03 fabio Exp $";
106 extern int ddTotalNISwaps;
107 static int ddTotalNumberLinearTr;
159 int wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
162 for (i = 0; i < nvars; i++) {
163 for (j = 0; j < wordsPerRow; j++) {
164 word = table->
linear[i*wordsPerRow + j];
165 for (k = 0; k <
BPL; k++) {
166 retval = fprintf(table->
out,
"%ld",word & 1);
167 if (retval == 0)
return(0);
171 retval = fprintf(table->
out,
"\n");
172 if (retval == 0)
return(0);
196 int nvars = table->
size;
197 int wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
204 word = wordsPerRow * x + (y >>
LOGBPL);
206 result = (int) ((table->
linear[word] >> bit) & 1);
255 ddTotalNumberLinearTr = 0;
262 if (table->
linear == NULL) {
264 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
266 (void) fprintf(table->
out,
"\n");
268 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
272 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
274 (void) fprintf(table->
out,
"\n");
276 if (result == 0)
goto cuddLinearAndSiftingOutOfMem;
284 goto cuddLinearAndSiftingOutOfMem;
289 goto cuddLinearAndSiftingOutOfMem;
292 for (i = 0; i <
size; i++) {
302 x = table->
perm[var[i]];
303 if (x < lower || x > upper)
continue;
308 if (!result)
goto cuddLinearAndSiftingOutOfMem;
310 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
311 (void) fprintf(table->
out,
"-");
312 }
else if (table->
keys > (
unsigned) previousSize + table->
isolated) {
313 (void) fprintf(table->
out,
"+");
314 (void) fprintf(table->
out,
"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->
keys - table->
isolated, var[i]);
316 (void) fprintf(table->
out,
"=");
329 (void) fprintf(table->
out,
"\n#:L_LINSIFT %8d: linear trans.",
330 ddTotalNumberLinearTr);
335 cuddLinearAndSiftingOutOfMem:
373 int oldxkeys, oldykeys;
374 int newxkeys, newykeys;
375 int comple, newcomplement;
379 DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
380 DdNode *g,*next,*last=NULL;
402 ddTotalNumberLinearTr++;
425 isolated = - ((table->
vars[xindex]->
ref == 1) +
426 (table->
vars[yindex]->
ref == 1));
436 for (i = 0; i < xslots; i++) {
438 if (f == sentinel)
continue;
445 while ((next = f->
next) != sentinel) {
458 table->swapSteps += oldxkeys;
471 if ((
int) f1->
index == yindex) {
482 if ((
int) f0->
index == yindex) {
501 previousP = &(ylist[posn]);
503 while (f11 <
cuddT(newf1)) {
504 previousP = &(newf1->
next);
507 while (f11 ==
cuddT(newf1) && f00 <
cuddE(newf1)) {
508 previousP = &(newf1->
next);
511 if (
cuddT(newf1) == f11 &&
cuddE(newf1) == f00) {
516 goto cuddLinearOutOfMem;
517 newf1->
index = yindex; newf1->
ref = 1;
524 newf1->
next = *previousP;
555 previousP = &(ylist[posn]);
557 while (f01 <
cuddT(newf0)) {
558 previousP = &(newf0->
next);
561 while (f01 ==
cuddT(newf0) && f10 <
cuddE(newf0)) {
562 previousP = &(newf0->
next);
565 if (
cuddT(newf0) == f01 &&
cuddE(newf0) == f10) {
570 goto cuddLinearOutOfMem;
571 newf0->
index = yindex; newf0->
ref = 1;
578 newf0->
next = *previousP;
596 previousP = &(xlist[posn]);
598 while (newf1 <
cuddT(tmp)) {
599 previousP = &(tmp->
next);
602 while (newf1 ==
cuddT(tmp) && newf0 <
cuddE(tmp)) {
603 previousP = &(tmp->
next);
606 f->
next = *previousP;
614 for (i = 0; i < yslots; i++) {
615 previousP = &(ylist[i]);
617 while (f != sentinel) {
628 previousP = &(f->
next);
632 *previousP = sentinel;
637 (void) fprintf(table->
out,
"Linearly combining %d and %d\n",x,y);
641 for (i = 0; i < yslots; i++) {
643 while (f != sentinel) {
650 if (count != newykeys) {
651 fprintf(table->
err,
"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count);
654 fprintf(table->
err,
"Error in id's of ylist\twrong id's = %d\n",idcheck);
657 for (i = 0; i < xslots; i++) {
659 while (f != sentinel) {
666 if (count != newxkeys || newxkeys != oldxkeys) {
667 fprintf(table->
err,
"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count);
670 fprintf(table->
err,
"Error in id's of xlist\twrong id's = %d\n",idcheck);
673 isolated += (table->
vars[xindex]->
ref == 1) +
674 (table->
vars[yindex]->
ref == 1);
685 table->
keys += newykeys - oldykeys;
699 (void) fprintf(table->
err,
"Error: cuddLinearInPlace out of memory\n");
724 for (i = 0; i < yindex; i++) {
733 for (i = yindex+1; i < table->
size; i++) {
771 wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
772 words = wordsPerRow * nvars;
774 if (linear == NULL) {
778 table->
memused += words *
sizeof(long);
780 for (i = 0; i < words; i++) linear[i] = 0;
781 for (i = 0; i < nvars; i++) {
782 word = wordsPerRow * i + (i >>
LOGBPL);
784 linear[
word] = 1 << bit;
808 int wordsPerRow,oldWordsPerRow;
813 long *linear,*oldLinear;
816 oldWordsPerRow = ((oldNvars - 1) >>
LOGBPL) + 1;
817 oldWords = oldWordsPerRow * oldNvars;
818 oldLinear = table->
linear;
821 wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
822 words = wordsPerRow * nvars;
824 if (linear == NULL) {
828 table->
memused += (words - oldWords) *
sizeof(
long);
829 for (i = 0; i < words; i++) linear[i] = 0;
832 for (i = 0; i < oldNvars; i++) {
833 for (j = 0; j < oldWordsPerRow; j++) {
834 oldWord = oldWordsPerRow * i + j;
835 word = wordsPerRow * i + j;
836 linear[
word] = oldLinear[oldWord];
842 for (i = oldNvars; i < nvars; i++) {
843 word = wordsPerRow * i + (i >>
LOGBPL);
845 linear[
word] = 1 << bit;
878 return((*ptrX) - (*ptrY));
924 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
926 }
else if (x == xHigh) {
932 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
934 }
else if ((x - xLow) > (xHigh - x)) {
940 assert(moveUp == NULL || moveUp->
x == x);
946 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
954 assert(moveDown == NULL || moveDown->
y == x);
960 if (!result)
goto ddLinearAndSiftingAuxOutOfMem;
963 while (moveDown != NULL) {
964 move = moveDown->
next;
968 while (moveUp != NULL) {
976 ddLinearAndSiftingAuxOutOfMem:
977 while (moveDown != NULL) {
978 move = moveDown->
next;
982 while (moveUp != NULL) {
1036 for (x = xLow + 1; x < y; x++) {
1039 isolated = table->
vars[xindex]->
ref == 1;
1043 isolated = table->
vars[yindex]->
ref == 1;
1047 while (x >= xLow && L <= limitSize) {
1051 for (z = xLow + 1; z < y; z++) {
1054 isolated = table->
vars[zindex]->
ref == 1;
1058 isolated = table->
vars[yindex]->
ref == 1;
1061 (void) fprintf(table->
out,
"checkL(%d) != L(%d)\n",checkL,L);
1065 if (size == 0)
goto ddLinearAndSiftingUpOutOfMem;
1067 if (newsize == 0)
goto ddLinearAndSiftingUpOutOfMem;
1069 if (move == NULL)
goto ddLinearAndSiftingUpOutOfMem;
1075 if (newsize >= size) {
1081 if (newsize == 0)
goto ddLinearAndSiftingUpOutOfMem;
1083 if (newsize != size) {
1084 (void) fprintf(table->
out,
"Change in size after identity transformation! From %d to %d\n",size,newsize);
1095 isolated = table->
vars[xindex]->
ref == 1;
1098 if ((
double) size > (
double) limitSize * table->
maxGrowth)
break;
1099 if (size < limitSize) limitSize =
size;
1105 ddLinearAndSiftingUpOutOfMem:
1106 while (moves != NULL) {
1154 for (y = xHigh; y > x; y--) {
1157 isolated = table->
vars[yindex]->
ref == 1;
1163 while (y <= xHigh && size - R < limitSize) {
1166 for (z = xHigh; z > x; z--) {
1169 isolated = table->
vars[zindex]->
ref == 1;
1174 (void) fprintf(table->
out,
"checkR(%d) != R(%d)\n",checkR,R);
1180 isolated = table->
vars[yindex]->
ref == 1;
1184 if (size == 0)
goto ddLinearAndSiftingDownOutOfMem;
1186 if (newsize == 0)
goto ddLinearAndSiftingDownOutOfMem;
1188 if (move == NULL)
goto ddLinearAndSiftingDownOutOfMem;
1194 if (newsize >= size) {
1200 if (newsize == 0)
goto ddLinearAndSiftingDownOutOfMem;
1201 if (newsize != size) {
1202 (void) fprintf(table->
out,
"Change in size after identity transformation! From %d to %d\n",size,newsize);
1210 if ((
double) size > (
double) limitSize * table->
maxGrowth)
break;
1211 if (size < limitSize) limitSize =
size;
1217 ddLinearAndSiftingDownOutOfMem:
1218 while (moves != NULL) {
1250 for (move = moves; move != NULL; move = move->
next) {
1251 if (move->
size < size) {
1256 for (move = moves; move != NULL; move = move->
next) {
1257 if (move->
size == size)
return(1);
1260 if (!res)
return(0);
1263 if (!res)
return(0);
1266 if (!res)
return(0);
1292 Move *invmoves = NULL;
1297 for (move = moves; move != NULL; move = move->
next) {
1299 if (invmove == NULL)
goto ddUndoMovesOutOfMem;
1300 invmove->
x = move->
x;
1301 invmove->
y = move->
y;
1302 invmove->
next = invmoves;
1307 if (!size)
goto ddUndoMovesOutOfMem;
1311 if (!size)
goto ddUndoMovesOutOfMem;
1313 if (!size)
goto ddUndoMovesOutOfMem;
1316 (void) fprintf(table->
err,
"Unforseen event in ddUndoMoves!\n");
1320 if (!size)
goto ddUndoMovesOutOfMem;
1322 if (!size)
goto ddUndoMovesOutOfMem;
1329 ddUndoMovesOutOfMem:
1330 while (invmoves != NULL) {
1331 move = invmoves->
next;
1359 int nvars = table->
size;
1360 int wordsPerRow = ((nvars - 1) >>
LOGBPL) + 1;
1361 int xstart = wordsPerRow * x;
1362 int ystart = wordsPerRow * y;
1363 long *linear = table->
linear;
1365 for (i = 0; i < wordsPerRow; i++) {
1366 linear[xstart+i] ^= linear[ystart+i];
static char rcsid[] DD_UNUSED
unsigned short DdHalfWord
#define cuddDeallocMove(unique, node)
static void cuddXorLinear(DdManager *table, int x, int y)
int(* DD_QSFP)(const void *, const void *)
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)
#define ABC_ALLOC(type, num)
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
unsigned __int64 word
DECLARATIONS ///.
#define ABC_NAMESPACE_IMPL_END
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)
#define ABC_NAMESPACE_IMPL_START
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)