src/bdd/cudd/cuddApprox.c File Reference

#include "util_hack.h"
#include "cuddInt.h"
Include dependency graph for cuddApprox.c:

Go to the source code of this file.

Data Structures

struct  NodeData
struct  ApproxInfo
struct  GlobalQueueItem
struct  LocalQueueItem

Defines

#define DBL_MAX_EXP   1024
#define NOTHING   0
#define REPLACE_T   1
#define REPLACE_E   2
#define REPLACE_N   3
#define REPLACE_TT   4
#define REPLACE_TE   5
#define DONT_CARE   0
#define CARE   1
#define TOTAL_CARE   2
#define CARE_ERROR   3

Functions

static void updateParity ARGS ((DdNode *node, ApproxInfo *info, int newparity))
static NodeData *gatherInfoAux ARGS ((DdNode *node, ApproxInfo *info, int parity))
static ApproxInfo *gatherInfo ARGS ((DdManager *dd, DdNode *node, int numVars, int parity))
static int computeSavings ARGS ((DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue))
static int UAmarkNodes ARGS ((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality))
static DdNode *UAbuildSubset ARGS ((DdManager *dd, DdNode *node, ApproxInfo *info))
static int RAmarkNodes ARGS ((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality))
static int BAmarkNodes ARGS ((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0))
static int BAapplyBias ARGS ((DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache))
DdNodeCudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)
DdNodeCudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)
DdNodeCudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
DdNodeCudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
DdNodeCudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)
DdNodeCudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)
DdNodecuddUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)
DdNodecuddRemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
DdNodecuddBiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)
static void updateParity (DdNode *node, ApproxInfo *info, int newparity)
static NodeDatagatherInfoAux (DdNode *node, ApproxInfo *info, int parity)
static ApproxInfogatherInfo (DdManager *dd, DdNode *node, int numVars, int parity)
static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)
static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)
static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality)
static DdNodeUAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info)
static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality)
static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0)
static DdNodeRAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info)
static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"

Define Documentation

#define CARE   1

Definition at line 69 of file cuddApprox.c.

#define CARE_ERROR   3

Definition at line 71 of file cuddApprox.c.

#define DBL_MAX_EXP   1024

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

FileName [cuddApprox.c]

PackageName [cudd]

Synopsis [Procedures to approximate a given BDD.]

Description [External procedures provided by this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c]

Author [Fabio Somenzi]

Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]

Definition at line 52 of file cuddApprox.c.

#define DONT_CARE   0

Definition at line 68 of file cuddApprox.c.

#define NOTHING   0

Definition at line 61 of file cuddApprox.c.

#define REPLACE_E   2

Definition at line 63 of file cuddApprox.c.

#define REPLACE_N   3

Definition at line 64 of file cuddApprox.c.

#define REPLACE_T   1

Definition at line 62 of file cuddApprox.c.

#define REPLACE_TE   5

Definition at line 66 of file cuddApprox.c.

#define REPLACE_TT   4

Definition at line 65 of file cuddApprox.c.

#define TOTAL_CARE   2

Definition at line 70 of file cuddApprox.c.


Function Documentation

static int BAapplyBias ARGS ( (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache)   )  [static]
static int BAmarkNodes ARGS ( (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0)   )  [static]
static int RAmarkNodes ARGS ( (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality)   )  [static]
static DdNode *RAbuildSubset ARGS ( (DdManager *dd, DdNode *node, ApproxInfo *info)   )  [static]
static int UAmarkNodes ARGS ( (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality)   )  [static]
static int updateRefs ARGS ( (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)   )  [static]
static ApproxInfo* gatherInfo ARGS ( (DdManager *dd, DdNode *node, int numVars, int parity)   )  [static]
static NodeData* gatherInfoAux ARGS ( (DdNode *node, ApproxInfo *info, int parity)   )  [static]
static void updateParity ARGS ( (DdNode *node, ApproxInfo *info, int newparity)   )  [static]

AutomaticStart

static int BAapplyBias ( DdManager dd,
DdNode f,
DdNode b,
ApproxInfo info,
DdHashTable cache 
) [static]

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

Synopsis [Finds don't care nodes.]

Description [Finds don't care nodes by traversing f and b in parallel. Returns the care status of the visited f node if successful; CARE_ERROR otherwise.]

SideEffects [None]

SeeAlso [cuddBiasedUnderApprox]

Definition at line 2121 of file cuddApprox.c.

02127 {
02128     DdNode *one, *zero, *res;
02129     DdNode *Ft, *Fe, *B, *Bt, *Be;
02130     unsigned int topf, topb;
02131     NodeData *infoF;
02132     int careT, careE;
02133 
02134     one = DD_ONE(dd);
02135     zero = Cudd_Not(one);
02136 
02137     if (!st_lookup(info->table, (char *) f, (char **)&infoF))
02138         return(CARE_ERROR);
02139     if (f == one) return(TOTAL_CARE);
02140     if (b == zero) return(infoF->care);
02141     if (infoF->care == TOTAL_CARE) return(TOTAL_CARE);
02142 
02143     if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) &&
02144         (res = cuddHashTableLookup2(cache,f,b)) != NULL) {
02145         if (res->ref == 0) {
02146             cache->manager->dead++;
02147             cache->manager->constants.dead++;
02148         }
02149         return(infoF->care);
02150     }
02151 
02152     topf = dd->perm[f->index];
02153     B = Cudd_Regular(b);
02154     topb = cuddI(dd,B->index);
02155     if (topf <= topb) {
02156         Ft = cuddT(f); Fe = cuddE(f);
02157     } else {
02158         Ft = Fe = f;
02159     }
02160     if (topb <= topf) {
02161         /* We know that b is not constant because f is not. */
02162         Bt = cuddT(B); Be = cuddE(B);
02163         if (Cudd_IsComplement(b)) {
02164             Bt = Cudd_Not(Bt);
02165             Be = Cudd_Not(Be);
02166         }
02167     } else {
02168         Bt = Be = b;
02169     }
02170 
02171     careT = BAapplyBias(dd, Ft, Bt, info, cache);
02172     if (careT == CARE_ERROR)
02173         return(CARE_ERROR);
02174     careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache);
02175     if (careE == CARE_ERROR)
02176         return(CARE_ERROR);
02177     if (careT == TOTAL_CARE && careE == TOTAL_CARE) {
02178         infoF->care = TOTAL_CARE;
02179     } else {
02180         infoF->care = CARE;
02181     }
02182 
02183     if (f->ref != 1 || Cudd_Regular(b)->ref != 1) {
02184         ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref;
02185         cuddSatDec(fanout);
02186         if (!cuddHashTableInsert2(cache,f,b,one,fanout)) {
02187             return(CARE_ERROR);
02188         }
02189     }
02190     return(infoF->care);
02191 
02192 } /* end of BAapplyBias */

static int BAmarkNodes ( DdManager dd,
DdNode f,
ApproxInfo info,
int  threshold,
double  quality1,
double  quality0 
) [static]

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

Synopsis [Marks nodes for remapping.]

Description [Marks nodes for remapping. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddRemapUnderApprox]

Definition at line 1655 of file cuddApprox.c.

