abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddSubsetSP.c File Reference
#include "misc/util/util_hack.h"
#include "cuddInt.h"

Go to the source code of this file.

Data Structures

struct  NodeDist
 
struct  AssortedInfo
 

Macros

#define DEFAULT_PAGE_SIZE   2048 /* page size to store the BFS queue element type */
 
#define DEFAULT_NODE_DIST_PAGE_SIZE   2048 /* page sizesto store NodeDist_t type */
 
#define MAXSHORTINT
 
#define INITIAL_PAGES
 

Typedefs

typedef struct NodeDist NodeDist_t
 

Functions

static void ResizeNodeDistPages (void)
 
static void ResizeQueuePages (void)
 
static void CreateTopDist (st__table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp)
 
static int CreateBotDist (DdNode *node, st__table *pathTable, unsigned int *pathLengthArray, FILE *fp)
 
static st__tableCreatePathTable (DdNode *node, unsigned int *pathLengthArray, FILE *fp)
 
static unsigned int AssessPathLength (unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp)
 
static DdNodeBuildSubsetBdd (DdManager *dd, st__table *pathTable, DdNode *node, struct AssortedInfo *info, st__table *subsetNodeTable)
 
static enum st__retval stPathTableDdFree (char *key, char *value, char *arg)
 
DdNodeCudd_SubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
 
DdNodeCudd_SupersetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
 
DdNodecuddSubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
 

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.34 2009/02/19 16:23:19 fabio Exp $"
 
static int memOut
 
static DdNodezero
 
static DdNodeone
 
static NodeDist_t ** nodeDistPages
 
static int nodeDistPageIndex
 
static int nodeDistPage
 
static int nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE
 
static int maxNodeDistPages
 
static NodeDist_tcurrentNodeDistPage
 
static DdNode *** queuePages
 
static int queuePageIndex
 
static int queuePage
 
static int queuePageSize = DEFAULT_PAGE_SIZE
 
static int maxQueuePages
 
static DdNode ** currentQueuePage
 

Macro Definition Documentation

#define DEFAULT_NODE_DIST_PAGE_SIZE   2048 /* page sizesto store NodeDist_t type */

Definition at line 83 of file cuddSubsetSP.c.

#define DEFAULT_PAGE_SIZE   2048 /* page size to store the BFS queue element type */

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

FileName [cuddSubsetSP.c]

PackageName [cudd]

