src/cuBdd/cuddExact.c File Reference

#include "util.h"
#include "cuddInt.h"
Include dependency graph for cuddExact.c:

Go to the source code of this file.

Functions

static int getMaxBinomial (int n)
static DdHalfWord ** getMatrix (int rows, int cols)
static void freeMatrix (DdHalfWord **matrix)
static int getLevelKeys (DdManager *table, int l)
static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper)
static int ddSiftUp (DdManager *table, int x, int xLow)
static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)
static int ddCountRoots (DdManager *table, int lower, int upper)
static void ddClearGlobal (DdManager *table, int lower, int maxlevel)
static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)
static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)
static void pushDown (DdHalfWord *order, int j, int level)
static DdHalfWordinitSymmInfo (DdManager *table, int lower, int upper)
static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level)
int cuddExact (DdManager *table, int lower, int upper)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.28 2009/02/19 16:19:19 fabio Exp $"

Function Documentation

static int checkSymmInfo ( DdManager table,
DdHalfWord symmInfo,
int  index,
int  level 
) [static]

Function********************************************************************

Synopsis [Check symmetry condition.]

Description [Returns 1 if a variable is the one with the highest index among those belonging to a symmetry group that are in the top part of the BDD. The top part is given by level.]

SideEffects [None]

SeeAlso [initSymmInfo]

Definition at line 1004 of file cuddExact.c.

01009 {
01010     int i;
01011 
01012     i = symmInfo[index];
01013     while (i != index) {
01014         if (index < i && table->perm[i] <= level)
01015             return(0);
01016         i = symmInfo[i];
01017     }
01018     return(1);
01019 
01020 } /* end of checkSymmInfo */

static int computeLB ( DdManager table,
DdHalfWord order,
int  roots,
int  cost,
int  lower,
int  upper,
int  level 
) [static]

Function********************************************************************

Synopsis [Computes a lower bound on the size of a BDD.]

Description [Computes a lower bound on the size of a BDD from the following factors:

  • size of the lower part of it;
  • size of the part of the upper part not subjected to reordering;
  • number of roots in the part of the BDD subjected to reordering;
  • variable in the support of the roots in the upper part of the BDD subjected to reordering.

    SideEffects [None]

    SeeAlso []

Definition at line 809 of file cuddExact.c.

00818 {
00819     int i;
00820     int lb = cost;
00821     int lb1 = 0;
00822     int lb2;
00823     int support;
00824     DdHalfWord ref;
00825 
00826     /* The levels not involved in reordering are not going to change.
00827     ** Add their sizes to the lower bound.
00828     */
00829     for (i = 0; i < lower; i++) {
00830         lb += getLevelKeys(table,i);
00831     }
00832     /* If a variable is in the support, then there is going
00833     ** to be at least one node labeled by that variable.
00834     */
00835     for (i = lower; i <= lower+level; i++) {
00836         support = table->subtables[i].keys > 1 ||
00837             table->vars[order[i-lower]]->ref > 1;
00838         lb1 += support;
00839     }
00840 
00841     /* Estimate the number of nodes required to connect the roots to
00842     ** the nodes in the bottom part. */
00843     if (lower+level+1 < table->size) {
00844         if (lower+level < upper)
00845             ref = table->vars[order[level+1]]->ref;
00846         else
00847             ref = table->vars[table->invperm[upper+1]]->ref;
00848         lb2 = table->subtables[lower+level+1].keys -
00849             (ref > (DdHalfWord) 1) - roots;
00850     } else {
00851         lb2 = 0;
00852     }
00853 
00854     lb += lb1 > lb2 ? lb1 : lb2;
00855 
00856     return(lb);
00857 
00858 } /* end of computeLB */

int cuddExact ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Exact variable ordering algorithm.]