01662 {
01663     DdLevelQueue *queue;
01664     DdLevelQueue *localQueue;
01665     NodeData *infoN, *infoT, *infoE;
01666     GlobalQueueItem *item;
01667     DdNode *node, *T, *E;
01668     DdNode *shared; /* grandchild shared by the two children of node */
01669     double numOnset;
01670     double impact, impactP, impactN;
01671     double minterms;
01672     double quality;
01673     int savings;
01674     int replace;
01675 
01676 #if 0
01677     (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n",
01678                   info->size, info->minterms);
01679 #endif
01680     queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size);
01681     if (queue == NULL) {
01682         return(0);
01683     }
01684     localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem),
01685                                     dd->initSlots);
01686     if (localQueue == NULL) {
01687         cuddLevelQueueQuit(queue);
01688         return(0);
01689     }
01690     /* Enqueue regular pointer to root and initialize impact. */
01691     node = Cudd_Regular(f);
01692     item = (GlobalQueueItem *)
01693         cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index));
01694     if (item == NULL) {
01695         cuddLevelQueueQuit(queue);
01696         cuddLevelQueueQuit(localQueue);
01697         return(0);
01698     }
01699     if (Cudd_IsComplement(f)) {
01700         item->impactP = 0.0;
01701         item->impactN = 1.0;
01702     } else {
01703         item->impactP = 1.0;
01704         item->impactN = 0.0;
01705     }
01706     /* The nodes retrieved here are guaranteed to be non-terminal.
01707     ** The initial node is not terminal because constant nodes are
01708     ** dealt with in the calling procedure. Subsequent nodes are inserted
01709     ** only if they are not terminal. */
01710     while (queue->first != NULL) {
01711         /* If the size of the subset is below the threshold, quit. */
01712         if (info->size <= threshold)
01713             break;
01714         item = (GlobalQueueItem *) queue->first;
01715         node = item->node;
01716 #ifdef DD_DEBUG
01717         assert(item->impactP >= 0 && item->impactP <= 1.0);
01718         assert(item->impactN >= 0 && item->impactN <= 1.0);
01719         assert(!Cudd_IsComplement(node));
01720         assert(!Cudd_IsConstant(node));
01721 #endif
01722         if (!st_lookup(info->table, (char *)node, (char **)&infoN)) {
01723             cuddLevelQueueQuit(queue);
01724             cuddLevelQueueQuit(localQueue);
01725             return(0);
01726         }
01727         quality = infoN->care ? quality1 : quality0;
01728 #ifdef DD_DEBUG
01729         assert(infoN->parity >= 1 && infoN->parity <= 3);
01730 #endif
01731         if (infoN->parity == 3) {
01732             /* This node can be reached through paths of different parity.
01733             ** It is not safe to replace it, because remapping will give
01734             ** an incorrect result, while replacement by 0 may cause node
01735             ** splitting. */
01736             cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01737             continue;
01738         }
01739         T = cuddT(node);
01740         E = cuddE(node);
01741         shared = NULL;
01742         impactP = item->impactP;
01743         impactN = item->impactN;
01744         if (Cudd_bddLeq(dd,T,E)) {
01745             /* Here we know that E is regular. */
01746 #ifdef DD_DEBUG
01747             assert(!Cudd_IsComplement(E));
01748 #endif
01749             (void) st_lookup(info->table, (char *)T, (char **)&infoT);
01750             (void) st_lookup(info->table, (char *)E, (char **)&infoE);
01751             if (infoN->parity == 1) {
01752                 impact = impactP;
01753                 minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0;
01754                 if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) {
01755                     savings = 1 + computeSavings(dd,E,NULL,info,localQueue);
01756                     if (savings == 1) {
01757                         cuddLevelQueueQuit(queue);
01758                         cuddLevelQueueQuit(localQueue);
01759                         return(0);
01760                     }
01761                 } else {
01762                     savings = 1;
01763                 }
01764                 replace = REPLACE_E;
01765             } else {
01766 #ifdef DD_DEBUG
01767                 assert(infoN->parity == 2);
01768 #endif
01769                 impact = impactN;
01770                 minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0;
01771                 if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) {
01772                     savings = 1 + computeSavings(dd,T,NULL,info,localQueue);
01773                     if (savings == 1) {
01774                         cuddLevelQueueQuit(queue);
01775                         cuddLevelQueueQuit(localQueue);
01776                         return(0);
01777                     }
01778                 } else {
01779                     savings = 1;
01780                 }
01781                 replace = REPLACE_T;
01782             }
01783             numOnset = impact * minterms;
01784         } else if (Cudd_bddLeq(dd,E,T)) {
01785             /* Here E may be complemented. */
01786             DdNode *Ereg = Cudd_Regular(E);
01787             (void) st_lookup(info->table, (char *)T, (char **)&infoT);
01788             (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE);
01789             if (infoN->parity == 1) {
01790                 impact = impactP;
01791                 minterms = infoT->mintermsP/2.0 -
01792                     ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0;
01793                 if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) {
01794                     savings = 1 + computeSavings(dd,T,NULL,info,localQueue);
01795                     if (savings == 1) {
01796                         cuddLevelQueueQuit(queue);
01797                         cuddLevelQueueQuit(localQueue);
01798                         return(0);
01799                     }
01800                 } else {
01801                     savings = 1;
01802                 }
01803                 replace = REPLACE_T;
01804             } else {
01805 #ifdef DD_DEBUG
01806                 assert(infoN->parity == 2);
01807 #endif
01808                 impact = impactN;
01809                 minterms = ((E == Ereg) ? infoE->mintermsN :
01810                             infoE->mintermsP)/2.0 - infoT->mintermsN/2.0;
01811                 if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) {
01812                     savings = 1 + computeSavings(dd,E,NULL,info,localQueue);
01813                     if (savings == 1) {
01814                         cuddLevelQueueQuit(queue);
01815                         cuddLevelQueueQuit(localQueue);
01816                         return(0);
01817                     }
01818                 } else {
01819                     savings = 1;
01820                 }
01821                 replace = REPLACE_E;
01822             }
01823             numOnset = impact * minterms;
01824         } else {
01825             DdNode *Ereg = Cudd_Regular(E);
01826             DdNode *TT = cuddT(T);
01827             DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E));
01828             if (T->index == Ereg->index && TT == ET) {
01829                 shared = TT;
01830                 replace = REPLACE_TT;
01831             } else {
01832                 DdNode *TE = cuddE(T);
01833                 DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E));
01834                 if (T->index == Ereg->index && TE == EE) {
01835                     shared = TE;
01836                     replace = REPLACE_TE;
01837                 } else {
01838                     replace = REPLACE_N;
01839                 }
01840             }
01841             numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN;
01842             savings = computeSavings(dd,node,shared,info,localQueue);
01843             if (shared != NULL) {
01844                 NodeData *infoS;
01845                 (void) st_lookup(info->table, (char *)Cudd_Regular(shared),
01846                                  (char **)&infoS);
01847                 if (Cudd_IsComplement(shared)) {
01848                     numOnset -= (infoS->mintermsN * impactP +
01849                         infoS->mintermsP * impactN)/2.0;
01850                 } else {
01851                     numOnset -= (infoS->mintermsP * impactP +
01852                         infoS->mintermsN * impactN)/2.0;
01853                 }
01854                 savings--;
01855             }
01856         }
01857 
01858         cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01859 #if 0
01860         if (replace == REPLACE_T || replace == REPLACE_E)
01861             (void) printf("node %p: impact = %g numOnset = %g savings %d\n",
01862                           node, impact, numOnset, savings);
01863         else
01864             (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n",
01865                           node, impactP, impactN, numOnset, savings);
01866 #endif
01867         if ((1 - numOnset / info->minterms) >
01868             quality * (1 - (double) savings / info->size)) {
01869             infoN->replace = replace;
01870             info->size -= savings;
01871             info->minterms -=numOnset;
01872 #if 0
01873             (void) printf("remap(%d): new size = %d new minterms = %g\n",
01874                           replace, info->size, info->minterms);
01875 #endif
01876             if (replace == REPLACE_N) {
01877                 savings -= updateRefs(dd,node,NULL,info,localQueue);
01878             } else if (replace == REPLACE_T) {
01879                 savings -= updateRefs(dd,node,E,info,localQueue);
01880             } else if (replace == REPLACE_E) {
01881                 savings -= updateRefs(dd,node,T,info,localQueue);
01882             } else {
01883 #ifdef DD_DEBUG
01884                 assert(replace == REPLACE_TT || replace == REPLACE_TE);
01885 #endif
01886                 savings -= updateRefs(dd,node,shared,info,localQueue) - 1;
01887             }
01888             assert(savings == 0);
01889         } else {
01890             replace = NOTHING;
01891         }
01892         if (replace == REPLACE_N) continue;
01893         if ((replace == REPLACE_E || replace == NOTHING) &&
01894             !cuddIsConstant(cuddT(node))) {
01895             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node),
01896                                          cuddI(dd,cuddT(node)->index));
01897             if (replace == REPLACE_E) {
01898                 item->impactP += impactP;
01899                 item->impactN += impactN;
01900             } else {
01901                 item->impactP += impactP/2.0;
01902                 item->impactN += impactN/2.0;
01903             }
01904         }
01905         if ((replace == REPLACE_T || replace == NOTHING) &&
01906             !Cudd_IsConstant(cuddE(node))) {
01907             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)),
01908                                          cuddI(dd,Cudd_Regular(cuddE(node))->index));
01909             if (Cudd_IsComplement(cuddE(node))) {
01910                 if (replace == REPLACE_T) {
01911                     item->impactP += impactN;
01912                     item->impactN += impactP;
01913                 } else {
01914                     item->impactP += impactN/2.0;
01915                     item->impactN += impactP/2.0;
01916                 }
01917             } else {
01918                 if (replace == REPLACE_T) {
01919                     item->impactP += impactP;
01920                     item->impactN += impactN;
01921                 } else {
01922                     item->impactP += impactP/2.0;
01923                     item->impactN += impactN/2.0;
01924                 }
01925             }
01926         }
01927         if ((replace == REPLACE_TT || replace == REPLACE_TE) &&
01928             !Cudd_IsConstant(shared)) {
01929             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared),
01930                                          cuddI(dd,Cudd_Regular(shared)->index));
01931             if (Cudd_IsComplement(shared)) {
01932                 if (replace == REPLACE_T) {
01933                     item->impactP += impactN;
01934                     item->impactN += impactP;
01935                 } else {
01936                     item->impactP += impactN/2.0;
01937                     item->impactN += impactP/2.0;
01938                 }
01939             } else {
01940                 if (replace == REPLACE_T) {
01941                     item->impactP += impactP;
01942                     item->impactN += impactN;
01943                 } else {
01944                     item->impactP += impactP/2.0;
01945                     item->impactN += impactN/2.0;
01946                 }
01947             }
01948         }
01949     }
01950 
01951     cuddLevelQueueQuit(queue);
01952     cuddLevelQueueQuit(localQueue);
01953     return(1);
01954 
01955 } /* end of BAmarkNodes */