Synopsis [Procedure to subset the given BDD choosing the shortest paths (largest cubes) in the BDD.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso [cuddSubsetHB.c]

Author [Kavita Ravi]

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 82 of file cuddSubsetSP.c.

#define INITIAL_PAGES
Value:
128 /* number of initial pages for the
* queue/NodeDist_t type */

Definition at line 89 of file cuddSubsetSP.c.

#define MAXSHORTINT
Value:
((DdHalfWord) ~0) /* constant defined to store
* maximum distance of a node
* from the root or the
* constant
*/
unsigned short DdHalfWord
Definition: cudd.h:262

Definition at line 84 of file cuddSubsetSP.c.

Typedef Documentation

typedef struct NodeDist NodeDist_t

Definition at line 122 of file cuddSubsetSP.c.

Function Documentation

static unsigned int AssessPathLength ( unsigned int *  pathLengthArray,
int  threshold,
int  numVars,
unsigned int *  excess,
FILE *  fp 
)
static

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

Synopsis [Chooses the maximum allowable path length of nodes under the threshold.]

Description [Chooses the maximum allowable path length under each node. The corner cases are when the threshold is larger than the number of nodes in the BDD iself, in which case 'numVars + 1' is returned. If all nodes of a particular path length are needed, then the maxpath returned is the next one with excess nodes = 0;]

SideEffects [None]

SeeAlso []

Definition at line 1171 of file cuddSubsetSP.c.

1177 {
1178  unsigned int i, maxpath;
1179  int temp;
1180 
1181  temp = threshold;
1182  i = 0;
1183  maxpath = 0;
1184  /* quit loop if i reaches max number of variables or if temp reaches
1185  * below zero
1186  */
1187  while ((i < (unsigned) numVars+1) && (temp > 0)) {
1188  if (pathLengthArray[i] > 0) {
1189  maxpath = i;
1190  temp = temp - pathLengthArray[i];
1191  }
1192  i++;
1193  }
1194  /* if all nodes of max path are needed */
1195  if (temp >= 0) {
1196  maxpath++; /* now maxpath becomes the next maxppath or max number
1197  of variables */
1198  *excess = 0;
1199  } else { /* normal case when subset required is less than size of
1200  original BDD */
1201  *excess = temp + pathLengthArray[maxpath];
1202  }
1203 
1204  if (maxpath == 0) {
1205  fprintf(fp, "Path Length array seems to be all zeroes, check\n");
1206  }
1207  return(maxpath);
1208 
1209 } /* end of AssessPathLength */
unsigned int maxpath
Definition: cuddSubsetSP.c:111
static DdNode * BuildSubsetBdd ( DdManager dd,
st__table pathTable,
DdNode node,
struct AssortedInfo info,
st__table subsetNodeTable 
)
static

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

Synopsis [Builds the BDD with nodes labeled with path length less than or equal to maxpath]

Description [Builds the BDD with nodes labeled with path length under maxpath and as many nodes labeled maxpath as determined by the threshold. The procedure uses the path table to determine which nodes in the original bdd need to be retained. This procedure picks a shortest path (tie break decided by taking the child with the shortest distance to the constant) and recurs down the path till it reaches the constant. the procedure then starts building the subset upward from the constant. All nodes labeled by path lengths less than the given maxpath are used to build the subset. However, in the case of nodes that have label equal to maxpath, as many are chosen as required by the threshold. This number is stored in the info structure in the field thresholdReached. This field is decremented whenever a node labeled maxpath is encountered and the nodes labeled maxpath are aggregated in a maxpath table. As soon as the thresholdReached count goes to 0, the shortest path from this node to the constant is found. The extraction of nodes with the above labeling is based on the fact that each node, labeled with a path length, P, has at least one child labeled P or less. So extracting all nodes labeled a given path length P ensures complete paths between the root and the constant. Extraction of a partial number of nodes with a given path length may result in incomplete paths and hence the additional number of nodes are grabbed to complete the path. Since the Bdd is built bottom-up, other nodes labeled maxpath do lie on complete paths. The procedure may cause the subset to have a larger or smaller number of nodes than the specified threshold. The increase in the number of nodes is caused by the building of a subset and the reduction by recombination. However in most cases, the recombination overshadows the increase and the procedure returns a result with lower number of nodes than specified. The subsetNodeTable is NIL when there is no hard limit on the number of nodes. Further efforts towards keeping the subset closer to the threshold number were abandoned in favour of keeping the procedure simple and fast.]

SideEffects [SubsetNodeTable is changed if it is not NIL.]

SeeAlso []

Definition at line 1255 of file cuddSubsetSP.c.

1261 {
1262  DdNode *N, *Nv, *Nnv;
1263  DdNode *ThenBranch, *ElseBranch, *childBranch;
1264  DdNode *child, *regChild, *regNnv = NULL, *regNv = NULL;
1265  NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv;
1266  DdNode *neW, *topv, *regNew;
1267  char *entry;
1268  unsigned int topid;
1269  unsigned int childPathLength, oddLen, evenLen, NnvPathLength = 0, NvPathLength = 0;
1270  unsigned int NvBotDist, NnvBotDist;
1271  int tiebreakChild;
1272  int processingDone, thenDone, elseDone;
1273 
1274 
1275 #ifdef DD_DEBUG
1276  numCalls++;
1277 #endif
1278  if (Cudd_IsConstant(node))
1279  return(node);
1280 
1281  N = Cudd_Regular(node);
1282  /* Find node in table. */
1283  if (! st__lookup(pathTable, (const char *)N, (char **)&nodeStat)) {
1284  (void) fprintf(dd->err, "Something wrong, node must be in table \n");
1286  return(NULL);
1287  }
1288  /* If the node in the table has been visited, then return the corresponding
1289  ** Dd. Since a node can become a subset of itself, its
1290  ** complement (that is te same node reached by a different parity) will
1291  ** become a superset of the original node and result in some minterms
1292  ** that were not in the original set. Hence two different results are
1293  ** maintained, corresponding to the odd and even parities.
1294  */
1295 
1296  /* If this node is reached with an odd parity, get odd parity results. */
1297  if (Cudd_IsComplement(node)) {
1298  if (nodeStat->compResult != NULL) {
1299 #ifdef DD_DEBUG
1300  hits++;
1301 #endif
1302  return(nodeStat->compResult);
1303  }
1304  } else {
1305  /* if this node is reached with an even parity, get even parity
1306  * results
1307  */
1308  if (nodeStat->regResult != NULL) {
1309 #ifdef DD_DEBUG
1310  hits++;
1311 #endif
1312  return(nodeStat->regResult);
1313  }
1314  }
1315 
1316 
1317  /* get children */
1318  Nv = Cudd_T(N);
1319  Nnv = Cudd_E(N);
1320 
1321  Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
1322  Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
1323 
1324  /* no child processed */
1325  processingDone = 0;
1326  /* then child not processed */
1327  thenDone = 0;
1328  ThenBranch = NULL;
1329  /* else child not processed */
1330  elseDone = 0;
1331  ElseBranch = NULL;
1332  /* if then child constant, branch is the child */
1333  if (Cudd_IsConstant(Nv)) {
1334  /*shortest path found */
1335  if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) {
1336  info->findShortestPath = 0;
1337  }
1338 
1339  ThenBranch = Nv;
1340  cuddRef(ThenBranch);
1341  if (ThenBranch == NULL) {
1342  return(NULL);
1343  }
1344 
1345  thenDone++;
1346  processingDone++;
1347  NvBotDist = MAXSHORTINT;
1348  } else {
1349  /* Derive regular child for table lookup. */
1350  regNv = Cudd_Regular(Nv);
1351  /* Get node data for shortest path length. */
1352  if (! st__lookup(pathTable, (const char *)regNv, (char **)&nodeStatNv) ) {
1353  (void) fprintf(dd->err, "Something wrong, node must be in table\n");
1355  return(NULL);
1356  }
1357  /* Derive shortest path length for child. */
1358  if ((nodeStatNv->oddTopDist != MAXSHORTINT) &&
1359  (nodeStatNv->oddBotDist != MAXSHORTINT)) {
1360  oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist);
1361  } else {
1362  oddLen = MAXSHORTINT;
1363  }
1364 
1365  if ((nodeStatNv->evenTopDist != MAXSHORTINT) &&
1366  (nodeStatNv->evenBotDist != MAXSHORTINT)) {
1367  evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist);
1368  } else {
1369  evenLen = MAXSHORTINT;
1370  }
1371 
1372  NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen;
1373  NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist:
1374  nodeStatNv->evenBotDist;
1375  }
1376  /* if else child constant, branch is the child */
1377  if (Cudd_IsConstant(Nnv)) {
1378  /*shortest path found */
1379  if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) {
1380  info->findShortestPath = 0;
1381  }
1382 
1383  ElseBranch = Nnv;
1384  cuddRef(ElseBranch);
1385  if (ElseBranch == NULL) {
1386  return(NULL);
1387  }
1388 
1389  elseDone++;
1390  processingDone++;
1391  NnvBotDist = MAXSHORTINT;
1392  } else {
1393  /* Derive regular child for table lookup. */
1394  regNnv = Cudd_Regular(Nnv);
1395  /* Get node data for shortest path length. */
1396  if (! st__lookup(pathTable, (const char *)regNnv, (char **)&nodeStatNnv) ) {
1397  (void) fprintf(dd->err, "Something wrong, node must be in table\n");
1399  return(NULL);
1400  }
1401  /* Derive shortest path length for child. */
1402  if ((nodeStatNnv->oddTopDist != MAXSHORTINT) &&
1403  (nodeStatNnv->oddBotDist != MAXSHORTINT)) {
1404  oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist);
1405  } else {
1406  oddLen = MAXSHORTINT;
1407  }
1408 
1409  if ((nodeStatNnv->evenTopDist != MAXSHORTINT) &&
1410  (nodeStatNnv->evenBotDist != MAXSHORTINT)) {
1411  evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist);
1412  } else {
1413  evenLen = MAXSHORTINT;
1414  }
1415 
1416  NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen;
1417  NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist :
1418  nodeStatNnv->evenBotDist;
1419  }
1420 
1421  tiebreakChild = (NvBotDist <= NnvBotDist) ? 1 : 0;
1422  /* while both children not processed */
1423  while (processingDone != 2) {
1424  if (!processingDone) {
1425  /* if no child processed */
1426  /* pick the child with shortest path length and record which one
1427  * picked
1428  */
1429  if ((NvPathLength < NnvPathLength) ||
1430  ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) {
1431  child = Nv;
1432  regChild = regNv;
1433  thenDone = 1;
1434  childPathLength = NvPathLength;
1435  } else {
1436  child = Nnv;
1437  regChild = regNnv;
1438  elseDone = 1;
1439  childPathLength = NnvPathLength;
1440  } /* then path length less than else path length */
1441  } else {
1442  /* if one child processed, process the other */
1443  if (thenDone) {
1444  child = Nnv;
1445  regChild = regNnv;
1446  elseDone = 1;
1447  childPathLength = NnvPathLength;
1448  } else {
1449  child = Nv;
1450  regChild = regNv;
1451  thenDone = 1;
1452  childPathLength = NvPathLength;
1453  } /* end of else pick the Then child if ELSE child processed */
1454  } /* end of else one child has been processed */
1455 
1456  /* ignore (replace with constant 0) all nodes which lie on paths larger
1457  * than the maximum length of the path required
1458  */
1459  if (childPathLength > info->maxpath) {
1460  /* record nodes visited */
1461  childBranch = zero;
1462  } else {
1463  if (childPathLength < info->maxpath) {
1464  if (info->findShortestPath) {
1465  info->findShortestPath = 0;
1466  }
1467  childBranch = BuildSubsetBdd(dd, pathTable, child, info,
1468  subsetNodeTable);
1469 
1470  } else { /* Case: path length of node = maxpath */
1471  /* If the node labeled with maxpath is found in the
1472  ** maxpathTable, use it to build the subset BDD. */
1473  if ( st__lookup(info->maxpathTable, (char *)regChild,
1474  (char **)&entry)) {
1475  /* When a node that is already been chosen is hit,
1476  ** the quest for a complete path is over. */
1477  if (info->findShortestPath) {
1478  info->findShortestPath = 0;
1479  }
1480  childBranch = BuildSubsetBdd(dd, pathTable, child, info,
1481  subsetNodeTable);
1482  } else {
1483  /* If node is not found in the maxpathTable and
1484  ** the threshold has been reached, then if the
1485  ** path needs to be completed, continue. Else
1486  ** replace the node with a zero. */
1487  if (info->thresholdReached <= 0) {
1488  if (info->findShortestPath) {
1489  if ( st__insert(info->maxpathTable, (char *)regChild,
1490  (char *)NIL(char)) == st__OUT_OF_MEM) {
1491  memOut = 1;
1492  (void) fprintf(dd->err, "OUT of memory\n");
1493  info->thresholdReached = 0;
1494  childBranch = zero;
1495  } else {
1496  info->thresholdReached--;
1497  childBranch = BuildSubsetBdd(dd, pathTable,
1498  child, info,subsetNodeTable);
1499  }
1500  } else { /* not find shortest path, we dont need this
1501  node */
1502  childBranch = zero;
1503  }
1504  } else { /* Threshold hasn't been reached,
1505  ** need the node. */
1506  if ( st__insert(info->maxpathTable, (char *)regChild,
1507  (char *)NIL(char)) == st__OUT_OF_MEM) {
1508  memOut = 1;
1509  (void) fprintf(dd->err, "OUT of memory\n");
1510  info->thresholdReached = 0;
1511  childBranch = zero;
1512  } else {
1513  info->thresholdReached--;
1514  if (info->thresholdReached <= 0) {
1515  info->findShortestPath = 1;
1516  }
1517  childBranch = BuildSubsetBdd(dd, pathTable,
1518  child, info, subsetNodeTable);
1519 
1520  } /* end of st__insert successful */
1521  } /* end of threshold hasnt been reached yet */
1522  } /* end of else node not found in maxpath table */
1523  } /* end of if (path length of node = maxpath) */
1524  } /* end if !(childPathLength > maxpath) */
1525  if (childBranch == NULL) {
1526  /* deref other stuff incase reordering has taken place */
1527  if (ThenBranch != NULL) {
1528  Cudd_RecursiveDeref(dd, ThenBranch);
1529  ThenBranch = NULL;
1530  }
1531  if (ElseBranch != NULL) {
1532  Cudd_RecursiveDeref(dd, ElseBranch);
1533  ElseBranch = NULL;
1534  }
1535  return(NULL);
1536  }
1537 
1538  cuddRef(childBranch);
1539 
1540  if (child == Nv) {
1541  ThenBranch = childBranch;
1542  } else {
1543  ElseBranch = childBranch;
1544  }
1545  processingDone++;
1546 
1547  } /*end of while processing Nv, Nnv */
1548 
1549  info->findShortestPath = 0;
1550  topid = Cudd_NodeReadIndex(N);
1551  topv = Cudd_ReadVars(dd, topid);
1552  cuddRef(topv);
1553  neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch);
1554  if (neW != NULL) {
1555  cuddRef(neW);
1556  }
1557  Cudd_RecursiveDeref(dd, topv);
1558  Cudd_RecursiveDeref(dd, ThenBranch);
1559  Cudd_RecursiveDeref(dd, ElseBranch);
1560 
1561 
1562  /* Hard Limit of threshold has been imposed */
1563  if (subsetNodeTable != NIL( st__table)) {
1564  /* check if a new node is created */
1565  regNew = Cudd_Regular(neW);
1566  /* subset node table keeps all new nodes that have been created to keep
1567  * a running count of how many nodes have been built in the subset.
1568  */
1569  if (! st__lookup(subsetNodeTable, (char *)regNew, (char **)&entry)) {
1570  if (!Cudd_IsConstant(regNew)) {
1571  if ( st__insert(subsetNodeTable, (char *)regNew,
1572  (char *)NULL) == st__OUT_OF_MEM) {
1573  (void) fprintf(dd->err, "Out of memory\n");
1574  return (NULL);
1575  }
1576  if ( st__count(subsetNodeTable) > info->threshold) {
1577  info->thresholdReached = 0;
1578  }
1579  }
1580  }
1581  }
1582 
1583 
1584  if (neW == NULL) {
1585  return(NULL);
1586  } else {
1587  /*store computed result in regular form*/
1588  if (Cudd_IsComplement(node)) {
1589  nodeStat->compResult = neW;
1590  cuddRef(nodeStat->compResult);
1591  /* if the new node is the same as the corresponding node in the
1592  * original bdd then its complement need not be computed as it
1593  * cannot be larger than the node itself
1594  */
1595  if (neW == node) {
1596 #ifdef DD_DEBUG
1597  thishit++;
1598 #endif
1599  /* if a result for the node has already been computed, then
1600  * it can only be smaller than teh node itself. hence store
1601  * the node result in order not to break recombination
1602  */
1603  if (nodeStat->regResult != NULL) {
1604  Cudd_RecursiveDeref(dd, nodeStat->regResult);
1605  }
1606  nodeStat->regResult = Cudd_Not(neW);
1607  cuddRef(nodeStat->regResult);
1608  }
1609 
1610  } else {
1611  nodeStat->regResult = neW;
1612  cuddRef(nodeStat->regResult);
1613  if (neW == node) {
1614 #ifdef DD_DEBUG
1615  thishit++;
1616 #endif
1617  if (nodeStat->compResult != NULL) {
1618  Cudd_RecursiveDeref(dd, nodeStat->compResult);
1619  }
1620  nodeStat->compResult = Cudd_Not(neW);
1621  cuddRef(nodeStat->compResult);
1622  }
1623  }
1624 
1625  cuddDeref(neW);
1626  return(neW);
1627  } /* end of else i.e. Subset != NULL */
1628 } /* end of BuildSubsetBdd */
DdHalfWord oddBotDist
Definition: cuddSubsetSP.c:103
#define cuddRef(n)
Definition: cuddInt.h:584
#define Cudd_T(node)
Definition: cudd.h:440
static DdNode * zero
Definition: cuddSubsetSP.c:140
#define cuddDeref(n)
Definition: cuddInt.h:604
st__table * maxpathTable
Definition: cuddSubsetSP.c:114
#define Cudd_E(node)
Definition: cudd.h:455
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
static int memOut
Definition: cuddSubsetSP.c:139
DdHalfWord oddTopDist
Definition: cuddSubsetSP.c:101
#define MAXSHORTINT
Definition: cuddSubsetSP.c:84
DdNode * Cudd_ReadVars(DdManager *dd, int i)
Definition: cuddAPI.c:2407
#define NIL(type)
Definition: avl.h:25
static int * entry
Definition: cuddGroup.c:122
DdNode * compResult
Definition: cuddSubsetSP.c:106
unsigned int maxpath
Definition: cuddSubsetSP.c:111
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define st__count(table)
Definition: st.h:71
Definition: st.h:52
DdNode * regResult
Definition: cuddSubsetSP.c:105
int thresholdReached
Definition: cuddSubsetSP.c:113
int findShortestPath
Definition: cuddSubsetSP.c:112
#define st__OUT_OF_MEM
Definition: st.h:113
DdHalfWord evenBotDist
Definition: cuddSubsetSP.c:104
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
unsigned int Cudd_NodeReadIndex(DdNode *node)
Definition: cuddAPI.c:2277
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdHalfWord evenTopDist
Definition: cuddSubsetSP.c:102
#define DD_ONE(dd)
Definition: cuddInt.h:911
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static DdNode * BuildSubsetBdd(DdManager *dd, st__table *pathTable, DdNode *node, struct AssortedInfo *info, st__table *subsetNodeTable)
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
static int CreateBotDist ( DdNode node,
st__table pathTable,
unsigned int *  pathLengthArray,
FILE *  fp 
)
static

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

