88 #define DD_NORMAL_SIFT 0 89 #define DD_LAZY_SIFT 1 92 #define DD_SIFT_DOWN 0 116 static char rcsid[]
DD_UNUSED =
"$Id: cuddGroup.c,v 1.49 2012/02/05 01:07:18 fabio Exp $";
122 extern int ddTotalNISwaps;
123 static int extsymmcalls;
125 static int secdiffcalls;
127 static int secdiffmisfire;
218 level = (low < (
unsigned int) dd->
size) ? dd->
perm[low] : low;
284 tempTree = table->
tree == NULL;
292 if (pr > 0 && !tempTree) (void) fprintf(table->
out,
"cuddTreeSifting:");
303 (void) fprintf(table->
out,
"\n");
305 (void) fprintf(table->
out,
"#:IM_NODES %8d: group tree nodes\n",
306 ddCountInternalMtrNodes(table,table->
tree));
313 for (i = 0; i < nvars; i++)
324 (void) fprintf(table->
out,
"\nextsymmcalls = %d\n",extsymmcalls);
325 (void) fprintf(table->
out,
"extsymm = %d",extsymm);
329 (void) fprintf(table->
out,
"\nsecdiffcalls = %d\n",secdiffcalls);
330 (void) fprintf(table->
out,
"secdiff = %d\n",secdiff);
331 (void) fprintf(table->
out,
"secdiffmisfire = %d",secdiffmisfire);
375 while (auxnode != NULL) {
376 if (auxnode->
child != NULL) {
389 }
else if (auxnode->
size > 1) {
413 ddCountInternalMtrNodes(
423 while (auxnode != NULL) {
426 count = ddCountInternalMtrNodes(table,auxnode->
child);
461 unsigned int initialSize;
472 (void) fprintf(table->
out,
" ");
486 if (initialSize <= table->keys - table->
isolated)
490 (
void) fprintf(table->
out,
"\n");
492 }
while (result != 0);
511 (void) fprintf(table->
err,
512 "Unknown group ckecking method\n");
529 (void) fprintf(table->
err,
530 "Unknown group ckecking method\n");
534 (void) fprintf(table->
out,
"\n");
538 if (initialSize <= table->keys - table->
isolated)
542 (
void) fprintf(table->
out,
"\n");
544 }
while (result != 0);
558 result =
cuddGa(table,lower,upper);
567 if (initialSize <= table->keys - table->
isolated)
571 (
void) fprintf(table->
out,
"\n");
573 }
while (result != 0);
594 if (pr > 0) (void) fprintf(table->
out,
"ddReorderChildren:");
630 if ((
int) treenode->
low >= table->
size) {
631 *lower = table->
size;
636 *lower = low = (
unsigned int) table->
perm[treenode->
index];
637 high = (
int) (low + treenode->
size - 1);
639 if (high >= table->
size) {
648 if (auxnode == NULL) {
649 *upper = (
unsigned int) table->
size - 1;
656 while (auxnode != NULL) {
657 int thisLower = table->
perm[auxnode->
low];
658 int thisUpper = thisLower + auxnode->
size - 1;
659 if (thisUpper >= table->
size && thisLower < table->size)
660 *upper = (
unsigned int) thisLower - 1;
666 *upper = (
unsigned int) high;
671 assert(treenode->
size >= *upper - *lower + 1);
698 return((*ptrX) - (*ptrY));
736 unsigned previousSize;
745 var =
ALLOC(
int,nvars);
748 goto ddGroupSiftingOutOfMem;
753 goto ddGroupSiftingOutOfMem;
755 sifted =
ALLOC(
int,nvars);
756 if (sifted == NULL) {
758 goto ddGroupSiftingOutOfMem;
762 for (i = 0, classes = 0; i < nvars; i++) {
772 qsort((
void *)var,classes,
sizeof(
int),
776 for (i = 0; i < nvars; i ++) {
791 if (sifted[xindex] == 1)
793 x = table->
perm[xindex];
812 if (!result)
goto ddGroupSiftingOutOfMem;
817 x = table->
perm[xindex];
819 if (x != upper && sifted[table->
invperm[x+1]] == 0 &&
826 if (x != lower && sifted[table->
invperm[x-1]] == 0 &&
838 while ((
unsigned) x < table->subtables[x].next)
842 if (!result)
goto ddGroupSiftingOutOfMem;
845 (void) fprintf(table->
out,
"_");
846 }
else if (table->
keys > previousSize + table->
isolated) {
847 (void) fprintf(table->
out,
"^");
849 (void) fprintf(table->
out,
"*");
854 (void) fprintf(table->
out,
"-");
855 }
else if (table->
keys > previousSize + table->
isolated) {
856 (void) fprintf(table->
out,
"+");
858 (void) fprintf(table->
out,
"=");
865 x = table->
perm[xindex];
872 }
while (x != xInit);
875 if (lazyFlag == 0 && dissolve) {
880 }
while (x != xInit);
885 if (pr > 0) (void) fprintf(table->
out,
"ddGroupSifting:");
897 ddGroupSiftingOutOfMem:
899 if (var != NULL)
FREE(var);
900 if (sifted != NULL)
FREE(sifted);
933 while ((
unsigned) gybot < table->subtables[gybot].next)
977 if (pr > 0) (void) fprintf(table->
out,
978 "ddGroupSiftingAux from %d to %d\n",xLow,xHigh);
994 for (y = x; y > xLow; y--) {
995 if (!checkFunction(table,y-1,y))
1006 for (y = x; y < xHigh; y++) {
1007 if (!checkFunction(table,y,y+1))
1011 while ((
unsigned) topbot < table->subtables[topbot].next) {
1023 while ((
unsigned) x < table->subtables[x].next)
1031 if (x == xHigh)
return(1);
1034 goto ddGroupSiftingAuxOutOfMem;
1043 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1054 goto ddGroupSiftingAuxOutOfMem;
1063 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1065 }
else if (x - xLow > xHigh - x) {
1067 goto ddGroupSiftingAuxOutOfMem;
1074 while ((
unsigned) x < table->subtables[x].next)
1079 assert((
unsigned) x <= table->subtables[x].next);
1083 goto ddGroupSiftingAuxOutOfMem;
1091 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1098 goto ddGroupSiftingAuxOutOfMem;
1104 while ((
unsigned) x < table->subtables[x].next)
1112 goto ddGroupSiftingAuxOutOfMem;
1120 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1123 while (moves != NULL) {
1131 ddGroupSiftingAuxOutOfMem:
1132 while (moves != NULL) {
1194 while ((
unsigned) gybot < table->subtables[gybot].next)
1196 for (z = xLow + 1; z <= gybot; z++) {
1199 isolated = table->
vars[zindex]->
ref == 1;
1205 while (x >= xLow && L <= limitSize) {
1208 while ((
unsigned) gybot < table->subtables[gybot].next)
1211 for (z = xLow + 1; z <= gybot; z++) {
1214 isolated = table->
vars[zindex]->
ref == 1;
1218 if (pr > 0 && L != checkL) {
1219 (void) fprintf(table->
out,
1220 "Inaccurate lower bound: L = %d checkL = %d\n",
1225 if (checkFunction(table,x,y)) {
1233 if (move == NULL)
goto ddGroupSiftingUpOutOfMem;
1238 move->
next = *moves;
1249 if (size == 0)
goto ddGroupSiftingUpOutOfMem;
1252 isolated = table->
vars[xindex]->
ref == 1;
1256 if (move == NULL)
goto ddGroupSiftingUpOutOfMem;
1261 move->
next = *moves;
1265 if (pr > 0) (void) fprintf(table->
out,
1266 "ddGroupSiftingUp (2 single groups):\n");
1268 if ((
double) size > (double) limitSize * table->
maxGrowth)
1270 if (size < limitSize) limitSize = size;
1273 if (size == 0)
goto ddGroupSiftingUpOutOfMem;
1279 isolated = table->
vars[zindex]->
ref == 1;
1283 }
while (z != (
int) (*moves)->y);
1284 if ((
double) size > (
double) limitSize * table->
maxGrowth)
1286 if (size < limitSize) limitSize = size;
1294 ddGroupSiftingUpOutOfMem:
1295 while (*moves != NULL) {
1296 move = (*moves)->
next;
1331 int isolated, allVars;
1360 for (z = xHigh; z > gxtop; z--) {
1363 isolated = table->
vars[zindex]->
ref == 1;
1369 while (y <= xHigh && size - R < limitSize) {
1373 for (z = xHigh; z > gxtop; z--) {
1376 isolated = table->
vars[zindex]->
ref == 1;
1387 if (checkFunction(table,x,y)) {
1393 if (move == NULL)
goto ddGroupSiftingDownOutOfMem;
1398 move->
next = *moves;
1406 isolated = table->
vars[yindex]->
ref == 1;
1414 if (size == 0)
goto ddGroupSiftingDownOutOfMem;
1418 if (move == NULL)
goto ddGroupSiftingDownOutOfMem;
1423 move->
next = *moves;
1427 if (pr > 0) (void) fprintf(table->
out,
1428 "ddGroupSiftingDown (2 single groups):\n");
1430 if ((
double) size > (double) limitSize * table->
maxGrowth)
1432 if (size < limitSize) limitSize = size;
1443 isolated = table->
vars[zindex]->
ref == 1;
1447 }
while (z <= gybot);
1449 if (size == 0)
goto ddGroupSiftingDownOutOfMem;
1450 if ((
double) size > (
double) limitSize * table->
maxGrowth)
1452 if (size < limitSize) limitSize = size;
1456 for (z = gxtop + 1; z <= gybot; z++) {
1459 isolated = table->
vars[zindex]->
ref == 1;
1470 ddGroupSiftingDownOutOfMem:
1471 while (*moves != NULL) {
1472 move = (*moves)->
next;
1501 int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1503 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 1504 int initialSize,bestSize;
1514 xsize = xbot - xtop + 1;
1516 while ((
unsigned) ybot < table->subtables[ybot].next)
1519 ysize = ybot - ytop + 1;
1521 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 1522 initialSize = bestSize = table->
keys - table->
isolated;
1525 for (i = 1; i <= ysize; i++) {
1526 for (j = 1; j <= xsize; j++) {
1528 if (size == 0)
goto ddGroupMoveOutOfMem;
1529 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 1530 if (size < bestSize)
1533 swapx = x; swapy = y;
1540 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 1541 if ((bestSize < initialSize) && (bestSize < size))
1542 (void) fprintf(table->
out,
"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size);
1547 for (i = 0; i < ysize - 1; i++) {
1555 for (i = 0; i < xsize - 1; i++) {
1562 if (pr > 0) (void) fprintf(table->
out,
"ddGroupMove:\n");
1567 if (move == NULL)
goto ddGroupMoveOutOfMem;
1572 move->
next = *moves;
1577 ddGroupMoveOutOfMem:
1578 while (*moves != NULL) {
1579 move = (*moves)->
next;
1605 int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1616 xsize = xbot - xtop + 1;
1618 while ((
unsigned) ybot < table->subtables[ybot].next)
1621 ysize = ybot - ytop + 1;
1624 for (i = 1; i <= ysize; i++) {
1625 for (j = 1; j <= xsize; j++) {
1638 for (i = 0; i < ysize - 1; i++) {
1646 for (i = 0; i < xsize - 1; i++) {
1653 if (pr > 0) (void) fprintf(table->
out,
"ddGroupMoveBackward:\n");
1685 unsigned int pairlev;
1692 for (move = moves; move != NULL; move = move->
next) {
1693 if (move->
size < size) {
1696 }
else if (move->
size == size) {
1697 if (end_move == NULL) end_move = move;
1703 if (moves != NULL) {
1705 index = (upFlag == 1) ?
1710 for (move = moves; move != NULL; move = move->
next) {
1711 if (move->
size == size) {
1713 tmp_diff = (move->
x > pairlev) ?
1714 move->
x - pairlev : pairlev - move->
x;
1716 tmp_diff = (move->
y > pairlev) ?
1717 move->
y - pairlev : pairlev - move->
y;
1719 if (tmp_diff < diff) {
1728 for (move = moves; move != NULL; move = move->
next) {
1729 if (move->
size < size) {
1738 for (move = moves; move != NULL; move = move->
next) {
1740 if (move == end_move)
return(1);
1742 if (move->
size == size)
return(1);
1747 if (!res)
return(0);
1749 if (pr > 0) (void) fprintf(table->
out,
"ddGroupSiftingBackward:\n");
1758 if (!res)
return(0);
1794 if (treenode != table->
tree) {
1795 for (i = low; i < high; i++)
1802 saveindex = treenode->
index;
1803 newindex = table->
invperm[low];
1806 auxnode->
index = newindex;
1807 if (auxnode->
parent == NULL ||
1810 auxnode = auxnode->
parent;
1838 while ((
unsigned) boty < table->subtables[boty].next)
1896 if (x==0)
return(0);
1905 threshold = table->
recomb / 100.0;
1906 if (Sx < threshold) {
1910 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 1911 (void) fprintf(table->
out,
1912 "Second difference for %d = %g Pos(%d)\n",
1948 DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
1998 for (i = 0; i < slots; i++) {
2000 while (f != sentinel) {
2005 notproj = f1 != one || f0 != one || f->
ref != (
DdHalfWord) 1;
2006 if (f1->
index == (
unsigned) yindex) {
2010 if ((
int) f0->
index != yindex) {
2022 if ((
int) f0->
index == yindex) {
2038 if (f01 != f10 && f11 != f00) {
2053 for (i = 0; i < slots; i++) {
2055 while (f != sentinel) {
2056 TotalRefCount += f->
ref;
2063 res = arccount >= TotalRefCount - arccounter;
2065 #if defined(DD_DEBUG) && defined(DD_VERBOSE) 2067 (void) fprintf(table->
out,
2068 "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n",
2098 int xindex = table->
invperm[x];
2099 int yindex = table->
invperm[y];
2137 if (index >= dd->
size || index < 0)
return(0);
2161 if (index >= dd->
size || index < 0)
return(0);
2185 if (index >= dd->
size || index < 0)
return(-1);
Cudd_AggregationType groupcheck
unsigned short DdHalfWord
unsigned short MtrHalfWord
#define cuddDeallocMove(unique, node)
static unsigned int originalSize
static int ddGroupSifting(DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag)
static int ddGroupSiftingUp(DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves)
static int ddIsVarHandled(DdManager *dd, int index)
int cuddAnnealing(DdManager *table, int lower, int upper)
int(* DD_QSFP)(const void *, const void *)
MtrNode * Cudd_MakeTreeNode(DdManager *dd, unsigned int low, unsigned int size, unsigned int type)
#define Cudd_Regular(node)
static int ddGroupMoveBackward(DdManager *table, int x, int y)
int cuddNextLow(DdManager *table, int x)
static int ddNoCheck(DdManager *table, int x, int y)
int cuddSifting(DdManager *table, int lower, int upper)
static int ddSetVarHandled(DdManager *dd, int index)
void Mtr_ReorderGroups(MtrNode *treenode, int *permutation)
int(* DD_CHKFP)(DdManager *, int, int)
static int ddExtSymmCheck(DdManager *table, int x, int y)
#define MTR_TEST(node, flag)
int Cudd_ReadSize(DdManager *dd)
int cuddExact(DdManager *table, int lower, int upper)
void Cudd_FreeTree(DdManager *dd)
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
static int ddGroupSiftingDown(DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves)
static int ddResetVarHandled(DdManager *dd, int index)
int ddTotalNumberSwapping
#define Cudd_IsComplement(node)
static void ddFindNodeHiLo(DdManager *table, MtrNode *treenode, int *lower, int *upper)
static void ddMergeGroups(DdManager *table, MtrNode *treenode, int low, int high)
static int ddGroupMove(DdManager *table, int x, int y, Move **moves)
int cuddTreeSifting(DdManager *table, Cudd_ReorderingType method)
int Cudd_bddIsVarToBeUngrouped(DdManager *dd, int index)
static int ddGroupSiftingBackward(DdManager *table, Move *moves, int size, int upFlag, int lazyFlag)
int cuddWindowReorder(DdManager *table, int low, int high, Cudd_ReorderingType submethod)
DdNode * cuddDynamicAllocNode(DdManager *table)
static int ddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
int cuddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
int cuddNextHigh(DdManager *table, int x)
int cuddGa(DdManager *table, int lower, int upper)
static int ddSecDiffCheck(DdManager *table, int x, int y)
void Mtr_PrintGroups(MtrNode *root, int silent)
static void ddCreateGroup(DdManager *table, int x, int y)
int Cudd_bddIsVarToBeGrouped(DdManager *dd, int index)
static int ddVarGroupCheck(DdManager *table, int x, int y)
static char rcsid [] DD_UNUSED
int cuddSwapInPlace(DdManager *table, int x, int y)
MtrNode * Mtr_InitGroupTree(int lower, int size)
static void ddDissolveGroup(DdManager *table, int x, int y)
static int ddReorderChildren(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
int Cudd_bddReadPairIndex(DdManager *dd, int index)
static int ddGroupSiftingAux(DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag)
static int ddUniqueCompareGroup(int *ptrX, int *ptrY)
int cuddLinearAndSifting(DdManager *table, int lower, int upper)
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)
int cuddTestInteract(DdManager *table, int x, int y)
int cuddSymmSifting(DdManager *table, int lower, int upper)