static int computeSavings ( DdManager dd,
DdNode f,
DdNode skip,
ApproxInfo info,
DdLevelQueue queue 
) [static]

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

Synopsis [Counts the nodes that would be eliminated if a given node were replaced by zero.]

Description [Counts the nodes that would be eliminated if a given node were replaced by zero. This procedure uses a queue passed by the caller for efficiency: since the queue is left empty at the endof the search, it can be reused as is by the next search. Returns the count (always striclty positive) if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddUnderApprox]

Definition at line 970 of file cuddApprox.c.

00976 {
00977     NodeData *infoN;
00978     LocalQueueItem *item;
00979     DdNode *node;
00980     int savings = 0;
00981 
00982     node = Cudd_Regular(f);
00983     skip = Cudd_Regular(skip);
00984     /* Insert the given node in the level queue. Its local reference
00985     ** count is set equal to the function reference count so that the
00986     ** search will continue from it when it is retrieved. */
00987     item = (LocalQueueItem *)
00988         cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index));
00989     if (item == NULL)
00990         return(0);
00991     (void) st_lookup(info->table, (char *)node, (char **)&infoN);
00992     item->localRef = infoN->functionRef;
00993 
00994     /* Process the queue. */
00995     while (queue->first != NULL) {
00996         item = (LocalQueueItem *) queue->first;
00997         node = item->node;
00998         cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
00999         if (node == skip) continue;
01000         (void) st_lookup(info->table, (char *)node, (char **)&infoN);
01001         if (item->localRef != infoN->functionRef) {
01002             /* This node is shared. */
01003             continue;
01004         }
01005         savings++;
01006         if (!cuddIsConstant(cuddT(node))) {
01007             item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node),
01008                                          cuddI(dd,cuddT(node)->index));
01009             if (item == NULL) return(0);
01010             item->localRef++;
01011         }
01012         if (!Cudd_IsConstant(cuddE(node))) {
01013             item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)),
01014                                          cuddI(dd,Cudd_Regular(cuddE(node))->index));
01015             if (item == NULL) return(0);
01016             item->localRef++;
01017         }
01018     }
01019 
01020 #ifdef DD_DEBUG
01021     /* At the end of a local search the queue should be empty. */
01022     assert(queue->size == 0);
01023 #endif
01024     return(savings);
01025 
01026 } /* end of computeSavings */

DdNode* Cudd_BiasedOverApprox ( DdManager dd,
DdNode f,
DdNode b,
int  numVars,
int  threshold,
double  quality1,
double  quality0 
)

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

Synopsis [Extracts a dense superset from a BDD with the biased underapproximation method.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize]

Definition at line 432 of file cuddApprox.c.

00440 {
00441     DdNode *subset, *g;
00442 
00443     g = Cudd_Not(f);    
00444     do {
00445         dd->reordered = 0;
00446         subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1,
00447                                       quality0);
00448     } while (dd->reordered == 1);
00449     
00450     return(Cudd_NotCond(subset, (subset != NULL)));
00451     
00452 } /* end of Cudd_BiasedOverApprox */

DdNode* Cudd_BiasedUnderApprox ( DdManager dd,
DdNode f,
DdNode b,
int  numVars,
int  threshold,
double  quality1,
double  quality0 
)

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

Synopsis [Extracts a dense subset from a BDD with the biased underapproximation method.]

Description [Extracts a dense subset from a BDD. This procedure uses a biased remapping technique and density as the cost function. The bias is a function. This procedure tries to approximate where the bias is 0 and preserve the given function where the bias is 1. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_RemapUnderApprox Cudd_ReadSize]

Definition at line 382 of file cuddApprox.c.

00390 {
00391     DdNode *subset;
00392 
00393     do {
00394         dd->reordered = 0;
00395         subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1,
00396                                        quality0);
00397     } while (dd->reordered == 1);
00398 
00399     return(subset);
00400 
00401 } /* end of Cudd_BiasedUnderApprox */

DdNode* Cudd_OverApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  safe,
double  quality 
)

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

Synopsis [Extracts a dense superset from a BDD with Shiple's underapproximation method.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]

Definition at line 244 of file cuddApprox.c.

00251 {
00252     DdNode *subset, *g;
00253 
00254     g = Cudd_Not(f);    
00255     do {
00256         dd->reordered = 0;
00257         subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality);
00258     } while (dd->reordered == 1);
00259     
00260     return(Cudd_NotCond(subset, (subset != NULL)));
00261     
00262 } /* end of Cudd_OverApprox */

DdNode* Cudd_RemapOverApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
double  quality 
)

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

Synopsis [Extracts a dense superset from a BDD with the remapping underapproximation method.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]

Definition at line 335 of file cuddApprox.c.

00341 {
00342     DdNode *subset, *g;
00343 
00344     g = Cudd_Not(f);    
00345     do {
00346         dd->reordered = 0;
00347         subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality);
00348     } while (dd->reordered == 1);
00349     
00350     return(Cudd_NotCond(subset, (subset != NULL)));
00351     
00352 } /* end of Cudd_RemapOverApprox */

DdNode* Cudd_RemapUnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
double  quality 
)

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

Synopsis [Extracts a dense subset from a BDD with the remapping underapproximation method.]

Description [Extracts a dense subset from a BDD. This procedure uses a remapping technique and density as the cost function. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize]

Definition at line 289 of file cuddApprox.c.

00295 {
00296     DdNode *subset;
00297 
00298     do {
00299         dd->reordered = 0;
00300         subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality);
00301     } while (dd->reordered == 1);
00302 
00303     return(subset);
00304 
00305 } /* end of Cudd_RemapUnderApprox */

DdNode* Cudd_UnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  safe,
double  quality 
)

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

