91 #define DD_NORMAL_SIFT 0
92 #define DD_LAZY_SIFT 1
95 #define DD_SIFT_DOWN 0
119 static char rcsid[]
DD_UNUSED =
"$Id: cuddGroup.c,v 1.44 2009/02/21 18:24:10 fabio Exp $";
125 extern int ddTotalNISwaps;
126 static int extsymmcalls;
128 static int secdiffcalls;
130 static int secdiffmisfire;
221 level = (low < (
unsigned int) dd->
size) ? dd->
perm[low] : low;
287 tempTree = table->
tree == NULL;
295 if (pr > 0 && !tempTree) (void) fprintf(table->
out,
"cuddTreeSifting:");
306 (void) fprintf(table->
out,
"\n");
308 (void) fprintf(table->
out,
"#:IM_NODES %8d: group tree nodes\n",
309 ddCountInternalMtrNodes(table,table->
tree));
316 for (i = 0; i < nvars; i++)
327 (void) fprintf(table->
out,
"\nextsymmcalls = %d\n",extsymmcalls);
328 (void) fprintf(table->
out,
"extsymm = %d",extsymm);
332 (void) fprintf(table->
out,
"\nsecdiffcalls = %d\n",secdiffcalls);
333 (void) fprintf(table->
out,
"secdiff = %d\n",secdiff);
334 (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,
" ");
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");
542 (
void) fprintf(table->
out,
"\n");
544 }
while (result != 0);
558 result =
cuddGa(table,lower,upper);
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;
748 goto ddGroupSiftingOutOfMem;
753 goto ddGroupSiftingOutOfMem;
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 ++) {
786 if (sifted[xindex] == 1)
788 x = table->
perm[xindex];
807 if (!result)
goto ddGroupSiftingOutOfMem;
812 x = table->
perm[xindex];
814 if (x != upper && sifted[table->
invperm[x+1]] == 0 &&
821 if (x != lower && sifted[table->
invperm[x-1]] == 0 &&
833 while ((
unsigned) x < table->subtables[x].next)
837 if (!result)
goto ddGroupSiftingOutOfMem;
840 (void) fprintf(table->
out,
"_");
841 }
else if (table->
keys > previousSize + table->
isolated) {
842 (void) fprintf(table->
out,
"^");
844 (void) fprintf(table->
out,
"*");
849 (void) fprintf(table->
out,
"-");
850 }
else if (table->
keys > previousSize + table->
isolated) {
851 (void) fprintf(table->
out,
"+");
853 (void) fprintf(table->
out,
"=");
860 x = table->
perm[xindex];
867 }
while (x != xInit);
870 if (lazyFlag == 0 && dissolve) {
875 }
while (x != xInit);
880 if (pr > 0) (void) fprintf(table->
out,
"ddGroupSifting:");
892 ddGroupSiftingOutOfMem:
895 if (sifted != NULL)
ABC_FREE(sifted);
928 while ((
unsigned) gybot < table->subtables[gybot].next)
972 if (pr > 0) (void) fprintf(table->
out,
973 "ddGroupSiftingAux from %d to %d\n",xLow,xHigh);
989 for (y = x; y > xLow; y--) {
990 if (!checkFunction(table,y-1,y))
1001 for (y = x; y < xHigh; y++) {
1002 if (!checkFunction(table,y,y+1))
1006 while ((
unsigned) topbot < table->subtables[topbot].next) {
1018 while ((
unsigned) x < table->subtables[x].next)
1026 if (x == xHigh)
return(1);
1029 goto ddGroupSiftingAuxOutOfMem;
1038 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1049 goto ddGroupSiftingAuxOutOfMem;
1058 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1060 }
else if (x - xLow > xHigh - x) {
1062 goto ddGroupSiftingAuxOutOfMem;
1069 while ((
unsigned) x < table->subtables[x].next)
1074 assert((
unsigned) x <= table->subtables[x].next);
1078 goto ddGroupSiftingAuxOutOfMem;
1086 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1093 goto ddGroupSiftingAuxOutOfMem;
1099 while ((
unsigned) x < table->subtables[x].next)
1107 goto ddGroupSiftingAuxOutOfMem;
1115 if (!result)
goto ddGroupSiftingAuxOutOfMem;
1118 while (moves != NULL) {
1126 ddGroupSiftingAuxOutOfMem:
1127 while (moves != NULL) {
1189 while ((
unsigned) gybot < table->subtables[gybot].next)
1191 for (z = xLow + 1; z <= gybot; z++) {
1194 isolated = table->
vars[zindex]->
ref == 1;
1200 while (x >= xLow && L <= limitSize) {
1203 while ((
unsigned) gybot < table->subtables[gybot].next)
1206 for (z = xLow + 1; z <= gybot; z++) {
1209 isolated = table->
vars[zindex]->
ref == 1;
1213 if (pr > 0 && L != checkL) {
1214 (void) fprintf(table->
out,
1215 "Inaccurate lower bound: L = %d checkL = %d\n",
1220 if (checkFunction(table,x,y)) {
1228 if (move == NULL)
goto ddGroupSiftingUpOutOfMem;
1233 move->
next = *moves;
1244 if (size == 0)
goto ddGroupSiftingUpOutOfMem;
1247 isolated = table->
vars[xindex]->
ref == 1;
1251 if (move == NULL)
goto ddGroupSiftingUpOutOfMem;
1256 move->
next = *moves;
1260 if (pr > 0) (void) fprintf(table->
out,
1261 "ddGroupSiftingUp (2 single groups):\n");
1263 if ((
double) size > (double) limitSize * table->
maxGrowth)
1265 if (size < limitSize) limitSize =
size;
1268 if (size == 0)
goto ddGroupSiftingUpOutOfMem;
1274 isolated = table->
vars[zindex]->
ref == 1;
1278 }
while (z != (
int) (*moves)->y);
1279 if ((
double) size > (
double) limitSize * table->
maxGrowth)
1281 if (size < limitSize) limitSize =
size;
1289 ddGroupSiftingUpOutOfMem:
1290 while (*moves != NULL) {
1291 move = (*moves)->
next;
1326 int isolated, allVars;
1355 for (z = xHigh; z > gxtop; z--) {
1358 isolated = table->
vars[zindex]->
ref == 1;
1364 while (y <= xHigh && size - R < limitSize) {
1368 for (z = xHigh; z > gxtop; z--) {
1371 isolated = table->
vars[zindex]->
ref == 1;
1382 if (checkFunction(table,x,y)) {
1388 if (move == NULL)
goto ddGroupSiftingDownOutOfMem;
1393 move->
next = *moves;
1401 isolated = table->
vars[yindex]->
ref == 1;
1409 if (size == 0)
goto ddGroupSiftingDownOutOfMem;
1413 if (move == NULL)
goto ddGroupSiftingDownOutOfMem;
1418 move->
next = *moves;
1422 if (pr > 0) (void) fprintf(table->
out,
1423 "ddGroupSiftingDown (2 single groups):\n");
1425 if ((
double) size > (double) limitSize * table->
maxGrowth)
1427 if (size < limitSize) limitSize =
size;
1438 isolated = table->
vars[zindex]->
ref == 1;
1442 }
while (z <= gybot);
1444 if (size == 0)
goto ddGroupSiftingDownOutOfMem;
1445 if ((
double) size > (
double) limitSize * table->
maxGrowth)
1447 if (size < limitSize) limitSize =
size;
1451 for (z = gxtop + 1; z <= gybot; z++) {
1454 isolated = table->
vars[zindex]->
ref == 1;
1465 ddGroupSiftingDownOutOfMem:
1466 while (*moves != NULL) {
1467 move = (*moves)->
next;
1496 int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1497 int swapx = -1,swapy = -1;
1498 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1499 int initialSize,bestSize;
1509 xsize = xbot - xtop + 1;
1511 while ((
unsigned) ybot < table->subtables[ybot].next)
1514 ysize = ybot - ytop + 1;
1516 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1517 initialSize = bestSize = table->
keys - table->
isolated;
1520 for (i = 1; i <= ysize; i++) {
1521 for (j = 1; j <= xsize; j++) {
1523 if (size == 0)
goto ddGroupMoveOutOfMem;
1524 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1525 if (size < bestSize)
1528 swapx = x; swapy = y;
1535 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1536 if ((bestSize < initialSize) && (bestSize < size))
1537 (void) fprintf(table->
out,
"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size);
1542 for (i = 0; i < ysize - 1; i++) {
1550 for (i = 0; i < xsize - 1; i++) {
1557 if (pr > 0) (void) fprintf(table->
out,
"ddGroupMove:\n");
1562 if (move == NULL)
goto ddGroupMoveOutOfMem;
1567 move->
next = *moves;
1572 ddGroupMoveOutOfMem:
1573 while (*moves != NULL) {
1574 move = (*moves)->
next;
1600 int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
1611 xsize = xbot - xtop + 1;
1613 while ((
unsigned) ybot < table->subtables[ybot].next)
1616 ysize = ybot - ytop + 1;
1619 for (i = 1; i <= ysize; i++) {
1620 for (j = 1; j <= xsize; j++) {
1633 for (i = 0; i < ysize - 1; i++) {
1641 for (i = 0; i < xsize - 1; i++) {
1648 if (pr > 0) (void) fprintf(table->
out,
"ddGroupMoveBackward:\n");
1677 Move *end_move = NULL;
1680 unsigned int pairlev;
1687 for (move = moves; move != NULL; move = move->
next) {
1688 if (move->
size < size) {
1691 }
else if (move->
size == size) {
1692 if (end_move == NULL) end_move = move;
1698 if (moves != NULL) {
1700 index = (upFlag == 1) ?
1705 for (move = moves; move != NULL; move = move->
next) {
1706 if (move->
size == size) {
1708 tmp_diff = (move->
x > pairlev) ?
1709 move->
x - pairlev : pairlev - move->
x;
1711 tmp_diff = (move->
y > pairlev) ?
1712 move->
y - pairlev : pairlev - move->
y;
1714 if (tmp_diff < diff) {
1723 for (move = moves; move != NULL; move = move->
next) {
1724 if (move->
size < size) {
1733 for (move = moves; move != NULL; move = move->
next) {
1735 if (move == end_move)
return(1);
1737 if (move->
size == size)
return(1);
1742 if (!res)
return(0);
1744 if (pr > 0) (void) fprintf(table->
out,
"ddGroupSiftingBackward:\n");
1753 if (!res)
return(0);
1789 if (treenode != table->
tree) {
1790 for (i = low; i < high; i++)
1797 saveindex = treenode->
index;
1798 newindex = table->
invperm[low];
1801 auxnode->
index = newindex;
1802 if (auxnode->
parent == NULL ||
1805 auxnode = auxnode->
parent;
1833 while ((
unsigned) boty < table->subtables[boty].next)
1891 if (x==0)
return(0);
1900 threshold = table->
recomb / 100.0;
1901 if (Sx < threshold) {
1905 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
1906 (void) fprintf(table->
out,
1907 "Second difference for %d = %g Pos(%d)\n",
1943 DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
1993 for (i = 0; i < slots; i++) {
1995 while (f != sentinel) {
2000 notproj = f1 != one || f0 != one || f->
ref != (
DdHalfWord) 1;
2001 if (f1->
index == (
unsigned) yindex) {
2005 if ((
int) f0->
index != yindex) {
2017 if ((
int) f0->
index == yindex) {
2033 if (f01 != f10 && f11 != f00) {
2048 for (i = 0; i < slots; i++) {
2050 while (f != sentinel) {
2051 TotalRefCount += f->
ref;
2058 res = arccount >= TotalRefCount - arccounter;
2060 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
2062 (void) fprintf(table->
out,
2063 "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n",
2093 int xindex = table->
invperm[x];
2094 int yindex = table->
invperm[y];
2132 if (index >= dd->
size || index < 0)
return(0);
2156 if (index >= dd->
size || index < 0)
return(0);
2180 if (index >= dd->
size || index < 0)
return(-1);
Cudd_AggregationType groupcheck
int cuddExact(DdManager *table, int lower, int upper)
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)
MtrNode * Cudd_MakeTreeNode(DdManager *dd, unsigned int low, unsigned int size, unsigned int type)
int(* DD_QSFP)(const void *, const void *)
#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)
#define ABC_ALLOC(type, num)
static int ddExtSymmCheck(DdManager *table, int x, int y)
int cuddGa(DdManager *table, int lower, int upper)
#define MTR_TEST(node, flag)
int Cudd_ReadSize(DdManager *dd)
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)
#define ABC_NAMESPACE_IMPL_END
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)
#define ABC_NAMESPACE_IMPL_START
int cuddNextHigh(DdManager *table, int x)
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)
int cuddAnnealing(DdManager *table, int lower, int upper)
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)
int(* DD_CHKFP)(DdManager *, int, int)