Description [Exact variable ordering algorithm. Finds an optimum order for the variables between lower and upper. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 149 of file cuddExact.c.

00153 {
00154     int k, i, j;
00155     int maxBinomial, oldSubsets, newSubsets;
00156     int subsetCost;
00157     int size;                   /* number of variables to be reordered */
00158     int unused, nvars, level, result;
00159     int upperBound, lowerBound, cost;
00160     int roots;
00161     char *mask = NULL;
00162     DdHalfWord  *symmInfo = NULL;
00163     DdHalfWord **newOrder = NULL;
00164     DdHalfWord **oldOrder = NULL;
00165     int *newCost = NULL;
00166     int *oldCost = NULL;
00167     DdHalfWord **tmpOrder;
00168     int *tmpCost;
00169     DdHalfWord *bestOrder = NULL;
00170     DdHalfWord *order;
00171 #ifdef DD_STATS
00172     int  ddTotalSubsets;
00173 #endif
00174 
00175     /* Restrict the range to be reordered by excluding unused variables
00176     ** at the two ends. */
00177     while (table->subtables[lower].keys == 1 &&
00178            table->vars[table->invperm[lower]]->ref == 1 &&
00179            lower < upper)
00180         lower++;
00181     while (table->subtables[upper].keys == 1 &&
00182            table->vars[table->invperm[upper]]->ref == 1 &&
00183            lower < upper)
00184         upper--;
00185     if (lower == upper) return(1); /* trivial problem */
00186 
00187     /* Apply symmetric sifting to get a good upper bound and to extract
00188     ** symmetry information. */
00189     result = cuddSymmSiftingConv(table,lower,upper);
00190     if (result == 0) goto cuddExactOutOfMem;
00191 
00192 #ifdef DD_STATS
00193     (void) fprintf(table->out,"\n");
00194     ddTotalShuffles = 0;
00195     ddTotalSubsets = 0;
00196 #endif
00197 
00198     /* Initialization. */
00199     nvars = table->size;
00200     size = upper - lower + 1;
00201     /* Count unused variable among those to be reordered.  This is only
00202     ** used to compute maxBinomial. */
00203     unused = 0;
00204     for (i = lower + 1; i < upper; i++) {
00205         if (table->subtables[i].keys == 1 &&
00206             table->vars[table->invperm[i]]->ref == 1)
00207             unused++;
00208     }
00209 
00210     /* Find the maximum number of subsets we may have to store. */
00211     maxBinomial = getMaxBinomial(size - unused);
00212     if (maxBinomial == -1) goto cuddExactOutOfMem;
00213 
00214     newOrder = getMatrix(maxBinomial, size);
00215     if (newOrder == NULL) goto cuddExactOutOfMem;
00216 
00217     newCost = ALLOC(int, maxBinomial);
00218     if (newCost == NULL) goto cuddExactOutOfMem;
00219 
00220     oldOrder = getMatrix(maxBinomial, size);
00221     if (oldOrder == NULL) goto cuddExactOutOfMem;
00222 
00223     oldCost = ALLOC(int, maxBinomial);
00224     if (oldCost == NULL) goto cuddExactOutOfMem;
00225 
00226     bestOrder = ALLOC(DdHalfWord, size);
00227     if (bestOrder == NULL) goto cuddExactOutOfMem;
00228 
00229     mask = ALLOC(char, nvars);
00230     if (mask == NULL) goto cuddExactOutOfMem;
00231 
00232     symmInfo = initSymmInfo(table, lower, upper);
00233     if (symmInfo == NULL) goto cuddExactOutOfMem;
00234 
00235     roots = ddCountRoots(table, lower, upper);
00236 
00237     /* Initialize the old order matrix for the empty subset and the best
00238     ** order to the current order. The cost for the empty subset includes
00239     ** the cost of the levels between upper and the constants. These levels
00240     ** are not going to change. Hence, we count them only once.
00241     */
00242     oldSubsets = 1;
00243     for (i = 0; i < size; i++) {
00244         oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower];
00245     }
00246     subsetCost = table->constants.keys;
00247     for (i = upper + 1; i < nvars; i++)
00248         subsetCost += getLevelKeys(table,i);
00249     oldCost[0] = subsetCost;
00250     /* The upper bound is initialized to the current size of the BDDs. */
00251     upperBound = table->keys - table->isolated;
00252 
00253     /* Now consider subsets of increasing size. */
00254     for (k = 1; k <= size; k++) {
00255 #ifdef DD_STATS
00256         (void) fprintf(table->out,"Processing subsets of size %d\n", k);
00257         fflush(table->out);
00258 #endif
00259         newSubsets = 0;
00260         level = size - k;               /* offset of first bottom variable */
00261 
00262         for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */
00263             order = oldOrder[i];
00264             cost = oldCost[i];
00265             lowerBound = computeLB(table, order, roots, cost, lower, upper,
00266                                    level);
00267             if (lowerBound >= upperBound)
00268                 continue;
00269             /* Impose new order. */
00270             result = ddShuffle(table, order, lower, upper);
00271             if (result == 0) goto cuddExactOutOfMem;
00272             upperBound = updateUB(table,upperBound,bestOrder,lower,upper);
00273             /* For each top bottom variable. */
00274             for (j = level; j >= 0; j--) {
00275                 /* Skip unused variables. */
00276                 if (table->subtables[j+lower-1].keys == 1 &&
00277                     table->vars[table->invperm[j+lower-1]]->ref == 1) continue;
00278                 /* Find cost under this order. */
00279                 subsetCost = cost + getLevelKeys(table, lower + level);
00280                 newSubsets = updateEntry(table, order, level, subsetCost,
00281                                          newOrder, newCost, newSubsets, mask,
00282                                          lower, upper);
00283                 if (j == 0)
00284                     break;
00285                 if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0)
00286                     continue;
00287                 pushDown(order,j-1,level);
00288                 /* Impose new order. */
00289                 result = ddShuffle(table, order, lower, upper);
00290                 if (result == 0) goto cuddExactOutOfMem;
00291                 upperBound = updateUB(table,upperBound,bestOrder,lower,upper);
00292             } /* for each bottom variable */
00293         } /* for each subset of size k */
00294 
00295         /* New orders become old orders in preparation for next iteration. */
00296         tmpOrder = oldOrder; tmpCost = oldCost;
00297         oldOrder = newOrder; oldCost = newCost;
00298         newOrder = tmpOrder; newCost = tmpCost;
00299 #ifdef DD_STATS
00300         ddTotalSubsets += newSubsets;
00301 #endif
00302         oldSubsets = newSubsets;
00303     }
00304     result = ddShuffle(table, bestOrder, lower, upper);
00305     if (result == 0) goto cuddExactOutOfMem;
00306 #ifdef DD_STATS
00307 #ifdef DD_VERBOSE
00308     (void) fprintf(table->out,"\n");
00309 #endif
00310     (void) fprintf(table->out,"#:S_EXACT   %8d: total subsets\n",
00311                    ddTotalSubsets);
00312     (void) fprintf(table->out,"#:H_EXACT   %8d: total shuffles",
00313                    ddTotalShuffles);
00314 #endif
00315 
00316     freeMatrix(newOrder);
00317     freeMatrix(oldOrder);
00318     FREE(bestOrder);
00319     FREE(oldCost);
00320     FREE(newCost);
00321     FREE(symmInfo);
00322     FREE(mask);
00323     return(1);
00324 
00325 cuddExactOutOfMem:
00326 
00327     if (newOrder != NULL) freeMatrix(newOrder);
00328     if (oldOrder != NULL) freeMatrix(oldOrder);
00329     if (bestOrder != NULL) FREE(bestOrder);
00330     if (oldCost != NULL) FREE(oldCost);
00331     if (newCost != NULL) FREE(newCost);
00332     if (symmInfo != NULL) FREE(symmInfo);
00333     if (mask != NULL) FREE(mask);
00334     table->errorCode = CUDD_MEMORY_OUT;
00335     return(0);
00336 
00337 } /* end of cuddExact */

