abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
abcFx.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [abcFx.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Network and node package.]
8 
9  Synopsis [Implementation of traditional "fast_extract" algorithm.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - April 26, 2013.]
16 
17  Revision [$Id: abcFx.c,v 1.00 2013/04/26 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "base/abc/abc.h"
22 #include "misc/vec/vecWec.h"
23 #include "misc/vec/vecQue.h"
24 #include "misc/vec/vecHsh.h"
25 
27 
28 ////////////////////////////////////////////////////////////////////////
29 /// DECLARATIONS ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 /*
33  The code in this file implements the traditional "fast_extract" algorithm,
34  which extracts two-cube divisors concurrently with single-cube two-literal divisors,
35  as proposed in the TCAD'92 paper by J. Rajski and J. Vasudevamurthi.
36 
37  Integration notes:
38 
39  It is assumed that each object (primary input or internal node) in the original network
40  is associated with a unique integer number, called object identifier (ObjId, for short).
41 
42  The user's input data given to 'fast_extract" is an array of cubes (pMan->vCubes).
43  Each cube is an array of integers, in which the first entry contains ObjId of the node,
44  to which this cube belongs in the original network. The following entries of a cube are
45  SOP literals of this cube. Each literal is represtned as 2*FaninId + ComplAttr, where FaninId
46  is ObjId of the fanin node and ComplAttr is 1 if literal is complemented, and 0 otherwise.
47 
48  The user's output data produced by 'fast_extract' is also an array of cubes (pMan->vCubes).
49  If no divisors have been extracted, the output array is the same as the input array.
50  If some divisors have been extracted, the output array contains updated old cubes and new cubes
51  representing the extracted divisors. The new divisors have their ObjId starting from the
52  largest ObjId used in the cubes. To give the user more flexibility, which may be needed when some
53  ObjIds are already used for primary output nodes, which do not participate in fast_extract,
54  the parameter ObjIdMax is passed to procedure Fx_FastExtract(). The new divisors will receive
55  their ObjId starting from ObjIdMax onward, as divisor extaction proceeds.
56 
57  The following two requirements are imposed on the input and output array of cubes:
58  (1) The array of cubes should be sorted by the first entry in each cube (that is, cubes belonging
59  to the same node should form a contiguous range).
60  (2) Literals in a cube should be sorted in the increasing order of the integer numbers.
61 
62  To integrate this code into a calling application, such as ABC, the input cube array should
63  be generated (below this is done by the procedure Abc_NtkFxRetrieve) and the output cube array
64  should be incorporated into the current network (below this is done by the procedure Abc_NtkFxInsert).
65  In essence, the latter procedure performs the following:
66  - removes the current fanins and SOPs of each node in the network
67  - adds new nodes for each new divisor introduced by "fast_extract"
68  - populates fanins and SOPs of each node, both old and new, as indicaded by the resulting cube array.
69 
70  Implementation notes:
71 
72  The implementation is optimized for simplicity and speed of computation.
73  (1) Main input/output data-structure (pMan->vCubes) is the array of cubes which is dynamically updated by the algorithm.
74  (2) Auxiliary data-structure (pMan->vLits) is the array of arrays. The i-th array contains IDs of cubes which have literal i.
75  It may be convenient to think about the first (second) array as rows (columns) of a sparse matrix,
76  although the sparse matrix data-structure is not used in the proposed implementation.
77  (3) Hash table (pMan->pHash) hashes the normalized divisors (represented as integer arrays) into integer numbers.
78  (4) Array of divisor weights (pMan->vWeights), that is, the number of SOP literals to be saved by extacting each divisor.
79  (5) Priority queue (pMan->vPrio), which sorts divisor (integer numbers) by their weight
80  (6) Integer array (pMan->vVarCube), which maps each ObjId into the first cube of this object,
81  or -1, if there is no cubes as in the case of a primary input.
82 
83 */
84 
85 typedef struct Fx_Man_t_ Fx_Man_t;
86 struct Fx_Man_t_
87 {
88  // user's data
89  Vec_Wec_t * vCubes; // cube -> lit
90  int LitCountMax;// max size of divisor to extract
91  // internal data
92  Vec_Wec_t * vLits; // lit -> cube
93  Vec_Int_t * vCounts; // literal counts (currently not used)
94  Hsh_VecMan_t * pHash; // hash table for normalized divisors
95  Vec_Flt_t * vWeights; // divisor weights
96  Vec_Que_t * vPrio; // priority queue for divisors by weight
97  Vec_Int_t * vVarCube; // mapping ObjId into its first cube
98  Vec_Int_t * vLevels; // variable levels
99  // temporary data to update the data-structure when a divisor is extracted
100  Vec_Int_t * vCubesS; // single cubes for the given divisor
101  Vec_Int_t * vCubesD; // cube pairs for the given divisor
102  Vec_Int_t * vCompls; // complemented attribute of each cube pair
103  Vec_Int_t * vCubeFree; // cube-free divisor
104  Vec_Int_t * vDiv; // selected divisor
105  // statistics
106  abctime timeStart; // starting time
107  int nVars; // original problem variables
108  int nLits; // the number of SOP literals
109  int nDivs; // the number of extracted divisors
110  int nCompls; // the number of complements
111  int nPairsS; // number of lit pairs
112  int nPairsD; // number of cube pairs
113  int nDivsS; // single cube divisors
114  int nDivMux[3]; // 0 = mux, 1 = compl mux, 2 = no mux
115 };
116 
117 static inline int Fx_ManGetFirstVarCube( Fx_Man_t * p, Vec_Int_t * vCube ) { return Vec_IntEntry( p->vVarCube, Vec_IntEntry(vCube, 0) ); }
118 
119 #define Fx_ManForEachCubeVec( vVec, vCubes, vCube, i ) \
120  for ( i = 0; (i < Vec_IntSize(vVec)) && ((vCube) = Vec_WecEntry(vCubes, Vec_IntEntry(vVec, i))); i++ )
121 
122 ////////////////////////////////////////////////////////////////////////
123 /// FUNCTION DEFINITIONS ///
124 ////////////////////////////////////////////////////////////////////////
125 
126 /**Function*************************************************************
127 
128  Synopsis [Retrieves SOP information for fast_extract.]
129 
130  Description []
131 
132  SideEffects []
133 
134  SeeAlso []
135 
136 ***********************************************************************/
138 {
139  Vec_Wec_t * vCubes;
140  Vec_Int_t * vCube;
141  Abc_Obj_t * pNode;
142  char * pCube, * pSop;
143  int nVars, i, v, Lit;
144  assert( Abc_NtkIsSopLogic(pNtk) );
145  vCubes = Vec_WecAlloc( 1000 );
146  Abc_NtkForEachNode( pNtk, pNode, i )
147  {
148  pSop = (char *)pNode->pData;
149  nVars = Abc_SopGetVarNum(pSop);
150  assert( nVars == Abc_ObjFaninNum(pNode) );
151 // if ( nVars < 2 ) continue;
152  Abc_SopForEachCube( pSop, nVars, pCube )
153  {
154  vCube = Vec_WecPushLevel( vCubes );
155  Vec_IntPush( vCube, Abc_ObjId(pNode) );
156  Abc_CubeForEachVar( pCube, Lit, v )
157  {
158  if ( Lit == '0' )
159  Vec_IntPush( vCube, Abc_Var2Lit(Abc_ObjFaninId(pNode, v), 1) );
160  else if ( Lit == '1' )
161  Vec_IntPush( vCube, Abc_Var2Lit(Abc_ObjFaninId(pNode, v), 0) );
162  }
163  Vec_IntSelectSort( Vec_IntArray(vCube) + 1, Vec_IntSize(vCube) - 1 );
164  }
165  }
166  return vCubes;
167 }
168 
169 /**Function*************************************************************
170 
171  Synopsis [Inserts SOP information after fast_extract.]
172 
173  Description []
174 
175  SideEffects []
176 
177  SeeAlso []
178 
179 ***********************************************************************/
180 void Abc_NtkFxInsert( Abc_Ntk_t * pNtk, Vec_Wec_t * vCubes )
181 {
182  Vec_Int_t * vCube, * vPres, * vFirst, * vCount;
183  Abc_Obj_t * pNode, * pFanin;
184  char * pCube, * pSop;
185  int i, k, v, Lit, iFanin, iNodeMax = 0;
186  assert( Abc_NtkIsSopLogic(pNtk) );
187  // check that cubes have no gaps and are ordered by first node
188  Lit = -1;
189  Vec_WecForEachLevel( vCubes, vCube, i )
190  {
191  assert( Vec_IntSize(vCube) > 0 );
192  assert( Lit <= Vec_IntEntry(vCube, 0) );
193  Lit = Vec_IntEntry(vCube, 0);
194  }
195  // find the largest index
196  Vec_WecForEachLevel( vCubes, vCube, i )
197  iNodeMax = Abc_MaxInt( iNodeMax, Vec_IntEntry(vCube, 0) );
198  // quit if nothing changes
199  if ( iNodeMax < Abc_NtkObjNumMax(pNtk) )
200  {
201  printf( "The network is unchanged by fast extract.\n" );
202  return;
203  }
204  // create new nodes
205  for ( i = Abc_NtkObjNumMax(pNtk); i <= iNodeMax; i++ )
206  {
207  pNode = Abc_NtkCreateNode( pNtk );
208  assert( i == (int)Abc_ObjId(pNode) );
209  }
210  // create node fanins
211  vFirst = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
212  vCount = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
213  Vec_WecForEachLevel( vCubes, vCube, i )
214  {
215  iFanin = Vec_IntEntry( vCube, 0 );
216  if ( Vec_IntEntry(vCount, iFanin) == 0 )
217  Vec_IntWriteEntry( vFirst, iFanin, i );
218  Vec_IntAddToEntry( vCount, iFanin, 1 );
219  }
220  // create node SOPs
221  vPres = Vec_IntStartFull( Abc_NtkObjNumMax(pNtk) );
222  Abc_NtkForEachNode( pNtk, pNode, i )
223  {
224 // if ( Vec_IntEntry(vCount, i) == 0 ) continue;
225  Abc_ObjRemoveFanins( pNode );
226  // create fanins
227  assert( Vec_IntEntry(vCount, i) > 0 );
228  for ( k = 0; k < Vec_IntEntry(vCount, i); k++ )
229  {
230  vCube = Vec_WecEntry( vCubes, Vec_IntEntry(vFirst, i) + k );
231  assert( Vec_IntEntry( vCube, 0 ) == i );
232  Vec_IntForEachEntryStart( vCube, Lit, v, 1 )
233  {
234  pFanin = Abc_NtkObj(pNtk, Abc_Lit2Var(Lit));
235  if ( Vec_IntEntry(vPres, Abc_ObjId(pFanin)) >= 0 )
236  continue;
237  Vec_IntWriteEntry(vPres, Abc_ObjId(pFanin), Abc_ObjFaninNum(pNode));
238  Abc_ObjAddFanin( pNode, pFanin );
239  }
240  }
241  // create SOP
242  pSop = pCube = Abc_SopStart( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntEntry(vCount, i), Abc_ObjFaninNum(pNode) );
243  for ( k = 0; k < Vec_IntEntry(vCount, i); k++ )
244  {
245  vCube = Vec_WecEntry( vCubes, Vec_IntEntry(vFirst, i) + k );
246  assert( Vec_IntEntry( vCube, 0 ) == i );
247  Vec_IntForEachEntryStart( vCube, Lit, v, 1 )
248  {
249  pFanin = Abc_NtkObj(pNtk, Abc_Lit2Var(Lit));
250  iFanin = Vec_IntEntry(vPres, Abc_ObjId(pFanin));
251  assert( iFanin >= 0 && iFanin < Abc_ObjFaninNum(pNode) );
252  pCube[iFanin] = Abc_LitIsCompl(Lit) ? '0' : '1';
253  }
254  pCube += Abc_ObjFaninNum(pNode) + 3;
255  }
256  // complement SOP if the original one was complemented
257  if ( pNode->pData && Abc_SopIsComplement((char *)pNode->pData) )
258  Abc_SopComplement( pSop );
259  pNode->pData = pSop;
260  // clean fanins
261  Abc_ObjForEachFanin( pNode, pFanin, v )
262  Vec_IntWriteEntry( vPres, Abc_ObjId(pFanin), -1 );
263  }
264  Vec_IntFree( vFirst );
265  Vec_IntFree( vCount );
266  Vec_IntFree( vPres );
267 }
268 
269 /**Function*************************************************************
270 
271  Synopsis [Makes sure the nodes do not have complemented and duplicated fanins.]
272 
273  Description []
274 
275  SideEffects []
276 
277  SeeAlso []
278 
279 ***********************************************************************/
281 {
282  Abc_Obj_t * pNode;
283  int i;
284 // Abc_NtkForEachObj( pNtk, pNode, i )
285 // Abc_ObjPrint( stdout, pNode );
286  Abc_NtkForEachNode( pNtk, pNode, i )
287  if ( !Vec_IntCheckUniqueSmall( &pNode->vFanins ) )
288  return 0;
289  return 1;
290 }
291 
292 /**Function*************************************************************
293 
294  Synopsis []
295 
296  Description []
297 
298  SideEffects []
299 
300  SeeAlso []
301 
302 ***********************************************************************/
303 int Abc_NtkFxPerform( Abc_Ntk_t * pNtk, int nNewNodesMax, int LitCountMax, int fVerbose, int fVeryVerbose )
304 {
305  extern int Fx_FastExtract( Vec_Wec_t * vCubes, int ObjIdMax, int nNewNodesMax, int LitCountMax, int fVerbose, int fVeryVerbose );
306  Vec_Wec_t * vCubes;
307  assert( Abc_NtkIsSopLogic(pNtk) );
308  // check unique fanins
309  if ( !Abc_NtkFxCheck(pNtk) )
310  {
311  printf( "Abc_NtkFastExtract: Nodes have duplicated fanins. FX is not performed.\n" );
312  return 0;
313  }
314  // sweep removes useless nodes
315  Abc_NtkCleanup( pNtk, 0 );
316 // Abc_NtkOrderFanins( pNtk );
317  // makes sure the SOPs are SCC-free and D1C-free
318  Abc_NtkMakeLegit( pNtk );
319  // collect information about the covers
320  vCubes = Abc_NtkFxRetrieve( pNtk );
321  // call the fast extract procedure
322  if ( Fx_FastExtract( vCubes, Abc_NtkObjNumMax(pNtk), nNewNodesMax, LitCountMax, fVerbose, fVeryVerbose ) > 0 )
323  {
324  // update the network
325  Abc_NtkFxInsert( pNtk, vCubes );
326  Vec_WecFree( vCubes );
327  if ( !Abc_NtkCheck( pNtk ) )
328  printf( "Abc_NtkFxPerform: The network check has failed.\n" );
329  return 1;
330  }
331  else
332  printf( "Warning: The network has not been changed by \"fx\".\n" );
333  Vec_WecFree( vCubes );
334  return 0;
335 }
336 
337 
338 
339 /**Function*************************************************************
340 
341  Synopsis [Starting the manager.]
342 
343  Description []
344 
345  SideEffects []
346 
347  SeeAlso []
348 
349 ***********************************************************************/
351 {
352  Fx_Man_t * p;
353  p = ABC_CALLOC( Fx_Man_t, 1 );
354  p->vCubes = vCubes;
355  // temporary data
356  p->vCubesS = Vec_IntAlloc( 100 );
357  p->vCubesD = Vec_IntAlloc( 100 );
358  p->vCompls = Vec_IntAlloc( 100 );
359  p->vCubeFree = Vec_IntAlloc( 100 );
360  p->vDiv = Vec_IntAlloc( 100 );
361  return p;
362 }
364 {
365 // Vec_WecFree( p->vCubes );
366  Vec_WecFree( p->vLits );
367  Vec_IntFree( p->vCounts );
368  Hsh_VecManStop( p->pHash );
369  Vec_FltFree( p->vWeights );
370  Vec_QueFree( p->vPrio );
371  Vec_IntFree( p->vVarCube );
372  Vec_IntFree( p->vLevels );
373  // temporary data
374  Vec_IntFree( p->vCubesS );
375  Vec_IntFree( p->vCubesD );
376  Vec_IntFree( p->vCompls );
377  Vec_IntFree( p->vCubeFree );
378  Vec_IntFree( p->vDiv );
379  ABC_FREE( p );
380 }
381 
382 /**Function*************************************************************
383 
384  Synopsis [Compute levels of the nodes.]
385 
386  Description []
387 
388  SideEffects []
389 
390  SeeAlso []
391 
392 ***********************************************************************/
393 static inline int Fx_ManComputeLevelDiv( Fx_Man_t * p, Vec_Int_t * vCubeFree )
394 {
395  int i, Lit, Level = 0;
396  Vec_IntForEachEntry( vCubeFree, Lit, i )
397  Level = Abc_MaxInt( Level, Vec_IntEntry(p->vLevels, Abc_Lit2Var(Abc_Lit2Var(Lit))) );
398  return Abc_MinInt( Level, 800 );
399 }
400 static inline int Fx_ManComputeLevelCube( Fx_Man_t * p, Vec_Int_t * vCube )
401 {
402  int k, Lit, Level = 0;
403  Vec_IntForEachEntryStart( vCube, Lit, k, 1 )
404  Level = Abc_MaxInt( Level, Vec_IntEntry(p->vLevels, Abc_Lit2Var(Lit)) );
405  return Level;
406 }
408 {
409  Vec_Int_t * vCube;
410  int i, iVar, iFirst = 0;
411  iVar = Vec_IntEntry( Vec_WecEntry(p->vCubes,0), 0 );
412  p->vLevels = Vec_IntStart( p->nVars );
413  Vec_WecForEachLevel( p->vCubes, vCube, i )
414  {
415  if ( iVar != Vec_IntEntry(vCube, 0) )
416  {
417  // add the number of cubes
418  Vec_IntAddToEntry( p->vLevels, iVar, i - iFirst );
419  iVar = Vec_IntEntry(vCube, 0);
420  iFirst = i;
421  }
422  Vec_IntUpdateEntry( p->vLevels, iVar, Fx_ManComputeLevelCube(p, vCube) );
423  }
424 }
425 
426 /**Function*************************************************************
427 
428  Synopsis [Printing procedures.]
429 
430  Description []
431 
432  SideEffects []
433 
434  SeeAlso []
435 
436 ***********************************************************************/
437 static inline char Fx_PrintDivLit( int Lit ) { return (Abc_LitIsCompl(Lit) ? 'A' : 'a') + Abc_Lit2Var(Lit); }
438 static inline void Fx_PrintDivOneReal( Vec_Int_t * vDiv )
439 {
440  int i, Lit;
441  Vec_IntForEachEntry( vDiv, Lit, i )
442  if ( !Abc_LitIsCompl(Lit) )
443  printf( "%c", Fx_PrintDivLit(Abc_Lit2Var(Lit)) );
444  printf( " + " );
445  Vec_IntForEachEntry( vDiv, Lit, i )
446  if ( Abc_LitIsCompl(Lit) )
447  printf( "%c", Fx_PrintDivLit(Abc_Lit2Var(Lit)) );
448 }
449 static inline void Fx_PrintDivOne( Vec_Int_t * vDiv )
450 {
451  int i, Lit;
452  Vec_IntForEachEntry( vDiv, Lit, i )
453  if ( !Abc_LitIsCompl(Lit) )
454  printf( "%c", Fx_PrintDivLit( Abc_Var2Lit(i, Abc_LitIsCompl(Lit)) ) );
455  printf( " + " );
456  Vec_IntForEachEntry( vDiv, Lit, i )
457  if ( Abc_LitIsCompl(Lit) )
458  printf( "%c", Fx_PrintDivLit( Abc_Var2Lit(i, Abc_LitIsCompl(Lit)) ) );
459 }
460 static inline void Fx_PrintDivArray( Vec_Int_t * vDiv )
461 {
462  int i, Lit;
463  Vec_IntForEachEntry( vDiv, Lit, i )
464  if ( !Abc_LitIsCompl(Lit) )
465  printf( "%d(1) ", Abc_Lit2Var(Lit) );
466  printf( " + " );
467  Vec_IntForEachEntry( vDiv, Lit, i )
468  if ( Abc_LitIsCompl(Lit) )
469  printf( "%d(2) ", Abc_Lit2Var(Lit) );
470 }
471 static inline void Fx_PrintDiv( Fx_Man_t * p, int iDiv )
472 {
473  int i;
474  printf( "%4d : ", p->nDivs );
475  printf( "Div %7d : ", iDiv );
476  printf( "Weight %12.5f ", Vec_FltEntry(p->vWeights, iDiv) );
477 // printf( "Compl %4d ", p->nCompls );
478  Fx_PrintDivOne( Hsh_VecReadEntry(p->pHash, iDiv) );
479  for ( i = Vec_IntSize(Hsh_VecReadEntry(p->pHash, iDiv)) + 3; i < 16; i++ )
480  printf( " " );
481  printf( "Lits =%7d ", p->nLits );
482  printf( "Divs =%8d ", Hsh_VecSize(p->pHash) );
483  Abc_PrintTime( 1, "Time", Abc_Clock() - p->timeStart );
484 }
485 static void Fx_PrintDivisors( Fx_Man_t * p )
486 {
487  int iDiv;
488  for ( iDiv = 0; iDiv < Vec_FltSize(p->vWeights); iDiv++ )
489  Fx_PrintDiv( p, iDiv );
490 }
491 static void Fx_PrintLiterals( Fx_Man_t * p )
492 {
493  Vec_Int_t * vTemp;
494  int i;
495  Vec_WecForEachLevel( p->vLits, vTemp, i )
496  {
497  printf( "%c : ", Fx_PrintDivLit(i) );
498  Vec_IntPrint( vTemp );
499  }
500 }
501 static void Fx_PrintMatrix( Fx_Man_t * p )
502 {
503  Vec_Int_t * vCube;
504  int i, v, Lit, nObjs;
505  char * pLine;
506  if ( Vec_WecSize(p->vLits)/2 > 26 )
507  return;
508  printf( " " );
509  nObjs = Vec_WecSize(p->vLits)/2;
510  for ( i = 0; i < Abc_MinInt(nObjs, 26); i++ )
511  printf( "%c", 'a' + i );
512  printf( "\n" );
513  pLine = ABC_CALLOC( char, nObjs+1 );
514  Vec_WecForEachLevel( p->vCubes, vCube, i )
515  {
516  if ( Vec_IntSize(vCube) == 0 )
517  continue;
518  memset( pLine, '-', nObjs );
519  Vec_IntForEachEntryStart( vCube, Lit, v, 1 )
520  {
521  assert( Abc_Lit2Var(Lit) < nObjs );
522  pLine[Abc_Lit2Var(Lit)] = Abc_LitIsCompl(Lit) ? '0' : '1';
523  }
524  printf( "%6d : %s %4d\n", i, pLine, Vec_IntEntry(vCube, 0) );
525  }
526  ABC_FREE( pLine );
527  Fx_PrintLiterals( p );
528  Fx_PrintDivisors( p );
529 }
530 static void Fx_PrintStats( Fx_Man_t * p, abctime clk )
531 {
532  printf( "Cubes =%8d ", Vec_WecSizeUsed(p->vCubes) );
533  printf( "Lits =%8d ", Vec_WecSizeUsed(p->vLits) );
534  printf( "Divs =%8d ", Hsh_VecSize(p->pHash) );
535  printf( "Divs+ =%8d ", Vec_QueSize(p->vPrio) );
536  printf( "Compl =%8d ", p->nDivMux[1] );
537  printf( "Extr =%7d ", p->nDivs );
538 // printf( "DivsS =%6d ", p->nDivsS );
539 // printf( "PairS =%6d ", p->nPairsS );
540 // printf( "PairD =%6d ", p->nPairsD );
541  Abc_PrintTime( 1, "Time", clk );
542 // printf( "\n" );
543 }
544 
545 /**Function*************************************************************
546 
547  Synopsis [Returns 1 if the divisor should be complemented.]
548 
549  Description [Normalizes the divisor by putting, first, positive control
550  literal first and, second, positive data1 literal. As the result,
551  a MUX divisor is (ab + !ac) and an XOR divisor is (ab + !a!b).]
552 
553  SideEffects []
554 
555  SeeAlso []
556 
557 ***********************************************************************/
558 static int Fx_ManDivNormalize( Vec_Int_t * vCubeFree ) // return 1 if complemented
559 {
560  int * L = Vec_IntArray(vCubeFree);
561  int RetValue = 0, LitA0 = -1, LitB0 = -1, LitA1 = -1, LitB1 = -1;
562  assert( Vec_IntSize(vCubeFree) == 4 );
563  if ( Abc_LitIsCompl(L[0]) != Abc_LitIsCompl(L[1]) && (L[0] >> 2) == (L[1] >> 2) ) // diff cubes, same vars
564  {
565  if ( Abc_LitIsCompl(L[2]) == Abc_LitIsCompl(L[3]) )
566  return -1;
567  LitA0 = Abc_Lit2Var(L[0]), LitB0 = Abc_Lit2Var(L[1]);
568  if ( Abc_LitIsCompl(L[0]) == Abc_LitIsCompl(L[2]) )
569  {
570  assert( Abc_LitIsCompl(L[1]) == Abc_LitIsCompl(L[3]) );
571  LitA1 = Abc_Lit2Var(L[2]), LitB1 = Abc_Lit2Var(L[3]);
572  }
573  else
574  {
575  assert( Abc_LitIsCompl(L[0]) == Abc_LitIsCompl(L[3]) );
576  assert( Abc_LitIsCompl(L[1]) == Abc_LitIsCompl(L[2]) );
577  LitA1 = Abc_Lit2Var(L[3]), LitB1 = Abc_Lit2Var(L[2]);
578  }
579  }
580  else if ( Abc_LitIsCompl(L[1]) != Abc_LitIsCompl(L[2]) && (L[1] >> 2) == (L[2] >> 2) )
581  {
582  if ( Abc_LitIsCompl(L[0]) == Abc_LitIsCompl(L[3]) )
583  return -1;
584  LitA0 = Abc_Lit2Var(L[1]), LitB0 = Abc_Lit2Var(L[2]);
585  if ( Abc_LitIsCompl(L[1]) == Abc_LitIsCompl(L[0]) )
586  LitA1 = Abc_Lit2Var(L[0]), LitB1 = Abc_Lit2Var(L[3]);
587  else
588  LitA1 = Abc_Lit2Var(L[3]), LitB1 = Abc_Lit2Var(L[0]);
589  }
590  else if ( Abc_LitIsCompl(L[2]) != Abc_LitIsCompl(L[3]) && (L[2] >> 2) == (L[3] >> 2) )
591  {
592  if ( Abc_LitIsCompl(L[0]) == Abc_LitIsCompl(L[1]) )
593  return -1;
594  LitA0 = Abc_Lit2Var(L[2]), LitB0 = Abc_Lit2Var(L[3]);
595  if ( Abc_LitIsCompl(L[2]) == Abc_LitIsCompl(L[0]) )
596  LitA1 = Abc_Lit2Var(L[0]), LitB1 = Abc_Lit2Var(L[1]);
597  else
598  LitA1 = Abc_Lit2Var(L[1]), LitB1 = Abc_Lit2Var(L[0]);
599  }
600  else
601  return -1;
602  assert( LitA0 == Abc_LitNot(LitB0) );
603  if ( Abc_LitIsCompl(LitA0) )
604  {
605  ABC_SWAP( int, LitA0, LitB0 );
606  ABC_SWAP( int, LitA1, LitB1 );
607  }
608  assert( !Abc_LitIsCompl(LitA0) );
609  if ( Abc_LitIsCompl(LitA1) )
610  {
611  LitA1 = Abc_LitNot(LitA1);
612  LitB1 = Abc_LitNot(LitB1);
613  RetValue = 1;
614  }
615  assert( !Abc_LitIsCompl(LitA1) );
616  // arrange literals in such as a way that
617  // - the first two literals are control literals from different cubes
618  // - the third literal is non-complented data input
619  // - the forth literal is possibly complemented data input
620  L[0] = Abc_Var2Lit( LitA0, 0 );
621  L[1] = Abc_Var2Lit( LitB0, 1 );
622  L[2] = Abc_Var2Lit( LitA1, 0 );
623  L[3] = Abc_Var2Lit( LitB1, 1 );
624  return RetValue;
625 }
626 
627 /**Function*************************************************************
628 
629  Synopsis [Find a cube-free divisor of the two cubes.]
630 
631  Description []
632 
633  SideEffects []
634 
635  SeeAlso []
636 
637 ***********************************************************************/
638 int Fx_ManDivFindCubeFree( Vec_Int_t * vArr1, Vec_Int_t * vArr2, Vec_Int_t * vCubeFree )
639 {
640  int * pBeg1 = vArr1->pArray + 1; // skip variable ID
641  int * pBeg2 = vArr2->pArray + 1; // skip variable ID
642  int * pEnd1 = vArr1->pArray + vArr1->nSize;
643  int * pEnd2 = vArr2->pArray + vArr2->nSize;
644  int Counter = 0, fAttr0 = 0, fAttr1 = 1;
645  Vec_IntClear( vCubeFree );
646  while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
647  {
648  if ( *pBeg1 == *pBeg2 )
649  pBeg1++, pBeg2++, Counter++;
650  else if ( *pBeg1 < *pBeg2 )
651  Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg1++, fAttr0) );
652  else
653  {
654  if ( Vec_IntSize(vCubeFree) == 0 )
655  fAttr0 = 1, fAttr1 = 0;
656  Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg2++, fAttr1) );
657  }
658  }
659  while ( pBeg1 < pEnd1 )
660  Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg1++, fAttr0) );
661  while ( pBeg2 < pEnd2 )
662  Vec_IntPush( vCubeFree, Abc_Var2Lit(*pBeg2++, fAttr1) );
663  if ( Vec_IntSize(vCubeFree) == 0 )
664  printf( "The SOP has duplicated cubes.\n" );
665  else if ( Vec_IntSize(vCubeFree) == 1 )
666  printf( "The SOP has contained cubes.\n" );
667  else if ( Vec_IntSize(vCubeFree) == 2 && Abc_Lit2Var(Abc_Lit2Var(Vec_IntEntry(vCubeFree, 0))) == Abc_Lit2Var(Abc_Lit2Var(Vec_IntEntry(vCubeFree, 1))) )
668  printf( "The SOP has distance-1 cubes or it is not a prime cover. Please make sure the result verifies.\n" );
669  assert( !Abc_LitIsCompl(Vec_IntEntry(vCubeFree, 0)) );
670  return Counter;
671 }
672 
673 /**Function*************************************************************
674 
675  Synopsis [Procedures operating on a two-cube divisor.]
676 
677  Description []
678 
679  SideEffects []
680 
681  SeeAlso []
682 
683 ***********************************************************************/
684 static inline void Fx_ManDivFindPivots( Vec_Int_t * vDiv, int * pLit0, int * pLit1 )
685 {
686  int i, Lit;
687  *pLit0 = -1;
688  *pLit1 = -1;
689  Vec_IntForEachEntry( vDiv, Lit, i )
690  {
691  if ( Abc_LitIsCompl(Lit) )
692  {
693  if ( *pLit1 == -1 )
694  *pLit1 = Abc_Lit2Var(Lit);
695  }
696  else
697  {
698  if ( *pLit0 == -1 )
699  *pLit0 = Abc_Lit2Var(Lit);
700  }
701  if ( *pLit0 >= 0 && *pLit1 >= 0 )
702  return;
703  }
704 }
705 static inline int Fx_ManDivRemoveLits( Vec_Int_t * vCube, Vec_Int_t * vDiv, int fCompl )
706 {
707  int i, Lit, Count = 0;
708  assert( !fCompl || Vec_IntSize(vDiv) == 4 );
709  Vec_IntForEachEntry( vDiv, Lit, i )
710  Count += Vec_IntRemove1( vCube, Abc_Lit2Var(Lit) ^ (fCompl && i > 1) ); // the last two lits can be complemented
711  return Count;
712 }
713 static inline void Fx_ManDivAddLits( Vec_Int_t * vCube, Vec_Int_t * vCube2, Vec_Int_t * vDiv )
714 {
715  int i, Lit, * pArray;
716 // Vec_IntClear( vCube );
717 // Vec_IntClear( vCube2 );
718  Vec_IntForEachEntry( vDiv, Lit, i )
719  if ( Abc_LitIsCompl(Lit) )
720  Vec_IntPush( vCube2, Abc_Lit2Var(Lit) );
721  else
722  Vec_IntPush( vCube, Abc_Lit2Var(Lit) );
723  if ( Vec_IntSize(vDiv) == 4 && Vec_IntSize(vCube) == 3 )
724  {
725  assert( Vec_IntSize(vCube2) == 3 );
726  pArray = Vec_IntArray(vCube);
727  if ( pArray[1] > pArray[2] )
728  ABC_SWAP( int, pArray[1], pArray[2] );
729  pArray = Vec_IntArray(vCube2);
730  if ( pArray[1] > pArray[2] )
731  ABC_SWAP( int, pArray[1], pArray[2] );
732  }
733 }
734 
735 /**Function*************************************************************
736 
737  Synopsis [Setting up the data-structure.]
738 
739  Description []
740 
741  SideEffects []
742 
743  SeeAlso []
744 
745 ***********************************************************************/
746 void Fx_ManCreateLiterals( Fx_Man_t * p, int nVars )
747 {
748  Vec_Int_t * vCube;
749  int i, k, Lit, Count;
750  // find the number of variables
751  p->nVars = p->nLits = 0;
752  Vec_WecForEachLevel( p->vCubes, vCube, i )
753  {
754  assert( Vec_IntSize(vCube) > 0 );
755  p->nVars = Abc_MaxInt( p->nVars, Vec_IntEntry(vCube, 0) );
756  p->nLits += Vec_IntSize(vCube) - 1;
757  Vec_IntForEachEntryStart( vCube, Lit, k, 1 )
758  p->nVars = Abc_MaxInt( p->nVars, Abc_Lit2Var(Lit) );
759  }
760 // p->nVars++;
761  assert( p->nVars < nVars );
762  p->nVars = nVars;
763  // count literals
764  p->vCounts = Vec_IntStart( 2*p->nVars );
765  Vec_WecForEachLevel( p->vCubes, vCube, i )
766  Vec_IntForEachEntryStart( vCube, Lit, k, 1 )
767  Vec_IntAddToEntry( p->vCounts, Lit, 1 );
768  // start literals
769  p->vLits = Vec_WecStart( 2*p->nVars );
770  Vec_IntForEachEntry( p->vCounts, Count, Lit )
771  Vec_IntGrow( Vec_WecEntry(p->vLits, Lit), Count );
772  // fill out literals
773  Vec_WecForEachLevel( p->vCubes, vCube, i )
774  Vec_IntForEachEntryStart( vCube, Lit, k, 1 )
775  Vec_WecPush( p->vLits, Lit, i );
776  // create mapping of variable into the first cube
777  p->vVarCube = Vec_IntStartFull( p->nVars );
778  Vec_WecForEachLevel( p->vCubes, vCube, i )
779  if ( Vec_IntEntry(p->vVarCube, Vec_IntEntry(vCube, 0)) == -1 )
780  Vec_IntWriteEntry( p->vVarCube, Vec_IntEntry(vCube, 0), i );
781 }
782 int Fx_ManCubeSingleCubeDivisors( Fx_Man_t * p, Vec_Int_t * vPivot, int fRemove, int fUpdate )
783 {
784  int k, n, Lit, Lit2, iDiv;
785  if ( Vec_IntSize(vPivot) < 2 )
786  return 0;
787  Vec_IntForEachEntryStart( vPivot, Lit, k, 1 )
788  Vec_IntForEachEntryStart( vPivot, Lit2, n, k+1 )
789  {
790  assert( Lit < Lit2 );
791  Vec_IntClear( p->vCubeFree );
792  Vec_IntPush( p->vCubeFree, Abc_Var2Lit(Abc_LitNot(Lit), 0) );
793  Vec_IntPush( p->vCubeFree, Abc_Var2Lit(Abc_LitNot(Lit2), 1) );
794  iDiv = Hsh_VecManAdd( p->pHash, p->vCubeFree );
795  if ( !fRemove )
796  {
797  if ( Vec_FltSize(p->vWeights) == iDiv )
798  {
799  Vec_FltPush(p->vWeights, -2 + 0.9 - 0.001 * Fx_ManComputeLevelDiv(p, p->vCubeFree));
800  p->nDivsS++;
801  }
802  assert( iDiv < Vec_FltSize(p->vWeights) );
803  Vec_FltAddToEntry( p->vWeights, iDiv, 1 );
804  p->nPairsS++;
805  }
806  else
807  {
808  assert( iDiv < Vec_FltSize(p->vWeights) );
809  Vec_FltAddToEntry( p->vWeights, iDiv, -1 );
810  p->nPairsS--;
811  }
812  if ( fUpdate )
813  {
814  if ( Vec_QueIsMember(p->vPrio, iDiv) )
815  Vec_QueUpdate( p->vPrio, iDiv );
816  else if ( !fRemove )
817  Vec_QuePush( p->vPrio, iDiv );
818  }
819  }
820  return Vec_IntSize(vPivot) * (Vec_IntSize(vPivot) - 1) / 2;
821 }
822 void Fx_ManCubeDoubleCubeDivisors( Fx_Man_t * p, int iFirst, Vec_Int_t * vPivot, int fRemove, int fUpdate )
823 {
824  Vec_Int_t * vCube;
825  int i, iDiv, Base;
826  Vec_WecForEachLevelStart( p->vCubes, vCube, i, iFirst )
827  {
828  if ( Vec_IntSize(vCube) == 0 || vCube == vPivot )
829  continue;
830  if ( Vec_WecIntHasMark(vCube) && Vec_WecIntHasMark(vPivot) && vCube > vPivot )
831  continue;
832  if ( Vec_IntEntry(vCube, 0) != Vec_IntEntry(vPivot, 0) )
833  break;
834  Base = Fx_ManDivFindCubeFree( vCube, vPivot, p->vCubeFree );
835  if ( Vec_IntSize(p->vCubeFree) == 4 )
836  {
837  int Value = Fx_ManDivNormalize( p->vCubeFree );
838  if ( Value == 0 )
839  p->nDivMux[0]++;
840  else if ( Value == 1 )
841  p->nDivMux[1]++;
842  else
843  p->nDivMux[2]++;
844  }
845  if ( p->LitCountMax && p->LitCountMax < Vec_IntSize(p->vCubeFree) )
846  continue;
847  iDiv = Hsh_VecManAdd( p->pHash, p->vCubeFree );
848  if ( !fRemove )
849  {
850  if ( iDiv == Vec_FltSize(p->vWeights) )
851  Vec_FltPush(p->vWeights, -Vec_IntSize(p->vCubeFree) + 0.9 - 0.0009 * Fx_ManComputeLevelDiv(p, p->vCubeFree));
852  assert( iDiv < Vec_FltSize(p->vWeights) );
853  Vec_FltAddToEntry( p->vWeights, iDiv, Base + Vec_IntSize(p->vCubeFree) - 1 );
854  p->nPairsD++;
855  }
856  else
857  {
858  assert( iDiv < Vec_FltSize(p->vWeights) );
859  Vec_FltAddToEntry( p->vWeights, iDiv, -(Base + Vec_IntSize(p->vCubeFree) - 1) );
860  p->nPairsD--;
861  }
862  if ( fUpdate )
863  {
864  if ( Vec_QueIsMember(p->vPrio, iDiv) )
865  Vec_QueUpdate( p->vPrio, iDiv );
866  else if ( !fRemove )
867  Vec_QuePush( p->vPrio, iDiv );
868  }
869  }
870 }
872 {
873  Vec_Int_t * vCube;
874  float Weight;
875  int i;
876  // alloc hash table
877  assert( p->pHash == NULL );
878  p->pHash = Hsh_VecManStart( 1000 );
879  p->vWeights = Vec_FltAlloc( 1000 );
880  // create single-cube two-literal divisors
881  Vec_WecForEachLevel( p->vCubes, vCube, i )
882  Fx_ManCubeSingleCubeDivisors( p, vCube, 0, 0 ); // add - no update
883  assert( p->nDivsS == Vec_FltSize(p->vWeights) );
884  // create two-cube divisors
885  Vec_WecForEachLevel( p->vCubes, vCube, i )
886  Fx_ManCubeDoubleCubeDivisors( p, i+1, vCube, 0, 0 ); // add - no update
887  // create queue with all divisors
888  p->vPrio = Vec_QueAlloc( Vec_FltSize(p->vWeights) );
889  Vec_QueSetPriority( p->vPrio, Vec_FltArrayP(p->vWeights) );
890  Vec_FltForEachEntry( p->vWeights, Weight, i )
891  if ( Weight > 0.0 )
892  Vec_QuePush( p->vPrio, i );
893 }
894 
895 
896 /**Function*************************************************************
897 
898  Synopsis [Compress the cubes by removing unused ones.]
899 
900  Description []
901 
902  SideEffects []
903 
904  SeeAlso []
905 
906 ***********************************************************************/
907 static inline void Fx_ManCompressCubes( Vec_Wec_t * vCubes, Vec_Int_t * vLit2Cube )
908 {
909  int i, CubeId, k = 0;
910  Vec_IntForEachEntry( vLit2Cube, CubeId, i )
911  if ( Vec_IntSize(Vec_WecEntry(vCubes, CubeId)) > 0 )
912  Vec_IntWriteEntry( vLit2Cube, k++, CubeId );
913  Vec_IntShrink( vLit2Cube, k );
914 }
915 
916 
917 /**Function*************************************************************
918 
919  Synopsis [Find command cube pairs.]
920 
921  Description []
922 
923  SideEffects []
924 
925  SeeAlso []
926 
927 ***********************************************************************/
928 static inline int Fx_ManGetCubeVar( Vec_Wec_t * vCubes, int iCube ) { return Vec_IntEntry( Vec_WecEntry(vCubes, iCube), 0 ); }
929 void Fx_ManFindCommonPairs( Vec_Wec_t * vCubes, Vec_Int_t * vPart0, Vec_Int_t * vPart1, Vec_Int_t * vPairs, Vec_Int_t * vCompls, Vec_Int_t * vDiv, Vec_Int_t * vCubeFree )
930 {
931  int * pBeg1 = vPart0->pArray;
932  int * pBeg2 = vPart1->pArray;
933  int * pEnd1 = vPart0->pArray + vPart0->nSize;
934  int * pEnd2 = vPart1->pArray + vPart1->nSize;
935  int i, k, i_, k_, fCompl, CubeId1, CubeId2;
936  Vec_IntClear( vPairs );
937  Vec_IntClear( vCompls );
938  while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
939  {
940  CubeId1 = Fx_ManGetCubeVar(vCubes, *pBeg1);
941  CubeId2 = Fx_ManGetCubeVar(vCubes, *pBeg2);
942  if ( CubeId1 == CubeId2 )
943  {
944  for ( i = 1; pBeg1+i < pEnd1; i++ )
945  if ( CubeId1 != Fx_ManGetCubeVar(vCubes, pBeg1[i]) )
946  break;
947  for ( k = 1; pBeg2+k < pEnd2; k++ )
948  if ( CubeId1 != Fx_ManGetCubeVar(vCubes, pBeg2[k]) )
949  break;
950  for ( i_ = 0; i_ < i; i_++ )
951  for ( k_ = 0; k_ < k; k_++ )
952  {
953  if ( pBeg1[i_] == pBeg2[k_] )
954  continue;
955  Fx_ManDivFindCubeFree( Vec_WecEntry(vCubes, pBeg1[i_]), Vec_WecEntry(vCubes, pBeg2[k_]), vCubeFree );
956  fCompl = (Vec_IntSize(vCubeFree) == 4 && Fx_ManDivNormalize(vCubeFree) == 1);
957  if ( !Vec_IntEqual( vDiv, vCubeFree ) )
958  continue;
959  Vec_IntPush( vPairs, pBeg1[i_] );
960  Vec_IntPush( vPairs, pBeg2[k_] );
961  Vec_IntPush( vCompls, fCompl );
962  }
963  pBeg1 += i;
964  pBeg2 += k;
965  }
966  else if ( CubeId1 < CubeId2 )
967  pBeg1++;
968  else
969  pBeg2++;
970  }
971 }
972 
973 /**Function*************************************************************
974 
975  Synopsis [Updates the data-structure when one divisor is selected.]
976 
977  Description []
978 
979  SideEffects []
980 
981  SeeAlso []
982 
983 ***********************************************************************/
984 void Fx_ManUpdate( Fx_Man_t * p, int iDiv )
985 {
986  Vec_Int_t * vCube, * vCube2, * vLitP, * vLitN;
987  Vec_Int_t * vDiv = p->vDiv;
988  int nLitsNew = p->nLits - (int)Vec_FltEntry(p->vWeights, iDiv);
989  int i, k, Lit0, Lit1, iVarNew, RetValue, Level;
990  float Diff = Vec_FltEntry(p->vWeights, iDiv) - (float)((int)Vec_FltEntry(p->vWeights, iDiv));
991  assert( Diff > 0.0 && Diff < 1.0 );
992 
993  // get the divisor and select pivot variables
994  p->nDivs++;
995  Vec_IntClear( vDiv );
996  Vec_IntAppend( vDiv, Hsh_VecReadEntry(p->pHash, iDiv) );
997  Fx_ManDivFindPivots( vDiv, &Lit0, &Lit1 );
998  assert( Lit0 >= 0 && Lit1 >= 0 );
999 
1000  // if the input cover is not prime, it may happen that we are extracting divisor (x + !x)
1001  // although it is not strictly correct, it seems to be fine to just skip such divisors
1002  if ( Abc_Lit2Var(Lit0) == Abc_Lit2Var(Lit1) && Vec_IntSize(Hsh_VecReadEntry(p->pHash, iDiv)) == 2 )
1003  return;
1004 
1005  // collect single-cube-divisor cubes
1006  Vec_IntClear( p->vCubesS );
1007  if ( Vec_IntSize(vDiv) == 2 )
1008  {
1009  Fx_ManCompressCubes( p->vCubes, Vec_WecEntry(p->vLits, Abc_LitNot(Lit0)) );
1010  Fx_ManCompressCubes( p->vCubes, Vec_WecEntry(p->vLits, Abc_LitNot(Lit1)) );
1011  Vec_IntTwoRemoveCommon( Vec_WecEntry(p->vLits, Abc_LitNot(Lit0)), Vec_WecEntry(p->vLits, Abc_LitNot(Lit1)), p->vCubesS );
1012  }
1013 
1014  // collect double-cube-divisor cube pairs
1015  Fx_ManCompressCubes( p->vCubes, Vec_WecEntry(p->vLits, Lit0) );
1016  Fx_ManCompressCubes( p->vCubes, Vec_WecEntry(p->vLits, Lit1) );
1017  Fx_ManFindCommonPairs( p->vCubes, Vec_WecEntry(p->vLits, Lit0), Vec_WecEntry(p->vLits, Lit1), p->vCubesD, p->vCompls, vDiv, p->vCubeFree );
1018 
1019  // subtract cost of single-cube divisors
1020  Fx_ManForEachCubeVec( p->vCubesS, p->vCubes, vCube, i )
1021  Fx_ManCubeSingleCubeDivisors( p, vCube, 1, 1 ); // remove - update
1022  Fx_ManForEachCubeVec( p->vCubesD, p->vCubes, vCube, i )
1023  Fx_ManCubeSingleCubeDivisors( p, vCube, 1, 1 ); // remove - update
1024 
1025  // mark the cubes to be removed
1026  Vec_WecMarkLevels( p->vCubes, p->vCubesS );
1027  Vec_WecMarkLevels( p->vCubes, p->vCubesD );
1028 
1029  // subtract cost of double-cube divisors
1030  Fx_ManForEachCubeVec( p->vCubesS, p->vCubes, vCube, i )
1031  Fx_ManCubeDoubleCubeDivisors( p, Fx_ManGetFirstVarCube(p, vCube), vCube, 1, 1 ); // remove - update
1032  Fx_ManForEachCubeVec( p->vCubesD, p->vCubes, vCube, i )
1033  Fx_ManCubeDoubleCubeDivisors( p, Fx_ManGetFirstVarCube(p, vCube), vCube, 1, 1 ); // remove - update
1034 
1035  // unmark the cubes to be removed
1036  Vec_WecUnmarkLevels( p->vCubes, p->vCubesS );
1037  Vec_WecUnmarkLevels( p->vCubes, p->vCubesD );
1038 
1039  // create new divisor
1040  iVarNew = Vec_WecSize( p->vLits ) / 2;
1041  assert( Vec_IntSize(p->vVarCube) == iVarNew );
1042  Vec_IntPush( p->vVarCube, Vec_WecSize(p->vCubes) );
1043  vCube = Vec_WecPushLevel( p->vCubes );
1044  Vec_IntPush( vCube, iVarNew );
1045  if ( Vec_IntSize(vDiv) == 2 )
1046  {
1047  Vec_IntPush( vCube, Abc_LitNot(Lit0) );
1048  Vec_IntPush( vCube, Abc_LitNot(Lit1) );
1049  Level = 1 + Fx_ManComputeLevelCube( p, vCube );
1050  }
1051  else
1052  {
1053  vCube2 = Vec_WecPushLevel( p->vCubes );
1054  vCube = Vec_WecEntry( p->vCubes, Vec_WecSize(p->vCubes) - 2 );
1055  Vec_IntPush( vCube2, iVarNew );
1056  Fx_ManDivAddLits( vCube, vCube2, vDiv );
1057  Level = 2 + Abc_MaxInt( Fx_ManComputeLevelCube(p, vCube), Fx_ManComputeLevelCube(p, vCube2) );
1058  }
1059  assert( Vec_IntSize(p->vLevels) == iVarNew );
1060  Vec_IntPush( p->vLevels, Level );
1061  // do not add new cubes to the matrix
1062  p->nLits += Vec_IntSize( vDiv );
1063  // create new literals
1064  vLitP = Vec_WecPushLevel( p->vLits );
1065  vLitN = Vec_WecPushLevel( p->vLits );
1066  vLitP = Vec_WecEntry( p->vLits, Vec_WecSize(p->vLits) - 2 );
1067  // create updated single-cube divisor cubes
1068  Fx_ManForEachCubeVec( p->vCubesS, p->vCubes, vCube, i )
1069  {
1070  RetValue = Vec_IntRemove1( vCube, Abc_LitNot(Lit0) );
1071  RetValue += Vec_IntRemove1( vCube, Abc_LitNot(Lit1) );
1072  assert( RetValue == 2 );
1073  Vec_IntPush( vCube, Abc_Var2Lit(iVarNew, 0) );
1074  Vec_IntPush( vLitP, Vec_WecLevelId(p->vCubes, vCube) );
1075  p->nLits--;
1076  }
1077  // create updated double-cube divisor cube pairs
1078  k = 0;
1079  p->nCompls = 0;
1080  assert( Vec_IntSize(p->vCubesD) % 2 == 0 );
1081  assert( Vec_IntSize(p->vCubesD) == 2 * Vec_IntSize(p->vCompls) );
1082  for ( i = 0; i < Vec_IntSize(p->vCubesD); i += 2 )
1083  {
1084  int fCompl = Vec_IntEntry(p->vCompls, i/2);
1085  p->nCompls += fCompl;
1086  vCube = Vec_WecEntry( p->vCubes, Vec_IntEntry(p->vCubesD, i) );
1087  vCube2 = Vec_WecEntry( p->vCubes, Vec_IntEntry(p->vCubesD, i+1) );
1088  RetValue = Fx_ManDivRemoveLits( vCube, vDiv, fCompl ); // cube 2*i
1089  RetValue += Fx_ManDivRemoveLits( vCube2, vDiv, fCompl ); // cube 2*i+1
1090  assert( RetValue == Vec_IntSize(vDiv) );
1091  if ( Vec_IntSize(vDiv) == 2 || fCompl )
1092  {
1093  Vec_IntPush( vCube, Abc_Var2Lit(iVarNew, 1) );
1094  Vec_IntPush( vLitN, Vec_WecLevelId(p->vCubes, vCube) );
1095  }
1096  else
1097  {
1098  Vec_IntPush( vCube, Abc_Var2Lit(iVarNew, 0) );
1099  Vec_IntPush( vLitP, Vec_WecLevelId(p->vCubes, vCube) );
1100  }
1101  p->nLits -= Vec_IntSize(vDiv) + Vec_IntSize(vCube2) - 2;
1102  // remove second cube
1103  Vec_IntWriteEntry( p->vCubesD, k++, Vec_WecLevelId(p->vCubes, vCube) );
1104  Vec_IntClear( vCube2 );
1105  }
1106  assert( k == Vec_IntSize(p->vCubesD) / 2 );
1107  Vec_IntShrink( p->vCubesD, k );
1108  Vec_IntSort( p->vCubesD, 0 );
1109 
1110  // add cost of single-cube divisors
1111  Fx_ManForEachCubeVec( p->vCubesS, p->vCubes, vCube, i )
1112  Fx_ManCubeSingleCubeDivisors( p, vCube, 0, 1 ); // add - update
1113  Fx_ManForEachCubeVec( p->vCubesD, p->vCubes, vCube, i )
1114  Fx_ManCubeSingleCubeDivisors( p, vCube, 0, 1 ); // add - update
1115 
1116  // mark the cubes to be removed
1117  Vec_WecMarkLevels( p->vCubes, p->vCubesS );
1118  Vec_WecMarkLevels( p->vCubes, p->vCubesD );
1119 
1120  // add cost of double-cube divisors
1121  Fx_ManForEachCubeVec( p->vCubesS, p->vCubes, vCube, i )
1122  Fx_ManCubeDoubleCubeDivisors( p, Fx_ManGetFirstVarCube(p, vCube), vCube, 0, 1 ); // add - update
1123  Fx_ManForEachCubeVec( p->vCubesD, p->vCubes, vCube, i )
1124  Fx_ManCubeDoubleCubeDivisors( p, Fx_ManGetFirstVarCube(p, vCube), vCube, 0, 1 ); // add - update
1125 
1126  // unmark the cubes to be removed
1127  Vec_WecUnmarkLevels( p->vCubes, p->vCubesS );
1128  Vec_WecUnmarkLevels( p->vCubes, p->vCubesD );
1129 
1130  // add cost of the new divisor
1131  if ( Vec_IntSize(vDiv) > 2 )
1132  {
1133  vCube = Vec_WecEntry( p->vCubes, Vec_WecSize(p->vCubes) - 2 );
1134  vCube2 = Vec_WecEntry( p->vCubes, Vec_WecSize(p->vCubes) - 1 );
1135  Fx_ManCubeSingleCubeDivisors( p, vCube, 0, 1 ); // add - update
1136  Fx_ManCubeSingleCubeDivisors( p, vCube2, 0, 1 ); // add - update
1137  Vec_IntForEachEntryStart( vCube, Lit0, i, 1 )
1138  Vec_WecPush( p->vLits, Lit0, Vec_WecLevelId(p->vCubes, vCube) );
1139  Vec_IntForEachEntryStart( vCube2, Lit0, i, 1 )
1140  Vec_WecPush( p->vLits, Lit0, Vec_WecLevelId(p->vCubes, vCube2) );
1141  }
1142 
1143  // remove these cubes from the lit array of the divisor
1144  Vec_IntForEachEntry( vDiv, Lit0, i )
1145  {
1146  Vec_IntTwoRemove( Vec_WecEntry(p->vLits, Abc_Lit2Var(Lit0)), p->vCubesD );
1147  if ( p->nCompls && i > 1 ) // the last two lits are possibly complemented
1148  Vec_IntTwoRemove( Vec_WecEntry(p->vLits, Abc_LitNot(Abc_Lit2Var(Lit0))), p->vCubesD );
1149  }
1150 
1151  // check predicted improvement: (new SOP lits == old SOP lits - divisor weight)
1152  assert( p->nLits == nLitsNew );
1153 }
1154 
1155 /**Function*************************************************************
1156 
1157  Synopsis [Implements the traditional fast_extract algorithm.]
1158 
1159  Description [J. Rajski and J. Vasudevamurthi, "The testability-
1160  preserving concurrent decomposition and factorization of Boolean
1161  expressions", IEEE TCAD, Vol. 11, No. 6, June 1992, pp. 778-793.]
1162 
1163  SideEffects []
1164 
1165  SeeAlso []
1166 
1167 ***********************************************************************/
1168 int Fx_FastExtract( Vec_Wec_t * vCubes, int ObjIdMax, int nNewNodesMax, int LitCountMax, int fVerbose, int fVeryVerbose )
1169 {
1170  int fVeryVeryVerbose = 0;
1171  int i, iDiv;
1172  Fx_Man_t * p;
1173  abctime clk = Abc_Clock();
1174  // initialize the data-structure
1175  p = Fx_ManStart( vCubes );
1176  p->LitCountMax = LitCountMax;
1177  Fx_ManCreateLiterals( p, ObjIdMax );
1178  Fx_ManComputeLevel( p );
1179  Fx_ManCreateDivisors( p );
1180  if ( fVeryVerbose )
1181  Fx_PrintMatrix( p );
1182  if ( fVerbose )
1183  Fx_PrintStats( p, Abc_Clock() - clk );
1184  // perform extraction
1185  p->timeStart = Abc_Clock();
1186  for ( i = 0; i < nNewNodesMax && Vec_QueTopPriority(p->vPrio) > 0.0; i++ )
1187  {
1188  iDiv = Vec_QuePop(p->vPrio);
1189  if ( fVeryVerbose )
1190  Fx_PrintDiv( p, iDiv );
1191  Fx_ManUpdate( p, iDiv );
1192  if ( fVeryVeryVerbose )
1193  Fx_PrintMatrix( p );
1194  }
1195  if ( fVerbose )
1196  Fx_PrintStats( p, Abc_Clock() - clk );
1197  Fx_ManStop( p );
1198  // return the result
1199  Vec_WecRemoveEmpty( vCubes );
1200  return 1;
1201 }
1202 
1203 
1204 
1205 ////////////////////////////////////////////////////////////////////////
1206 /// END OF FILE ///
1207 ////////////////////////////////////////////////////////////////////////
1208 
1209 
1211 
static int Hsh_VecManAdd(Hsh_VecMan_t *p, Vec_Int_t *vVec)
Definition: vecHsh.h:340
char * memset()
int nPairsD
Definition: abcFx.c:112
static void Fx_PrintDivOneReal(Vec_Int_t *vDiv)
Definition: abcFx.c:438
static int * Vec_IntArray(Vec_Int_t *p)
Definition: vecInt.h:328
static unsigned Abc_ObjId(Abc_Obj_t *pObj)
Definition: abc.h:329
static void Vec_WecRemoveEmpty(Vec_Wec_t *vCubes)
Definition: vecWec.h:676
ABC_DLL int Abc_NtkMakeLegit(Abc_Ntk_t *pNtk)
Definition: abcFanOrder.c:461
Vec_Int_t * vCompls
Definition: abcFx.c:102
ABC_DLL char * Abc_SopStart(Mem_Flex_t *pMan, int nCubes, int nVars)
Definition: abcSop.c:76
void Abc_NtkFxInsert(Abc_Ntk_t *pNtk, Vec_Wec_t *vCubes)
Definition: abcFx.c:180
#define Vec_FltForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecFlt.h:54
Vec_Int_t * vCounts
Definition: abcFx.c:93
static Vec_Wec_t * Vec_WecAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecWec.h:87
static void Fx_ManCompressCubes(Vec_Wec_t *vCubes, Vec_Int_t *vLit2Cube)
Definition: abcFx.c:907
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition: vecWec.h:42
static int Vec_IntCheckUniqueSmall(Vec_Int_t *p)
Definition: vecInt.h:1336
int nLits
Definition: abcFx.c:108
Fx_Man_t * Fx_ManStart(Vec_Wec_t *vCubes)
Definition: abcFx.c:350
Hsh_VecMan_t * pHash
Definition: abcFx.c:94
static int Abc_NtkObjNumMax(Abc_Ntk_t *pNtk)
Definition: abc.h:284
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
static void Fx_ManDivFindPivots(Vec_Int_t *vDiv, int *pLit0, int *pLit1)
Definition: abcFx.c:684
#define Abc_SopForEachCube(pSop, nFanins, pCube)
Definition: abc.h:531
static void Vec_WecFree(Vec_Wec_t *p)
Definition: vecWec.h:345
static void Vec_WecMarkLevels(Vec_Wec_t *vCubes, Vec_Int_t *vLevels)
Definition: vecWec.h:644
static int Fx_ManGetCubeVar(Vec_Wec_t *vCubes, int iCube)
Definition: abcFx.c:928
static float Vec_QueTopPriority(Vec_Que_t *p)
Definition: vecQue.h:143
static void Vec_FltFree(Vec_Flt_t *p)
Definition: vecFlt.h:218
int Fx_ManCubeSingleCubeDivisors(Fx_Man_t *p, Vec_Int_t *vPivot, int fRemove, int fUpdate)
Definition: abcFx.c:782
static Vec_Wec_t * Vec_WecStart(int nSize)
Definition: vecWec.h:98
static Vec_Int_t * Vec_WecPushLevel(Vec_Wec_t *p)
Definition: vecWec.h:284
static int Abc_Var2Lit(int Var, int fCompl)
Definition: abc_global.h:263
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
static char Fx_PrintDivLit(int Lit)
Definition: abcFx.c:437
typedefABC_NAMESPACE_IMPL_START struct Fx_Man_t_ Fx_Man_t
DECLARATIONS ///.
Definition: abcFx.c:85
static void Vec_WecUnmarkLevels(Vec_Wec_t *vCubes, Vec_Int_t *vLevels)
Definition: vecWec.h:654
typedefABC_NAMESPACE_HEADER_START struct Vec_Que_t_ Vec_Que_t
INCLUDES ///.
Definition: vecQue.h:40
Vec_Int_t vFanins
Definition: abc.h:143
int nPairsS
Definition: abcFx.c:111
abctime timeStart
Definition: abcFx.c:106
static Vec_Flt_t * Vec_FltAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecFlt.h:78
static int Fx_ManComputeLevelDiv(Fx_Man_t *p, Vec_Int_t *vCubeFree)
Definition: abcFx.c:393
void Fx_ManStop(Fx_Man_t *p)
Definition: abcFx.c:363
static int Vec_WecSizeUsed(Vec_Wec_t *p)
Definition: vecWec.h:210
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition: abcCheck.c:61
static int Abc_NtkIsSopLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:264
static void Fx_PrintDivArray(Vec_Int_t *vDiv)
Definition: abcFx.c:460
static int Vec_QuePop(Vec_Que_t *p)
Definition: vecQue.h:234
static int Fx_ManDivNormalize(Vec_Int_t *vCubeFree)
Definition: abcFx.c:558
#define Abc_CubeForEachVar(pCube, Value, i)
Definition: abc.h:529
ABC_DLL int Abc_NtkCleanup(Abc_Ntk_t *pNtk, int fVerbose)
Definition: abcSweep.c:476
static abctime Abc_Clock()
Definition: abc_global.h:279
static int Abc_MaxInt(int a, int b)
Definition: abc_global.h:238
Vec_Flt_t * vWeights
Definition: abcFx.c:95
static Abc_Obj_t * Abc_NtkObj(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:314
void Fx_ManCreateDivisors(Fx_Man_t *p)
Definition: abcFx.c:871
static void Vec_IntSort(Vec_Int_t *p, int fReverse)
Definition: vecInt.h:1293
static Vec_Int_t * Vec_IntStartFull(int nSize)
Definition: vecInt.h:119
void Fx_ManCubeDoubleCubeDivisors(Fx_Man_t *p, int iFirst, Vec_Int_t *vPivot, int fRemove, int fUpdate)
Definition: abcFx.c:822
static void Vec_FltPush(Vec_Flt_t *p, float Entry)
Definition: vecFlt.h:528
static int Vec_WecSize(Vec_Wec_t *p)
Definition: vecWec.h:193
#define ABC_SWAP(Type, a, b)
Definition: abc_global.h:218
static void Hsh_VecManStop(Hsh_VecMan_t *p)
Definition: vecHsh.h:301
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition: abcFanio.c:84
static int Fx_ManDivRemoveLits(Vec_Int_t *vCube, Vec_Int_t *vDiv, int fCompl)
Definition: abcFx.c:705
int nVars
Definition: abcFx.c:107
Vec_Int_t * vCubeFree
Definition: abcFx.c:103
static void Vec_IntGrow(Vec_Int_t *p, int nCapMin)
Definition: bblif.c:336
int nDivsS
Definition: abcFx.c:113
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
static int Vec_QueSize(Vec_Que_t *p)
Definition: vecQue.h:134
static void Vec_IntWriteEntry(Vec_Int_t *p, int i, int Entry)
Definition: bblif.c:285
void * pManFunc
Definition: abc.h:191
Vec_Wec_t * vCubes
Definition: abcFx.c:89
static void Vec_IntSelectSort(int *pArray, int nSize)
Definition: vecInt.h:1740
static int Abc_MinInt(int a, int b)
Definition: abc_global.h:239
static Vec_Int_t * Vec_IntStart(int nSize)
Definition: bblif.c:172
static int Abc_LitIsCompl(int Lit)
Definition: abc_global.h:265
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition: vecWec.h:55
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
static void Vec_IntAddToEntry(Vec_Int_t *p, int i, int Addition)
Definition: bblif.c:302
static int Vec_IntTwoRemove(Vec_Int_t *vArr1, Vec_Int_t *vArr2)
Definition: vecInt.h:1626
static int Vec_IntEntry(Vec_Int_t *p, int i)
Definition: bblif.c:268
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static void Vec_IntUpdateEntry(Vec_Int_t *p, int i, int Value)
Definition: vecInt.h:468
static void Fx_PrintLiterals(Fx_Man_t *p)
Definition: abcFx.c:491
int Abc_NtkFxPerform(Abc_Ntk_t *pNtk, int nNewNodesMax, int LitCountMax, int fVerbose, int fVeryVerbose)
Definition: abcFx.c:303
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
static void Vec_IntAppend(Vec_Int_t *vVec1, Vec_Int_t *vVec2)
static int Counter
static int Vec_IntTwoRemoveCommon(Vec_Int_t *vArr1, Vec_Int_t *vArr2, Vec_Int_t *vArr)
Definition: vecInt.h:1588
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
Definition: vecInt.h:56
void Fx_ManUpdate(Fx_Man_t *p, int iDiv)
Definition: abcFx.c:984
void Fx_ManCreateLiterals(Fx_Man_t *p, int nVars)
Definition: abcFx.c:746
static Hsh_VecMan_t * Hsh_VecManStart(int nEntries)
Definition: vecHsh.h:292
Vec_Int_t * vCubesS
Definition: abcFx.c:100
static void Fx_PrintStats(Fx_Man_t *p, abctime clk)
Definition: abcFx.c:530
int nDivMux[3]
Definition: abcFx.c:114
ABC_DLL void Abc_ObjRemoveFanins(Abc_Obj_t *pObj)
Definition: abcFanio.c:141
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition: abc.h:461
static void Fx_PrintDiv(Fx_Man_t *p, int iDiv)
Definition: abcFx.c:471
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static Vec_Int_t * Vec_WecEntry(Vec_Wec_t *p, int i)
Definition: vecWec.h:142
#define Fx_ManForEachCubeVec(vVec, vCubes, vCube, i)
Definition: abcFx.c:119
int Fx_ManDivFindCubeFree(Vec_Int_t *vArr1, Vec_Int_t *vArr2, Vec_Int_t *vCubeFree)
Definition: abcFx.c:638
static void Fx_ManDivAddLits(Vec_Int_t *vCube, Vec_Int_t *vCube2, Vec_Int_t *vDiv)
Definition: abcFx.c:713
static int Abc_LitNot(int Lit)
Definition: abc_global.h:266
static int Hsh_VecSize(Hsh_VecMan_t *p)
Definition: vecHsh.h:315
static void Vec_FltAddToEntry(Vec_Flt_t *p, int i, float Addition)
Definition: vecFlt.h:381
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
#define Vec_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
Definition: vecWec.h:59
ABC_DLL void Abc_SopComplement(char *pSop)
Definition: abcSop.c:600
static int Vec_IntEqual(Vec_Int_t *p1, Vec_Int_t *p2)
Definition: vecInt.h:1201
int Fx_FastExtract(Vec_Wec_t *vCubes, int ObjIdMax, int nNewNodesMax, int LitCountMax, int fVerbose, int fVeryVerbose)
Definition: abcFx.c:1168
static float ** Vec_FltArrayP(Vec_Flt_t *p)
Definition: vecFlt.h:278
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
static void Vec_IntShrink(Vec_Int_t *p, int nSizeNew)
Definition: bblif.c:435
#define ABC_FREE(obj)
Definition: abc_global.h:232
void Fx_ManFindCommonPairs(Vec_Wec_t *vCubes, Vec_Int_t *vPart0, Vec_Int_t *vPart1, Vec_Int_t *vPairs, Vec_Int_t *vCompls, Vec_Int_t *vDiv, Vec_Int_t *vCubeFree)
Definition: abcFx.c:929
static int Vec_WecLevelId(Vec_Wec_t *p, Vec_Int_t *vLevel)
Definition: vecWec.h:172
static int Vec_WecIntHasMark(Vec_Int_t *vVec)
Definition: vecWec.h:641
static void Vec_QueUpdate(Vec_Que_t *p, int v)
Definition: vecQue.h:199
static Abc_Obj_t * Abc_NtkCreateNode(Abc_Ntk_t *pNtk)
Definition: abc.h:308
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
static int Abc_Lit2Var(int Lit)
Definition: abc_global.h:264
static int Fx_ManComputeLevelCube(Fx_Man_t *p, Vec_Int_t *vCube)
Definition: abcFx.c:400
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
Definition: vecFlt.h:42
void Fx_ManComputeLevel(Fx_Man_t *p)
Definition: abcFx.c:407
ABC_DLL int Abc_SopGetVarNum(char *pSop)
Definition: abcSop.c:536
static int Vec_QueIsMember(Vec_Que_t *p, int v)
Definition: vecQue.h:216
static void Vec_QueFree(Vec_Que_t *p)
Definition: vecQue.h:83
static void Fx_PrintDivisors(Fx_Man_t *p)
Definition: abcFx.c:485
Vec_Int_t * vDiv
Definition: abcFx.c:104
#define assert(ex)
Definition: util_old.h:213
static Vec_Int_t * Hsh_VecReadEntry(Hsh_VecMan_t *p, int i)
Definition: vecHsh.h:308
static float Vec_FltEntry(Vec_Flt_t *p, int i)
Definition: vecFlt.h:342
static void Vec_IntPrint(Vec_Int_t *vVec)
Definition: vecInt.h:1803
Vec_Int_t * vLevels
Definition: abcFx.c:98
Vec_Int_t * vVarCube
Definition: abcFx.c:97
Vec_Wec_t * vLits
Definition: abcFx.c:92
static int Abc_ObjFaninId(Abc_Obj_t *pObj, int i)
Definition: abc.h:366
void * pData
Definition: abc.h:145
static void Fx_PrintDivOne(Vec_Int_t *vDiv)
Definition: abcFx.c:449
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
static void Vec_IntClear(Vec_Int_t *p)
Definition: bblif.c:452
ABC_INT64_T abctime
Definition: abc_global.h:278
static int Vec_FltSize(Vec_Flt_t *p)
Definition: vecFlt.h:294
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecInt.h:54
static Vec_Que_t * Vec_QueAlloc(int nCap)
MACRO DEFINITIONS ///.
Definition: vecQue.h:71
Vec_Int_t * vCubesD
Definition: abcFx.c:101
int Abc_NtkFxCheck(Abc_Ntk_t *pNtk)
Definition: abcFx.c:280
Vec_Que_t * vPrio
Definition: abcFx.c:96
int nDivs
Definition: abcFx.c:109
ABC_DLL int Abc_SopIsComplement(char *pSop)
Definition: abcSop.c:655
int LitCountMax
Definition: abcFx.c:90
static int Vec_IntRemove1(Vec_Int_t *p, int Entry)
Definition: vecInt.h:929
Vec_Wec_t * Abc_NtkFxRetrieve(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition: abcFx.c:137
static void Vec_QuePush(Vec_Que_t *p, int v)
Definition: vecQue.h:221
static int Fx_ManGetFirstVarCube(Fx_Man_t *p, Vec_Int_t *vCube)
Definition: abcFx.c:117
static void Vec_QueSetPriority(Vec_Que_t *p, float **pCosts)
Definition: vecQue.h:95
static void Fx_PrintMatrix(Fx_Man_t *p)
Definition: abcFx.c:501
static void Vec_WecPush(Vec_Wec_t *p, int Level, int Entry)
Definition: vecWec.h:275
int nCompls
Definition: abcFx.c:110