Synopsis [Extracts a dense subset from a BDD with Shiple's underapproximation method.]

Description [Extracts a dense subset from a BDD. This procedure uses a variant of Tom Shiple's underapproximation method. The main difference from the original method is that density is used as cost function. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]

Definition at line 197 of file cuddApprox.c.

00204 {
00205     DdNode *subset;
00206 
00207     do {
00208         dd->reordered = 0;
00209         subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality);
00210     } while (dd->reordered == 1);
00211 
00212     return(subset);
00213 
00214 } /* end of Cudd_UnderApprox */

DdNode* cuddBiasedUnderApprox ( DdManager dd,
DdNode f,
DdNode b,
int  numVars,
int  threshold,
double  quality1,
double  quality0 
)

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

Synopsis [Applies the biased remapping underappoximation algorithm.]

Description [Applies the biased remapping underappoximation algorithm. Proceeds in three phases:

  • collect information on each node in the BDD; this is done via DFS.
  • traverse the BDD in top-down fashion and compute for each node whether remapping increases density.
  • traverse the BDD via DFS and actually perform the elimination.

Returns the approximated BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_BiasedUnderApprox]

Definition at line 660 of file cuddApprox.c.

00668 {
00669     ApproxInfo *info;
00670     DdNode *subset;
00671     int result;
00672     DdHashTable *cache;
00673 
00674     if (f == NULL) {
00675         fprintf(dd->err, "Cannot subset, nil object\n");
00676         dd->errorCode = CUDD_INVALID_ARG;
00677         return(NULL);
00678     }
00679 
00680     if (Cudd_IsConstant(f)) {
00681         return(f);
00682     }
00683 
00684     /* Create table where node data are accessible via a hash table. */
00685     info = gatherInfo(dd, f, numVars, TRUE);
00686     if (info == NULL) {
00687         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00688         dd->errorCode = CUDD_MEMORY_OUT;
00689         return(NULL);
00690     }
00691 
00692     cache = cuddHashTableInit(dd,2,2);
00693     result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache);
00694     if (result == CARE_ERROR) {
00695         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00696         cuddHashTableQuit(cache);
00697         FREE(info->page);
00698         st_free_table(info->table);
00699         FREE(info);
00700         dd->errorCode = CUDD_MEMORY_OUT;
00701         return(NULL);
00702     }
00703     cuddHashTableQuit(cache);
00704 
00705     /* Mark nodes that should be replaced by zero. */
00706     result = BAmarkNodes(dd, f, info, threshold, quality1, quality0);
00707     if (result == 0) {
00708         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00709         FREE(info->page);
00710         st_free_table(info->table);
00711         FREE(info);
00712         dd->errorCode = CUDD_MEMORY_OUT;
00713         return(NULL);
00714     }
00715 
00716     /* Build the result. */
00717     subset = RAbuildSubset(dd, f, info);
00718 #if 1
00719     if (subset && info->size < Cudd_DagSize(subset))
00720         (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n",
00721                        info->size, Cudd_DagSize(subset));
00722 #endif
00723     FREE(info->page);
00724     st_free_table(info->table);
00725     FREE(info);
00726 
00727 #ifdef DD_DEBUG
00728     if (subset != NULL) {
00729         cuddRef(subset);
00730 #if 0
00731         (void) Cudd_DebugCheck(dd);
00732         (void) Cudd_CheckKeys(dd);
00733 #endif
00734         if (!Cudd_bddLeq(dd, subset, f)) {
00735             (void) fprintf(dd->err, "Wrong subset\n");
00736         }
00737         cuddDeref(subset);
00738         dd->errorCode = CUDD_INTERNAL_ERROR;
00739     }
00740 #endif
00741     return(subset);
00742 
00743 } /* end of cuddBiasedUnderApprox */

DdNode* cuddRemapUnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
double  quality 
)

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

Synopsis [Applies the remapping underappoximation algorithm.]

Description [Applies the remapping underappoximation algorithm. Proceeds in three phases:

  • collect information on each node in the BDD; this is done via DFS.
  • traverse the BDD in top-down fashion and compute for each node whether remapping increases density.
  • traverse the BDD via DFS and actually perform the elimination.

Returns the approximated BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_RemapUnderApprox]

Definition at line 570 of file cuddApprox.c.

00576 {
00577     ApproxInfo *info;
00578     DdNode *subset;
00579     int result;
00580 
00581     if (f == NULL) {
00582         fprintf(dd->err, "Cannot subset, nil object\n");
00583         dd->errorCode = CUDD_INVALID_ARG;
00584         return(NULL);
00585     }
00586 
00587     if (Cudd_IsConstant(f)) {
00588         return(f);
00589     }
00590 
00591     /* Create table where node data are accessible via a hash table. */
00592     info = gatherInfo(dd, f, numVars, TRUE);
00593     if (info == NULL) {
00594         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00595         dd->errorCode = CUDD_MEMORY_OUT;
00596         return(NULL);
00597     }
00598 
00599     /* Mark nodes that should be replaced by zero. */
00600     result = RAmarkNodes(dd, f, info, threshold, quality);
00601     if (result == 0) {
00602         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00603         FREE(info->page);
00604         st_free_table(info->table);
00605         FREE(info);
00606         dd->errorCode = CUDD_MEMORY_OUT;
00607         return(NULL);
00608     }
00609 
00610     /* Build the result. */
00611     subset = RAbuildSubset(dd, f, info);
00612 #if 1
00613     if (subset && info->size < Cudd_DagSize(subset))
00614         (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n",
00615                        info->size, Cudd_DagSize(subset));
00616 #endif
00617     FREE(info->page);
00618     st_free_table(info->table);
00619     FREE(info);
00620 
00621 #ifdef DD_DEBUG
00622     if (subset != NULL) {
00623         cuddRef(subset);
00624 #if 0
00625         (void) Cudd_DebugCheck(dd);
00626         (void) Cudd_CheckKeys(dd);
00627 #endif
00628         if (!Cudd_bddLeq(dd, subset, f)) {
00629             (void) fprintf(dd->err, "Wrong subset\n");
00630         }
00631         cuddDeref(subset);
00632         dd->errorCode = CUDD_INTERNAL_ERROR;
00633     }
00634 #endif
00635     return(subset);
00636 
00637 } /* end of cuddRemapUnderApprox */

DdNode* cuddUnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  safe,
double  quality 
)

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