Synopsis [ Labels each node with the shortest distance from the constant.]

Description [Labels each node with the shortest distance from the constant. This is done in a DFS search of the BDD. Each node has an odd and even parity distance from the sink (since there exists paths to both zero and one) which is less than MAXSHORTINT. At each node these distances are updated using the minimum distance of its children from the constant. SInce now both the length from the root and child is known, the minimum path length(length of the shortest path between the root and the constant that this node lies on) of this node can be calculated and used to update the pathLengthArray]

SideEffects [Updates Path Table and path length array]

SeeAlso [CreatePathTable CreateTopDist AssessPathLength]

Definition at line 836 of file cuddSubsetSP.c.

841 {
842  DdNode *N, *Nv, *Nnv;
843  DdNode *realChild;
844  DdNode *child, *regChild;
845  NodeDist_t *nodeStat, *nodeStatChild;
846  unsigned int oddLen, evenLen, pathLength;
847  DdHalfWord botDist;
848  int processingDone;
849 
850  if (Cudd_IsConstant(node))
851  return(1);
852  N = Cudd_Regular(node);
853  /* each node has one table entry */
854  /* update as you go down the min dist of each node from
855  the root in each (odd and even) parity */
856  if (! st__lookup(pathTable, (const char *)N, (char **)&nodeStat)) {
857  fprintf(fp, "Something wrong, the entry doesn't exist\n");
858  return(0);
859  }
860 
861  /* compute length of odd parity distances */
862  if ((nodeStat->oddTopDist != MAXSHORTINT) &&
863  (nodeStat->oddBotDist != MAXSHORTINT))
864  oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist);
865  else
866  oddLen = MAXSHORTINT;
867 
868  /* compute length of even parity distances */
869  if (!((nodeStat->evenTopDist == MAXSHORTINT) ||
870  (nodeStat->evenBotDist == MAXSHORTINT)))
871  evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist);
872  else
873  evenLen = MAXSHORTINT;
874 
875  /* assign pathlength to minimum of the two */
876  pathLength = (oddLen <= evenLen) ? oddLen : evenLen;
877 
878  Nv = Cudd_T(N);
879  Nnv = Cudd_E(N);
880 
881  /* process each child */
882  processingDone = 0;
883  while (processingDone != 2) {
884  if (!processingDone) {
885  child = Nv;
886  } else {
887  child = Nnv;
888  }
889 
890  realChild = Cudd_NotCond(child, Cudd_IsComplement(node));
891  regChild = Cudd_Regular(child);
892  if (Cudd_IsConstant(realChild)) {
893  /* Found a minterm; count parity and shortest distance
894  ** from the constant.
895  */
896  if (Cudd_IsComplement(child))
897  nodeStat->oddBotDist = 1;
898  else
899  nodeStat->evenBotDist = 1;
900  } else {
901  /* If node not in table, recur. */
902  if (! st__lookup(pathTable, (const char *)regChild, (char **)&nodeStatChild)) {
903  fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n");
904  return(0);
905  }
906 
907  if (nodeStatChild->oddBotDist == MAXSHORTINT) {
908  if (nodeStatChild->evenBotDist == MAXSHORTINT) {
909  if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp))
910  return(0);
911  } else {
912  fprintf(fp, "Something wrong, both bot nodeStats should be there\n");
913  return(0);
914  }
915  }
916 
917  /* Update shortest distance from the constant depending on
918  ** parity. */
919 
920  if (Cudd_IsComplement(child)) {
921  /* If parity on the edge then add 1 to even distance
922  ** of child to get odd parity distance and add 1 to
923  ** odd distance of child to get even parity
924  ** distance. Change distance of current node only if
925  ** the calculated distance is less than existing
926  ** distance. */
927  if (nodeStatChild->oddBotDist != MAXSHORTINT)
928  botDist = nodeStatChild->oddBotDist + 1;
929  else
930  botDist = MAXSHORTINT;
931  if (nodeStat->evenBotDist > botDist )
932  nodeStat->evenBotDist = botDist;
933 
934  if (nodeStatChild->evenBotDist != MAXSHORTINT)
935  botDist = nodeStatChild->evenBotDist + 1;
936  else
937  botDist = MAXSHORTINT;
938  if (nodeStat->oddBotDist > botDist)
939  nodeStat->oddBotDist = botDist;
940 
941  } else {
942  /* If parity on the edge then add 1 to even distance
943  ** of child to get even parity distance and add 1 to
944  ** odd distance of child to get odd parity distance.
945  ** Change distance of current node only if the
946  ** calculated distance is lesser than existing
947  ** distance. */
948  if (nodeStatChild->evenBotDist != MAXSHORTINT)
949  botDist = nodeStatChild->evenBotDist + 1;
950  else
951  botDist = MAXSHORTINT;
952  if (nodeStat->evenBotDist > botDist)
953  nodeStat->evenBotDist = botDist;
954 
955  if (nodeStatChild->oddBotDist != MAXSHORTINT)
956  botDist = nodeStatChild->oddBotDist + 1;
957  else
958  botDist = MAXSHORTINT;
959  if (nodeStat->oddBotDist > botDist)
960  nodeStat->oddBotDist = botDist;
961  }
962  } /* end of else (if not constant child ) */
963  processingDone++;
964  } /* end of while processing Nv, Nnv */
965 
966  /* Compute shortest path length on the fly. */
967  if ((nodeStat->oddTopDist != MAXSHORTINT) &&
968  (nodeStat->oddBotDist != MAXSHORTINT))
969  oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist);
970  else
971  oddLen = MAXSHORTINT;
972 
973  if ((nodeStat->evenTopDist != MAXSHORTINT) &&
974  (nodeStat->evenBotDist != MAXSHORTINT))
975  evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist);
976  else
977  evenLen = MAXSHORTINT;
978 
979  /* Update path length array that has number of nodes of a particular
980  ** path length. */
981  if (oddLen < pathLength ) {
982  if (pathLength != MAXSHORTINT)
983  pathLengthArray[pathLength]--;
984  if (oddLen != MAXSHORTINT)
985  pathLengthArray[oddLen]++;
986  pathLength = oddLen;
987  }
988  if (evenLen < pathLength ) {
989  if (pathLength != MAXSHORTINT)
990  pathLengthArray[pathLength]--;
991  if (evenLen != MAXSHORTINT)
992  pathLengthArray[evenLen]++;
993  }
994 
995  return(1);
996 
997 } /*end of CreateBotDist */
DdHalfWord oddBotDist
Definition: cuddSubsetSP.c:103
#define Cudd_T(node)
Definition: cudd.h:440
unsigned short DdHalfWord
Definition: cudd.h:262
#define Cudd_E(node)
Definition: cudd.h:455
Definition: cudd.h:278
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
DdHalfWord oddTopDist
Definition: cuddSubsetSP.c:101
#define MAXSHORTINT
Definition: cuddSubsetSP.c:84
static int CreateBotDist(DdNode *node, st__table *pathTable, unsigned int *pathLengthArray, FILE *fp)
Definition: cuddSubsetSP.c:836
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdHalfWord evenBotDist
Definition: cuddSubsetSP.c:104
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdHalfWord evenTopDist
Definition: cuddSubsetSP.c:102
static st__table * CreatePathTable ( DdNode node,
unsigned int *  pathLengthArray,
FILE *  fp 
)
static

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

