95 static char rcsid[]
DD_UNUSED =
"$Id: cuddExact.c,v 1.28 2009/02/19 16:19:19 fabio Exp $";
99 static int ddTotalShuffles;
159 int maxBinomial, oldSubsets, newSubsets;
162 int unused, nvars, level,
result;
163 int upperBound, lowerBound, cost;
189 if (lower == upper)
return(1);
194 if (result == 0)
goto cuddExactOutOfMem;
197 (void) fprintf(table->
out,
"\n");
204 size = upper - lower + 1;
208 for (i = lower + 1; i < upper; i++) {
216 if (maxBinomial == -1)
goto cuddExactOutOfMem;
219 if (newOrder == NULL)
goto cuddExactOutOfMem;
222 if (newCost == NULL)
goto cuddExactOutOfMem;
225 if (oldOrder == NULL)
goto cuddExactOutOfMem;
228 if (oldCost == NULL)
goto cuddExactOutOfMem;
231 if (bestOrder == NULL)
goto cuddExactOutOfMem;
234 if (mask == NULL)
goto cuddExactOutOfMem;
237 if (symmInfo == NULL)
goto cuddExactOutOfMem;
247 for (i = 0; i <
size; i++) {
251 for (i = upper + 1; i < nvars; i++)
253 oldCost[0] = subsetCost;
258 for (k = 1; k <=
size; k++) {
260 (void) fprintf(table->
out,
"Processing subsets of size %d\n", k);
266 for (i = 0; i < oldSubsets; i++) {
269 lowerBound =
computeLB(table, order, roots, cost, lower, upper,
271 if (lowerBound >= upperBound)
274 result =
ddShuffle(table, order, lower, upper);
275 if (result == 0)
goto cuddExactOutOfMem;
276 upperBound =
updateUB(table,upperBound,bestOrder,lower,upper);
278 for (j = level; j >= 0; j--) {
284 newSubsets =
updateEntry(table, order, level, subsetCost,
285 newOrder, newCost, newSubsets, mask,
293 result =
ddShuffle(table, order, lower, upper);
294 if (result == 0)
goto cuddExactOutOfMem;
295 upperBound =
updateUB(table,upperBound,bestOrder,lower,upper);
300 tmpOrder = oldOrder; tmpCost = oldCost;
301 oldOrder = newOrder; oldCost = newCost;
302 newOrder = tmpOrder; newCost = tmpCost;
304 ddTotalSubsets += newSubsets;
306 oldSubsets = newSubsets;
308 result =
ddShuffle(table, bestOrder, lower, upper);
309 if (result == 0)
goto cuddExactOutOfMem;
312 (void) fprintf(table->
out,
"\n");
314 (void) fprintf(table->
out,
"#:S_EXACT %8d: total subsets\n",
316 (void) fprintf(table->
out,
"#:H_EXACT %8d: total shuffles",
333 if (bestOrder != NULL)
ABC_FREE(bestOrder);
334 if (oldCost != NULL)
ABC_FREE(oldCost);
335 if (newCost != NULL)
ABC_FREE(newCost);
336 if (symmInfo != NULL)
ABC_FREE(symmInfo);
368 if (n < 0 || n > 33)
return(-1);
369 if (n < 2)
return(1);
371 for (result = (
double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) {
404 if (x == 0)
return(y);
405 if (y == 0)
return(x);
407 a = x; b = y; lsbMask = 1;
458 if (cols*rows == 0)
return(NULL);
460 if (matrix == NULL)
return(NULL);
462 if (matrix[0] == NULL) {
466 for (i = 1; i < rows; i++) {
467 matrix[i] = matrix[i-1] + cols;
517 isolated = table->
vars[x]->
ref == 1;
569 numvars = table->
size;
571 (void) fprintf(table->
out,
"%d:", ddTotalShuffles);
572 for (level = 0; level <
numvars; level++) {
573 (void) fprintf(table->
out,
" %d", table->
invperm[level]);
575 (void) fprintf(table->
out,
"\n");
578 for (level = 0; level <= upper - lower; level++) {
579 index = permutation[level];
580 position = table->
perm[index];
584 result =
ddSiftUp(table,position,level+lower);
585 if (!result)
return(0);
592 if (finalSize < initialSize) {
593 (void) fprintf(table->
out,
"-");
594 }
else if (finalSize > initialSize) {
595 (void) fprintf(table->
out,
"+");
597 (void) fprintf(table->
out,
"=");
599 if ((ddTotalShuffles & 63) == 0) (
void) fprintf(table->
out,
"\n");
668 if (newBound < oldBound) {
670 (void) fprintf(table->
out,
"New upper bound = %d\n", newBound);
673 for (i = lower; i <= upper; i++)
711 int maxlevel = lower;
713 for (i = lower; i <= upper; i++) {
716 for (j = 0; j < slots; j++) {
718 while (f != sentinel) {
732 if (table->
perm[
cuddT(f)->index] > maxlevel)
778 for (i = lower; i <= maxlevel; i++) {
781 for (j = 0; j < slots; j++) {
783 while (f != sentinel) {
833 for (i = 0; i < lower; i++) {
839 for (i = lower; i <= lower+level; i++) {
841 table->
vars[order[i-lower]]->
ref > 1;
847 if (lower+level+1 < table->
size) {
848 if (lower+level < upper)
849 ref = table->
vars[order[level+1]]->
ref;
858 lb += lb1 > lb2 ? lb1 : lb2;
893 int size = upper - lower + 1;
896 for (i = lower; i <= upper; i++)
902 for (i = 0; i < subsets; i++) {
904 for (j = level; j <
size; j++) {
905 if (mask[subset[j]] == 0)
911 if (i == subsets || cost < costs[i]) {
912 for (j = 0; j <
size; j++)
913 orders[i][j] = order[j];
915 subsets += (i == subsets);
943 for (i = j; i < level; i++) {
944 order[i] = order[i+1];
977 int level, index,
next, nextindex;
981 if (symmInfo == NULL)
return(NULL);
983 for (level = lower; level <= upper; level++) {
987 symmInfo[index] = nextindex;
1016 i = symmInfo[index];
1017 while (i != index) {
1018 if (index < i && table->perm[i] <= level)
int cuddExact(DdManager *table, int lower, int upper)
unsigned short DdHalfWord
static int ddShuffle(DdManager *table, DdHalfWord *permutation, int lower, int upper)
static int computeLB(DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)
static void ddClearGlobal(DdManager *table, int lower, int maxlevel)
static void freeMatrix(DdHalfWord **matrix)
static int getMaxBinomial(int n)
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
static int getLevelKeys(DdManager *table, int l)
#define Cudd_IsConstant(node)
#define Cudd_Regular(node)
int cuddNextLow(DdManager *table, int x)
static void pushDown(DdHalfWord *order, int j, int level)
#define ABC_ALLOC(type, num)
for(p=first;p->value< newval;p=p->next)
static int updateUB(DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
#define Cudd_IsComplement(node)
static DdHalfWord ** getMatrix(int rows, int cols)
#define ABC_NAMESPACE_IMPL_END
static int checkSymmInfo(DdManager *table, DdHalfWord *symmInfo, int index, int level)
#define Cudd_Complement(node)
#define ABC_NAMESPACE_IMPL_START
static int ddCountRoots(DdManager *table, int lower, int upper)
int cuddSwapInPlace(DdManager *table, int x, int y)
static DdHalfWord * initSymmInfo(DdManager *table, int lower, int upper)
static int updateEntry(DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)
static int ddSiftUp(DdManager *table, int x, int xLow)