Synopsis [Applies Tom Shiple's underappoximation algorithm.]

Description [Applies Tom Shiple's underappoximation algorithm. Proceeds in three phases:

  • collect information on each node in the BDD; this is done via DFS.
  • traverse the BDD in top-down fashion and compute for each node whether its elimination increases density.
  • traverse the BDD via DFS and actually perform the elimination.

Returns the approximated BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_UnderApprox]

Definition at line 480 of file cuddApprox.c.

00487 {
00488     ApproxInfo *info;
00489     DdNode *subset;
00490     int result;
00491 
00492     if (f == NULL) {
00493         fprintf(dd->err, "Cannot subset, nil object\n");
00494         return(NULL);
00495     }
00496 
00497     if (Cudd_IsConstant(f)) {
00498         return(f);
00499     }
00500 
00501     /* Create table where node data are accessible via a hash table. */
00502     info = gatherInfo(dd, f, numVars, safe);
00503     if (info == NULL) {
00504         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00505         dd->errorCode = CUDD_MEMORY_OUT;
00506         return(NULL);
00507     }
00508 
00509     /* Mark nodes that should be replaced by zero. */
00510     result = UAmarkNodes(dd, f, info, threshold, safe, quality);
00511     if (result == 0) {
00512         (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
00513         FREE(info->page);
00514         st_free_table(info->table);
00515         FREE(info);
00516         dd->errorCode = CUDD_MEMORY_OUT;
00517         return(NULL);
00518     }
00519 
00520     /* Build the result. */
00521     subset = UAbuildSubset(dd, f, info);
00522 #if 1
00523     if (subset && info->size < Cudd_DagSize(subset))
00524         (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n",
00525                        info->size, Cudd_DagSize(subset));
00526 #endif
00527     FREE(info->page);
00528     st_free_table(info->table);
00529     FREE(info);
00530 
00531 #ifdef DD_DEBUG
00532     if (subset != NULL) {
00533         cuddRef(subset);
00534 #if 0
00535         (void) Cudd_DebugCheck(dd);
00536         (void) Cudd_CheckKeys(dd);
00537 #endif
00538         if (!Cudd_bddLeq(dd, subset, f)) {
00539             (void) fprintf(dd->err, "Wrong subset\n");
00540             dd->errorCode = CUDD_INTERNAL_ERROR;
00541         }
00542         cuddDeref(subset);
00543     }
00544 #endif
00545     return(subset);
00546 
00547 } /* end of cuddUnderApprox */

static ApproxInfo* gatherInfo ( DdManager dd,
DdNode node,
int  numVars,
int  parity 
) [static]

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

Synopsis [Gathers information about each node.]

Description [Counts minterms and computes reference counts of each node in the BDD . The minterm count is separately computed for the node and its complement. This is to avoid cancellation errors. Returns a pointer to the data structure holding the information gathered if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddUnderApprox gatherInfoAux]

Definition at line 876 of file cuddApprox.c.

00881 {
00882     ApproxInfo  *info;
00883     NodeData *infoTop;
00884 
00885     /* If user did not give numVars value, set it to the maximum
00886     ** exponent that the pow function can take. The -1 is due to the
00887     ** discrepancy in the value that pow takes and the value that
00888     ** log gives.
00889     */
00890     if (numVars == 0) {
00891         numVars = DBL_MAX_EXP - 1;
00892     }
00893 
00894     info = ALLOC(ApproxInfo,1);
00895     if (info == NULL) {
00896         dd->errorCode = CUDD_MEMORY_OUT;
00897         return(NULL);
00898     }
00899     info->max = pow(2.0,(double) numVars);
00900     info->one = DD_ONE(dd);
00901     info->zero = Cudd_Not(info->one);
00902     info->size = Cudd_DagSize(node);
00903     /* All the information gathered will be stored in a contiguous
00904     ** piece of memory, which is allocated here. This can be done
00905     ** efficiently because we have counted the number of nodes of the
00906     ** BDD. info->index points to the next available entry in the array
00907     ** that stores the per-node information. */
00908     info->page = ALLOC(NodeData,info->size);
00909     if (info->page == NULL) {
00910         dd->errorCode = CUDD_MEMORY_OUT;
00911         FREE(info);
00912         return(NULL);
00913     }
00914     memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */
00915     info->table = st_init_table(st_ptrcmp,st_ptrhash);
00916     if (info->table == NULL) {
00917         FREE(info->page);
00918         FREE(info);
00919         return(NULL);
00920     }
00921     /* We visit the DAG in post-order DFS. Hence, the constant node is
00922     ** in first position, and the root of the DAG is in last position. */
00923 
00924     /* Info for the constant node: Initialize only fields different from 0. */
00925     if (st_insert(info->table, (char *)info->one, (char *)info->page) == ST_OUT_OF_MEM) {
00926         FREE(info->page);
00927         FREE(info);
00928         st_free_table(info->table);
00929         return(NULL);
00930     }
00931     info->page[0].mintermsP = info->max;
00932     info->index = 1;
00933 
00934     infoTop = gatherInfoAux(node,info,parity);
00935     if (infoTop == NULL) {
00936         FREE(info->page);
00937         st_free_table(info->table);
00938         FREE(info);
00939         return(NULL);
00940     }
00941     if (Cudd_IsComplement(node)) {
00942         info->minterms = infoTop->mintermsN;
00943     } else {
00944         info->minterms = infoTop->mintermsP;
00945     }
00946 
00947     infoTop->functionRef = 1;
00948     return(info);
00949 
00950 } /* end of gatherInfo */

static NodeData* gatherInfoAux ( DdNode node,
ApproxInfo info,
int  parity 
) [static]

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

Synopsis [Recursively counts minterms and computes reference counts of each node in the BDD.]

Description [Recursively counts minterms and computes reference counts of each node in the BDD. Similar to the cuddCountMintermAux which recursively counts the number of minterms for the dag rooted at each node in terms of the total number of variables (max). It assumes that the node pointer passed to it is regular and it maintains the invariant.]

SideEffects [None]

SeeAlso [gatherInfo]

Definition at line 806 of file cuddApprox.c.

00810 {
00811     DdNode      *N, *Nt, *Ne;
00812     NodeData    *infoN, *infoT, *infoE;
00813 
00814     N = Cudd_Regular(node);
00815 
00816     /* Check whether entry for this node exists. */
00817     if (st_lookup(info->table, (char *)N, (char **)&infoN)) {
00818         if (parity) {
00819             /* Update parity and propagate. */
00820             updateParity(N, info, 1 +  (int) Cudd_IsComplement(node));
00821         }
00822         return(infoN);
00823     }
00824 
00825     /* Compute the cofactors. */
00826     Nt = Cudd_NotCond(cuddT(N), N != node);
00827     Ne = Cudd_NotCond(cuddE(N), N != node);
00828 
00829     infoT = gatherInfoAux(Nt, info, parity);
00830     if (infoT == NULL) return(NULL);
00831     infoE = gatherInfoAux(Ne, info, parity);
00832     if (infoE == NULL) return(NULL);
00833 
00834     infoT->functionRef++;
00835     infoE->functionRef++;
00836 
00837     /* Point to the correct location in the page. */
00838     infoN = &(info->page[info->index++]);
00839     infoN->parity |= 1 + (short) Cudd_IsComplement(node);
00840 
00841     infoN->mintermsP = infoT->mintermsP/2;
00842     infoN->mintermsN = infoT->mintermsN/2;
00843     if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) {
00844         infoN->mintermsP += infoE->mintermsN/2;
00845         infoN->mintermsN += infoE->mintermsP/2;
00846     } else {
00847         infoN->mintermsP += infoE->mintermsP/2;
00848         infoN->mintermsN += infoE->mintermsN/2;
00849     }
00850 
00851     /* Insert entry for the node in the table. */
00852     if (st_insert(info->table,(char *)N, (char *)infoN) == ST_OUT_OF_MEM) {
00853         return(NULL);
00854     }
00855     return(infoN);
00856 
00857 } /* end of gatherInfoAux */

static DdNode* RAbuildSubset ( DdManager dd,
DdNode node,
ApproxInfo info 
) [static]

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

Synopsis [Builds the subset BDD for cuddRemapUnderApprox.]

Description [Builds the subset BDDfor cuddRemapUnderApprox. Based on the info table, performs remapping or replacement at selected nodes. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddRemapUnderApprox]

Definition at line 1973 of file cuddApprox.c.

01977 {
01978     DdNode *Nt, *Ne, *N, *t, *e, *r;
01979     NodeData *infoN;
01980 
01981     if (Cudd_IsConstant(node))
01982         return(node);
01983 
01984     N = Cudd_Regular(node);
01985 
01986     Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node));
01987     Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node));
01988 
01989     if (st_lookup(info->table, (char *)N, (char **)&infoN)) {
01990         if (N == node ) {
01991             if (infoN->resultP != NULL) {
01992                 return(infoN->resultP);
01993             }
01994         } else {
01995             if (infoN->resultN != NULL) {
01996                 return(infoN->resultN);
01997             }
01998         }
01999         if (infoN->replace == REPLACE_T) {
02000             r = RAbuildSubset(dd, Ne, info);
02001             return(r);
02002         } else if (infoN->replace == REPLACE_E) {
02003             r = RAbuildSubset(dd, Nt, info);
02004             return(r);
02005         } else if (infoN->replace == REPLACE_N) {
02006             return(info->zero);
02007         } else if (infoN->replace == REPLACE_TT) {
02008             DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)),
02009                                        Cudd_IsComplement(node));
02010             int index = cuddT(N)->index;
02011             DdNode *e = info->zero;
02012             DdNode *t = RAbuildSubset(dd, Ntt, info);
02013             if (t == NULL) {
02014                 return(NULL);
02015             }
02016             cuddRef(t);
02017             if (Cudd_IsComplement(t)) {
02018                 t = Cudd_Not(t);
02019                 e = Cudd_Not(e);
02020                 r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
02021                 if (r == NULL) {
02022                     Cudd_RecursiveDeref(dd, t);
02023                     return(NULL);
02024                 }
02025                 r = Cudd_Not(r);
02026             } else {
02027                 r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
02028                 if (r == NULL) {
02029                     Cudd_RecursiveDeref(dd, t);
02030                     return(NULL);
02031                 }
02032             }
02033             cuddDeref(t);
02034             return(r);
02035         } else if (infoN->replace == REPLACE_TE) {
02036             DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)),
02037                                        Cudd_IsComplement(node));
02038             int index = cuddT(N)->index;
02039             DdNode *t = info->one;
02040             DdNode *e = RAbuildSubset(dd, Nte, info);
02041             if (e == NULL) {
02042                 return(NULL);
02043             }
02044             cuddRef(e);
02045             e = Cudd_Not(e);
02046             r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
02047             if (r == NULL) {
02048                 Cudd_RecursiveDeref(dd, e);
02049                 return(NULL);
02050             }
02051             r =Cudd_Not(r);
02052             cuddDeref(e);
02053             return(r);
02054         }
02055     } else {
02056         (void) fprintf(dd->err,
02057                        "Something is wrong, ought to be in info table\n");
02058         dd->errorCode = CUDD_INTERNAL_ERROR;
02059         return(NULL);
02060     }
02061 
02062     t = RAbuildSubset(dd, Nt, info);
02063     if (t == NULL) {
02064         return(NULL);
02065     }
02066     cuddRef(t);
02067 
02068     e = RAbuildSubset(dd, Ne, info);
02069     if (e == NULL) {
02070         Cudd_RecursiveDeref(dd,t);
02071         return(NULL);
02072     }
02073     cuddRef(e);
02074 
02075     if (Cudd_IsComplement(t)) {
02076         t = Cudd_Not(t);
02077         e = Cudd_Not(e);
02078         r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e);
02079         if (r == NULL) {
02080             Cudd_RecursiveDeref(dd, e);
02081             Cudd_RecursiveDeref(dd, t);
02082             return(NULL);
02083         }
02084         r = Cudd_Not(r);
02085     } else {
02086         r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e);
02087         if (r == NULL) {
02088             Cudd_RecursiveDeref(dd, e);
02089             Cudd_RecursiveDeref(dd, t);
02090             return(NULL);
02091         }
02092     }
02093     cuddDeref(t);
02094     cuddDeref(e);
02095 
02096     if (N == node) {
02097         infoN->resultP = r;
02098     } else {
02099         infoN->resultN = r;
02100     }
02101 
02102     return(r);
02103 
02104 } /* end of RAbuildSubset */