Synopsis [ The outer procedure to label each node with its shortest distance from the root and constant]

Description [ The outer procedure to label each node with its shortest distance from the root and constant. Calls CreateTopDist and CreateBotDist. The basis for computing the distance between root and constant is that the distance may be the sum of even distances from the node to the root and constant or the sum of odd distances from the node to the root and constant. Both CreateTopDist and CreateBotDist create the odd and even parity distances from the root and constant respectively.]

SideEffects [None]

SeeAlso [CreateTopDist CreateBotDist]

Definition at line 1019 of file cuddSubsetSP.c.

1023 {
1024 
1025  st__table *pathTable;
1026  NodeDist_t *nodeStat;
1027  DdHalfWord topLen;
1028  DdNode *N;
1029  int i, numParents;
1030  int insertValue;
1031  DdNode **childPage;
1032  int parentPage;
1033  int childQueueIndex, parentQueueIndex;
1034 
1035  /* Creating path Table for storing data about nodes */
1036  pathTable = st__init_table( st__ptrcmp, st__ptrhash);
1037 
1038  /* initializing pages for info about each node */
1041  if (nodeDistPages == NULL) {
1042  goto OUT_OF_MEM;
1043  }
1044  nodeDistPage = 0;
1047  if (currentNodeDistPage == NULL) {
1048  for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
1050  goto OUT_OF_MEM;
1051  }
1052  nodeDistPageIndex = 0;
1053 
1054  /* Initializing pages for the BFS search queue, implemented as an array. */
1057  if (queuePages == NULL) {
1058  goto OUT_OF_MEM;
1059  }
1060  queuePage = 0;
1062  if (currentQueuePage == NULL) {
1063  for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]);
1065  goto OUT_OF_MEM;
1066  }
1067  queuePageIndex = 0;
1068 
1069  /* Enter the root node into the queue to start with. */
1070  parentPage = queuePage;
1071  parentQueueIndex = queuePageIndex;
1072  topLen = 0;
1073  *(currentQueuePage + queuePageIndex) = node;
1074  queuePageIndex++;
1075  childPage = currentQueuePage;
1076  childQueueIndex = queuePageIndex;
1077 
1078  N = Cudd_Regular(node);
1079 
1081  if (memOut) {
1082  for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
1084  for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]);
1086  st__free_table(pathTable);
1087  goto OUT_OF_MEM;
1088  }
1089 
1091  nodeDistPageIndex++;
1092 
1093  nodeStat->oddTopDist = MAXSHORTINT;
1094  nodeStat->evenTopDist = MAXSHORTINT;
1095  nodeStat->evenBotDist = MAXSHORTINT;
1096  nodeStat->oddBotDist = MAXSHORTINT;
1097  nodeStat->regResult = NULL;
1098  nodeStat->compResult = NULL;
1099 
1100  insertValue = st__insert(pathTable, (char *)N, (char *)nodeStat);
1101  if (insertValue == st__OUT_OF_MEM) {
1102  memOut = 1;
1103  for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
1105  for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]);
1107  st__free_table(pathTable);
1108  goto OUT_OF_MEM;
1109  } else if (insertValue == 1) {
1110  fprintf(fp, "Something wrong, the entry exists but didnt show up in st__lookup\n");
1111  return(NULL);
1112  }
1113 
1114  if (Cudd_IsComplement(node)) {
1115  nodeStat->oddTopDist = 0;
1116  } else {
1117  nodeStat->evenTopDist = 0;
1118  }
1119  numParents = 1;
1120  /* call the function that counts the distance of each node from the
1121  * root
1122  */
1123 #ifdef DD_DEBUG
1124  numCalls = 0;
1125 #endif
1126  CreateTopDist(pathTable, parentPage, parentQueueIndex, (int) topLen,
1127  childPage, childQueueIndex, numParents, fp);
1128  if (memOut) {
1129  fprintf(fp, "Out of Memory and cant count path lengths\n");
1130  goto OUT_OF_MEM;
1131  }
1132 
1133 #ifdef DD_DEBUG
1134  numCalls = 0;
1135 #endif
1136  /* call the function that counts the distance of each node from the
1137  * constant
1138  */
1139  if (!CreateBotDist(node, pathTable, pathLengthArray, fp)) return(NULL);
1140 
1141  /* free BFS queue pages as no longer required */
1142  for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]);
1144  return(pathTable);
1145 
1146 OUT_OF_MEM:
1147  (void) fprintf(fp, "Out of Memory, cannot allocate pages\n");
1148  memOut = 1;
1149  return(NULL);
1150 
1151 } /*end of CreatePathTable */
static int queuePageIndex
Definition: cuddSubsetSP.c:150
DdHalfWord oddBotDist
Definition: cuddSubsetSP.c:103
void st__free_table(st__table *table)
Definition: st.c:81
static void ResizeNodeDistPages(void)
Definition: cuddSubsetSP.c:512
static int nodeDistPageSize
Definition: cuddSubsetSP.c:145
unsigned short DdHalfWord
Definition: cudd.h:262
static int nodeDistPageIndex
Definition: cuddSubsetSP.c:143
Definition: cudd.h:278
static NodeDist_t * currentNodeDistPage
Definition: cuddSubsetSP.c:147
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
static int memOut
Definition: cuddSubsetSP.c:139
DdHalfWord oddTopDist
Definition: cuddSubsetSP.c:101
#define INITIAL_PAGES
Definition: cuddSubsetSP.c:89
#define MAXSHORTINT
Definition: cuddSubsetSP.c:84
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static DdNode ** currentQueuePage
Definition: cuddSubsetSP.c:154
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
DdNode * compResult
Definition: cuddSubsetSP.c:106
static int CreateBotDist(DdNode *node, st__table *pathTable, unsigned int *pathLengthArray, FILE *fp)
Definition: cuddSubsetSP.c:836
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode *** queuePages
Definition: cuddSubsetSP.c:149
static int maxNodeDistPages
Definition: cuddSubsetSP.c:146
static int maxQueuePages
Definition: cuddSubsetSP.c:153
Definition: st.h:52
DdNode * regResult
Definition: cuddSubsetSP.c:105
static int queuePageSize
Definition: cuddSubsetSP.c:152
static int nodeDistPage
Definition: cuddSubsetSP.c:144
#define st__OUT_OF_MEM
Definition: st.h:113
DdHalfWord evenBotDist
Definition: cuddSubsetSP.c:104
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int queuePage
Definition: cuddSubsetSP.c:151
DdHalfWord evenTopDist
Definition: cuddSubsetSP.c:102
int st__ptrhash(const char *, int)
Definition: st.c:468
static NodeDist_t ** nodeDistPages
Definition: cuddSubsetSP.c:142
static void CreateTopDist(st__table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp)
Definition: cuddSubsetSP.c:635
static void CreateTopDist ( st__table pathTable,
int  parentPage,
int  parentQueueIndex,
int  topLen,
DdNode **  childPage,
int  childQueueIndex,
int  numParents,
FILE *  fp 
)
static

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

