75 #define MV_OOM (Move *)1 90 static char rcsid[]
DD_UNUSED =
"$Id: cuddSymmetry.c,v 1.28 2012/02/05 01:07:19 fabio Exp $";
97 extern int ddTotalNISwaps;
145 int TotalSymmGroups = 0;
147 for (i = lower; i <= upper; i++) {
150 (void) fprintf(table->
out,
"Group:");
152 (void) fprintf(table->
out,
" %d",table->
invperm[x]);
162 (void) fprintf(table->
out,
"\n");
165 (void) fprintf(table->
out,
"Total Symmetric = %d\n",TotalSymm);
166 (void) fprintf(table->
out,
"Total Groups = %d\n",TotalSymmGroups);
193 DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
219 if (table->
vars[yindex]->
ref == 1)
223 xsymmy = xsymmyp = 1;
227 for (i = 0; i < slots; i++) {
229 while (f != sentinel) {
234 if ((
int) f1->
index == yindex) {
238 if ((
int) f0->
index != yindex) {
247 if ((
int) f0->
index == yindex) {
259 xsymmy &= f01 == f10;
260 xsymmyp &= f11 == f00;
261 if ((xsymmy == 0) && (xsymmyp == 0))
273 for (i = 0; i < slots; i++) {
275 while (f != sentinel) {
276 TotalRefCount += f->
ref;
281 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 282 if (arccount == TotalRefCount) {
284 (void) fprintf(table->
out,
285 "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
290 return(arccount == TotalRefCount);
341 goto ddSymmSiftingOutOfMem;
343 var =
ALLOC(
int,size);
346 goto ddSymmSiftingOutOfMem;
349 for (i = 0; i < size; i++) {
358 for (i = lower; i <= upper; i++) {
369 x = table->
perm[var[i]];
373 if (x < lower || x > upper)
continue;
376 if (!result)
goto ddSymmSiftingOutOfMem;
378 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
379 (void) fprintf(table->
out,
"-");
380 }
else if (table->
keys > (
unsigned) previousSize +
382 (void) fprintf(table->
out,
"+");
384 (void) fprintf(table->
out,
"=");
397 (void) fprintf(table->
out,
"\n#:S_SIFTING %8d: symmetric variables\n",
399 (void) fprintf(table->
out,
"#:G_SIFTING %8d: symmetric groups",
405 ddSymmSiftingOutOfMem:
408 if (var != NULL)
FREE(var);
466 goto ddSymmSiftingConvOutOfMem;
468 var =
ALLOC(
int,size);
471 goto ddSymmSiftingConvOutOfMem;
474 for (i = 0; i < size; i++) {
485 for (i = lower; i <= upper; i++) {
496 x = table->
perm[var[i]];
497 if (x < lower || x > upper)
continue;
504 if (!result)
goto ddSymmSiftingConvOutOfMem;
506 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
507 (void) fprintf(table->
out,
"-");
508 }
else if (table->
keys > (
unsigned) previousSize +
510 (void) fprintf(table->
out,
"+");
512 (void) fprintf(table->
out,
"=");
520 while ((
unsigned) initialSize > table->
keys - table->
isolated) {
523 (void) fprintf(table->
out,
"\n");
526 for (x = lower, classes = 0; x <= upper; x++, classes++) {
539 qsort((
void *)var,classes,
sizeof(
int),(
DD_QSFP)ddSymmUniqueCompare);
549 x = table->
perm[var[i]];
555 if (!result )
goto ddSymmSiftingConvOutOfMem;
557 if (table->
keys < (
unsigned) previousSize + table->
isolated) {
558 (void) fprintf(table->
out,
"-");
559 }
else if (table->
keys > (
unsigned) previousSize +
561 (void) fprintf(table->
out,
"+");
563 (void) fprintf(table->
out,
"=");
574 (void) fprintf(table->
out,
"\n#:S_SIFTING %8d: symmetric variables\n",
576 (void) fprintf(table->
out,
"#:G_SIFTING %8d: symmetric groups",
585 ddSymmSiftingConvOutOfMem:
588 if (var != NULL)
FREE(var);
619 return((*ptrX) - (*ptrY));
654 int initGroupSize, finalGroupSize;
667 if ((x - xLow) > (xHigh - x)) {
671 for (i = x; i > xLow; i--) {
684 for (i = x; i < xHigh; i++) {
689 while ((
unsigned) topbot < table->subtables[topbot].next) {
701 while ((
unsigned) x < table->subtables[x].next)
710 if (x == xHigh)
return(1);
716 if (moveDown ==
MV_OOM)
goto ddSymmSiftingAuxOutOfMem;
717 if (moveDown == NULL)
return(1);
722 while ((
unsigned) i < table->subtables[i].next) {
730 finalGroupSize = i - x + 1;
732 if (initGroupSize == finalGroupSize) {
740 if (!result)
goto ddSymmSiftingAuxOutOfMem;
747 if (x == xLow)
return(1);
749 initGroupSize = i - x + 1;
753 if (moveUp ==
MV_OOM)
goto ddSymmSiftingAuxOutOfMem;
754 if (moveUp == NULL)
return(1);
764 finalGroupSize = x - i + 1;
766 if (initGroupSize == finalGroupSize) {
774 if (!result)
goto ddSymmSiftingAuxOutOfMem;
776 }
else if ((x - xLow) > (xHigh - x)) {
780 if (moveDown ==
MV_OOM)
goto ddSymmSiftingAuxOutOfMem;
782 if (moveDown != NULL) {
785 while ((
unsigned) i < table->subtables[i].next) {
790 while ((
unsigned) i < table->subtables[i].next) {
800 initGroupSize = i - x + 1;
803 if (moveUp ==
MV_OOM)
goto ddSymmSiftingAuxOutOfMem;
805 if (moveUp != NULL) {
810 while ((
unsigned) x < table->subtables[x].next)
818 finalGroupSize = x - i + 1;
820 if (initGroupSize == finalGroupSize) {
824 while (moveDown != NULL) {
825 move = moveDown->
next;
833 if (!result)
goto ddSymmSiftingAuxOutOfMem;
841 if (moveUp ==
MV_OOM)
goto ddSymmSiftingAuxOutOfMem;
843 if (moveUp != NULL) {
847 while ((
unsigned) x < table->subtables[x].next)
856 initGroupSize = x - i + 1;
859 if (moveDown ==
MV_OOM)
goto ddSymmSiftingAuxOutOfMem;
861 if (moveDown != NULL) {
864 while ((
unsigned) i < table->subtables[i].next) {
876 finalGroupSize = i - x + 1;
878 if (initGroupSize == finalGroupSize) {
882 while (moveUp != NULL) {
891 if (!result)
goto ddSymmSiftingAuxOutOfMem;
894 while (moveDown != NULL) {
895 move = moveDown->
next;
899 while (moveUp != NULL) {
907 ddSymmSiftingAuxOutOfMem:
909 while (moveDown != NULL) {
910 move = moveDown->
next;
916 while (moveUp != NULL) {
955 int initGroupSize, finalGroupSize;
969 initGroupSize = x - i + 1;
973 if (moveDown ==
MV_OOM)
goto ddSymmSiftingConvAuxOutOfMem;
974 if (moveDown == NULL)
return(1);
978 while ((
unsigned) i < table->subtables[i].next) {
986 finalGroupSize = i - x + 1;
988 if (initGroupSize == finalGroupSize) {
996 if (!result)
goto ddSymmSiftingConvAuxOutOfMem;
1000 while ((
unsigned) x < table->subtables[x].next)
1005 if (x == xLow)
return(1);
1007 initGroupSize = i - x + 1;
1011 if (moveUp ==
MV_OOM)
goto ddSymmSiftingConvAuxOutOfMem;
1012 if (moveUp == NULL)
return(1);
1021 finalGroupSize = x - i + 1;
1023 if (initGroupSize == finalGroupSize) {
1032 goto ddSymmSiftingConvAuxOutOfMem;
1034 }
else if ((x - xLow) > (xHigh - x)) {
1037 if (moveDown ==
MV_OOM)
goto ddSymmSiftingConvAuxOutOfMem;
1039 if (moveDown != NULL) {
1042 while ((
unsigned) i < table->subtables[i].next) {
1046 while ((
unsigned) x < table->subtables[x].next)
1056 initGroupSize = i - x + 1;
1059 if (moveUp ==
MV_OOM)
goto ddSymmSiftingConvAuxOutOfMem;
1061 if (moveUp != NULL) {
1066 while ((
unsigned) x < table->subtables[x].next)
1074 finalGroupSize = x - i + 1;
1076 if (initGroupSize == finalGroupSize) {
1080 while (moveDown != NULL) {
1081 move = moveDown->
next;
1089 if (!result)
goto ddSymmSiftingConvAuxOutOfMem;
1097 if (moveUp ==
MV_OOM)
goto ddSymmSiftingConvAuxOutOfMem;
1099 if (moveUp != NULL) {
1104 while ((
unsigned) x < table->subtables[x].next)
1112 initGroupSize = x - i + 1;
1115 if (moveDown ==
MV_OOM)
goto ddSymmSiftingConvAuxOutOfMem;
1117 if (moveDown != NULL) {
1120 while ((
unsigned) i < table->subtables[i].next) {
1132 finalGroupSize = i - x + 1;
1134 if (initGroupSize == finalGroupSize) {
1138 while (moveUp != NULL) {
1139 move = moveUp->
next;
1147 if (!result)
goto ddSymmSiftingConvAuxOutOfMem;
1150 while (moveDown != NULL) {
1151 move = moveDown->
next;
1155 while (moveUp != NULL) {
1156 move = moveUp->
next;
1163 ddSymmSiftingConvAuxOutOfMem:
1164 if (moveDown !=
MV_OOM) {
1165 while (moveDown != NULL) {
1166 move = moveDown->
next;
1172 while (moveUp != NULL) {
1173 move = moveUp->
next;
1233 while ((
unsigned) gybot < table->subtables[gybot].next)
1235 for (z = xLow + 1; z <= gybot; z++) {
1238 isolated = table->
vars[zindex]->
ref == 1;
1244 while (x >= xLow && L <= limitSize) {
1247 while ((
unsigned) gybot < table->subtables[gybot].next)
1250 for (z = xLow + 1; z <= gybot; z++) {
1253 isolated = table->
vars[zindex]->
ref == 1;
1276 if (size == 0)
goto ddSymmSiftingUpOutOfMem;
1279 isolated = table->
vars[xindex]->
ref == 1;
1283 if (move == NULL)
goto ddSymmSiftingUpOutOfMem;
1289 if ((
double) size > (double) limitSize * table->
maxGrowth)
1291 if (size < limitSize) limitSize = size;
1294 if (size == 0)
goto ddSymmSiftingUpOutOfMem;
1300 isolated = table->
vars[zindex]->
ref == 1;
1304 }
while (z != (
int) moves->
y);
1305 if ((
double) size > (
double) limitSize * table->
maxGrowth)
1307 if (size < limitSize) limitSize = size;
1315 ddSymmSiftingUpOutOfMem:
1316 while (moves != NULL) {
1368 for (z = xHigh; z > gxtop; z--) {
1371 isolated = table->
vars[zindex]->
ref == 1;
1377 while (y <= xHigh && size - R < limitSize) {
1381 for (z = xHigh; z > gxtop; z--) {
1384 isolated = table->
vars[zindex]->
ref == 1;
1404 isolated = table->
vars[yindex]->
ref == 1;
1412 if (size == 0)
goto ddSymmSiftingDownOutOfMem;
1414 if (move == NULL)
goto ddSymmSiftingDownOutOfMem;
1420 if ((
double) size > (double) limitSize * table->
maxGrowth)
1422 if (size < limitSize) limitSize = size;
1430 isolated = table->
vars[zindex]->
ref == 1;
1434 }
while (z <= gybot);
1436 if (size == 0)
goto ddSymmSiftingDownOutOfMem;
1437 if ((
double) size > (
double) limitSize * table->
maxGrowth)
1439 if (size < limitSize) limitSize = size;
1442 for (z = gxtop + 1; z <= gybot; z++) {
1445 isolated = table->
vars[zindex]->
ref == 1;
1456 ddSymmSiftingDownOutOfMem:
1457 while (moves != NULL) {
1489 int xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1498 xsize = xbot - xtop + 1;
1500 while ((
unsigned) ybot < table->subtables[ybot].next)
1503 ysize = ybot - ytop + 1;
1506 for (i = 1; i <= ysize; i++) {
1507 for (j = 1; j <= xsize; j++) {
1509 if (size == 0)
return(0);
1510 swapx = x; swapy = y;
1520 for (i = 0; i < ysize-1 ; i++) {
1528 for (i = 0; i < xsize - 1 ; i++) {
1536 if (move == NULL)
return(0);
1540 move->
next = *moves;
1568 int xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1577 xsize = xbot - xtop + 1;
1579 while ((
unsigned) ybot < table->subtables[ybot].next)
1582 ysize = ybot - ytop + 1;
1585 for (i = 1; i <= ysize; i++) {
1586 for (j = 1; j <= xsize; j++) {
1588 if (size == 0)
return(0);
1598 for (i = 0; i < ysize-1 ; i++) {
1606 for (i = 0; i < xsize-1 ; i++) {
1640 for (move = moves; move != NULL; move = move->
next) {
1641 if (move->
size < size) {
1646 for (move = moves; move != NULL; move = move->
next) {
1647 if (move->
size == size)
return(1);
1657 if (!res)
return(0);
1685 int TotalSymmGroups = 0;
1687 for (i = lower; i <= upper; i++) {
1702 *symvars = TotalSymm;
1703 *symgroups = TotalSymmGroups;
#define cuddDeallocMove(unique, node)
void Cudd_SymmProfile(DdManager *table, int lower, int upper)
int(* DD_QSFP)(const void *, const void *)
static Move * ddSymmSiftingDown(DdManager *table, int x, int xHigh)
static int ddSymmGroupMoveBackward(DdManager *table, int x, int y)
int cuddSymmCheck(DdManager *table, int x, int y)
#define Cudd_Regular(node)
int cuddNextLow(DdManager *table, int x)
#define Cudd_IsComplement(node)
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
DdNode * cuddDynamicAllocNode(DdManager *table)
static int ddSymmSiftingConvAux(DdManager *table, int x, int xLow, int xHigh)
static int ddSymmSiftingBackward(DdManager *table, Move *moves, int size)
static Move * ddSymmSiftingUp(DdManager *table, int y, int xLow)
int cuddNextHigh(DdManager *table, int x)
int cuddSwapInPlace(DdManager *table, int x, int y)
static char rcsid [] DD_UNUSED
int ddTotalNumberSwapping
int cuddTestInteract(DdManager *table, int x, int y)
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
static int ddSymmGroupMove(DdManager *table, int x, int y, Move **moves)
int cuddSymmSifting(DdManager *table, int lower, int upper)
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)