abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dsdCheck.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [dsdCheck.c]
4 
5  PackageName [DSD: Disjoint-support decomposition package.]
6 
7  Synopsis [Procedures to check the identity of root functions.]
8 
9  Author [Alan Mishchenko]
10 
11  Affiliation [UC Berkeley]
12 
13  Date [Ver. 8.0. Started - September 22, 2003.]
14 
15  Revision [$Id: dsdCheck.c,v 1.0 2002/22/09 00:00:00 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include "dsdInt.h"
20 
22 
23 
24 ////////////////////////////////////////////////////////////////////////
25 /// DECLARATIONS ///
26 ////////////////////////////////////////////////////////////////////////
27 
28 typedef struct Dsd_Cache_t_ Dds_Cache_t;
29 typedef struct Dsd_Entry_t_ Dsd_Entry_t;
30 
32 {
35  int nSuccess;
36  int nFailure;
37 };
38 
40 {
41  DdNode * bX[5];
42 };
43 
45 
46 static int Dsd_CheckRootFunctionIdentity_rec( DdManager * dd, DdNode * bF1, DdNode * bF2, DdNode * bC1, DdNode * bC2 );
47 
48 ////////////////////////////////////////////////////////////////////////
49 /// FUNCTION DEFINITIONS ///
50 ////////////////////////////////////////////////////////////////////////
51 
52 /**Function********************************************************************
53 
54  Synopsis [(Re)allocates the local cache.]
55 
56  Description []
57 
58  SideEffects []
59 
60  SeeAlso []
61 
62 ******************************************************************************/
63 void Dsd_CheckCacheAllocate( int nEntries )
64 {
65  int nRequested;
66 
68  memset( pCache, 0, sizeof(Dds_Cache_t) );
69 
70  // check what is the size of the current cache
71  nRequested = Abc_PrimeCudd( nEntries );
72  if ( pCache->nTableSize != nRequested )
73  { // the current size is different
74  // deallocate the old, allocate the new
75  if ( pCache->nTableSize )
77  // allocate memory for the hash table
78  pCache->nTableSize = nRequested;
79  pCache->pTable = ABC_ALLOC( Dsd_Entry_t, nRequested );
80  }
81  // otherwise, there is no need to allocate, just clean
83 // printf( "\nThe number of allocated cache entries = %d.\n\n", pCache->nTableSize );
84 }
85 
86 /**Function********************************************************************
87 
88  Synopsis [Deallocates the local cache.]
89 
90  Description []
91 
92  SideEffects []
93 
94  SeeAlso []
95 
96 ******************************************************************************/
98 {
99  ABC_FREE( pCache->pTable );
100  ABC_FREE( pCache );
101 }
102 
103 /**Function********************************************************************
104 
105  Synopsis [Clears the local cache.]
106 
107  Description []
108 
109  SideEffects []
110 
111  SeeAlso []
112 
113 ******************************************************************************/
115 {
116  int i;
117  for ( i = 0; i < pCache->nTableSize; i++ )
118  pCache->pTable[0].bX[0] = NULL;
119 }
120 
121 
122 /**Function********************************************************************
123 
124  Synopsis [Checks whether it is true that bF1(bC1=0) == bF2(bC2=0).]
125 
126  Description []
127 
128  SideEffects []
129 
130  SeeAlso []
131 
132 ******************************************************************************/
133 int Dsd_CheckRootFunctionIdentity( DdManager * dd, DdNode * bF1, DdNode * bF2, DdNode * bC1, DdNode * bC2 )
134 {
135  int RetValue;
136 // pCache->nSuccess = 0;
137 // pCache->nFailure = 0;
138  RetValue = Dsd_CheckRootFunctionIdentity_rec(dd, bF1, bF2, bC1, bC2);
139 // printf( "Cache success = %d. Cache failure = %d.\n", pCache->nSuccess, pCache->nFailure );
140  return RetValue;
141 }
142 
143 /**Function********************************************************************
144 
145  Synopsis [Performs the recursive step of Dsd_CheckRootFunctionIdentity().]
146 
147  Description []
148 
149  SideEffects []
150 
151  SeeAlso []
152 
153 ******************************************************************************/
154 int Dsd_CheckRootFunctionIdentity_rec( DdManager * dd, DdNode * bF1, DdNode * bF2, DdNode * bC1, DdNode * bC2 )
155 {
156  unsigned HKey;
157 
158  // if either bC1 or bC2 is zero, the test is true
159 // if ( bC1 == b0 || bC2 == b0 ) return 1;
160  assert( bC1 != b0 );
161  assert( bC2 != b0 );
162 
163  // if both bC1 and bC2 are one - perform comparison
164  if ( bC1 == b1 && bC2 == b1 ) return (int)( bF1 == bF2 );
165 
166  if ( bF1 == b0 )
167  return Cudd_bddLeq( dd, bC2, Cudd_Not(bF2) );
168 
169  if ( bF1 == b1 )
170  return Cudd_bddLeq( dd, bC2, bF2 );
171 
172  if ( bF2 == b0 )
173  return Cudd_bddLeq( dd, bC1, Cudd_Not(bF1) );
174 
175  if ( bF2 == b1 )
176  return Cudd_bddLeq( dd, bC1, bF1 );
177 
178  // otherwise, keep expanding
179 
180  // check cache
181 // HKey = _Hash( ((unsigned)bF1), ((unsigned)bF2), ((unsigned)bC1), ((unsigned)bC2) );
182  HKey = hashKey4( bF1, bF2, bC1, bC2, pCache->nTableSize );
183  if ( pCache->pTable[HKey].bX[0] == bF1 &&
184  pCache->pTable[HKey].bX[1] == bF2 &&
185  pCache->pTable[HKey].bX[2] == bC1 &&
186  pCache->pTable[HKey].bX[3] == bC2 )
187  {
188  pCache->nSuccess++;
189  return (int)(ABC_PTRUINT_T)pCache->pTable[HKey].bX[4]; // the last bit records the result (yes/no)
190  }
191  else
192  {
193 
194  // determine the top variables
195  int RetValue;
196  DdNode * bA[4] = { bF1, bF2, bC1, bC2 }; // arguments
197  DdNode * bAR[4] = { Cudd_Regular(bF1), Cudd_Regular(bF2), Cudd_Regular(bC1), Cudd_Regular(bC2) }; // regular arguments
198  int CurLevel[4] = { cuddI(dd,bAR[0]->index), cuddI(dd,bAR[1]->index), cuddI(dd,bAR[2]->index), cuddI(dd,bAR[3]->index) };
199  int TopLevel = CUDD_CONST_INDEX;
200  int i;
201  DdNode * bE[4], * bT[4];
202  DdNode * bF1next, * bF2next, * bC1next, * bC2next;
203 
204  pCache->nFailure++;
205 
206  // determine the top level
207  for ( i = 0; i < 4; i++ )
208  if ( TopLevel > CurLevel[i] )
209  TopLevel = CurLevel[i];
210 
211  // compute the cofactors
212  for ( i = 0; i < 4; i++ )
213  if ( TopLevel == CurLevel[i] )
214  {
215  if ( bA[i] != bAR[i] ) // complemented
216  {
217  bE[i] = Cudd_Not(cuddE(bAR[i]));
218  bT[i] = Cudd_Not(cuddT(bAR[i]));
219  }
220  else
221  {
222  bE[i] = cuddE(bAR[i]);
223  bT[i] = cuddT(bAR[i]);
224  }
225  }
226  else
227  bE[i] = bT[i] = bA[i];
228 
229  // solve subproblems
230  // three cases are possible
231 
232  // (1) the top var belongs to both C1 and C2
233  // in this case, any cofactor of F1 and F2 will do,
234  // as long as the corresponding cofactor of C1 and C2 is not equal to 0
235  if ( TopLevel == CurLevel[2] && TopLevel == CurLevel[3] )
236  {
237  if ( bE[2] != b0 ) // C1
238  {
239  bF1next = bE[0];
240  bC1next = bE[2];
241  }
242  else
243  {
244  bF1next = bT[0];
245  bC1next = bT[2];
246  }
247  if ( bE[3] != b0 ) // C2
248  {
249  bF2next = bE[1];
250  bC2next = bE[3];
251  }
252  else
253  {
254  bF2next = bT[1];
255  bC2next = bT[3];
256  }
257  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bF1next, bF2next, bC1next, bC2next );
258  }
259  // (2) the top var belongs to either C1 or C2
260  // in this case normal splitting of cofactors
261  else if ( TopLevel == CurLevel[2] && TopLevel != CurLevel[3] )
262  {
263  if ( bE[2] != b0 ) // C1
264  {
265  bF1next = bE[0];
266  bC1next = bE[2];
267  }
268  else
269  {
270  bF1next = bT[0];
271  bC1next = bT[2];
272  }
273  // split around this variable
274  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bF1next, bE[1], bC1next, bE[3] );
275  if ( RetValue == 1 ) // test another branch; otherwise, there is no need to test
276  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bF1next, bT[1], bC1next, bT[3] );
277  }
278  else if ( TopLevel != CurLevel[2] && TopLevel == CurLevel[3] )
279  {
280  if ( bE[3] != b0 ) // C2
281  {
282  bF2next = bE[1];
283  bC2next = bE[3];
284  }
285  else
286  {
287  bF2next = bT[1];
288  bC2next = bT[3];
289  }
290  // split around this variable
291  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bE[0], bF2next, bE[2], bC2next );
292  if ( RetValue == 1 ) // test another branch; otherwise, there is no need to test
293  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bT[0], bF2next, bT[2], bC2next );
294  }
295  // (3) the top var does not belong to C1 and C2
296  // in this case normal splitting of cofactors
297  else // if ( TopLevel != CurLevel[2] && TopLevel != CurLevel[3] )
298  {
299  // split around this variable
300  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bE[0], bE[1], bE[2], bE[3] );
301  if ( RetValue == 1 ) // test another branch; otherwise, there is no need to test
302  RetValue = Dsd_CheckRootFunctionIdentity_rec( dd, bT[0], bT[1], bT[2], bT[3] );
303  }
304 
305  // set cache
306  for ( i = 0; i < 4; i++ )
307  pCache->pTable[HKey].bX[i] = bA[i];
308  pCache->pTable[HKey].bX[4] = (DdNode*)(ABC_PTRUINT_T)RetValue;
309 
310  return RetValue;
311  }
312 }
313 
314 ////////////////////////////////////////////////////////////////////////
315 /// END OF FILE ///
316 ////////////////////////////////////////////////////////////////////////
317 
319 
char * memset()
static int Abc_PrimeCudd(unsigned int p)
Definition: abc_global.h:383
DdNode * bX[5]
Definition: dsdCheck.c:41
int nSuccess
Definition: dsdCheck.c:35
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define b1
Definition: extraBdd.h:76
#define Cudd_Regular(node)
Definition: cudd.h:397
void Dsd_CheckCacheAllocate(int nEntries)
FUNCTION DEFINITIONS ///.
Definition: dsdCheck.c:63
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int Dsd_CheckRootFunctionIdentity(DdManager *dd, DdNode *bF1, DdNode *bF2, DdNode *bC1, DdNode *bC2)
Definition: dsdCheck.c:133
typedefABC_NAMESPACE_IMPL_START struct Dsd_Cache_t_ Dds_Cache_t
DECLARATIONS ///.
Definition: dsdCheck.c:28
Definition: dsdCheck.c:39
#define hashKey4(a, b, c, d, TSIZE)
Definition: extraBdd.h:92
void Dsd_CheckCacheClear()
Definition: dsdCheck.c:114
static Dds_Cache_t * pCache
Definition: dsdCheck.c:44
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static int Dsd_CheckRootFunctionIdentity_rec(DdManager *dd, DdNode *bF1, DdNode *bF2, DdNode *bC1, DdNode *bC2)
Definition: dsdCheck.c:154
#define CUDD_CONST_INDEX
Definition: cudd.h:117
#define cuddT(node)
Definition: cuddInt.h:636
void Dsd_CheckCacheDeallocate()
Definition: dsdCheck.c:97
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define cuddI(dd, index)
Definition: cuddInt.h:686
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
#define b0
Definition: extraBdd.h:75
#define ABC_FREE(obj)
Definition: abc_global.h:232
int nTableSize
Definition: dsdCheck.c:34
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
int nFailure
Definition: dsdCheck.c:36
Dsd_Entry_t * pTable
Definition: dsdCheck.c:33