abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
extraZddTrunc.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [extraZddTrunc.c]
4 
5  PackageName [extra]
6 
7  Synopsis [Procedure to truncate a ZDD using variable probabilities.]
8 
9  Author [Alan Mishchenko]
10 
11  Affiliation [UC Berkeley]
12 
13  Date [Ver. 2.0. Started - September 1, 2003.]
14 
15  Revision [$Id: extraZddTrunc.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <assert.h>
23 
24 #include "misc/st/st.h"
25 #include "bdd/cudd/cuddInt.h"
26 
27 #ifdef _WIN32
28 #define inline __inline // compatible with MS VS 6.0
29 #endif
30 
32 
33 
34 #define TEST_VAR_MAX 10
35 #define TEST_SET_MAX 10
36 
37 /*---------------------------------------------------------------------------*/
38 /* Constant declarations */
39 /*---------------------------------------------------------------------------*/
40 
41 /*---------------------------------------------------------------------------*/
42 /* Stucture declarations */
43 /*---------------------------------------------------------------------------*/
44 
45 /*---------------------------------------------------------------------------*/
46 /* Type declarations */
47 /*---------------------------------------------------------------------------*/
48 
49 /*---------------------------------------------------------------------------*/
50 /* Variable declarations */
51 /*---------------------------------------------------------------------------*/
52 
53 /*---------------------------------------------------------------------------*/
54 /* Macro declarations */
55 /*---------------------------------------------------------------------------*/
56 
57 
58 /**AutomaticStart*************************************************************/
59 
60 /*---------------------------------------------------------------------------*/
61 /* Static function prototypes */
62 /*---------------------------------------------------------------------------*/
63 
64 
65 // dynamic vector of intergers
66 typedef struct Vec_Int_t_ Vec_Int_t;
67 struct Vec_Int_t_
68 {
69  int nCap;
70  int nSize;
71  int * pArray;
72 };
73 static inline Vec_Int_t * Vec_IntAlloc( int nCap )
74 {
75  Vec_Int_t * p;
76  p = ABC_ALLOC( Vec_Int_t, 1 );
77  if ( nCap > 0 && nCap < 16 )
78  nCap = 16;
79  p->nSize = 0;
80  p->nCap = nCap;
81  p->pArray = p->nCap? ABC_ALLOC( int, p->nCap ) : NULL;
82  return p;
83 }
84 static inline void Vec_IntFree( Vec_Int_t * p )
85 {
86  ABC_FREE( p->pArray );
87  ABC_FREE( p );
88 }
89 static inline int * Vec_IntReleaseArray( Vec_Int_t * p )
90 {
91  int * pArray = p->pArray;
92  p->nCap = 0;
93  p->nSize = 0;
94  p->pArray = NULL;
95  return pArray;
96 }
97 static inline int Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
98 {
99  assert( i >= 0 && i < p->nSize );
100  return p->pArray[i] += Addition;
101 }
102 static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
103 {
104  if ( p->nCap >= nCapMin )
105  return;
106  p->pArray = ABC_REALLOC( int, p->pArray, nCapMin );
107  assert( p->pArray );
108  p->nCap = nCapMin;
109 }
110 static inline int Vec_IntPop( Vec_Int_t * p )
111 {
112  assert( p->nSize > 0 );
113  return p->pArray[--p->nSize];
114 }
115 static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
116 {
117  if ( p->nSize == p->nCap )
118  {
119  if ( p->nCap < 16 )
120  Vec_IntGrow( p, 16 );
121  else
122  Vec_IntGrow( p, 2 * p->nCap );
123  }
124  p->pArray[p->nSize++] = Entry;
125 }
126 static inline void Vec_IntAppend( Vec_Int_t * vVec1, Vec_Int_t * vVec2 )
127 {
128  int i;
129  for ( i = 0; i < vVec2->nSize; i++ )
130  Vec_IntPush( vVec1, vVec2->pArray[i] );
131 }
132 
133 
134 /**AutomaticEnd***************************************************************/
135 
136 
137 /*---------------------------------------------------------------------------*/
138 /* Definition of exported functions */
139 /*---------------------------------------------------------------------------*/
140 
141 /**Function********************************************************************
142 
143  Synopsis [Compute the set of subsets whose probability is more than ProbLimit.]
144 
145  Description [The resulting array has the following form: The first integer entry
146  is the number of resulting subsets. The following integer entries in the array
147  contain as many subsets. Each subset is an array of integers followed by -1.
148  See how subsets are printed in the included test procedure below.]
149 
150  SideEffects []
151 
152  SeeAlso []
153 
154 ******************************************************************************/
156  DdManager * dd,
157  DdNode * zFunc, // zFunc is the ZDD to be truncated
158  double * pVarProbs, // pVarProbs is probabilities of each variable (should have at least dd->sizeZ entries)
159  double ProbLimit, // ProbLimit is the limit on the probabilities (only those more than this will be collected)
160  double ProbThis, // current path probability
161  Vec_Int_t * vSubset, // current subset under construction
162  Vec_Int_t * vResult ) // resulting subsets to be returned to the user
163 {
164  // quit if probability of the path is less then the limit
165  if ( ProbThis < ProbLimit )
166  return;
167  // quit if there is no subsets
168  if ( zFunc == Cudd_ReadZero(dd) )
169  return;
170  // quit and save a new subset if there is one
171  if ( zFunc == Cudd_ReadOne(dd) )
172  {
173  Vec_IntAddToEntry( vResult, 0, 1 );
174  Vec_IntAppend( vResult, vSubset );
175  Vec_IntPush( vResult, -1 );
176  return;
177  }
178  // call recursively for the set without the given variable
179  Extra_zddTruncate_rec( dd, cuddE(zFunc), pVarProbs, ProbLimit, ProbThis, vSubset, vResult );
180  // call recursively for the set with the given variable
181  Vec_IntPush( vSubset, Cudd_NodeReadIndex(zFunc) );
182  Extra_zddTruncate_rec( dd, cuddT(zFunc), pVarProbs, ProbLimit, ProbThis * pVarProbs[Cudd_NodeReadIndex(zFunc)], vSubset, vResult );
183  Vec_IntPop( vSubset );
184 }
186  DdManager * dd,
187  DdNode * zFunc, // zFunc is the ZDD to be truncated
188  double * pVarProbs, // pVarProbs is probabilities of each variable (should have at least dd->sizeZ entries)
189  double ProbLimit ) // ProbLimit is the limit on the probabilities (only those more than this will be collected)
190 {
191  Vec_Int_t * vSubset, * vResult;
192  int i, sizeZ = Cudd_ReadZddSize(dd);
193  int * pResult;
194  // check that probabilities are reasonable
195  assert( ProbLimit > 0 && ProbLimit <= 1 );
196  for ( i = 0; i < sizeZ; i++ )
197  assert( pVarProbs[i] > 0 && pVarProbs[i] <= 1 );
198  // enumerate assignments satisfying the probability limit
199  vSubset = Vec_IntAlloc( sizeZ );
200  vResult = Vec_IntAlloc( 10 * sizeZ );
201  Vec_IntPush( vResult, 0 );
202  Extra_zddTruncate_rec( dd, zFunc, pVarProbs, ProbLimit, 1, vSubset, vResult );
203  Vec_IntFree( vSubset );
204  pResult = Vec_IntReleaseArray( vResult );
205  Vec_IntFree( vResult );
206  return pResult;
207 } // end of Extra_zddTruncate
208 
209 /**Function*************************************************************
210 
211  Synopsis [Creates the combination composed of a single ZDD variable.]
212 
213  Description []
214 
215  SideEffects []
216 
217  SeeAlso []
218 
219 ***********************************************************************/
220 DdNode * Extra_zddVariable( DdManager * dd, int iVar )
221 {
222  DdNode * zRes;
223  do {
224  dd->reordered = 0;
225  zRes = cuddZddGetNode( dd, iVar, Cudd_ReadOne(dd), Cudd_ReadZero(dd) );
226  } while (dd->reordered == 1);
227  return zRes;
228 }
229 
230 /**Function********************************************************************
231 
232  Synopsis [Creates ZDD representing a given set of subsets.]
233 
234  Description []
235 
236  SideEffects []
237 
238  SeeAlso []
239 
240 ******************************************************************************/
242  DdManager * dd,
243  int pSubsets[][TEST_VAR_MAX+1],
244  int nSubsets )
245 {
246  int i, k;
247  DdNode * zOne, * zVar, * zRes, * zTemp;
248  zRes = Cudd_ReadZero(dd); Cudd_Ref( zRes );
249  for ( i = 0; i < nSubsets; i++ )
250  {
251  zOne = Cudd_ReadOne(dd); Cudd_Ref( zOne );
252  for ( k = 0; pSubsets[i][k] != -1; k++ )
253  {
254  assert( pSubsets[i][k] < TEST_VAR_MAX );
255  zVar = Extra_zddVariable( dd, pSubsets[i][k] );
256  zOne = Cudd_zddUnateProduct( dd, zTemp = zOne, zVar ); Cudd_Ref( zOne );
257  Cudd_RecursiveDerefZdd( dd, zTemp );
258  }
259  zRes = Cudd_zddUnion( dd, zRes, zOne ); Cudd_Ref( zRes );
260  Cudd_RecursiveDerefZdd( dd, zOne );
261  }
262  Cudd_Deref( zRes );
263  return zRes;
264 }
265 
266 /**Function********************************************************************
267 
268  Synopsis [Prints a set of subsets represented using as an array.]
269 
270  Description []
271 
272  SideEffects []
273 
274  SeeAlso []
275 
276 ******************************************************************************/
277 void Extra_zddPrintSubsets( int * pSubsets )
278 {
279  int i, k, Counter = 0;
280  printf( "The set contains %d subsets:\n", pSubsets[0] );
281  for ( i = k = 0; i < pSubsets[0]; i++ )
282  {
283  printf( "Subset %3d : {", Counter );
284  for ( k++; pSubsets[k] != -1; k++ )
285  printf( " %d", pSubsets[k] );
286  printf( " }\n" );
287  Counter++;
288  }
289 }
290 
291 /**Function********************************************************************
292 
293  Synopsis [Testbench for the above truncation procedure.]
294 
295  Description []
296 
297  SideEffects []
298 
299  SeeAlso []
300 
301 ******************************************************************************/
303 {
304  // input data
305  int nSubsets = 5;
306  int pSubsets[TEST_SET_MAX][TEST_VAR_MAX+1] = { {0, 3, 5, -1}, {1, 2, 3, 6, 9, -1}, {1, 5, 7, 8, -1}, {2, 4, -1}, {0, 5, 6, 9, -1} };
307  // varible probabilities
308  double pVarProbs[TEST_VAR_MAX] = { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 };
309  double ProbLimit = 0.001;
310  // output data
311  int * pOutput;
312  // start the manager and create ZDD representing the input subsets
314  DdNode * zFunc = Extra_zddCreateSubsets( dd, pSubsets, nSubsets ); Cudd_Ref( zFunc );
315  assert( nSubsets <= TEST_SET_MAX );
316  // print the input ZDD
317  printf( "The initial ZDD representing %d subsets:\n", nSubsets );
318  Cudd_zddPrintMinterm( dd, zFunc );
319  // compute the result of truncation
320  pOutput = Extra_zddTruncate( dd, zFunc, pVarProbs, ProbLimit );
321  // print the resulting ZDD
322  printf( "The resulting ZDD representing %d subsets:\n", pOutput[0] );
323  // print the resulting subsets
324  Extra_zddPrintSubsets( pOutput );
325  // cleanup
326  ABC_FREE( pOutput );
327  Cudd_RecursiveDerefZdd( dd, zFunc );
328  Cudd_Quit( dd );
329 }
330 
331 
332 
333 
334 ////////////////////////////////////////////////////////////////////////
335 /// END OF FILE ///
336 ////////////////////////////////////////////////////////////////////////
338 
DdNode * Extra_zddCreateSubsets(DdManager *dd, int pSubsets[][TEST_VAR_MAX+1], int nSubsets)
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
static void Vec_IntFree(Vec_Int_t *p)
Definition: extraZddTrunc.c:84
#define CUDD_UNIQUE_SLOTS
Definition: cudd.h:97
#define TEST_VAR_MAX
Definition: extraZddTrunc.c:34
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
static Llb_Mgr_t * p
Definition: llb3Image.c:950
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
#define ABC_REALLOC(type, obj, num)
Definition: abc_global.h:233
#define CUDD_CACHE_SLOTS
Definition: cudd.h:98
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * Cudd_ReadZero(DdManager *dd)
Definition: cuddAPI.c:1036
int * Extra_zddTruncate(DdManager *dd, DdNode *zFunc, double *pVarProbs, double ProbLimit)
DdNode * Cudd_zddUnion(DdManager *dd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:178
#define TEST_SET_MAX
Definition: extraZddTrunc.c:35
int reordered
Definition: cuddInt.h:409
int * pArray
Definition: bblif.c:42
static void Vec_IntPush(Vec_Int_t *p, int Entry)
static Vec_Int_t * Vec_IntAlloc(int nCap)
Definition: extraZddTrunc.c:73
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
int Cudd_ReadZddSize(DdManager *dd)
Definition: cuddAPI.c:1461
DdManager * Cudd_Init(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
Definition: cuddInit.c:125
int nCap
Definition: bblif.c:40
static int Vec_IntPop(Vec_Int_t *p)
static void Vec_IntGrow(Vec_Int_t *p, int nCapMin)
static void Vec_IntAppend(Vec_Int_t *vVec1, Vec_Int_t *vVec2)
static int Counter
#define cuddT(node)
Definition: cuddInt.h:636
int nSize
Definition: bblif.c:41
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
DdNode * Cudd_zddUnateProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:176
DdNode * Cudd_ReadOne(DdManager *dd)
Definition: cuddAPI.c:987
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int Cudd_NodeReadIndex(DdNode *node)
Definition: cuddAPI.c:2277
void Extra_zddTruncateTest()
static int Vec_IntAddToEntry(Vec_Int_t *p, int i, int Addition)
Definition: extraZddTrunc.c:97
int Cudd_zddPrintMinterm(DdManager *zdd, DdNode *node)
Definition: cuddZddUtil.c:135
void Extra_zddPrintSubsets(int *pSubsets)
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * Extra_zddVariable(DdManager *dd, int iVar)
#define assert(ex)
Definition: util_old.h:213
void Cudd_Quit(DdManager *unique)
Definition: cuddInit.c:225
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
void Extra_zddTruncate_rec(DdManager *dd, DdNode *zFunc, double *pVarProbs, double ProbLimit, double ProbThis, Vec_Int_t *vSubset, Vec_Int_t *vResult)
static int * Vec_IntReleaseArray(Vec_Int_t *p)
Definition: extraZddTrunc.c:89