static void ddClearGlobal ( DdManager table,
int  lower,
int  maxlevel 
) [static]

Function********************************************************************

Synopsis [Scans the DD and clears the LSB of the next pointers.]

Description [Scans the DD and clears the LSB of the next pointers. The LSB of the next pointers are used as markers to tell whether a node was reached. Once the roots are counted, these flags are reset.]

SideEffects [None]

SeeAlso [ddCountRoots]

Definition at line 763 of file cuddExact.c.

00767 {
00768     int i,j;
00769     DdNode *f;
00770     DdNodePtr *nodelist;
00771     DdNode *sentinel = &(table->sentinel);
00772     int slots;
00773 
00774     for (i = lower; i <= maxlevel; i++) {
00775         nodelist = table->subtables[i].nodelist;
00776         slots = table->subtables[i].slots;
00777         for (j = 0; j < slots; j++) {
00778             f = nodelist[j];
00779             while (f != sentinel) {
00780                 f->next = Cudd_Regular(f->next);
00781                 f = f->next;
00782             }
00783         }
00784     }
00785 
00786 } /* end of ddClearGlobal */

static int ddCountRoots ( DdManager table,
int  lower,
int  upper 
) [static]

Function********************************************************************

Synopsis [Counts the number of roots.]

Description [Counts the number of roots at the levels between lower and upper. The computation is based on breadth-first search. A node is a root if it is not reachable from any previously visited node. (All the nodes at level lower are therefore considered roots.) The visited flag uses the LSB of the next pointer. Returns the root count. The roots that are constant nodes are always ignored.]