Synopsis [ Labels each node with its shortest distance from the root]

Description [ Labels each node with its shortest distance from the root. This is done in a BFS search of the BDD. The nodes are processed in a queue implemented as pages(array) to reduce memory fragmentation. An entry is created for each node visited. The distance from the root to the node with the corresponding parity is updated. The procedure is called recursively each recusion level handling nodes at a given level from the root.]

SideEffects [Creates entries in the pathTable]

SeeAlso [CreatePathTable CreateBotDist]

Definition at line 635 of file cuddSubsetSP.c.

644 {
645  NodeDist_t *nodeStat;
646  DdNode *N, *Nv, *Nnv, *node, *child, *regChild;
647  int i;
648  int processingDone, childrenCount;
649 
650 #ifdef DD_DEBUG
651  numCalls++;
652 
653  /* assume this procedure comes in with only the root node*/
654  /* set queue index to the next available entry for addition */
655  /* set queue page to page of addition */
656  if ((queuePages[parentPage] == childPage) && (parentQueueIndex ==
657  childQueueIndex)) {
658  fprintf(fp, "Should not happen that they are equal\n");
659  }
660  assert(queuePageIndex == childQueueIndex);
661  assert(currentQueuePage == childPage);
662 #endif
663  /* number children added to queue is initialized , needed for
664  * numParents in the next call
665  */
666  childrenCount = 0;
667  /* process all the nodes in this level */
668  while (numParents) {
669  numParents--;
670  if (parentQueueIndex == queuePageSize) {
671  parentPage++;
672  parentQueueIndex = 0;
673  }
674  /* a parent to process */
675  node = *(queuePages[parentPage] + parentQueueIndex);
676  parentQueueIndex++;
677  /* get its children */
678  N = Cudd_Regular(node);
679  Nv = Cudd_T(N);
680  Nnv = Cudd_E(N);
681 
682  Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node));
683  Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node));
684 
685  processingDone = 2;
686  while (processingDone) {
687  /* processing the THEN and the ELSE children, the THEN
688  * child first
689  */
690  if (processingDone == 2) {
691  child = Nv;
692  } else {
693  child = Nnv;
694  }
695 
696  regChild = Cudd_Regular(child);
697  /* dont process if the child is a constant */
698  if (!Cudd_IsConstant(child)) {
699  /* check is already visited, if not add a new entry in
700  * the path Table
701  */
702  if (! st__lookup(pathTable, (const char *)regChild, (char **)&nodeStat)) {
703  /* if not in table, has never been visited */
704  /* create entry for table */
707  if (memOut) {
708  for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]);
710  st__free_table(pathTable);
711  return;
712  }
713  /* New entry for child in path Table is created here */
715  nodeDistPageIndex++;
716 
717  /* Initialize fields of the node data */
718  nodeStat->oddTopDist = MAXSHORTINT;
719  nodeStat->evenTopDist = MAXSHORTINT;
720  nodeStat->evenBotDist = MAXSHORTINT;
721  nodeStat->oddBotDist = MAXSHORTINT;
722  nodeStat->regResult = NULL;
723  nodeStat->compResult = NULL;
724  /* update the table entry element, the distance keeps
725  * track of the parity of the path from the root
726  */
727  if (Cudd_IsComplement(child)) {
728  nodeStat->oddTopDist = (DdHalfWord) topLen + 1;
729  } else {
730  nodeStat->evenTopDist = (DdHalfWord) topLen + 1;
731  }
732 
733  /* insert entry element for child in the table */
734  if ( st__insert(pathTable, (char *)regChild,
735  (char *)nodeStat) == st__OUT_OF_MEM) {
736  memOut = 1;
737  for (i = 0; i <= nodeDistPage; i++)
740  for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]);
742  st__free_table(pathTable);
743  return;
744  }
745 
746  /* Create list element for this child to process its children.
747  * If this node has been processed already, then it appears
748  * in the path table and hence is never added to the list
749  * again.
750  */
751 
753  if (memOut) {
754  for (i = 0; i <= nodeDistPage; i++)
757  st__free_table(pathTable);
758  return;
759  }
760  *(currentQueuePage + queuePageIndex) = child;
761  queuePageIndex++;
762 
763  childrenCount++;
764  } else {
765  /* if not been met in a path with this parity before */
766  /* put in list */
767  if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist ==
768  MAXSHORTINT)) || ((!Cudd_IsComplement(child)) &&
769  (nodeStat->evenTopDist == MAXSHORTINT))) {
770 
772  if (memOut) {
773  for (i = 0; i <= nodeDistPage; i++)
776  st__free_table(pathTable);
777  return;
778 
779  }
780  *(currentQueuePage + queuePageIndex) = child;
781  queuePageIndex++;
782 
783  /* update the distance with the appropriate parity */
784  if (Cudd_IsComplement(child)) {
785  nodeStat->oddTopDist = (DdHalfWord) topLen + 1;
786  } else {
787  nodeStat->evenTopDist = (DdHalfWord) topLen + 1;
788  }
789  childrenCount++;
790  }
791 
792  } /* end of else (not found in st__table) */
793  } /*end of if Not constant child */
794  processingDone--;
795  } /*end of while processing Nv, Nnv */
796  } /*end of while numParents */
797 
798 #ifdef DD_DEBUG
799  assert(queuePages[parentPage] == childPage);
800  assert(parentQueueIndex == childQueueIndex);
801 #endif
802 
803  if (childrenCount != 0) {
804  topLen++;
805  childPage = currentQueuePage;
806  childQueueIndex = queuePageIndex;
807  CreateTopDist(pathTable, parentPage, parentQueueIndex, topLen,
808  childPage, childQueueIndex, childrenCount, fp);
809  }
810 
811  return;
812 
813 } /* end of CreateTopDist */
static int queuePageIndex
Definition: cuddSubsetSP.c:150
DdHalfWord oddBotDist
Definition: cuddSubsetSP.c:103
void st__free_table(st__table *table)
Definition: st.c:81
static void ResizeNodeDistPages(void)
Definition: cuddSubsetSP.c:512
static int nodeDistPageSize
Definition: cuddSubsetSP.c:145
#define Cudd_T(node)
Definition: cudd.h:440
unsigned short DdHalfWord
Definition: cudd.h:262
static int nodeDistPageIndex
Definition: cuddSubsetSP.c:143
#define Cudd_E(node)
Definition: cudd.h:455
Definition: cudd.h:278
static NodeDist_t * currentNodeDistPage
Definition: cuddSubsetSP.c:147
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
static int memOut
Definition: cuddSubsetSP.c:139
DdHalfWord oddTopDist
Definition: cuddSubsetSP.c:101
#define MAXSHORTINT
Definition: cuddSubsetSP.c:84
static DdNode ** currentQueuePage
Definition: cuddSubsetSP.c:154
DdNode * compResult
Definition: cuddSubsetSP.c:106
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode *** queuePages
Definition: cuddSubsetSP.c:149
static void ResizeQueuePages(void)
Definition: cuddSubsetSP.c:574
DdNode * regResult
Definition: cuddSubsetSP.c:105
static int queuePageSize
Definition: cuddSubsetSP.c:152
static int nodeDistPage
Definition: cuddSubsetSP.c:144
#define st__OUT_OF_MEM
Definition: st.h:113
DdHalfWord evenBotDist
Definition: cuddSubsetSP.c:104
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int queuePage
Definition: cuddSubsetSP.c:151
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define assert(ex)
Definition: util_old.h:213
DdHalfWord evenTopDist
Definition: cuddSubsetSP.c:102
static NodeDist_t ** nodeDistPages
Definition: cuddSubsetSP.c:142
static void CreateTopDist(st__table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp)
Definition: cuddSubsetSP.c:635
DdNode* Cudd_SubsetShortPaths ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  hardlimit 
)

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