static int RAmarkNodes ( DdManager dd,
DdNode f,
ApproxInfo info,
int  threshold,
double  quality 
) [static]

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

Synopsis [Marks nodes for remapping.]

Description [Marks nodes for remapping. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddRemapUnderApprox]

Definition at line 1342 of file cuddApprox.c.

01348 {
01349     DdLevelQueue *queue;
01350     DdLevelQueue *localQueue;
01351     NodeData *infoN, *infoT, *infoE;
01352     GlobalQueueItem *item;
01353     DdNode *node, *T, *E;
01354     DdNode *shared; /* grandchild shared by the two children of node */
01355     double numOnset;
01356     double impact, impactP, impactN;
01357     double minterms;
01358     int savings;
01359     int replace;
01360 
01361 #if 0
01362     (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n",
01363                   info->size, info->minterms);
01364 #endif
01365     queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size);
01366     if (queue == NULL) {
01367         return(0);
01368     }
01369     localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem),
01370                                     dd->initSlots);
01371     if (localQueue == NULL) {
01372         cuddLevelQueueQuit(queue);
01373         return(0);
01374     }
01375     /* Enqueue regular pointer to root and initialize impact. */
01376     node = Cudd_Regular(f);
01377     item = (GlobalQueueItem *)
01378         cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index));
01379     if (item == NULL) {
01380         cuddLevelQueueQuit(queue);
01381         cuddLevelQueueQuit(localQueue);
01382         return(0);
01383     }
01384     if (Cudd_IsComplement(f)) {
01385         item->impactP = 0.0;
01386         item->impactN = 1.0;
01387     } else {
01388         item->impactP = 1.0;
01389         item->impactN = 0.0;
01390     }
01391     /* The nodes retrieved here are guaranteed to be non-terminal.
01392     ** The initial node is not terminal because constant nodes are
01393     ** dealt with in the calling procedure. Subsequent nodes are inserted
01394     ** only if they are not terminal. */
01395     while (queue->first != NULL) {
01396         /* If the size of the subset is below the threshold, quit. */
01397         if (info->size <= threshold)
01398             break;
01399         item = (GlobalQueueItem *) queue->first;
01400         node = item->node;
01401 #ifdef DD_DEBUG
01402         assert(item->impactP >= 0 && item->impactP <= 1.0);
01403         assert(item->impactN >= 0 && item->impactN <= 1.0);
01404         assert(!Cudd_IsComplement(node));
01405         assert(!Cudd_IsConstant(node));
01406 #endif
01407         if (!st_lookup(info->table, (char *)node, (char **)&infoN)) {
01408             cuddLevelQueueQuit(queue);
01409             cuddLevelQueueQuit(localQueue);
01410             return(0);
01411         }
01412 #ifdef DD_DEBUG
01413         assert(infoN->parity >= 1 && infoN->parity <= 3);
01414 #endif
01415         if (infoN->parity == 3) {
01416             /* This node can be reached through paths of different parity.
01417             ** It is not safe to replace it, because remapping will give
01418             ** an incorrect result, while replacement by 0 may cause node
01419             ** splitting. */
01420             cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01421             continue;
01422         }
01423         T = cuddT(node);
01424         E = cuddE(node);
01425         shared = NULL;
01426         impactP = item->impactP;
01427         impactN = item->impactN;
01428         if (Cudd_bddLeq(dd,T,E)) {
01429             /* Here we know that E is regular. */
01430 #ifdef DD_DEBUG
01431             assert(!Cudd_IsComplement(E));
01432 #endif
01433             (void) st_lookup(info->table, (char *)T, (char **)&infoT);
01434             (void) st_lookup(info->table, (char *)E, (char **)&infoE);
01435             if (infoN->parity == 1) {
01436                 impact = impactP;
01437                 minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0;
01438                 if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) {
01439                     savings = 1 + computeSavings(dd,E,NULL,info,localQueue);
01440                     if (savings == 1) {
01441                         cuddLevelQueueQuit(queue);
01442                         cuddLevelQueueQuit(localQueue);
01443                         return(0);
01444                     }
01445                 } else {
01446                     savings = 1;
01447                 }
01448                 replace = REPLACE_E;
01449             } else {
01450 #ifdef DD_DEBUG
01451                 assert(infoN->parity == 2);
01452 #endif
01453                 impact = impactN;
01454                 minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0;
01455                 if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) {
01456                     savings = 1 + computeSavings(dd,T,NULL,info,localQueue);
01457                     if (savings == 1) {
01458                         cuddLevelQueueQuit(queue);
01459                         cuddLevelQueueQuit(localQueue);
01460                         return(0);
01461                     }
01462                 } else {
01463                     savings = 1;
01464                 }
01465                 replace = REPLACE_T;
01466             }
01467             numOnset = impact * minterms;
01468         } else if (Cudd_bddLeq(dd,E,T)) {
01469             /* Here E may be complemented. */
01470             DdNode *Ereg = Cudd_Regular(E);
01471             (void) st_lookup(info->table, (char *)T, (char **)&infoT);
01472             (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE);
01473             if (infoN->parity == 1) {
01474                 impact = impactP;
01475                 minterms = infoT->mintermsP/2.0 -
01476                     ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0;
01477                 if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) {
01478                     savings = 1 + computeSavings(dd,T,NULL,info,localQueue);
01479                     if (savings == 1) {
01480                         cuddLevelQueueQuit(queue);
01481                         cuddLevelQueueQuit(localQueue);
01482                         return(0);
01483                     }
01484                 } else {
01485                     savings = 1;
01486                 }
01487                 replace = REPLACE_T;
01488             } else {
01489 #ifdef DD_DEBUG
01490                 assert(infoN->parity == 2);
01491 #endif
01492                 impact = impactN;
01493                 minterms = ((E == Ereg) ? infoE->mintermsN :
01494                             infoE->mintermsP)/2.0 - infoT->mintermsN/2.0;
01495                 if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) {
01496                     savings = 1 + computeSavings(dd,E,NULL,info,localQueue);
01497                     if (savings == 1) {
01498                         cuddLevelQueueQuit(queue);
01499                         cuddLevelQueueQuit(localQueue);
01500                         return(0);
01501                     }
01502                 } else {
01503                     savings = 1;
01504                 }
01505                 replace = REPLACE_E;
01506             }
01507             numOnset = impact * minterms;
01508         } else {
01509             DdNode *Ereg = Cudd_Regular(E);
01510             DdNode *TT = cuddT(T);
01511             DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E));
01512             if (T->index == Ereg->index && TT == ET) {
01513                 shared = TT;
01514                 replace = REPLACE_TT;
01515             } else {
01516                 DdNode *TE = cuddE(T);
01517                 DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E));
01518                 if (T->index == Ereg->index && TE == EE) {
01519                     shared = TE;
01520                     replace = REPLACE_TE;
01521                 } else {
01522                     replace = REPLACE_N;
01523                 }
01524             }
01525             numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN;
01526             savings = computeSavings(dd,node,shared,info,localQueue);
01527             if (shared != NULL) {
01528                 NodeData *infoS;
01529                 (void) st_lookup(info->table, (char *)Cudd_Regular(shared),
01530                                  (char **)&infoS);
01531                 if (Cudd_IsComplement(shared)) {
01532                     numOnset -= (infoS->mintermsN * impactP +
01533                         infoS->mintermsP * impactN)/2.0;
01534                 } else {
01535                     numOnset -= (infoS->mintermsP * impactP +
01536                         infoS->mintermsN * impactN)/2.0;
01537                 }
01538                 savings--;
01539             }
01540         }
01541 
01542         cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01543 #if 0
01544         if (replace == REPLACE_T || replace == REPLACE_E)
01545             (void) printf("node %p: impact = %g numOnset = %g savings %d\n",
01546                           node, impact, numOnset, savings);
01547         else
01548             (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n",
01549                           node, impactP, impactN, numOnset, savings);
01550 #endif
01551         if ((1 - numOnset / info->minterms) >
01552             quality * (1 - (double) savings / info->size)) {
01553             infoN->replace = replace;
01554             info->size -= savings;
01555             info->minterms -=numOnset;
01556 #if 0
01557             (void) printf("remap(%d): new size = %d new minterms = %g\n",
01558                           replace, info->size, info->minterms);
01559 #endif
01560             if (replace == REPLACE_N) {
01561                 savings -= updateRefs(dd,node,NULL,info,localQueue);
01562             } else if (replace == REPLACE_T) {
01563                 savings -= updateRefs(dd,node,E,info,localQueue);
01564             } else if (replace == REPLACE_E) {
01565                 savings -= updateRefs(dd,node,T,info,localQueue);
01566             } else {
01567 #ifdef DD_DEBUG
01568                 assert(replace == REPLACE_TT || replace == REPLACE_TE);
01569 #endif
01570                 savings -= updateRefs(dd,node,shared,info,localQueue) - 1;
01571             }
01572             assert(savings == 0);
01573         } else {
01574             replace = NOTHING;
01575         }
01576         if (replace == REPLACE_N) continue;
01577         if ((replace == REPLACE_E || replace == NOTHING) &&
01578             !cuddIsConstant(cuddT(node))) {
01579             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node),
01580                                          cuddI(dd,cuddT(node)->index));
01581             if (replace == REPLACE_E) {
01582                 item->impactP += impactP;
01583                 item->impactN += impactN;
01584             } else {
01585                 item->impactP += impactP/2.0;
01586                 item->impactN += impactN/2.0;
01587             }
01588         }
01589         if ((replace == REPLACE_T || replace == NOTHING) &&
01590             !Cudd_IsConstant(cuddE(node))) {
01591             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)),
01592                                          cuddI(dd,Cudd_Regular(cuddE(node))->index));
01593             if (Cudd_IsComplement(cuddE(node))) {
01594                 if (replace == REPLACE_T) {
01595                     item->impactP += impactN;
01596                     item->impactN += impactP;
01597                 } else {
01598                     item->impactP += impactN/2.0;
01599                     item->impactN += impactP/2.0;
01600                 }
01601             } else {
01602                 if (replace == REPLACE_T) {
01603                     item->impactP += impactP;
01604                     item->impactN += impactN;
01605                 } else {
01606                     item->impactP += impactP/2.0;
01607                     item->impactN += impactN/2.0;
01608                 }
01609             }
01610         }
01611         if ((replace == REPLACE_TT || replace == REPLACE_TE) &&
01612             !Cudd_IsConstant(shared)) {
01613             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared),
01614                                          cuddI(dd,Cudd_Regular(shared)->index));
01615             if (Cudd_IsComplement(shared)) {
01616                 if (replace == REPLACE_T) {
01617                     item->impactP += impactN;
01618                     item->impactN += impactP;
01619                 } else {
01620                     item->impactP += impactN/2.0;
01621                     item->impactN += impactP/2.0;
01622                 }
01623             } else {
01624                 if (replace == REPLACE_T) {
01625                     item->impactP += impactP;
01626                     item->impactN += impactN;
01627                 } else {
01628                     item->impactP += impactP/2.0;
01629                     item->impactN += impactN/2.0;
01630                 }
01631             }
01632         }
01633     }
01634 
01635     cuddLevelQueueQuit(queue);
01636     cuddLevelQueueQuit(localQueue);
01637     return(1);
01638 
01639 } /* end of RAmarkNodes */