SideEffects [None]

SeeAlso [ddClearGlobal]

Definition at line 696 of file cuddExact.c.

00700 {
00701     int i,j;
00702     DdNode *f;
00703     DdNodePtr *nodelist;
00704     DdNode *sentinel = &(table->sentinel);
00705     int slots;
00706     int roots = 0;
00707     int maxlevel = lower;
00708 
00709     for (i = lower; i <= upper; i++) {
00710         nodelist = table->subtables[i].nodelist;
00711         slots = table->subtables[i].slots;
00712         for (j = 0; j < slots; j++) {
00713             f = nodelist[j];
00714             while (f != sentinel) {
00715                 /* A node is a root of the DAG if it cannot be
00716                 ** reached by nodes above it. If a node was never
00717                 ** reached during the previous depth-first searches,
00718                 ** then it is a root, and we start a new depth-first
00719                 ** search from it.
00720                 */
00721                 if (!Cudd_IsComplement(f->next)) {
00722                     if (f != table->vars[f->index]) {
00723                         roots++;
00724                     }
00725                 }
00726                 if (!Cudd_IsConstant(cuddT(f))) {
00727                     cuddT(f)->next = Cudd_Complement(cuddT(f)->next);
00728                     if (table->perm[cuddT(f)->index] > maxlevel)
00729                         maxlevel = table->perm[cuddT(f)->index];
00730                 }
00731                 if (!Cudd_IsConstant(cuddE(f))) {
00732                     Cudd_Regular(cuddE(f))->next =
00733                         Cudd_Complement(Cudd_Regular(cuddE(f))->next);
00734                     if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel)
00735                         maxlevel = table->perm[Cudd_Regular(cuddE(f))->index];
00736                 }
00737                 f = Cudd_Regular(f->next);
00738             }
00739         }
00740     }
00741     ddClearGlobal(table, lower, maxlevel);
00742 
00743     return(roots);
00744 
00745 } /* end of ddCountRoots */

static int ddShuffle ( DdManager table,
DdHalfWord permutation,
int  lower,
int  upper 
) [static]

Function********************************************************************

Synopsis [Reorders variables according to a given permutation.]

