abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
aigSplit.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [aigSplit.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [AIG package.]
8 
9  Synopsis [Splits the property output cone into a set of cofactor properties.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - April 28, 2007.]
16 
17  Revision [$Id: aigSplit.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "aig.h"
22 #include "aig/saig/saig.h"
23 #include "misc/extra/extraBdd.h"
24 
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 /// DECLARATIONS ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 ////////////////////////////////////////////////////////////////////////
33 /// FUNCTION DEFINITIONS ///
34 ////////////////////////////////////////////////////////////////////////
35 
36 /**Function*************************************************************
37 
38  Synopsis [Converts the node to MUXes.]
39 
40  Description []
41 
42  SideEffects []
43 
44  SeeAlso []
45 
46 ***********************************************************************/
47 Aig_Obj_t * Aig_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Aig_Man_t * pNew, st__table * tBdd2Node )
48 {
49  Aig_Obj_t * pNode, * pNode0, * pNode1, * pNodeC;
50  assert( !Cudd_IsComplement(bFunc) );
51  if ( st__lookup( tBdd2Node, (char *)bFunc, (char **)&pNode ) )
52  return pNode;
53  // solve for the children nodes
54  pNode0 = Aig_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNew, tBdd2Node );
55  pNode0 = Aig_NotCond( pNode0, Cudd_IsComplement(cuddE(bFunc)) );
56  pNode1 = Aig_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNew, tBdd2Node );
57  if ( ! st__lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeC ) )
58  assert( 0 );
59  // create the MUX node
60  pNode = Aig_Mux( pNew, pNodeC, pNode1, pNode0 );
61  st__insert( tBdd2Node, (char *)bFunc, (char *)pNode );
62  return pNode;
63 }
64 
65 /**Function*************************************************************
66 
67  Synopsis [Derives AIG for the BDDs of the cofactors.]
68 
69  Description []
70 
71  SideEffects []
72 
73  SeeAlso []
74 
75 ***********************************************************************/
77 {
78  DdNode * bFunc;
79  st__table * tBdd2Node;
80  Aig_Man_t * pNew;
81  Aig_Obj_t * pObj;
82  int i;
83  Aig_ManCleanData( p );
84  // generate AIG for BDD
85  pNew = Aig_ManStart( Aig_ManObjNum(p) );
86  pNew->pName = Abc_UtilStrsav( p->pName );
87  Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
88  Aig_ManForEachCi( p, pObj, i )
89  pObj->pData = Aig_ObjCreateCi( pNew );
90  // create the table mapping BDD nodes into the ABC nodes
91  tBdd2Node = st__init_table( st__ptrcmp, st__ptrhash );
92  // add the constant and the elementary vars
93  st__insert( tBdd2Node, (char *)Cudd_ReadOne(dd), (char *)Aig_ManConst1(pNew) );
94  Aig_ManForEachCi( p, pObj, i )
95  st__insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pObj->pData );
96  // build primary outputs for the cofactors
97  Vec_PtrForEachEntry( DdNode *, vCofs, bFunc, i )
98  {
99  if ( bFunc == Cudd_ReadLogicZero(dd) )
100  continue;
101  pObj = Aig_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNew, tBdd2Node );
102  pObj = Aig_NotCond( pObj, Cudd_IsComplement(bFunc) );
103  Aig_ObjCreateCo( pNew, pObj );
104  }
105  st__free_table( tBdd2Node );
106 
107  // duplicate the rest of the AIG
108  // add the POs
109  Aig_ManForEachCo( p, pObj, i )
110  {
111  if ( i == 0 )
112  continue;
113  Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin0(pObj) );
114  pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
115  }
116  Aig_ManCleanup( pNew );
117  Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
118  // check the resulting network
119  if ( !Aig_ManCheck(pNew) )
120  printf( "Aig_ManConvertBddsToAigs(): The check has failed.\n" );
121  return pNew;
122 }
123 
124 /**Function*************************************************************
125 
126  Synopsis [Returns the array of constraint candidates.]
127 
128  Description []
129 
130  SideEffects []
131 
132  SeeAlso []
133 
134 ***********************************************************************/
136 {
137  DdNode * bBdd0, * bBdd1;
138  if ( pObj->pData != NULL )
139  return (DdNode *)pObj->pData;
140  assert( Aig_ObjIsNode(pObj) );
141  bBdd0 = Aig_ManBuildPoBdd_rec( p, Aig_ObjFanin0(pObj), dd );
142  bBdd1 = Aig_ManBuildPoBdd_rec( p, Aig_ObjFanin1(pObj), dd );
143  bBdd0 = Cudd_NotCond( bBdd0, Aig_ObjFaninC0(pObj) );
144  bBdd1 = Cudd_NotCond( bBdd1, Aig_ObjFaninC1(pObj) );
145  pObj->pData = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( (DdNode *)pObj->pData );
146  return (DdNode *)pObj->pData;
147 }
148 
149 /**Function*************************************************************
150 
151  Synopsis [Derive BDDs for the cofactors.]
152 
153  Description []
154 
155  SideEffects []
156 
157  SeeAlso []
158 
159 ***********************************************************************/
161 {
162  Vec_Ptr_t * vCofs;
163  DdNode * bCube, * bTemp, * bCof, ** pbVars;
164  int i;
165  vCofs = Vec_PtrAlloc( 100 );
166  pbVars = (DdNode **)Vec_PtrArray(vSubset);
167  for ( i = 0; i < (1 << Vec_PtrSize(vSubset)); i++ )
168  {
169  bCube = Extra_bddBitsToCube( dd, i, Vec_PtrSize(vSubset), pbVars, 1 ); Cudd_Ref( bCube );
170  bCof = Cudd_Cofactor( dd, bFunc, bCube ); Cudd_Ref( bCof );
171  bCof = Cudd_bddAnd( dd, bTemp = bCof, bCube ); Cudd_Ref( bCof );
172  Cudd_RecursiveDeref( dd, bTemp );
173  Cudd_RecursiveDeref( dd, bCube );
174  Vec_PtrPush( vCofs, bCof );
175  }
176  return vCofs;
177 }
178 
179 /**Function*************************************************************
180 
181  Synopsis [Construct BDDs for the primary output.]
182 
183  Description []
184 
185  SideEffects []
186 
187  SeeAlso []
188 
189 ***********************************************************************/
191 {
192  DdManager * dd;
193  Aig_Obj_t * pObj;
194  int i;
195  assert( Saig_ManPoNum(p) == 1 );
196  Aig_ManCleanData( p );
199  pObj = Aig_ManConst1(p);
200  pObj->pData = Cudd_ReadOne(dd); Cudd_Ref( (DdNode *)pObj->pData );
201  Aig_ManForEachCi( p, pObj, i )
202  {
203  pObj->pData = Cudd_bddIthVar(dd, i); Cudd_Ref( (DdNode *)pObj->pData );
204  }
205  pObj = Aig_ManCo( p, 0 );
206  *pbFunc = Aig_ManBuildPoBdd_rec( p, Aig_ObjFanin0(pObj), dd ); Cudd_Ref( *pbFunc );
207  *pbFunc = Cudd_NotCond( *pbFunc, Aig_ObjFaninC0(pObj) );
208  Aig_ManForEachObj( p, pObj, i )
209  {
210  if ( pObj->pData )
211  Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
212  }
214  return dd;
215 }
216 
217 /**Function*************************************************************
218 
219  Synopsis [Randomly selects a random subset of inputs.]
220 
221  Description []
222 
223  SideEffects []
224 
225  SeeAlso []
226 
227 ***********************************************************************/
229 {
230  Vec_Ptr_t * vRes;
231  void * pEntry;
232  unsigned Rand;
233  vRes = Vec_PtrDup(vVec);
234  while ( Vec_PtrSize(vRes) > nVars )
235  {
236  Rand = Aig_ManRandom( 0 );
237  pEntry = Vec_PtrEntry( vRes, Rand % Vec_PtrSize(vRes) );
238  Vec_PtrRemove( vRes, pEntry );
239  }
240  return vRes;
241 }
242 
243 /**Function*************************************************************
244 
245  Synopsis []
246 
247  Description []
248 
249  SideEffects []
250 
251  SeeAlso []
252 
253 ***********************************************************************/
254 Aig_Man_t * Aig_ManSplit( Aig_Man_t * p, int nVars, int fVerbose )
255 {
256  Aig_Man_t * pRes;
257  Aig_Obj_t * pNode;
258  DdNode * bFunc;
259  DdManager * dd;
260  Vec_Ptr_t * vSupp, * vSubs, * vCofs;
261  int i;
262  abctime clk = Abc_Clock();
263  if ( Saig_ManPoNum(p) != 1 )
264  {
265  printf( "Currently works only for one primary output.\n" );
266  return NULL;
267  }
268  if ( nVars < 1 )
269  {
270  printf( "The number of cofactoring variables should be a positive number.\n" );
271  return NULL;
272  }
273  if ( nVars > 16 )
274  {
275  printf( "The number of cofactoring variables should be less than 17.\n" );
276  return NULL;
277  }
278  vSupp = Aig_Support( p, Aig_ObjFanin0(Aig_ManCo(p,0)) );
279  if ( Vec_PtrSize(vSupp) == 0 )
280  {
281  printf( "Property output function is a constant.\n" );
282  Vec_PtrFree( vSupp );
283  return NULL;
284  }
285  dd = Aig_ManBuildPoBdd( p, &bFunc ); // bFunc is referenced
286  if ( fVerbose )
287  printf( "Support =%5d. BDD size =%6d. ", Vec_PtrSize(vSupp), Cudd_DagSize(bFunc) );
288  vSubs = Aig_ManVecRandSubset( vSupp, nVars );
289  // replace nodes by their BDD variables
290  Vec_PtrForEachEntry( Aig_Obj_t *, vSubs, pNode, i )
291  Vec_PtrWriteEntry( vSubs, i, pNode->pData );
292  // derive cofactors and functions
293  vCofs = Aig_ManCofactorBdds( p, vSubs, dd, bFunc );
294  pRes = Aig_ManConvertBddsToAigs( p, dd, vCofs );
295  Vec_PtrFree( vSupp );
296  Vec_PtrFree( vSubs );
297  if ( fVerbose )
298  printf( "Created %d cofactors (out of %d). ", Saig_ManPoNum(pRes), Vec_PtrSize(vCofs) );
299  if ( fVerbose )
300  Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
301  // dereference
302  Cudd_RecursiveDeref( dd, bFunc );
303  Vec_PtrForEachEntry( DdNode *, vCofs, bFunc, i )
304  Cudd_RecursiveDeref( dd, bFunc );
305  Vec_PtrFree( vCofs );
306  Extra_StopManager( dd );
307  return pRes;
308 }
309 
310 ////////////////////////////////////////////////////////////////////////
311 /// END OF FILE ///
312 ////////////////////////////////////////////////////////////////////////
313 
314 
316 
Aig_Obj_t * Aig_ObjCreateCo(Aig_Man_t *p, Aig_Obj_t *pDriver)
Definition: aigObj.c:66
void st__free_table(st__table *table)
Definition: st.c:81
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
ABC_DLL int Aig_ManCheck(Aig_Man_t *p)
FUNCTION DECLARATIONS ///.
Definition: aigCheck.c:45
#define CUDD_UNIQUE_SLOTS
Definition: cudd.h:97
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
static int Saig_ManPoNum(Aig_Man_t *p)
Definition: saig.h:74
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition: aig.h:50
Aig_Man_t * Aig_ManConvertBddsToAigs(Aig_Man_t *p, DdManager *dd, Vec_Ptr_t *vCofs)
Definition: aigSplit.c:76
static Llb_Mgr_t * p
Definition: llb3Image.c:950
Aig_Man_t * Aig_ManSplit(Aig_Man_t *p, int nVars, int fVerbose)
Definition: aigSplit.c:254
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
static int Aig_ManObjNum(Aig_Man_t *p)
Definition: aig.h:258
void * pData
Definition: aig.h:87
DdNode * Cudd_ReadLogicZero(DdManager *dd)
Definition: cuddAPI.c:1058
#define Cudd_Regular(node)
Definition: cudd.h:397
static Aig_Obj_t * Aig_ObjFanin0(Aig_Obj_t *pObj)
Definition: aig.h:308
Aig_Man_t * Aig_ManStart(int nNodesMax)
DECLARATIONS ///.
Definition: aigMan.c:47
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
#define Aig_ManForEachCi(p, pObj, i)
ITERATORS ///.
Definition: aig.h:393
#define CUDD_CACHE_SLOTS
Definition: cudd.h:98
Aig_Obj_t * Aig_ObjCreateCi(Aig_Man_t *p)
DECLARATIONS ///.
Definition: aigObj.c:45
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
#define Aig_ManForEachCo(p, pObj, i)
Definition: aig.h:398
unsigned Aig_ManRandom(int fReset)
Definition: aigUtil.c:1157
static Vec_Ptr_t * Vec_PtrDup(Vec_Ptr_t *pVec)
Definition: vecPtr.h:169
static abctime Abc_Clock()
Definition: abc_global.h:279
void Extra_StopManager(DdManager *dd)
Definition: extraBddMisc.c:223
static Aig_Obj_t * Aig_ObjFanin1(Aig_Obj_t *pObj)
Definition: aig.h:309
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
static void Vec_PtrRemove(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:714
ABC_NAMESPACE_IMPL_START Aig_Obj_t * Aig_NodeBddToMuxes_rec(DdManager *dd, DdNode *bFunc, Aig_Man_t *pNew, st__table *tBdd2Node)
DECLARATIONS ///.
Definition: aigSplit.c:47
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
static int Aig_ObjIsNode(Aig_Obj_t *pObj)
Definition: aig.h:280
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:123
Vec_Ptr_t * Aig_Support(Aig_Man_t *p, Aig_Obj_t *pObj)
Definition: aigDfs.c:832
Definition: st.h:52
void Aig_ManSetRegNum(Aig_Man_t *p, int nRegs)
Definition: aigMan.c:438
static int Aig_ManCiNum(Aig_Man_t *p)
Definition: aig.h:251
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
DdManager * Cudd_Init(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
Definition: cuddInit.c:125
Aig_Obj_t * Aig_ManDupSimpleDfs_rec(Aig_Man_t *pNew, Aig_Man_t *p, Aig_Obj_t *pObj)
Definition: aigDup.c:157
Definition: aig.h:69
static Aig_Obj_t * Aig_ObjChild0Copy(Aig_Obj_t *pObj)
Definition: aig.h:312
#define cuddT(node)
Definition: cuddInt.h:636
static int Aig_ObjFaninC0(Aig_Obj_t *pObj)
Definition: aig.h:306
Vec_Ptr_t * Aig_ManCofactorBdds(Aig_Man_t *p, Vec_Ptr_t *vSubset, DdManager *dd, DdNode *bFunc)
Definition: aigSplit.c:160
static void Vec_PtrWriteEntry(Vec_Ptr_t *p, int i, void *Entry)
Definition: vecPtr.h:396
DdNode * Aig_ManBuildPoBdd_rec(Aig_Man_t *p, Aig_Obj_t *pObj, DdManager *dd)
Definition: aigSplit.c:135
static Aig_Obj_t * Aig_ManConst1(Aig_Man_t *p)
Definition: aig.h:264
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
static Aig_Obj_t * Aig_ManCo(Aig_Man_t *p, int i)
Definition: aig.h:267
static int Aig_ManRegNum(Aig_Man_t *p)
Definition: aig.h:260
DdNode * Cudd_ReadOne(DdManager *dd)
Definition: cuddAPI.c:987
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
Vec_Ptr_t * Aig_ManVecRandSubset(Vec_Ptr_t *vVec, int nVars)
Definition: aigSplit.c:228
DdManager * Aig_ManBuildPoBdd(Aig_Man_t *p, DdNode **pbFunc)
Definition: aigSplit.c:190
Aig_Obj_t * Aig_Mux(Aig_Man_t *p, Aig_Obj_t *pC, Aig_Obj_t *p1, Aig_Obj_t *p0)
Definition: aigOper.c:317
#define Aig_ManForEachObj(p, pObj, i)
Definition: aig.h:403
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
DdHalfWord index
Definition: cudd.h:279
DdNode * Cudd_bddIthVar(DdManager *dd, int i)
Definition: cuddAPI.c:416
static int Aig_ObjFaninC1(Aig_Obj_t *pObj)
Definition: aig.h:307
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
Definition: extraBddMisc.c:730
#define assert(ex)
Definition: util_old.h:213
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
void Cudd_AutodynEnable(DdManager *unique, Cudd_ReorderingType method)
Definition: cuddAPI.c:669
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
static Aig_Obj_t * Aig_NotCond(Aig_Obj_t *p, int c)
Definition: aig.h:248
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
ABC_INT64_T abctime
Definition: abc_global.h:278
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
void Aig_ManCleanData(Aig_Man_t *p)
Definition: aigUtil.c:205
static void ** Vec_PtrArray(Vec_Ptr_t *p)
Definition: vecPtr.h:279
int Aig_ManCleanup(Aig_Man_t *p)
Definition: aigMan.c:265
int st__ptrhash(const char *, int)
Definition: st.c:468
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223