Synopsis [Extracts a dense subset from a BDD with the shortest paths heuristic.]

Description [Extracts a dense subset from a BDD. This procedure tries to preserve the shortest paths of the input BDD, because they give many minterms and contribute few nodes. This procedure may increase the number of nodes in trying to create the subset or reduce the number of nodes due to recombination as compared to the original BDD. Hence the threshold may not be strictly adhered to. In practice, recombination overshadows the increase in the number of nodes and results in small BDDs as compared to the threshold. The hardlimit specifies whether threshold needs to be strictly adhered to. If it is set to 1, the procedure ensures that result is never larger than the specified limit but may be considerably less than the threshold. Returns a pointer to the BDD for the subset if successful; NULL otherwise. The value for numVars should be as close as possible to the size of the support of f for better efficiency. However, it is safe to pass the value returned by Cudd_ReadSize for numVars. If 0 is passed, then the value returned by Cudd_ReadSize is used.]

SideEffects [None]

SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]

Definition at line 220 of file cuddSubsetSP.c.

226 {
227  DdNode *subset;
228 
229  memOut = 0;
230  do {
231  dd->reordered = 0;
232  subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit);
233  } while((dd->reordered ==1) && (!memOut));
234 
235  return(subset);
236 
237 } /* end of Cudd_SubsetShortPaths */
DdNode * cuddSubsetShortPaths(DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
Definition: cuddSubsetSP.c:316
Definition: cudd.h:278
static int memOut
Definition: cuddSubsetSP.c:139
int reordered
Definition: cuddInt.h:409
DdNode* Cudd_SupersetShortPaths ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  hardlimit 
)

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