Description [Reorders variables according to a given permutation. The i-th permutation array contains the index of the variable that should be brought to the i-th level. ddShuffle assumes that no dead nodes are present and that the interaction matrix is properly initialized. The reordering is achieved by a series of upward sifts. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 537 of file cuddExact.c.

00542 {
00543     DdHalfWord  index;
00544     int         level;
00545     int         position;
00546 #if 0
00547     int         numvars;
00548 #endif
00549     int         result;
00550 #ifdef DD_STATS
00551     long        localTime;
00552     int         initialSize;
00553 #ifdef DD_VERBOSE
00554     int         finalSize;
00555 #endif
00556     int         previousSize;
00557 #endif
00558 
00559 #ifdef DD_STATS
00560     localTime = util_cpu_time();
00561     initialSize = table->keys - table->isolated;
00562 #endif
00563 
00564 #if 0
00565     numvars = table->size;
00566 
00567     (void) fprintf(table->out,"%d:", ddTotalShuffles);
00568     for (level = 0; level < numvars; level++) {
00569         (void) fprintf(table->out," %d", table->invperm[level]);
00570     }
00571     (void) fprintf(table->out,"\n");
00572 #endif
00573 
00574     for (level = 0; level <= upper - lower; level++) {
00575         index = permutation[level];
00576         position = table->perm[index];
00577 #ifdef DD_STATS
00578         previousSize = table->keys - table->isolated;
00579 #endif
00580         result = ddSiftUp(table,position,level+lower);
00581         if (!result) return(0);
00582     }
00583 
00584 #ifdef DD_STATS
00585     ddTotalShuffles++;
00586 #ifdef DD_VERBOSE
00587     finalSize = table->keys - table->isolated;
00588     if (finalSize < initialSize) {
00589         (void) fprintf(table->out,"-");
00590     } else if (finalSize > initialSize) {
00591         (void) fprintf(table->out,"+");
00592     } else {
00593         (void) fprintf(table->out,"=");
00594     }
00595     if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n");
00596     fflush(table->out);
00597 #endif
00598 #endif
00599 
00600     return(1);
00601 
00602 } /* end of ddShuffle */

static int ddSiftUp ( DdManager table,
int  x,
int  xLow 
) [static]

Function********************************************************************

Synopsis [Moves one variable up.]

Description [Takes a variable from position x and sifts it up to position xLow; xLow should be less than or equal to x. Returns 1 if successful; 0 otherwise]

SideEffects [None]

SeeAlso []

Definition at line 619 of file cuddExact.c.

00623 {
00624     int        y;
00625     int        size;
00626 
00627     y = cuddNextLow(table,x);
00628     while (y >= xLow) {
00629         size = cuddSwapInPlace(table,y,x);
00630         if (size == 0) {
00631             return(0);
00632         }
00633         x = y;
00634         y = cuddNextLow(table,x);
00635     }
00636     return(1);
00637 
00638 } /* end of ddSiftUp */

static void freeMatrix ( DdHalfWord **  matrix  )  [static]

Function********************************************************************

Synopsis [Frees a two-dimensional matrix allocated by getMatrix.]

Description []

SideEffects [None]

SeeAlso [getMatrix]

Definition at line 482 of file cuddExact.c.

00484 {
00485     FREE(matrix[0]);
00486     FREE(matrix);
00487     return;
00488 
00489 } /* end of freeMatrix */

static int getLevelKeys ( DdManager table,
int  l 
) [static]

Function********************************************************************

Synopsis [Returns the number of nodes at one level of a unique table.]

Description [Returns the number of nodes at one level of a unique table. The projection function, if isolated, is not counted.]

SideEffects [None]

SeeAlso []

Definition at line 505 of file cuddExact.c.

00508 {
00509     int isolated;
00510     int x;        /* x is an index */
00511 
00512     x = table->invperm[l];
00513     isolated = table->vars[x]->ref == 1;
00514 
00515     return(table->subtables[l].keys - isolated);
00516 
00517 } /* end of getLevelKeys */

static DdHalfWord ** getMatrix ( int  rows,
int  cols 
) [static]

Function********************************************************************

Synopsis [Allocates a two-dimensional matrix of ints.]

Description [Allocates a two-dimensional matrix of ints. Returns the pointer to the matrix if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [freeMatrix]

Definition at line 447 of file cuddExact.c.

00450 {
00451     DdHalfWord **matrix;
00452     int i;
00453 
00454     if (cols*rows == 0) return(NULL);
00455     matrix = ALLOC(DdHalfWord *, rows);
00456     if (matrix == NULL) return(NULL);
00457     matrix[0] = ALLOC(DdHalfWord, cols*rows);
00458     if (matrix[0] == NULL) {
00459         FREE(matrix);
00460         return(NULL);
00461     }
00462     for (i = 1; i < rows; i++) {
00463         matrix[i] = matrix[i-1] + cols;
00464     }
00465     return(matrix);
00466 
00467 } /* end of getMatrix */

static int getMaxBinomial ( int  n  )  [static]

AutomaticStart

Function********************************************************************

Synopsis [Returns the maximum value of (n choose k) for a given n.]

Description [Computes the maximum value of (n choose k) for a given n. The maximum value occurs for k = n/2 when n is even, or k = (n-1)/2 when n is odd. The algorithm used in this procedure avoids intermediate overflow problems. It is based on the identity

    binomial(n,k) = n/k * binomial(n-1,k-1).
  

Returns the computed value if successful; -1 if out of range.]

SideEffects [None]

SeeAlso []

Definition at line 359 of file cuddExact.c.

00361 {
00362     double i, j, result;
00363 
00364     if (n < 0 || n > 33) return(-1); /* error */
00365     if (n < 2) return(1);
00366 
00367     for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) {
00368         result *= i;
00369         result /= j;
00370     }
00371 
00372     return((int)result);
00373 
00374 } /* end of getMaxBinomial */

static DdHalfWord * initSymmInfo ( DdManager table,
int  lower,
int  upper 
) [static]

Function********************************************************************

Synopsis [Gathers symmetry information.]

Description [Translates the symmetry information stored in the next field of each subtable from level to indices. This procedure is called immediately after symmetric sifting, so that the next fields are correct. By translating this informaton in terms of indices, we make it independent of subsequent reorderings. The format used is that of the next fields: a circular list where each variable points to the next variable in the same symmetry group. Only the entries between lower and upper are considered. The procedure returns a pointer to an array holding the symmetry information if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [checkSymmInfo]

Definition at line 968 of file cuddExact.c.

00972 {
00973     int level, index, next, nextindex;
00974     DdHalfWord *symmInfo;
00975 
00976     symmInfo =  ALLOC(DdHalfWord, table->size);
00977     if (symmInfo == NULL) return(NULL);
00978 
00979     for (level = lower; level <= upper; level++) {
00980         index = table->invperm[level];
00981         next =  table->subtables[level].next;
00982         nextindex = table->invperm[next];
00983         symmInfo[index] = nextindex;
00984     }
00985     return(symmInfo);
00986 
00987 } /* end of initSymmInfo */

static void pushDown ( DdHalfWord order,
int  j,
int  level 
) [static]

Function********************************************************************

Synopsis [Pushes a variable in the order down to position "level."]

Description []

SideEffects [None]

SeeAlso []

Definition at line 930 of file cuddExact.c.

00934 {
00935     int i;
00936     DdHalfWord tmp;
00937 
00938     tmp = order[j];
00939     for (i = j; i < level; i++) {
00940         order[i] = order[i+1];
00941     }
00942     order[level] = tmp;
00943     return;
00944 
00945 } /* end of pushDown */

static int updateEntry ( DdManager table,
DdHalfWord order,
int  level,
int  cost,
DdHalfWord **  orders,
int *  costs,
int  subsets,
char *  mask,
int  lower,
int  upper 
) [static]

Function********************************************************************

Synopsis [Updates entry for a subset.]

Description [Updates entry for a subset. Finds the subset, if it exists. If the new order for the subset has lower cost, or if the subset did not exist, it stores the new order and cost. Returns the number of subsets currently in the table.]

SideEffects [None]

SeeAlso []

Definition at line 876 of file cuddExact.c.

00887 {
00888     int i, j;
00889     int size = upper - lower + 1;
00890 
00891     /* Build a mask that says what variables are in this subset. */
00892     for (i = lower; i <= upper; i++)
00893         mask[table->invperm[i]] = 0;
00894     for (i = level; i < size; i++)
00895         mask[order[i]] = 1;
00896 
00897     /* Check each subset until a match is found or all subsets are examined. */
00898     for (i = 0; i < subsets; i++) {
00899         DdHalfWord *subset = orders[i];
00900         for (j = level; j < size; j++) {
00901             if (mask[subset[j]] == 0)
00902                 break;
00903         }
00904         if (j == size)          /* no mismatches: success */
00905             break;
00906     }
00907     if (i == subsets || cost < costs[i]) {              /* add or replace */
00908         for (j = 0; j < size; j++)
00909             orders[i][j] = order[j];
00910         costs[i] = cost;
00911         subsets += (i == subsets);
00912     }
00913     return(subsets);
00914 
00915 } /* end of updateEntry */

static int updateUB ( DdManager table,
int  oldBound,
DdHalfWord bestOrder,
int  lower,
int  upper 
) [static]

Function********************************************************************

Synopsis [Updates the upper bound and saves the best order seen so far.]

Description [Updates the upper bound and saves the best order seen so far. Returns the current value of the upper bound.]

SideEffects [None]

SeeAlso []

Definition at line 654 of file cuddExact.c.

00660 {
00661     int i;
00662     int newBound = table->keys - table->isolated;
00663 
00664     if (newBound < oldBound) {
00665 #ifdef DD_STATS
00666         (void) fprintf(table->out,"New upper bound = %d\n", newBound);
00667         fflush(table->out);
00668 #endif
00669         for (i = lower; i <= upper; i++)
00670             bestOrder[i-lower] = (DdHalfWord) table->invperm[i];
00671         return(newBound);
00672     } else {
00673         return(oldBound);
00674     }
00675 
00676 } /* end of updateUB */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddExact.c,v 1.28 2009/02/19 16:19:19 fabio Exp $" [static]

CFile***********************************************************************

FileName [cuddExact.c]

PackageName [cudd]

Synopsis [Functions for exact variable reordering.]

Description [External procedures included in this file:

procedures included in this module:

Static procedures included in this module:

]

Author [Cheng Hua, Fabio Somenzi]

Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 91 of file cuddExact.c.


Generated on Tue Jan 12 13:57:19 2010 for glu-2.2 by  doxygen 1.6.1