static DdNode* UAbuildSubset ( DdManager dd,
DdNode node,
ApproxInfo info 
) [static]

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

Synopsis [Builds the subset BDD.]

Description [Builds the subset BDD. Based on the info table, replaces selected nodes by zero. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddUnderApprox]

Definition at line 1247 of file cuddApprox.c.

01251 {
01252 
01253     DdNode *Nt, *Ne, *N, *t, *e, *r;
01254     NodeData *infoN;
01255 
01256     if (Cudd_IsConstant(node))
01257         return(node);
01258 
01259     N = Cudd_Regular(node);
01260 
01261     if (st_lookup(info->table, (char *)N, (char **)&infoN)) {
01262         if (infoN->replace == TRUE) {
01263             return(info->zero);
01264         }
01265         if (N == node ) {
01266             if (infoN->resultP != NULL) {
01267                 return(infoN->resultP);
01268             }
01269         } else {
01270             if (infoN->resultN != NULL) {
01271                 return(infoN->resultN);
01272             }
01273         }
01274     } else {
01275         (void) fprintf(dd->err,
01276                        "Something is wrong, ought to be in info table\n");
01277         dd->errorCode = CUDD_INTERNAL_ERROR;
01278         return(NULL);
01279     }
01280 
01281     Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node));
01282     Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node));
01283 
01284     t = UAbuildSubset(dd, Nt, info);
01285     if (t == NULL) {
01286         return(NULL);
01287     }
01288     cuddRef(t);
01289 
01290     e = UAbuildSubset(dd, Ne, info);
01291     if (e == NULL) {
01292         Cudd_RecursiveDeref(dd,t);
01293         return(NULL);
01294     }
01295     cuddRef(e);
01296 
01297     if (Cudd_IsComplement(t)) {
01298         t = Cudd_Not(t);
01299         e = Cudd_Not(e);
01300         r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e);
01301         if (r == NULL) {
01302             Cudd_RecursiveDeref(dd, e);
01303             Cudd_RecursiveDeref(dd, t);
01304             return(NULL);
01305         }
01306         r = Cudd_Not(r);
01307     } else {
01308         r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e);
01309         if (r == NULL) {
01310             Cudd_RecursiveDeref(dd, e);
01311             Cudd_RecursiveDeref(dd, t);
01312             return(NULL);
01313         }
01314     }
01315     cuddDeref(t);
01316     cuddDeref(e);
01317 
01318     if (N == node) {
01319         infoN->resultP = r;
01320     } else {
01321         infoN->resultN = r;
01322     }
01323 
01324     return(r);
01325 
01326 } /* end of UAbuildSubset */