Synopsis [Extracts a dense superset from a BDD with the shortest paths heuristic.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the subset procedure except for the fact that it receives the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. This procedure tries to preserve the shortest paths of the complement BDD, because they give many minterms and contribute few nodes. This procedure may increase the number of nodes in trying to create the superset or reduce the number of nodes due to recombination as compared to the original BDD. Hence the threshold may not be strictly adhered to. In practice, recombination overshadows the increase in the number of nodes and results in small BDDs as compared to the threshold. The hardlimit specifies whether threshold needs to be strictly adhered to. If it is set to 1, the procedure ensures that result is never larger than the specified limit but may be considerably less than the threshold. Returns a pointer to the BDD for the superset if successful; NULL otherwise. The value for numVars should be as close as possible to the size of the support of f for better efficiency. However, it is safe to pass the value returned by Cudd_ReadSize for numVar. If 0 is passed, then the value returned by Cudd_ReadSize is used.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]

Definition at line 272 of file cuddSubsetSP.c.

278 {
279  DdNode *subset, *g;
280 
281  g = Cudd_Not(f);
282  memOut = 0;
283  do {
284  dd->reordered = 0;
285  subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit);
286  } while((dd->reordered ==1) && (!memOut));
287 
288  return(Cudd_NotCond(subset, (subset != NULL)));
289 
290 } /* end of Cudd_SupersetShortPaths */
DdNode * cuddSubsetShortPaths(DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
Definition: cuddSubsetSP.c:316
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static int memOut
Definition: cuddSubsetSP.c:139
int reordered
Definition: cuddInt.h:409
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode* cuddSubsetShortPaths ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  hardlimit 
)

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

Synopsis [The outermost procedure to return a subset of the given BDD with the shortest path lengths.]

Description [The outermost procedure to return a subset of the given BDD with the largest cubes. The path lengths are calculated, the maximum allowable path length is determined and the number of nodes of this path length that can be used to build a subset. If the threshold is larger than the size of the original BDD, the original BDD is returned. ]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths]

Definition at line 316 of file cuddSubsetSP.c.

322 {
323  st__table *pathTable;
324  DdNode *N, *subset;
325 
326  unsigned int *pathLengthArray;
327  unsigned int maxpath, oddLen, evenLen, pathLength, *excess;
328  int i;
329  NodeDist_t *nodeStat;
330  struct AssortedInfo *info;
331  st__table *subsetNodeTable;
332 
333  one = DD_ONE(dd);
334  zero = Cudd_Not(one);
335 
336  if (numVars == 0) {
337  /* set default value */
338  numVars = Cudd_ReadSize(dd);
339  }
340 
341  if (threshold > numVars) {
342  threshold = threshold - numVars;
343  }
344  if (f == NULL) {
345  fprintf(dd->err, "Cannot partition, nil object\n");
347  return(NULL);
348  }
349  if (Cudd_IsConstant(f))
350  return (f);
351 
352  pathLengthArray = ABC_ALLOC(unsigned int, numVars+1);
353  for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0;
354 
355 
356 #ifdef DD_DEBUG
357  numCalls = 0;
358 #endif
359 
360  pathTable = CreatePathTable(f, pathLengthArray, dd->err);
361 
362  if ((pathTable == NULL) || (memOut)) {
363  if (pathTable != NULL)
364  st__free_table(pathTable);
365  ABC_FREE(pathLengthArray);
366  return (NIL(DdNode));
367  }
368 
369  excess = ABC_ALLOC(unsigned int, 1);
370  *excess = 0;
371  maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess,
372  dd->err);
373 
374  if (maxpath != (unsigned) (numVars + 1)) {
375 
376  info = ABC_ALLOC(struct AssortedInfo, 1);
377  info->maxpath = maxpath;
378  info->findShortestPath = 0;
379  info->thresholdReached = *excess;
381  info->threshold = threshold;
382 
383 #ifdef DD_DEBUG
384  (void) fprintf(dd->out, "Path length array\n");
385  for (i = 0; i < (numVars+1); i++) {
386  if (pathLengthArray[i])
387  (void) fprintf(dd->out, "%d ",i);
388  }
389  (void) fprintf(dd->out, "\n");
390  for (i = 0; i < (numVars+1); i++) {
391  if (pathLengthArray[i])
392  (void) fprintf(dd->out, "%d ",pathLengthArray[i]);
393  }
394  (void) fprintf(dd->out, "\n");
395  (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n",
396  maxpath, info->thresholdReached);
397 #endif
398 
399  N = Cudd_Regular(f);
400  if (! st__lookup(pathTable, (const char *)N, (char **)&nodeStat)) {
401  fprintf(dd->err, "Something wrong, root node must be in table\n");
403  ABC_FREE(excess);
404  ABC_FREE(info);
405  return(NULL);
406  } else {
407  if ((nodeStat->oddTopDist != MAXSHORTINT) &&
408  (nodeStat->oddBotDist != MAXSHORTINT))
409  oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist);
410  else
411  oddLen = MAXSHORTINT;
412 
413  if ((nodeStat->evenTopDist != MAXSHORTINT) &&
414  (nodeStat->evenBotDist != MAXSHORTINT))
415  evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist);
416  else
417  evenLen = MAXSHORTINT;
418 
419  pathLength = (oddLen <= evenLen) ? oddLen : evenLen;
420  if (pathLength > maxpath) {
421  (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength);
423  return(NULL);
424  }
425  }
426 
427 #ifdef DD_DEBUG
428  numCalls = 0;
429  hits = 0;
430  thishit = 0;
431 #endif
432  /* initialize a table to store computed nodes */
433  if (hardlimit) {
434  subsetNodeTable = st__init_table( st__ptrcmp, st__ptrhash);
435  } else {
436  subsetNodeTable = NIL( st__table);
437  }
438  subset = BuildSubsetBdd(dd, pathTable, f, info, subsetNodeTable);
439  if (subset != NULL) {
440  cuddRef(subset);
441  }
442  /* record the number of times a computed result for a node is hit */
443 
444 #ifdef DD_DEBUG
445  (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n",
446  hits, thishit, numCalls);
447 #endif
448 
449  if (subsetNodeTable != NIL( st__table)) {
450  st__free_table(subsetNodeTable);
451  }
453  st__foreach(pathTable, stPathTableDdFree, (char *)dd);
454 
455  ABC_FREE(info);
456 
457  } else {/* if threshold larger than size of dd */
458  subset = f;
459  cuddRef(subset);
460  }
461  ABC_FREE(excess);
462  st__free_table(pathTable);
463  ABC_FREE(pathLengthArray);
464  for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
466 
467 #ifdef DD_DEBUG
468  /* check containment of subset in f */
469  if (subset != NULL) {
470  DdNode *check;
471  check = Cudd_bddIteConstant(dd, subset, f, one);
472  if (check != one) {
473  (void) fprintf(dd->err, "Wrong partition\n");
475  return(NULL);
476  }
477  }
478 #endif
479 
480  if (subset != NULL) {
481  cuddDeref(subset);
482  return(subset);
483  } else {
484  return(NULL);
485  }
486 
487 } /* end of cuddSubsetShortPaths */
DdHalfWord oddBotDist
Definition: cuddSubsetSP.c:103
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
static DdNode * zero
Definition: cuddSubsetSP.c:140
#define cuddDeref(n)
Definition: cuddInt.h:604
st__table * maxpathTable
Definition: cuddSubsetSP.c:114
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
FILE * err
Definition: cuddInt.h:442
static int memOut
Definition: cuddSubsetSP.c:139
DdHalfWord oddTopDist
Definition: cuddSubsetSP.c:101
#define MAXSHORTINT
Definition: cuddSubsetSP.c:84
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int Cudd_ReadSize(DdManager *dd)
Definition: cuddAPI.c:1441
#define NIL(type)
Definition: avl.h:25
static void check(int expr)
Definition: satSolver.c:46
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:174
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
unsigned int maxpath
Definition: cuddSubsetSP.c:111
FILE * out
Definition: cuddInt.h:441
Definition: st.h:52
int thresholdReached
Definition: cuddSubsetSP.c:113
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
static int nodeDistPage
Definition: cuddSubsetSP.c:144
int findShortestPath
Definition: cuddSubsetSP.c:112
static enum st__retval stPathTableDdFree(char *key, char *value, char *arg)
DdHalfWord evenBotDist
Definition: cuddSubsetSP.c:104
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static unsigned int AssessPathLength(unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp)
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdHalfWord evenTopDist
Definition: cuddSubsetSP.c:102
#define DD_ONE(dd)
Definition: cuddInt.h:911
static st__table * CreatePathTable(DdNode *node, unsigned int *pathLengthArray, FILE *fp)
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int st__ptrhash(const char *, int)
Definition: st.c:468
static DdNode * one
Definition: cuddSubsetSP.c:140
static NodeDist_t ** nodeDistPages
Definition: cuddSubsetSP.c:142
static DdNode * BuildSubsetBdd(DdManager *dd, st__table *pathTable, DdNode *node, struct AssortedInfo *info, st__table *subsetNodeTable)
static void ResizeNodeDistPages ( void  )
static

