#include "util_hack.h"
#include "cuddInt.h"
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)) |
DdNode * | Cudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality) |
DdNode * | Cudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality) |
DdNode * | Cudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality) |
DdNode * | Cudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality) |
DdNode * | Cudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0) |
DdNode * | Cudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0) |
DdNode * | cuddUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality) |
DdNode * | cuddRemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality) |
DdNode * | cuddBiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0) |
static void | updateParity (DdNode *node, ApproxInfo *info, int newparity) |
static NodeData * | gatherInfoAux (DdNode *node, ApproxInfo *info, int parity) |
static ApproxInfo * | gatherInfo (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 DdNode * | UAbuildSubset (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 DdNode * | RAbuildSubset (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 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.
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:
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:
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:
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 */
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.