static int UAmarkNodes ( DdManager dd,
DdNode f,
ApproxInfo info,
int  threshold,
int  safe,
double  quality 
) [static]

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

Synopsis [Marks nodes for replacement by zero.]

Description [Marks nodes for replacement by zero. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddUnderApprox]

Definition at line 1123 of file cuddApprox.c.

01130 {
01131     DdLevelQueue *queue;
01132     DdLevelQueue *localQueue;
01133     NodeData *infoN;
01134     GlobalQueueItem *item;
01135     DdNode *node;
01136     double numOnset;
01137     double impactP, impactN;
01138     int savings;
01139 
01140 #if 0
01141     (void) printf("initial size = %d initial minterms = %g\n",
01142                   info->size, info->minterms);
01143 #endif
01144     queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size);
01145     if (queue == NULL) {
01146         return(0);
01147     }
01148     localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem),
01149                                     dd->initSlots);
01150     if (localQueue == NULL) {
01151         cuddLevelQueueQuit(queue);
01152         return(0);
01153     }
01154     node = Cudd_Regular(f);
01155     item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index));
01156     if (item == NULL) {
01157         cuddLevelQueueQuit(queue);
01158         cuddLevelQueueQuit(localQueue);
01159         return(0);
01160     }
01161     if (Cudd_IsComplement(f)) {
01162         item->impactP = 0.0;
01163         item->impactN = 1.0;
01164     } else {
01165         item->impactP = 1.0;
01166         item->impactN = 0.0;
01167     }
01168     while (queue->first != NULL) {
01169         /* If the size of the subset is below the threshold, quit. */
01170         if (info->size <= threshold)
01171             break;
01172         item = (GlobalQueueItem *) queue->first;
01173         node = item->node;
01174         node = Cudd_Regular(node);
01175         (void) st_lookup(info->table, (char *)node, (char **)&infoN);
01176         if (safe && infoN->parity == 3) {
01177             cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01178             continue;
01179         }
01180         impactP = item->impactP;
01181         impactN = item->impactN;
01182         numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN;
01183         savings = computeSavings(dd,node,NULL,info,localQueue);
01184         if (savings == 0) {
01185             cuddLevelQueueQuit(queue);
01186             cuddLevelQueueQuit(localQueue);
01187             return(0);
01188         }
01189         cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01190 #if 0
01191         (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n",
01192                       node, impactP, impactN, numOnset, savings);
01193 #endif
01194         if ((1 - numOnset / info->minterms) >
01195             quality * (1 - (double) savings / info->size)) {
01196             infoN->replace = TRUE;
01197             info->size -= savings;
01198             info->minterms -=numOnset;
01199 #if 0
01200             (void) printf("replace: new size = %d new minterms = %g\n",
01201                           info->size, info->minterms);
01202 #endif
01203             savings -= updateRefs(dd,node,NULL,info,localQueue);
01204             assert(savings == 0);
01205             continue;
01206         }
01207         if (!cuddIsConstant(cuddT(node))) {
01208             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node),
01209                                          cuddI(dd,cuddT(node)->index));
01210             item->impactP += impactP/2.0;
01211             item->impactN += impactN/2.0;
01212         }
01213         if (!Cudd_IsConstant(cuddE(node))) {
01214             item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)),
01215                                          cuddI(dd,Cudd_Regular(cuddE(node))->index));
01216             if (Cudd_IsComplement(cuddE(node))) {
01217                 item->impactP += impactN/2.0;
01218                 item->impactN += impactP/2.0;
01219             } else {
01220                 item->impactP += impactP/2.0;
01221                 item->impactN += impactN/2.0;
01222             }
01223         }
01224     }
01225 
01226     cuddLevelQueueQuit(queue);
01227     cuddLevelQueueQuit(localQueue);
01228     return(1);
01229 
01230 } /* end of UAmarkNodes */

static void updateParity ( DdNode node,
ApproxInfo info,
int  newparity 
) [static]

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

Synopsis [Recursively update the parity of the paths reaching a node.]

Description [Recursively update the parity of the paths reaching a node. Assumes that node is regular and propagates the invariant.]

SideEffects [None]

SeeAlso [gatherInfoAux]

Definition at line 764 of file cuddApprox.c.

00768 {
00769     NodeData *infoN;
00770     DdNode *E;
00771 
00772     if (!st_lookup(info->table, (char *)node, (char **)&infoN)) return;
00773     if ((infoN->parity & newparity) != 0) return;
00774     infoN->parity |= newparity;
00775     if (Cudd_IsConstant(node)) return;
00776     updateParity(cuddT(node),info,newparity);
00777     E = cuddE(node);
00778     if (Cudd_IsComplement(E)) {
00779         updateParity(Cudd_Not(E),info,3-newparity);
00780     } else {
00781         updateParity(E,info,newparity);
00782     }
00783     return;
00784 
00785 } /* end of updateParity */

static int updateRefs ( DdManager dd,
DdNode f,
DdNode skip,
ApproxInfo info,
DdLevelQueue queue 
) [static]

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

Synopsis [Update function reference counts.]

Description [Update function reference counts to account for replacement. Returns the number of nodes saved if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [UAmarkNodes RAmarkNodes]

Definition at line 1042 of file cuddApprox.c.

01048 {
01049     NodeData *infoN;
01050     LocalQueueItem *item;
01051     DdNode *node;
01052     int savings = 0;
01053 
01054     node = Cudd_Regular(f);
01055     /* Insert the given node in the level queue. Its function reference
01056     ** count is set equal to 0 so that the search will continue from it
01057     ** when it is retrieved. */
01058     item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index));
01059     if (item == NULL)
01060         return(0);
01061     (void) st_lookup(info->table, (char *)node, (char **)&infoN);
01062     infoN->functionRef = 0;
01063 
01064     if (skip != NULL) {
01065         /* Increase the function reference count of the node to be skipped
01066         ** by 1 to account for the node pointing to it that will be created. */
01067         skip = Cudd_Regular(skip);
01068         (void) st_lookup(info->table, (char *)skip, (char **)&infoN);
01069         infoN->functionRef++;
01070     }
01071 
01072     /* Process the queue. */
01073     while (queue->first != NULL) {
01074         item = (LocalQueueItem *) queue->first;
01075         node = item->node;
01076         cuddLevelQueueDequeue(queue,cuddI(dd,node->index));
01077         (void) st_lookup(info->table, (char *)node, (char **)&infoN);
01078         if (infoN->functionRef != 0) {
01079             /* This node is shared or must be skipped. */
01080             continue;
01081         }
01082         savings++;
01083         if (!cuddIsConstant(cuddT(node))) {
01084             item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node),
01085                                          cuddI(dd,cuddT(node)->index));
01086             if (item == NULL) return(0);
01087             (void) st_lookup(info->table, (char *)cuddT(node),
01088                              (char **)&infoN);
01089             infoN->functionRef--;
01090         }
01091         if (!Cudd_IsConstant(cuddE(node))) {
01092             item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)),
01093                                          cuddI(dd,Cudd_Regular(cuddE(node))->index));
01094             if (item == NULL) return(0);
01095             (void) st_lookup(info->table, (char *)Cudd_Regular(cuddE(node)),
01096                              (char **)&infoN);
01097             infoN->functionRef--;
01098         }
01099     }
01100 
01101 #ifdef DD_DEBUG
01102     /* At the end of a local search the queue should be empty. */
01103     assert(queue->size == 0);
01104 #endif
01105     return(savings);
01106 
01107 } /* end of updateRefs */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $" [static]

Definition at line 140 of file cuddApprox.c.


Generated on Tue Jan 5 12:18:53 2010 for abc70930 by  doxygen 1.6.1