AutomaticStart

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

Synopsis [Resize the number of pages allocated to store the distances related to each node.]

Description [Resize the number of pages allocated to store the distances related to each node. The procedure moves the counter to the next page when the end of the page is reached and allocates new pages when necessary. ]

SideEffects [Changes the size of pages, page, page index, maximum number of pages freeing stuff in case of memory out. ]

SeeAlso []

Definition at line 512 of file cuddSubsetSP.c.

513 {
514  int i;
515  NodeDist_t **newNodeDistPages;
516 
517  /* move to next page */
518  nodeDistPage++;
519 
520  /* If the current page index is larger than the number of pages
521  * allocated, allocate a new page array. Page numbers are incremented by
522  * INITIAL_PAGES
523  */
525  newNodeDistPages = ABC_ALLOC(NodeDist_t *,maxNodeDistPages + INITIAL_PAGES);
526  if (newNodeDistPages == NULL) {
527  for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
529  memOut = 1;
530  return;
531  } else {
532  for (i = 0; i < maxNodeDistPages; i++) {
533  newNodeDistPages[i] = nodeDistPages[i];
534  }
535  /* Increase total page count */
536  maxNodeDistPages += INITIAL_PAGES;
538  nodeDistPages = newNodeDistPages;
539  }
540  }
541  /* Allocate a new page */
544  if (currentNodeDistPage == NULL) {
545  for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
547  memOut = 1;
548  return;
549  }
550  /* reset page index */
551  nodeDistPageIndex = 0;
552  return;
553 
554 } /* end of ResizeNodeDistPages */
static int nodeDistPageSize
Definition: cuddSubsetSP.c:145
static int nodeDistPageIndex
Definition: cuddSubsetSP.c:143
static NodeDist_t * currentNodeDistPage
Definition: cuddSubsetSP.c:147
static int memOut
Definition: cuddSubsetSP.c:139
#define INITIAL_PAGES
Definition: cuddSubsetSP.c:89
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static int maxNodeDistPages
Definition: cuddSubsetSP.c:146
static int nodeDistPage
Definition: cuddSubsetSP.c:144
#define ABC_FREE(obj)
Definition: abc_global.h:232
static NodeDist_t ** nodeDistPages
Definition: cuddSubsetSP.c:142
static void ResizeQueuePages ( void  )
static

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

Synopsis [Resize the number of pages allocated to store nodes in the BFS traversal of the Bdd .]

Description [Resize the number of pages allocated to store nodes in the BFS traversal of the Bdd. The procedure moves the counter to the next page when the end of the page is reached and allocates new pages when necessary.]

SideEffects [Changes the size of pages, page, page index, maximum number of pages freeing stuff in case of memory out. ]

SeeAlso []

Definition at line 574 of file cuddSubsetSP.c.

575 {
576  int i;
577  DdNode ***newQueuePages;
578 
579  queuePage++;
580  /* If the current page index is larger than the number of pages
581  * allocated, allocate a new page array. Page numbers are incremented by
582  * INITIAL_PAGES
583  */
584  if (queuePage == maxQueuePages) {
585  newQueuePages = ABC_ALLOC(DdNode **,maxQueuePages + INITIAL_PAGES);
586  if (newQueuePages == NULL) {
587  for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]);
589  memOut = 1;
590  return;
591  } else {
592  for (i = 0; i < maxQueuePages; i++) {
593  newQueuePages[i] = queuePages[i];
594  }
595  /* Increase total page count */
596  maxQueuePages += INITIAL_PAGES;
598  queuePages = newQueuePages;
599  }
600  }
601  /* Allocate a new page */
603  if (currentQueuePage == NULL) {
604  for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]);
606  memOut = 1;
607  return;
608  }
609  /* reset page index */
610  queuePageIndex = 0;
611  return;
612 
613 } /* end of ResizeQueuePages */
static int queuePageIndex
Definition: cuddSubsetSP.c:150
Definition: cudd.h:278
static int memOut
Definition: cuddSubsetSP.c:139
#define INITIAL_PAGES
Definition: cuddSubsetSP.c:89
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static DdNode ** currentQueuePage
Definition: cuddSubsetSP.c:154
static DdNode *** queuePages
Definition: cuddSubsetSP.c:149
static int maxQueuePages
Definition: cuddSubsetSP.c:153
static int queuePageSize
Definition: cuddSubsetSP.c:152
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int queuePage
Definition: cuddSubsetSP.c:151
static enum st__retval stPathTableDdFree ( char *  key,
char *  value,
char *  arg 
)
static

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

Synopsis [Procedure to free te result dds stored in the NodeDist pages.]

Description [None]

SideEffects [None]

SeeAlso []

Definition at line 1643 of file cuddSubsetSP.c.

1647 {
1648  NodeDist_t *nodeStat;
1649  DdManager *dd;
1650 
1651  nodeStat = (NodeDist_t *)value;
1652  dd = (DdManager *)arg;
1653  if (nodeStat->regResult != NULL) {
1654  Cudd_RecursiveDeref(dd, nodeStat->regResult);
1655  }
1656  if (nodeStat->compResult != NULL) {
1657  Cudd_RecursiveDeref(dd, nodeStat->compResult);
1658  }
1659  return( st__CONTINUE);
1660 
1661 } /* end of stPathTableFree */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
DdNode * compResult
Definition: cuddSubsetSP.c:106
DdNode * regResult
Definition: cuddSubsetSP.c:105
int value

Variable Documentation

NodeDist_t* currentNodeDistPage
static

Definition at line 147 of file cuddSubsetSP.c.

DdNode** currentQueuePage
static

Definition at line 154 of file cuddSubsetSP.c.

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

Definition at line 129 of file cuddSubsetSP.c.

int maxNodeDistPages
static

Definition at line 146 of file cuddSubsetSP.c.

int maxQueuePages
static

Definition at line 153 of file cuddSubsetSP.c.

int memOut
static

Definition at line 139 of file cuddSubsetSP.c.

int nodeDistPage
static

Definition at line 144 of file cuddSubsetSP.c.

int nodeDistPageIndex
static

Definition at line 143 of file cuddSubsetSP.c.

NodeDist_t** nodeDistPages
static

Definition at line 142 of file cuddSubsetSP.c.

int nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE
static

Definition at line 145 of file cuddSubsetSP.c.

DdNode * one
static

Definition at line 140 of file cuddSubsetSP.c.

int queuePage
static

Definition at line 151 of file cuddSubsetSP.c.

int queuePageIndex
static

Definition at line 150 of file cuddSubsetSP.c.

DdNode*** queuePages
static

Definition at line 149 of file cuddSubsetSP.c.

int queuePageSize = DEFAULT_PAGE_SIZE
static

Definition at line 152 of file cuddSubsetSP.c.

DdNode* zero
static

Definition at line 140 of file cuddSubsetSP.c.