abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
extraBddMisc.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [extraBddMisc.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [extra]
8 
9  Synopsis [DD-based utilities.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: extraBddMisc.c,v 1.4 2005/10/04 00:19:54 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "extraBdd.h"
22 
24 
25 
26 /*---------------------------------------------------------------------------*/
27 /* Constant declarations */
28 /*---------------------------------------------------------------------------*/
29 
30 /*---------------------------------------------------------------------------*/
31 /* Stucture declarations */
32 /*---------------------------------------------------------------------------*/
33 
34 /*---------------------------------------------------------------------------*/
35 /* Type declarations */
36 /*---------------------------------------------------------------------------*/
37 
38 /*---------------------------------------------------------------------------*/
39 /* Variable declarations */
40 /*---------------------------------------------------------------------------*/
41 
42 /*---------------------------------------------------------------------------*/
43 /* Macro declarations */
44 /*---------------------------------------------------------------------------*/
45 
46 
47 /**AutomaticStart*************************************************************/
48 
49 /*---------------------------------------------------------------------------*/
50 /* Static function prototypes */
51 /*---------------------------------------------------------------------------*/
52 
53 // file "extraDdTransfer.c"
54 static DdNode * extraTransferPermuteRecur( DdManager * ddS, DdManager * ddD, DdNode * f, st__table * table, int * Permute );
55 static DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute );
56 static DdNode * cuddBddPermuteRecur ARGS( ( DdManager * manager, DdHashTable * table, DdNode * node, int *permut ) );
57 
58 static DdNode * extraBddAndPermute( DdHashTable * table, DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute );
59 
60 // file "cuddUtils.c"
61 static void ddSupportStep(DdNode *f, int *support);
62 static void ddClearFlag(DdNode *f);
63 
64 static DdNode* extraZddPrimes( DdManager *dd, DdNode* F );
65 
66 /**AutomaticEnd***************************************************************/
67 
68 /*---------------------------------------------------------------------------*/
69 /* Definition of exported functions */
70 /*---------------------------------------------------------------------------*/
71 
72 /**Function********************************************************************
73 
74  Synopsis [Convert a {A,B}DD from a manager to another with variable remapping.]
75 
76  Description [Convert a {A,B}DD from a manager to another one. The orders of the
77  variables in the two managers may be different. Returns a
78  pointer to the {A,B}DD in the destination manager if successful; NULL
79  otherwise. The i-th entry in the array Permute tells what is the index
80  of the i-th variable from the old manager in the new manager.]
81 
82  SideEffects [None]
83 
84  SeeAlso []
85 
86 ******************************************************************************/
87 DdNode * Extra_TransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute )
88 {
89  DdNode * bRes;
90  do
91  {
92  ddDestination->reordered = 0;
93  bRes = extraTransferPermute( ddSource, ddDestination, f, Permute );
94  }
95  while ( ddDestination->reordered == 1 );
96  return ( bRes );
97 
98 } /* end of Extra_TransferPermute */
99 
100 /**Function********************************************************************
101 
102  Synopsis [Transfers the BDD from one manager into another level by level.]
103 
104  Description [Transfers the BDD from one manager into another while
105  preserving the correspondence between variables level by level.]
106 
107  SideEffects [None]
108 
109  SeeAlso []
110 
111 ******************************************************************************/
112 DdNode * Extra_TransferLevelByLevel( DdManager * ddSource, DdManager * ddDestination, DdNode * f )
113 {
114  DdNode * bRes;
115  int * pPermute;
116  int nMin, nMax, i;
117 
118  nMin = ddMin(ddSource->size, ddDestination->size);
119  nMax = ddMax(ddSource->size, ddDestination->size);
120  pPermute = ABC_ALLOC( int, nMax );
121  // set up the variable permutation
122  for ( i = 0; i < nMin; i++ )
123  pPermute[ ddSource->invperm[i] ] = ddDestination->invperm[i];
124  if ( ddSource->size > ddDestination->size )
125  {
126  for ( ; i < nMax; i++ )
127  pPermute[ ddSource->invperm[i] ] = -1;
128  }
129  bRes = Extra_TransferPermute( ddSource, ddDestination, f, pPermute );
130  ABC_FREE( pPermute );
131  return bRes;
132 }
133 
134 /**Function********************************************************************
135 
136  Synopsis [Remaps the function to depend on the topmost variables on the manager.]
137 
138  Description []
139 
140  SideEffects []
141 
142  SeeAlso []
143 
144 ******************************************************************************/
146  DdManager * dd,
147  DdNode * bF )
148 {
149  int * pPermute;
150  DdNode * bSupp, * bTemp, * bRes;
151  int Counter;
152 
153  pPermute = ABC_ALLOC( int, dd->size );
154 
155  // get support
156  bSupp = Cudd_Support( dd, bF ); Cudd_Ref( bSupp );
157 
158  // create the variable map
159  // to remap the DD into the upper part of the manager
160  Counter = 0;
161  for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
162  pPermute[bTemp->index] = dd->invperm[Counter++];
163 
164  // transfer the BDD and remap it
165  bRes = Cudd_bddPermute( dd, bF, pPermute ); Cudd_Ref( bRes );
166 
167  // remove support
168  Cudd_RecursiveDeref( dd, bSupp );
169 
170  // return
171  Cudd_Deref( bRes );
172  ABC_FREE( pPermute );
173  return bRes;
174 }
175 
176 /**Function********************************************************************
177 
178  Synopsis [Moves the BDD by the given number of variables up or down.]
179 
180  Description []
181 
182  SideEffects []
183 
184  SeeAlso [Extra_bddShift]
185 
186 ******************************************************************************/
188  DdManager * dd, /* the DD manager */
189  DdNode * bF,
190  int nVars)
191 {
192  DdNode * res;
193  DdNode * bVars;
194  if ( nVars == 0 )
195  return bF;
196  if ( Cudd_IsConstant(bF) )
197  return bF;
198  assert( nVars <= dd->size );
199  if ( nVars > 0 )
200  bVars = dd->vars[nVars];
201  else
202  bVars = Cudd_Not(dd->vars[-nVars]);
203 
204  do {
205  dd->reordered = 0;
206  res = extraBddMove( dd, bF, bVars );
207  } while (dd->reordered == 1);
208  return(res);
209 
210 } /* end of Extra_bddMove */
211 
212 /**Function*************************************************************
213 
214  Synopsis []
215 
216  Description []
217 
218  SideEffects []
219 
220  SeeAlso []
221 
222 ***********************************************************************/
224 {
225  int RetValue;
226  // check for remaining references in the package
227  RetValue = Cudd_CheckZeroRef( dd );
228  if ( RetValue > 10 )
229 // if ( RetValue )
230  printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
231 // Cudd_PrintInfo( dd, stdout );
232  Cudd_Quit( dd );
233 }
234 
235 /**Function********************************************************************
236 
237  Synopsis [Outputs the BDD in a readable format.]
238 
239  Description []
240 
241  SideEffects [None]
242 
243  SeeAlso []
244 
245 ******************************************************************************/
246 void Extra_bddPrint( DdManager * dd, DdNode * F )
247 {
248  DdGen * Gen;
249  int * Cube;
250  CUDD_VALUE_TYPE Value;
251  int nVars = dd->size;
252  int fFirstCube = 1;
253  int i;
254 
255  if ( F == NULL )
256  {
257  printf("NULL");
258  return;
259  }
260  if ( F == b0 )
261  {
262  printf("Constant 0");
263  return;
264  }
265  if ( F == b1 )
266  {
267  printf("Constant 1");
268  return;
269  }
270 
271  Cudd_ForeachCube( dd, F, Gen, Cube, Value )
272  {
273  if ( fFirstCube )
274  fFirstCube = 0;
275  else
276 // Output << " + ";
277  printf( " + " );
278 
279  for ( i = 0; i < nVars; i++ )
280  if ( Cube[i] == 0 )
281  printf( "[%d]'", i );
282 // printf( "%c'", (char)('a'+i) );
283  else if ( Cube[i] == 1 )
284  printf( "[%d]", i );
285 // printf( "%c", (char)('a'+i) );
286  }
287 
288 // printf("\n");
289 }
290 
291 /**Function********************************************************************
292 
293  Synopsis [Outputs the BDD in a readable format.]
294 
295  Description []
296 
297  SideEffects [None]
298 
299  SeeAlso []
300 
301 ******************************************************************************/
303 {
304  DdNode * bSupp;
305  bSupp = Cudd_Support( dd, F ); Cudd_Ref( bSupp );
306  Extra_bddPrint( dd, bSupp );
307  Cudd_RecursiveDeref( dd, bSupp );
308 }
309 
310 /**Function********************************************************************
311 
312  Synopsis [Returns the size of the support.]
313 
314  Description []
315 
316  SideEffects []
317 
318  SeeAlso []
319 
320 ******************************************************************************/
321 int Extra_bddSuppSize( DdManager * dd, DdNode * bSupp )
322 {
323  int Counter = 0;
324  while ( bSupp != b1 )
325  {
326  assert( !Cudd_IsComplement(bSupp) );
327  assert( cuddE(bSupp) == b0 );
328 
329  bSupp = cuddT(bSupp);
330  Counter++;
331  }
332  return Counter;
333 }
334 
335 /**Function********************************************************************
336 
337  Synopsis [Returns 1 if the support contains the given BDD variable.]
338 
339  Description []
340 
341  SideEffects []
342 
343  SeeAlso []
344 
345 ******************************************************************************/
346 int Extra_bddSuppContainVar( DdManager * dd, DdNode * bS, DdNode * bVar )
347 {
348  for( ; bS != b1; bS = cuddT(bS) )
349  if ( bS->index == bVar->index )
350  return 1;
351  return 0;
352 }
353 
354 /**Function********************************************************************
355 
356  Synopsis [Returns 1 if two supports represented as BDD cubes are overlapping.]
357 
358  Description []
359 
360  SideEffects []
361 
362  SeeAlso []
363 
364 ******************************************************************************/
366 {
367  while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
368  {
369  // if the top vars are the same, they intersect
370  if ( S1->index == S2->index )
371  return 1;
372  // if the top vars are different, skip the one, which is higher
373  if ( dd->perm[S1->index] < dd->perm[S2->index] )
374  S1 = cuddT(S1);
375  else
376  S2 = cuddT(S2);
377  }
378  return 0;
379 }
380 
381 /**Function********************************************************************
382 
383  Synopsis [Returns the number of different vars in two supports.]
384 
385  Description [Counts the number of variables that appear in one support and
386  does not appear in other support. If the number exceeds DiffMax, returns DiffMax.]
387 
388  SideEffects []
389 
390  SeeAlso []
391 
392 ******************************************************************************/
393 int Extra_bddSuppDifferentVars( DdManager * dd, DdNode * S1, DdNode * S2, int DiffMax )
394 {
395  int Result = 0;
396  while ( S1->index != CUDD_CONST_INDEX && S2->index != CUDD_CONST_INDEX )
397  {
398  // if the top vars are the same, this var is the same
399  if ( S1->index == S2->index )
400  {
401  S1 = cuddT(S1);
402  S2 = cuddT(S2);
403  continue;
404  }
405  // the top var is different
406  Result++;
407 
408  if ( Result >= DiffMax )
409  return DiffMax;
410 
411  // if the top vars are different, skip the one, which is higher
412  if ( dd->perm[S1->index] < dd->perm[S2->index] )
413  S1 = cuddT(S1);
414  else
415  S2 = cuddT(S2);
416  }
417 
418  // consider the remaining variables
419  if ( S1->index != CUDD_CONST_INDEX )
420  Result += Extra_bddSuppSize(dd,S1);
421  else if ( S2->index != CUDD_CONST_INDEX )
422  Result += Extra_bddSuppSize(dd,S2);
423 
424  if ( Result >= DiffMax )
425  return DiffMax;
426  return Result;
427 }
428 
429 
430 /**Function********************************************************************
431 
432  Synopsis [Checks the support containment.]
433 
434  Description [This function returns 1 if one support is contained in another.
435  In this case, bLarge (bSmall) is assigned to point to the larger (smaller) support.
436  If the supports are identical, return 0 and does not assign the supports!]
437 
438  SideEffects []
439 
440  SeeAlso []
441 
442 ******************************************************************************/
443 int Extra_bddSuppCheckContainment( DdManager * dd, DdNode * bL, DdNode * bH, DdNode ** bLarge, DdNode ** bSmall )
444 {
445  DdNode * bSL = bL;
446  DdNode * bSH = bH;
447  int fLcontainsH = 1;
448  int fHcontainsL = 1;
449  int TopVar;
450 
451  if ( bSL == bSH )
452  return 0;
453 
454  while ( bSL != b1 || bSH != b1 )
455  {
456  if ( bSL == b1 )
457  { // Low component has no vars; High components has some vars
458  fLcontainsH = 0;
459  if ( fHcontainsL == 0 )
460  return 0;
461  else
462  break;
463  }
464 
465  if ( bSH == b1 )
466  { // similarly
467  fHcontainsL = 0;
468  if ( fLcontainsH == 0 )
469  return 0;
470  else
471  break;
472  }
473 
474  // determine the topmost var of the supports by comparing their levels
475  if ( dd->perm[bSL->index] < dd->perm[bSH->index] )
476  TopVar = bSL->index;
477  else
478  TopVar = bSH->index;
479 
480  if ( TopVar == bSL->index && TopVar == bSH->index )
481  { // they are on the same level
482  // it does not tell us anything about their containment
483  // skip this var
484  bSL = cuddT(bSL);
485  bSH = cuddT(bSH);
486  }
487  else if ( TopVar == bSL->index ) // and TopVar != bSH->index
488  { // Low components is higher and contains more vars
489  // it is not possible that High component contains Low
490  fHcontainsL = 0;
491  // skip this var
492  bSL = cuddT(bSL);
493  }
494  else // if ( TopVar == bSH->index ) // and TopVar != bSL->index
495  { // similarly
496  fLcontainsH = 0;
497  // skip this var
498  bSH = cuddT(bSH);
499  }
500 
501  // check the stopping condition
502  if ( !fHcontainsL && !fLcontainsH )
503  return 0;
504  }
505  // only one of them can be true at the same time
506  assert( !fHcontainsL || !fLcontainsH );
507  if ( fHcontainsL )
508  {
509  *bLarge = bH;
510  *bSmall = bL;
511  }
512  else // fLcontainsH
513  {
514  *bLarge = bL;
515  *bSmall = bH;
516  }
517  return 1;
518 }
519 
520 
521 /**Function********************************************************************
522 
523  Synopsis [Finds variables on which the DD depends and returns them as am array.]
524 
525  Description [Finds the variables on which the DD depends. Returns an array
526  with entries set to 1 for those variables that belong to the support;
527  NULL otherwise. The array is allocated by the user and should have at least
528  as many entries as the maximum number of variables in BDD and ZDD parts of
529  the manager.]
530 
531  SideEffects [None]
532 
533  SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]
534 
535 ******************************************************************************/
536 int *
538  DdManager * dd, /* manager */
539  DdNode * f, /* DD whose support is sought */
540  int * support ) /* array allocated by the user */
541 {
542  int i, size;
543 
544  /* Initialize support array for ddSupportStep. */
545  size = ddMax(dd->size, dd->sizeZ);
546  for (i = 0; i < size; i++)
547  support[i] = 0;
548 
549  /* Compute support and clean up markers. */
550  ddSupportStep(Cudd_Regular(f),support);
552 
553  return(support);
554 
555 } /* end of Extra_SupportArray */
556 
557 /**Function********************************************************************
558 
559  Synopsis [Finds the variables on which a set of DDs depends.]
560 
561  Description [Finds the variables on which a set of DDs depends.
562  The set must contain either BDDs and ADDs, or ZDDs.
563  Returns a BDD consisting of the product of the variables if
564  successful; NULL otherwise.]
565 
566  SideEffects [None]
567 
568  SeeAlso [Cudd_Support Cudd_ClassifySupport]
569 
570 ******************************************************************************/
571 int *
573  DdManager * dd, /* manager */
574  DdNode ** F, /* array of DDs whose support is sought */
575  int n, /* size of the array */
576  int * support ) /* array allocated by the user */
577 {
578  int i, size;
579 
580  /* Allocate and initialize support array for ddSupportStep. */
581  size = ddMax( dd->size, dd->sizeZ );
582  for ( i = 0; i < size; i++ )
583  support[i] = 0;
584 
585  /* Compute support and clean up markers. */
586  for ( i = 0; i < n; i++ )
587  ddSupportStep( Cudd_Regular(F[i]), support );
588  for ( i = 0; i < n; i++ )
589  ddClearFlag( Cudd_Regular(F[i]) );
590 
591  return support;
592 }
593 
594 /**Function********************************************************************
595 
596  Synopsis [Find any cube belonging to the on-set of the function.]
597 
598  Description []
599 
600  SideEffects []
601 
602  SeeAlso []
603 
604 ******************************************************************************/
606 {
607  char * s_Temp;
608  DdNode * bCube, * bTemp;
609  int v;
610 
611  // get the vector of variables in the cube
612  s_Temp = ABC_ALLOC( char, dd->size );
613  Cudd_bddPickOneCube( dd, bF, s_Temp );
614 
615  // start the cube
616  bCube = b1; Cudd_Ref( bCube );
617  for ( v = 0; v < dd->size; v++ )
618  if ( s_Temp[v] == 0 )
619  {
620 // Cube &= !s_XVars[v];
621  bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(dd->vars[v]) ); Cudd_Ref( bCube );
622  Cudd_RecursiveDeref( dd, bTemp );
623  }
624  else if ( s_Temp[v] == 1 )
625  {
626 // Cube &= s_XVars[v];
627  bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[v] ); Cudd_Ref( bCube );
628  Cudd_RecursiveDeref( dd, bTemp );
629  }
630  Cudd_Deref(bCube);
631  ABC_FREE( s_Temp );
632  return bCube;
633 }
634 
635 /**Function********************************************************************
636 
637  Synopsis [Returns one cube contained in the given BDD.]
638 
639  Description [This function returns the cube with the smallest
640  bits-to-integer value.]
641 
642  SideEffects []
643 
644 ******************************************************************************/
646 {
647  DdNode * bFuncR, * bFunc0, * bFunc1;
648  DdNode * bRes0, * bRes1, * bRes;
649 
650  bFuncR = Cudd_Regular(bFunc);
651  if ( cuddIsConstant(bFuncR) )
652  return bFunc;
653 
654  // cofactor
655  if ( Cudd_IsComplement(bFunc) )
656  {
657  bFunc0 = Cudd_Not( cuddE(bFuncR) );
658  bFunc1 = Cudd_Not( cuddT(bFuncR) );
659  }
660  else
661  {
662  bFunc0 = cuddE(bFuncR);
663  bFunc1 = cuddT(bFuncR);
664  }
665 
666  // try to find the cube with the negative literal
667  bRes0 = Extra_bddGetOneCube( dd, bFunc0 ); Cudd_Ref( bRes0 );
668 
669  if ( bRes0 != b0 )
670  {
671  bRes = Cudd_bddAnd( dd, bRes0, Cudd_Not(dd->vars[bFuncR->index]) ); Cudd_Ref( bRes );
672  Cudd_RecursiveDeref( dd, bRes0 );
673  }
674  else
675  {
676  Cudd_RecursiveDeref( dd, bRes0 );
677  // try to find the cube with the positive literal
678  bRes1 = Extra_bddGetOneCube( dd, bFunc1 ); Cudd_Ref( bRes1 );
679  assert( bRes1 != b0 );
680  bRes = Cudd_bddAnd( dd, bRes1, dd->vars[bFuncR->index] ); Cudd_Ref( bRes );
681  Cudd_RecursiveDeref( dd, bRes1 );
682  }
683 
684  Cudd_Deref( bRes );
685  return bRes;
686 }
687 
688 /**Function********************************************************************
689 
690  Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]
691 
692  Description []
693 
694  SideEffects []
695 
696  SeeAlso []
697 
698 ******************************************************************************/
699 DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int iStop )
700 {
701  DdNode * bTemp, * bProd;
702  int i;
703  assert( iStart <= iStop );
704  assert( iStart >= 0 && iStart <= dd->size );
705  assert( iStop >= 0 && iStop <= dd->size );
706  bProd = b1; Cudd_Ref( bProd );
707  for ( i = iStart; i < iStop; i++ )
708  {
709  bProd = Cudd_bddAnd( dd, bTemp = bProd, dd->vars[i] ); Cudd_Ref( bProd );
710  Cudd_RecursiveDeref( dd, bTemp );
711  }
712  Cudd_Deref( bProd );
713  return bProd;
714 }
715 
716 /**Function********************************************************************
717 
718  Synopsis [Computes the cube of BDD variables corresponding to bits it the bit-code]
719 
720  Description [Returns a bdd composed of elementary bdds found in array BddVars[] such
721  that the bdd vars encode the number Value of bit length CodeWidth (if fMsbFirst is 1,
722  the most significant bit is encoded with the first bdd variable). If the variables
723  BddVars are not specified, takes the first CodeWidth variables of the manager]
724 
725  SideEffects []
726 
727  SeeAlso []
728 
729 ******************************************************************************/
730 DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst )
731 {
732  int z;
733  DdNode * bTemp, * bVar, * bVarBdd, * bResult;
734 
735  bResult = b1; Cudd_Ref( bResult );
736  for ( z = 0; z < CodeWidth; z++ )
737  {
738  bVarBdd = (pbVars)? pbVars[z]: dd->vars[z];
739  if ( fMsbFirst )
740  bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (CodeWidth-1-z)))==0 );
741  else
742  bVar = Cudd_NotCond( bVarBdd, (Code & (1 << (z)))==0 );
743  bResult = Cudd_bddAnd( dd, bTemp = bResult, bVar ); Cudd_Ref( bResult );
744  Cudd_RecursiveDeref( dd, bTemp );
745  }
746  Cudd_Deref( bResult );
747 
748  return bResult;
749 } /* end of Extra_bddBitsToCube */
750 
751 /**Function********************************************************************
752 
753  Synopsis [Finds the support as a negative polarity cube.]
754 
755  Description [Finds the variables on which a DD depends. Returns a BDD
756  consisting of the product of the variables in the negative polarity
757  if successful; NULL otherwise.]
758 
759  SideEffects [None]
760 
761  SeeAlso [Cudd_VectorSupport Cudd_Support]
762 
763 ******************************************************************************/
765 {
766  int *support;
767  DdNode *res, *tmp, *var;
768  int i, j;
769  int size;
770 
771  /* Allocate and initialize support array for ddSupportStep. */
772  size = ddMax( dd->size, dd->sizeZ );
773  support = ABC_ALLOC( int, size );
774  if ( support == NULL )
775  {
777  return ( NULL );
778  }
779  for ( i = 0; i < size; i++ )
780  {
781  support[i] = 0;
782  }
783 
784  /* Compute support and clean up markers. */
785  ddSupportStep( Cudd_Regular( f ), support );
786  ddClearFlag( Cudd_Regular( f ) );
787 
788  /* Transform support from array to cube. */
789  do
790  {
791  dd->reordered = 0;
792  res = DD_ONE( dd );
793  cuddRef( res );
794  for ( j = size - 1; j >= 0; j-- )
795  { /* for each level bottom-up */
796  i = ( j >= dd->size ) ? j : dd->invperm[j];
797  if ( support[i] == 1 )
798  {
799  var = cuddUniqueInter( dd, i, dd->one, Cudd_Not( dd->one ) );
800  //////////////////////////////////////////////////////////////////
801  var = Cudd_Not(var);
802  //////////////////////////////////////////////////////////////////
803  cuddRef( var );
804  tmp = cuddBddAndRecur( dd, res, var );
805  if ( tmp == NULL )
806  {
807  Cudd_RecursiveDeref( dd, res );
808  Cudd_RecursiveDeref( dd, var );
809  res = NULL;
810  break;
811  }
812  cuddRef( tmp );
813  Cudd_RecursiveDeref( dd, res );
814  Cudd_RecursiveDeref( dd, var );
815  res = tmp;
816  }
817  }
818  }
819  while ( dd->reordered == 1 );
820 
821  ABC_FREE( support );
822  if ( res != NULL )
823  cuddDeref( res );
824  return ( res );
825 
826 } /* end of Extra_SupportNeg */
827 
828 /**Function********************************************************************
829 
830  Synopsis [Returns 1 if the BDD is the BDD of elementary variable.]
831 
832  Description []
833 
834  SideEffects []
835 
836  SeeAlso []
837 
838 ******************************************************************************/
839 int Extra_bddIsVar( DdNode * bFunc )
840 {
841  bFunc = Cudd_Regular( bFunc );
842  if ( cuddIsConstant(bFunc) )
843  return 0;
844  return cuddIsConstant( cuddT(bFunc) ) && cuddIsConstant( Cudd_Regular(cuddE(bFunc)) );
845 }
846 
847 /**Function********************************************************************
848 
849  Synopsis [Creates AND composed of the first nVars of the manager.]
850 
851  Description []
852 
853  SideEffects []
854 
855  SeeAlso []
856 
857 ******************************************************************************/
858 DdNode * Extra_bddCreateAnd( DdManager * dd, int nVars )
859 {
860  DdNode * bFunc, * bTemp;
861  int i;
862  bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
863  for ( i = 0; i < nVars; i++ )
864  {
865  bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
866  Cudd_RecursiveDeref( dd, bTemp );
867  }
868  Cudd_Deref( bFunc );
869  return bFunc;
870 }
871 
872 /**Function********************************************************************
873 
874  Synopsis [Creates OR composed of the first nVars of the manager.]
875 
876  Description []
877 
878  SideEffects []
879 
880  SeeAlso []
881 
882 ******************************************************************************/
883 DdNode * Extra_bddCreateOr( DdManager * dd, int nVars )
884 {
885  DdNode * bFunc, * bTemp;
886  int i;
887  bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
888  for ( i = 0; i < nVars; i++ )
889  {
890  bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
891  Cudd_RecursiveDeref( dd, bTemp );
892  }
893  Cudd_Deref( bFunc );
894  return bFunc;
895 }
896 
897 /**Function********************************************************************
898 
899  Synopsis [Creates EXOR composed of the first nVars of the manager.]
900 
901  Description []
902 
903  SideEffects []
904 
905  SeeAlso []
906 
907 ******************************************************************************/
909 {
910  DdNode * bFunc, * bTemp;
911  int i;
912  bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
913  for ( i = 0; i < nVars; i++ )
914  {
915  bFunc = Cudd_bddXor( dd, bTemp = bFunc, Cudd_bddIthVar(dd,i) ); Cudd_Ref( bFunc );
916  Cudd_RecursiveDeref( dd, bTemp );
917  }
918  Cudd_Deref( bFunc );
919  return bFunc;
920 }
921 
922 /**Function********************************************************************
923 
924  Synopsis [Computes the set of primes as a ZDD.]
925 
926  Description []
927 
928  SideEffects []
929 
930  SeeAlso []
931 
932 ******************************************************************************/
934 {
935  DdNode *res;
936  do {
937  dd->reordered = 0;
938  res = extraZddPrimes(dd, F);
939  if ( dd->reordered == 1 )
940  printf("\nReordering in Extra_zddPrimes()\n");
941  } while (dd->reordered == 1);
942  return(res);
943 
944 } /* end of Extra_zddPrimes */
945 
946 /**Function********************************************************************
947 
948  Synopsis [Permutes the variables of the array of BDDs.]
949 
950  Description [Given a permutation in array permut, creates a new BDD
951  with permuted variables. There should be an entry in array permut
952  for each variable in the manager. The i-th entry of permut holds the
953  index of the variable that is to substitute the i-th variable.
954  The DDs in the resulting array are already referenced.]
955 
956  SideEffects [None]
957 
958  SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]
959 
960 ******************************************************************************/
961 void Extra_bddPermuteArray( DdManager * manager, DdNode ** bNodesIn, DdNode ** bNodesOut, int nNodes, int *permut )
962 {
963  DdHashTable *table;
964  int i, k;
965  do
966  {
967  manager->reordered = 0;
968  table = cuddHashTableInit( manager, 1, 2 );
969 
970  /* permute the output functions one-by-one */
971  for ( i = 0; i < nNodes; i++ )
972  {
973  bNodesOut[i] = cuddBddPermuteRecur( manager, table, bNodesIn[i], permut );
974  if ( bNodesOut[i] == NULL )
975  {
976  /* deref the array of the already computed outputs */
977  for ( k = 0; k < i; k++ )
978  Cudd_RecursiveDeref( manager, bNodesOut[k] );
979  break;
980  }
981  cuddRef( bNodesOut[i] );
982  }
983  /* Dispose of local cache. */
984  cuddHashTableQuit( table );
985  }
986  while ( manager->reordered == 1 );
987 } /* end of Extra_bddPermuteArray */
988 
989 
990 /**Function********************************************************************
991 
992  Synopsis [Computes the positive polarty cube composed of the first vars in the array.]
993 
994  Description []
995 
996  SideEffects []
997 
998  SeeAlso []
999 
1000 ******************************************************************************/
1001 DdNode * Extra_bddComputeCube( DdManager * dd, DdNode ** bXVars, int nVars )
1002 {
1003  DdNode * bRes;
1004  DdNode * bTemp;
1005  int i;
1006 
1007  bRes = b1; Cudd_Ref( bRes );
1008  for ( i = 0; i < nVars; i++ )
1009  {
1010  bRes = Cudd_bddAnd( dd, bTemp = bRes, bXVars[i] ); Cudd_Ref( bRes );
1011  Cudd_RecursiveDeref( dd, bTemp );
1012  }
1013 
1014  Cudd_Deref( bRes );
1015  return bRes;
1016 }
1017 
1018 /**Function********************************************************************
1019 
1020  Synopsis [Changes the polarity of vars listed in the cube.]
1021 
1022  Description []
1023 
1024  SideEffects []
1025 
1026  SeeAlso []
1027 
1028 ******************************************************************************/
1030  DdManager * dd, /* the DD manager */
1031  DdNode * bFunc,
1032  DdNode * bVars)
1033 {
1034  DdNode *res;
1035  do {
1036  dd->reordered = 0;
1037  res = extraBddChangePolarity( dd, bFunc, bVars );
1038  } while (dd->reordered == 1);
1039  return(res);
1040 
1041 } /* end of Extra_bddChangePolarity */
1042 
1043 
1044 /**Function*************************************************************
1045 
1046  Synopsis [Checks if the given variable belongs to the cube.]
1047 
1048  Description [Return -1 if the var does not appear in the cube.
1049  Otherwise, returns polarity (0 or 1) of the var in the cube.]
1050 
1051  SideEffects []
1052 
1053  SeeAlso []
1054 
1055 ***********************************************************************/
1056 int Extra_bddVarIsInCube( DdNode * bCube, int iVar )
1057 {
1058  DdNode * bCube0, * bCube1;
1059  while ( Cudd_Regular(bCube)->index != CUDD_CONST_INDEX )
1060  {
1061  bCube0 = Cudd_NotCond( cuddE(Cudd_Regular(bCube)), Cudd_IsComplement(bCube) );
1062  bCube1 = Cudd_NotCond( cuddT(Cudd_Regular(bCube)), Cudd_IsComplement(bCube) );
1063  // make sure it is a cube
1064  assert( (Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX) || // bCube0 == 0
1065  (Cudd_IsComplement(bCube1) && Cudd_Regular(bCube1)->index == CUDD_CONST_INDEX) ); // bCube1 == 0
1066  // quit if it is the last one
1067  if ( Cudd_Regular(bCube)->index == iVar )
1068  return (int)(Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX);
1069  // get the next cube
1070  if ( (Cudd_IsComplement(bCube0) && Cudd_Regular(bCube0)->index == CUDD_CONST_INDEX) )
1071  bCube = bCube1;
1072  else
1073  bCube = bCube0;
1074  }
1075  return -1;
1076 }
1077 
1078 /**Function*************************************************************
1079 
1080  Synopsis [Computes the AND of two BDD with different orders.]
1081 
1082  Description [Derives the result of Boolean AND of bF and bG in ddF.
1083  The array pPermute gives the mapping of variables of ddG into that of ddF.]
1084 
1085  SideEffects []
1086 
1087  SeeAlso []
1088 
1089 ***********************************************************************/
1090 DdNode * Extra_bddAndPermute( DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute )
1091 {
1092  DdHashTable * table;
1093  DdNode * bRes;
1094  do
1095  {
1096  ddF->reordered = 0;
1097  table = cuddHashTableInit( ddF, 2, 256 );
1098  if (table == NULL) return NULL;
1099  bRes = extraBddAndPermute( table, ddF, bF, ddG, bG, pPermute );
1100  if ( bRes ) cuddRef( bRes );
1101  cuddHashTableQuit( table );
1102  if ( bRes ) cuddDeref( bRes );
1103 //if ( ddF->reordered == 1 )
1104 //printf( "Reordering happened\n" );
1105  }
1106  while ( ddF->reordered == 1 );
1107 //printf( "|F| =%6d |G| =%6d |H| =%6d |F|*|G| =%9d\n",
1108 // Cudd_DagSize(bF), Cudd_DagSize(bG), Cudd_DagSize(bRes),
1109 // Cudd_DagSize(bF) * Cudd_DagSize(bG) );
1110  return ( bRes );
1111 }
1112 
1113 /*---------------------------------------------------------------------------*/
1114 /* Definition of internal functions */
1115 /*---------------------------------------------------------------------------*/
1116 
1117 /**Function********************************************************************
1118 
1119  Synopsis [Performs the reordering-sensitive step of Extra_bddMove().]
1120 
1121  Description []
1122 
1123  SideEffects []
1124 
1125  SeeAlso []
1126 
1127 ******************************************************************************/
1129  DdManager * dd, /* the DD manager */
1130  DdNode * bF,
1131  DdNode * bDist)
1132 {
1133  DdNode * bRes;
1134 
1135  if ( Cudd_IsConstant(bF) )
1136  return bF;
1137 
1138  if ( (bRes = cuddCacheLookup2(dd, extraBddMove, bF, bDist)) )
1139  return bRes;
1140  else
1141  {
1142  DdNode * bRes0, * bRes1;
1143  DdNode * bF0, * bF1;
1144  DdNode * bFR = Cudd_Regular(bF);
1145  int VarNew;
1146 
1147  if ( Cudd_IsComplement(bDist) )
1148  VarNew = bFR->index - Cudd_Not(bDist)->index;
1149  else
1150  VarNew = bFR->index + bDist->index;
1151  assert( VarNew < dd->size );
1152 
1153  // cofactor the functions
1154  if ( bFR != bF ) // bFunc is complemented
1155  {
1156  bF0 = Cudd_Not( cuddE(bFR) );
1157  bF1 = Cudd_Not( cuddT(bFR) );
1158  }
1159  else
1160  {
1161  bF0 = cuddE(bFR);
1162  bF1 = cuddT(bFR);
1163  }
1164 
1165  bRes0 = extraBddMove( dd, bF0, bDist );
1166  if ( bRes0 == NULL )
1167  return NULL;
1168  cuddRef( bRes0 );
1169 
1170  bRes1 = extraBddMove( dd, bF1, bDist );
1171  if ( bRes1 == NULL )
1172  {
1173  Cudd_RecursiveDeref( dd, bRes0 );
1174  return NULL;
1175  }
1176  cuddRef( bRes1 );
1177 
1178  /* only bRes0 and bRes1 are referenced at this point */
1179  bRes = cuddBddIteRecur( dd, dd->vars[VarNew], bRes1, bRes0 );
1180  if ( bRes == NULL )
1181  {
1182  Cudd_RecursiveDeref( dd, bRes0 );
1183  Cudd_RecursiveDeref( dd, bRes1 );
1184  return NULL;
1185  }
1186  cuddRef( bRes );
1187  Cudd_RecursiveDeref( dd, bRes0 );
1188  Cudd_RecursiveDeref( dd, bRes1 );
1189 
1190  /* insert the result into cache */
1191  cuddCacheInsert2( dd, extraBddMove, bF, bDist, bRes );
1192  cuddDeref( bRes );
1193  return bRes;
1194  }
1195 } /* end of extraBddMove */
1196 
1197 
1198 /**Function********************************************************************
1199 
1200  Synopsis [Finds three cofactors of the cover w.r.t. to the topmost variable.]
1201 
1202  Description [Finds three cofactors of the cover w.r.t. to the topmost variable.
1203  Does not check the cover for being a constant. Assumes that ZDD variables encoding
1204  positive and negative polarities are adjacent in the variable order. Is different
1205  from cuddZddGetCofactors3() in that it does not compute the cofactors w.r.t. the
1206  given variable but takes the cofactors with respent to the topmost variable.
1207  This function is more efficient when used in recursive procedures because it does
1208  not require referencing of the resulting cofactors (compare cuddZddProduct()
1209  and extraZddPrimeProduct()).]
1210 
1211  SideEffects [None]
1212 
1213  SeeAlso [cuddZddGetCofactors3]
1214 
1215 ******************************************************************************/
1216 void
1218  DdManager* dd, /* the manager */
1219  DdNode* zC, /* the cover */
1220  DdNode** zC0, /* the pointer to the negative var cofactor */
1221  DdNode** zC1, /* the pointer to the positive var cofactor */
1222  DdNode** zC2 ) /* the pointer to the cofactor without var */
1223 {
1224  if ( (zC->index & 1) == 0 )
1225  { /* the top variable is present in positive polarity and maybe in negative */
1226 
1227  DdNode *Temp = cuddE( zC );
1228  *zC1 = cuddT( zC );
1229  if ( cuddIZ(dd,Temp->index) == cuddIZ(dd,zC->index) + 1 )
1230  { /* Temp is not a terminal node
1231  * top var is present in negative polarity */
1232  *zC2 = cuddE( Temp );
1233  *zC0 = cuddT( Temp );
1234  }
1235  else
1236  { /* top var is not present in negative polarity */
1237  *zC2 = Temp;
1238  *zC0 = dd->zero;
1239  }
1240  }
1241  else
1242  { /* the top variable is present only in negative */
1243  *zC1 = dd->zero;
1244  *zC2 = cuddE( zC );
1245  *zC0 = cuddT( zC );
1246  }
1247 } /* extraDecomposeCover */
1248 
1249 /*---------------------------------------------------------------------------*/
1250 /* Definition of static Functions */
1251 /*---------------------------------------------------------------------------*/
1252 
1253 /**Function********************************************************************
1254 
1255  Synopsis [Convert a BDD from a manager to another one.]
1256 
1257  Description [Convert a BDD from a manager to another one. Returns a
1258  pointer to the BDD in the destination manager if successful; NULL
1259  otherwise.]
1260 
1261  SideEffects [None]
1262 
1263  SeeAlso [Extra_TransferPermute]
1264 
1265 ******************************************************************************/
1266 DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute )
1267 {
1268  DdNode *res;
1269  st__table *table = NULL;
1270  st__generator *gen = NULL;
1271  DdNode *key, *value;
1272 
1274  if ( table == NULL )
1275  goto failure;
1276  res = extraTransferPermuteRecur( ddS, ddD, f, table, Permute );
1277  if ( res != NULL )
1278  cuddRef( res );
1279 
1280  /* Dereference all elements in the table and dispose of the table.
1281  ** This must be done also if res is NULL to avoid leaks in case of
1282  ** reordering. */
1283  gen = st__init_gen( table );
1284  if ( gen == NULL )
1285  goto failure;
1286  while ( st__gen( gen, ( const char ** ) &key, ( char ** ) &value ) )
1287  {
1288  Cudd_RecursiveDeref( ddD, value );
1289  }
1290  st__free_gen( gen );
1291  gen = NULL;
1292  st__free_table( table );
1293  table = NULL;
1294 
1295  if ( res != NULL )
1296  cuddDeref( res );
1297  return ( res );
1298 
1299  failure:
1300  if ( table != NULL )
1301  st__free_table( table );
1302  if ( gen != NULL )
1303  st__free_gen( gen );
1304  return ( NULL );
1305 
1306 } /* end of extraTransferPermute */
1307 
1308 
1309 /**Function********************************************************************
1310 
1311  Synopsis [Performs the recursive step of Extra_TransferPermute.]
1312 
1313  Description [Performs the recursive step of Extra_TransferPermute.
1314  Returns a pointer to the result if successful; NULL otherwise.]
1315 
1316  SideEffects [None]
1317 
1318  SeeAlso [extraTransferPermute]
1319 
1320 ******************************************************************************/
1321 static DdNode *
1323  DdManager * ddS,
1324  DdManager * ddD,
1325  DdNode * f,
1326  st__table * table,
1327  int * Permute )
1328 {
1329  DdNode *ft, *fe, *t, *e, *var, *res;
1330  DdNode *one, *zero;
1331  int index;
1332  int comple = 0;
1333 
1334  statLine( ddD );
1335  one = DD_ONE( ddD );
1336  comple = Cudd_IsComplement( f );
1337 
1338  /* Trivial cases. */
1339  if ( Cudd_IsConstant( f ) )
1340  return ( Cudd_NotCond( one, comple ) );
1341 
1342 
1343  /* Make canonical to increase the utilization of the cache. */
1344  f = Cudd_NotCond( f, comple );
1345  /* Now f is a regular pointer to a non-constant node. */
1346 
1347  /* Check the cache. */
1348  if ( st__lookup( table, ( char * ) f, ( char ** ) &res ) )
1349  return ( Cudd_NotCond( res, comple ) );
1350 
1351  if ( ddS->TimeStop && Abc_Clock() > ddS->TimeStop )
1352  return NULL;
1353  if ( ddD->TimeStop && Abc_Clock() > ddD->TimeStop )
1354  return NULL;
1355 
1356  /* Recursive step. */
1357  if ( Permute )
1358  index = Permute[f->index];
1359  else
1360  index = f->index;
1361 
1362  ft = cuddT( f );
1363  fe = cuddE( f );
1364 
1365  t = extraTransferPermuteRecur( ddS, ddD, ft, table, Permute );
1366  if ( t == NULL )
1367  {
1368  return ( NULL );
1369  }
1370  cuddRef( t );
1371 
1372  e = extraTransferPermuteRecur( ddS, ddD, fe, table, Permute );
1373  if ( e == NULL )
1374  {
1375  Cudd_RecursiveDeref( ddD, t );
1376  return ( NULL );
1377  }
1378  cuddRef( e );
1379 
1380  zero = Cudd_Not(ddD->one);
1381  var = cuddUniqueInter( ddD, index, one, zero );
1382  if ( var == NULL )
1383  {
1384  Cudd_RecursiveDeref( ddD, t );
1385  Cudd_RecursiveDeref( ddD, e );
1386  return ( NULL );
1387  }
1388  res = cuddBddIteRecur( ddD, var, t, e );
1389 
1390  if ( res == NULL )
1391  {
1392  Cudd_RecursiveDeref( ddD, t );
1393  Cudd_RecursiveDeref( ddD, e );
1394  return ( NULL );
1395  }
1396  cuddRef( res );
1397  Cudd_RecursiveDeref( ddD, t );
1398  Cudd_RecursiveDeref( ddD, e );
1399 
1400  if ( st__add_direct( table, ( char * ) f, ( char * ) res ) ==
1401  st__OUT_OF_MEM )
1402  {
1403  Cudd_RecursiveDeref( ddD, res );
1404  return ( NULL );
1405  }
1406  return ( Cudd_NotCond( res, comple ) );
1407 
1408 } /* end of extraTransferPermuteRecur */
1409 
1410 /**Function********************************************************************
1411 
1412  Synopsis [Performs the recursive step of Cudd_Support.]
1413 
1414  Description [Performs the recursive step of Cudd_Support. Performs a
1415  DFS from f. The support is accumulated in supp as a side effect. Uses
1416  the LSB of the then pointer as visited flag.]
1417 
1418  SideEffects [None]
1419 
1420  SeeAlso [ddClearFlag]
1421 
1422 ******************************************************************************/
1423 static void
1425  DdNode * f,
1426  int * support)
1427 {
1428  if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
1429  return;
1430  }
1431 
1432  support[f->index] = 1;
1433  ddSupportStep(cuddT(f),support);
1434  ddSupportStep(Cudd_Regular(cuddE(f)),support);
1435  /* Mark as visited. */
1436  f->next = Cudd_Not(f->next);
1437  return;
1438 
1439 } /* end of ddSupportStep */
1440 
1441 
1442 /**Function********************************************************************
1443 
1444  Synopsis [Performs a DFS from f, clearing the LSB of the next
1445  pointers.]
1446 
1447  Description []
1448 
1449  SideEffects [None]
1450 
1451  SeeAlso [ddSupportStep ddDagInt]
1452 
1453 ******************************************************************************/
1454 static void
1456  DdNode * f)
1457 {
1458  if (!Cudd_IsComplement(f->next)) {
1459  return;
1460  }
1461  /* Clear visited flag. */
1462  f->next = Cudd_Regular(f->next);
1463  if (cuddIsConstant(f)) {
1464  return;
1465  }
1466  ddClearFlag(cuddT(f));
1468  return;
1469 
1470 } /* end of ddClearFlag */
1471 
1472 
1473 /**Function********************************************************************
1474 
1475  Synopsis [Composed three subcovers into one ZDD.]
1476 
1477  Description []
1478 
1479  SideEffects [None]
1480 
1481  SeeAlso []
1482 
1483 ******************************************************************************/
1484 DdNode *
1486  DdManager* dd, /* the manager */
1487  DdNode* zC0, /* the pointer to the negative var cofactor */
1488  DdNode* zC1, /* the pointer to the positive var cofactor */
1489  DdNode* zC2, /* the pointer to the cofactor without var */
1490  int TopVar) /* the index of the positive ZDD var */
1491 {
1492  DdNode * zRes, * zTemp;
1493  /* compose with-neg-var and without-var using the neg ZDD var */
1494  zTemp = cuddZddGetNode( dd, 2*TopVar + 1, zC0, zC2 );
1495  if ( zTemp == NULL )
1496  {
1497  Cudd_RecursiveDerefZdd(dd, zC0);
1498  Cudd_RecursiveDerefZdd(dd, zC1);
1499  Cudd_RecursiveDerefZdd(dd, zC2);
1500  return NULL;
1501  }
1502  cuddRef( zTemp );
1503  cuddDeref( zC0 );
1504  cuddDeref( zC2 );
1505 
1506  /* compose with-pos-var and previous result using the pos ZDD var */
1507  zRes = cuddZddGetNode( dd, 2*TopVar, zC1, zTemp );
1508  if ( zRes == NULL )
1509  {
1510  Cudd_RecursiveDerefZdd(dd, zC1);
1511  Cudd_RecursiveDerefZdd(dd, zTemp);
1512  return NULL;
1513  }
1514  cuddDeref( zC1 );
1515  cuddDeref( zTemp );
1516  return zRes;
1517 } /* extraComposeCover */
1518 
1519 /**Function********************************************************************
1520 
1521  Synopsis [Performs the recursive step of prime computation.]
1522 
1523  Description []
1524 
1525  SideEffects []
1526 
1527  SeeAlso []
1528 
1529 ******************************************************************************/
1531 {
1532  DdNode *zRes;
1533 
1534  if ( F == Cudd_Not( dd->one ) )
1535  return dd->zero;
1536  if ( F == dd->one )
1537  return dd->one;
1538 
1539  /* check cache */
1540  zRes = cuddCacheLookup1Zdd(dd, extraZddPrimes, F);
1541  if (zRes)
1542  return(zRes);
1543  {
1544  /* temporary variables */
1545  DdNode *bF01, *zP0, *zP1;
1546  /* three components of the prime set */
1547  DdNode *zResE, *zResP, *zResN;
1548  int fIsComp = Cudd_IsComplement( F );
1549 
1550  /* find cofactors of F */
1551  DdNode * bF0 = Cudd_NotCond( Cudd_E( F ), fIsComp );
1552  DdNode * bF1 = Cudd_NotCond( Cudd_T( F ), fIsComp );
1553 
1554  /* find the intersection of cofactors */
1555  bF01 = cuddBddAndRecur( dd, bF0, bF1 );
1556  if ( bF01 == NULL ) return NULL;
1557  cuddRef( bF01 );
1558 
1559  /* solve the problems for cofactors */
1560  zP0 = extraZddPrimes( dd, bF0 );
1561  if ( zP0 == NULL )
1562  {
1563  Cudd_RecursiveDeref( dd, bF01 );
1564  return NULL;
1565  }
1566  cuddRef( zP0 );
1567 
1568  zP1 = extraZddPrimes( dd, bF1 );
1569  if ( zP1 == NULL )
1570  {
1571  Cudd_RecursiveDeref( dd, bF01 );
1572  Cudd_RecursiveDerefZdd( dd, zP0 );
1573  return NULL;
1574  }
1575  cuddRef( zP1 );
1576 
1577  /* check for local unateness */
1578  if ( bF01 == bF0 ) /* unate increasing */
1579  {
1580  /* intersection is useless */
1581  cuddDeref( bF01 );
1582  /* the primes of intersection are the primes of F0 */
1583  zResE = zP0;
1584  /* there are no primes with negative var */
1585  zResN = dd->zero;
1586  cuddRef( zResN );
1587  /* primes with positive var are primes of F1 that are not primes of F01 */
1588  zResP = cuddZddDiff( dd, zP1, zP0 );
1589  if ( zResP == NULL )
1590  {
1591  Cudd_RecursiveDerefZdd( dd, zResE );
1592  Cudd_RecursiveDerefZdd( dd, zResN );
1593  Cudd_RecursiveDerefZdd( dd, zP1 );
1594  return NULL;
1595  }
1596  cuddRef( zResP );
1597  Cudd_RecursiveDerefZdd( dd, zP1 );
1598  }
1599  else if ( bF01 == bF1 ) /* unate decreasing */
1600  {
1601  /* intersection is useless */
1602  cuddDeref( bF01 );
1603  /* the primes of intersection are the primes of F1 */
1604  zResE = zP1;
1605  /* there are no primes with positive var */
1606  zResP = dd->zero;
1607  cuddRef( zResP );
1608  /* primes with negative var are primes of F0 that are not primes of F01 */
1609  zResN = cuddZddDiff( dd, zP0, zP1 );
1610  if ( zResN == NULL )
1611  {
1612  Cudd_RecursiveDerefZdd( dd, zResE );
1613  Cudd_RecursiveDerefZdd( dd, zResP );
1614  Cudd_RecursiveDerefZdd( dd, zP0 );
1615  return NULL;
1616  }
1617  cuddRef( zResN );
1618  Cudd_RecursiveDerefZdd( dd, zP0 );
1619  }
1620  else /* not unate */
1621  {
1622  /* primes without the top var are primes of F10 */
1623  zResE = extraZddPrimes( dd, bF01 );
1624  if ( zResE == NULL )
1625  {
1626  Cudd_RecursiveDerefZdd( dd, bF01 );
1627  Cudd_RecursiveDerefZdd( dd, zP0 );
1628  Cudd_RecursiveDerefZdd( dd, zP1 );
1629  return NULL;
1630  }
1631  cuddRef( zResE );
1632  Cudd_RecursiveDeref( dd, bF01 );
1633 
1634  /* primes with the negative top var are those of P0 that are not in F10 */
1635  zResN = cuddZddDiff( dd, zP0, zResE );
1636  if ( zResN == NULL )
1637  {
1638  Cudd_RecursiveDerefZdd( dd, zResE );
1639  Cudd_RecursiveDerefZdd( dd, zP0 );
1640  Cudd_RecursiveDerefZdd( dd, zP1 );
1641  return NULL;
1642  }
1643  cuddRef( zResN );
1644  Cudd_RecursiveDerefZdd( dd, zP0 );
1645 
1646  /* primes with the positive top var are those of P1 that are not in F10 */
1647  zResP = cuddZddDiff( dd, zP1, zResE );
1648  if ( zResP == NULL )
1649  {
1650  Cudd_RecursiveDerefZdd( dd, zResE );
1651  Cudd_RecursiveDerefZdd( dd, zResN );
1652  Cudd_RecursiveDerefZdd( dd, zP1 );
1653  return NULL;
1654  }
1655  cuddRef( zResP );
1656  Cudd_RecursiveDerefZdd( dd, zP1 );
1657  }
1658 
1659  zRes = extraComposeCover( dd, zResN, zResP, zResE, Cudd_Regular(F)->index );
1660  if ( zRes == NULL ) return NULL;
1661 
1662  /* insert the result into cache */
1663  cuddCacheInsert1(dd, extraZddPrimes, F, zRes);
1664  return zRes;
1665  }
1666 } /* end of extraZddPrimes */
1667 
1668 /**Function********************************************************************
1669 
1670  Synopsis [Implements the recursive step of Cudd_bddPermute.]
1671 
1672  Description [ Recursively puts the BDD in the order given in the array permut.
1673  Checks for trivial cases to terminate recursion, then splits on the
1674  children of this node. Once the solutions for the children are
1675  obtained, it puts into the current position the node from the rest of
1676  the BDD that should be here. Then returns this BDD.
1677  The key here is that the node being visited is NOT put in its proper
1678  place by this instance, but rather is switched when its proper position
1679  is reached in the recursion tree.<p>
1680  The DdNode * that is returned is the same BDD as passed in as node,
1681  but in the new order.]
1682 
1683  SideEffects [None]
1684 
1685  SeeAlso [Cudd_bddPermute cuddAddPermuteRecur]
1686 
1687 ******************************************************************************/
1688 static DdNode *
1689 cuddBddPermuteRecur( DdManager * manager /* DD manager */ ,
1690  DdHashTable * table /* computed table */ ,
1691  DdNode * node /* BDD to be reordered */ ,
1692  int *permut /* permutation array */ )
1693 {
1694  DdNode *N, *T, *E;
1695  DdNode *res;
1696  int index;
1697 
1698  statLine( manager );
1699  N = Cudd_Regular( node );
1700 
1701  /* Check for terminal case of constant node. */
1702  if ( cuddIsConstant( N ) )
1703  {
1704  return ( node );
1705  }
1706 
1707  /* If problem already solved, look up answer and return. */
1708  if ( N->ref != 1 && ( res = cuddHashTableLookup1( table, N ) ) != NULL )
1709  {
1710  return ( Cudd_NotCond( res, N != node ) );
1711  }
1712 
1713  /* Split and recur on children of this node. */
1714  T = cuddBddPermuteRecur( manager, table, cuddT( N ), permut );
1715  if ( T == NULL )
1716  return ( NULL );
1717  cuddRef( T );
1718  E = cuddBddPermuteRecur( manager, table, cuddE( N ), permut );
1719  if ( E == NULL )
1720  {
1721  Cudd_IterDerefBdd( manager, T );
1722  return ( NULL );
1723  }
1724  cuddRef( E );
1725 
1726  /* Move variable that should be in this position to this position
1727  ** by retrieving the single var BDD for that variable, and calling
1728  ** cuddBddIteRecur with the T and E we just created.
1729  */
1730  index = permut[N->index];
1731  res = cuddBddIteRecur( manager, manager->vars[index], T, E );
1732  if ( res == NULL )
1733  {
1734  Cudd_IterDerefBdd( manager, T );
1735  Cudd_IterDerefBdd( manager, E );
1736  return ( NULL );
1737  }
1738  cuddRef( res );
1739  Cudd_IterDerefBdd( manager, T );
1740  Cudd_IterDerefBdd( manager, E );
1741 
1742  /* Do not keep the result if the reference count is only 1, since
1743  ** it will not be visited again.
1744  */
1745  if ( N->ref != 1 )
1746  {
1747  ptrint fanout = ( ptrint ) N->ref;
1748  cuddSatDec( fanout );
1749  if ( !cuddHashTableInsert1( table, N, res, fanout ) )
1750  {
1751  Cudd_IterDerefBdd( manager, res );
1752  return ( NULL );
1753  }
1754  }
1755  cuddDeref( res );
1756  return ( Cudd_NotCond( res, N != node ) );
1757 
1758 } /* end of cuddBddPermuteRecur */
1759 
1760 
1761 /**Function********************************************************************
1762 
1763  Synopsis [Performs the reordering-sensitive step of Extra_bddChangePolarity().]
1764 
1765  Description []
1766 
1767  SideEffects []
1768 
1769  SeeAlso []
1770 
1771 ******************************************************************************/
1773  DdManager * dd, /* the DD manager */
1774  DdNode * bFunc,
1775  DdNode * bVars)
1776 {
1777  DdNode * bRes;
1778 
1779  if ( bVars == b1 )
1780  return bFunc;
1781  if ( Cudd_IsConstant(bFunc) )
1782  return bFunc;
1783 
1784  if ( (bRes = cuddCacheLookup2(dd, extraBddChangePolarity, bFunc, bVars)) )
1785  return bRes;
1786  else
1787  {
1788  DdNode * bFR = Cudd_Regular(bFunc);
1789  int LevelF = dd->perm[bFR->index];
1790  int LevelV = dd->perm[bVars->index];
1791 
1792  if ( LevelV < LevelF )
1793  bRes = extraBddChangePolarity( dd, bFunc, cuddT(bVars) );
1794  else // if ( LevelF <= LevelV )
1795  {
1796  DdNode * bRes0, * bRes1;
1797  DdNode * bF0, * bF1;
1798  DdNode * bVarsNext;
1799 
1800  // cofactor the functions
1801  if ( bFR != bFunc ) // bFunc is complemented
1802  {
1803  bF0 = Cudd_Not( cuddE(bFR) );
1804  bF1 = Cudd_Not( cuddT(bFR) );
1805  }
1806  else
1807  {
1808  bF0 = cuddE(bFR);
1809  bF1 = cuddT(bFR);
1810  }
1811 
1812  if ( LevelF == LevelV )
1813  bVarsNext = cuddT(bVars);
1814  else
1815  bVarsNext = bVars;
1816 
1817  bRes0 = extraBddChangePolarity( dd, bF0, bVarsNext );
1818  if ( bRes0 == NULL )
1819  return NULL;
1820  cuddRef( bRes0 );
1821 
1822  bRes1 = extraBddChangePolarity( dd, bF1, bVarsNext );
1823  if ( bRes1 == NULL )
1824  {
1825  Cudd_RecursiveDeref( dd, bRes0 );
1826  return NULL;
1827  }
1828  cuddRef( bRes1 );
1829 
1830  if ( LevelF == LevelV )
1831  { // swap the cofactors
1832  DdNode * bTemp;
1833  bTemp = bRes0;
1834  bRes0 = bRes1;
1835  bRes1 = bTemp;
1836  }
1837 
1838  /* only aRes0 and aRes1 are referenced at this point */
1839 
1840  /* consider the case when Res0 and Res1 are the same node */
1841  if ( bRes0 == bRes1 )
1842  bRes = bRes1;
1843  /* consider the case when Res1 is complemented */
1844  else if ( Cudd_IsComplement(bRes1) )
1845  {
1846  bRes = cuddUniqueInter(dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
1847  if ( bRes == NULL )
1848  {
1849  Cudd_RecursiveDeref(dd,bRes0);
1850  Cudd_RecursiveDeref(dd,bRes1);
1851  return NULL;
1852  }
1853  bRes = Cudd_Not(bRes);
1854  }
1855  else
1856  {
1857  bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
1858  if ( bRes == NULL )
1859  {
1860  Cudd_RecursiveDeref(dd,bRes0);
1861  Cudd_RecursiveDeref(dd,bRes1);
1862  return NULL;
1863  }
1864  }
1865  cuddDeref( bRes0 );
1866  cuddDeref( bRes1 );
1867  }
1868 
1869  /* insert the result into cache */
1870  cuddCacheInsert2(dd, extraBddChangePolarity, bFunc, bVars, bRes);
1871  return bRes;
1872  }
1873 } /* end of extraBddChangePolarity */
1874 
1875 
1876 
1877 static int Counter = 0;
1878 
1879 /**Function*************************************************************
1880 
1881  Synopsis [Computes the AND of two BDD with different orders.]
1882 
1883  Description []
1884 
1885  SideEffects []
1886 
1887  SeeAlso []
1888 
1889 ***********************************************************************/
1890 DdNode * extraBddAndPermute( DdHashTable * table, DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute )
1891 {
1892  DdNode * bF0, * bF1, * bG0, * bG1, * bRes0, * bRes1, * bRes, * bVar;
1893  int LevF, LevG, Lev;
1894 
1895  // if F == 0, return 0
1896  if ( bF == Cudd_Not(ddF->one) )
1897  return Cudd_Not(ddF->one);
1898  // if G == 0, return 0
1899  if ( bG == Cudd_Not(ddG->one) )
1900  return Cudd_Not(ddF->one);
1901  // if G == 1, return F
1902  if ( bG == ddG->one )
1903  return bF;
1904  // cannot use F == 1, because the var order of G has to be changed
1905 
1906  // check cache
1907  if ( //(Cudd_Regular(bF)->ref != 1 || Cudd_Regular(bG)->ref != 1) &&
1908  (bRes = cuddHashTableLookup2(table, bF, bG)) )
1909  return bRes;
1910  Counter++;
1911 
1912  if ( ddF->TimeStop && Abc_Clock() > ddF->TimeStop )
1913  return NULL;
1914  if ( ddG->TimeStop && Abc_Clock() > ddG->TimeStop )
1915  return NULL;
1916 
1917  // find the topmost variable in F and G using var order of F
1918  LevF = cuddI( ddF, Cudd_Regular(bF)->index );
1919  LevG = cuddI( ddF, pPermute ? pPermute[Cudd_Regular(bG)->index] : Cudd_Regular(bG)->index );
1920  Lev = Abc_MinInt( LevF, LevG );
1921  assert( Lev < ddF->size );
1922  bVar = ddF->vars[ddF->invperm[Lev]];
1923 
1924  // cofactor
1925  bF0 = (Lev < LevF) ? bF : Cudd_NotCond( cuddE(Cudd_Regular(bF)), Cudd_IsComplement(bF) );
1926  bF1 = (Lev < LevF) ? bF : Cudd_NotCond( cuddT(Cudd_Regular(bF)), Cudd_IsComplement(bF) );
1927  bG0 = (Lev < LevG) ? bG : Cudd_NotCond( cuddE(Cudd_Regular(bG)), Cudd_IsComplement(bG) );
1928  bG1 = (Lev < LevG) ? bG : Cudd_NotCond( cuddT(Cudd_Regular(bG)), Cudd_IsComplement(bG) );
1929 
1930  // call for cofactors
1931  bRes0 = extraBddAndPermute( table, ddF, bF0, ddG, bG0, pPermute );
1932  if ( bRes0 == NULL )
1933  return NULL;
1934  cuddRef( bRes0 );
1935  // call for cofactors
1936  bRes1 = extraBddAndPermute( table, ddF, bF1, ddG, bG1, pPermute );
1937  if ( bRes1 == NULL )
1938  {
1939  Cudd_IterDerefBdd( ddF, bRes0 );
1940  return NULL;
1941  }
1942  cuddRef( bRes1 );
1943 
1944  // compose the result
1945  bRes = cuddBddIteRecur( ddF, bVar, bRes1, bRes0 );
1946  if ( bRes == NULL )
1947  {
1948  Cudd_IterDerefBdd( ddF, bRes0 );
1949  Cudd_IterDerefBdd( ddF, bRes1 );
1950  return NULL;
1951  }
1952  cuddRef( bRes );
1953  Cudd_IterDerefBdd( ddF, bRes0 );
1954  Cudd_IterDerefBdd( ddF, bRes1 );
1955 
1956  // cache the result
1957 // if ( Cudd_Regular(bF)->ref != 1 || Cudd_Regular(bG)->ref != 1 )
1958  {
1959  ptrint fanout = (ptrint)Cudd_Regular(bF)->ref * Cudd_Regular(bG)->ref;
1960  cuddSatDec(fanout);
1961  cuddHashTableInsert2( table, bF, bG, bRes, fanout );
1962  }
1963  cuddDeref( bRes );
1964  return bRes;
1965 }
1966 
1967 /**Function*************************************************************
1968 
1969  Synopsis [Testbench.]
1970 
1971  Description [This procedure takes BDD manager ddF and two BDDs
1972  in this manager (bF and bG). It creates a new manager ddG,
1973  transfers bG into it and then reorders it, resulting in bG2.
1974  Then it tries to compute the product of bF and bG2 in ddF.]
1975 
1976  SideEffects []
1977 
1978  SeeAlso []
1979 
1980 ***********************************************************************/
1981 void Extra_TestAndPerm( DdManager * ddF, DdNode * bF, DdNode * bG )
1982 {
1983  DdManager * ddG;
1984  DdNode * bG2, * bRes1, * bRes2;
1985  abctime clk;
1986  // disable variable ordering in ddF
1987  Cudd_AutodynDisable( ddF );
1988 
1989  // create new BDD manager
1990  ddG = Cudd_Init( ddF->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
1991  // transfer BDD into it
1992  Cudd_ShuffleHeap( ddG, ddF->invperm );
1993  bG2 = Extra_TransferLevelByLevel( ddF, ddG, bG ); Cudd_Ref( bG2 );
1994  // reorder the new manager
1996 
1997  // compute the result
1998 clk = Abc_Clock();
1999  bRes1 = Cudd_bddAnd( ddF, bF, bG ); Cudd_Ref( bRes1 );
2000 Abc_PrintTime( 1, "Runtime of Cudd_bddAnd ", Abc_Clock() - clk );
2001 
2002  // compute the result
2003 Counter = 0;
2004 clk = Abc_Clock();
2005  bRes2 = Extra_bddAndPermute( ddF, bF, ddG, bG2, NULL ); Cudd_Ref( bRes2 );
2006 Abc_PrintTime( 1, "Runtime of new procedure", Abc_Clock() - clk );
2007 printf( "Recursive calls = %d\n", Counter );
2008 printf( "|F| =%6d |G| =%6d |H| =%6d |F|*|G| =%9d ",
2009  Cudd_DagSize(bF), Cudd_DagSize(bG), Cudd_DagSize(bRes2),
2010  Cudd_DagSize(bF) * Cudd_DagSize(bG) );
2011 
2012  if ( bRes1 == bRes2 )
2013  printf( "Result verified.\n\n" );
2014  else
2015  printf( "Result is incorrect.\n\n" );
2016 
2017  Cudd_RecursiveDeref( ddF, bRes1 );
2018  Cudd_RecursiveDeref( ddF, bRes2 );
2019  // quit the new manager
2020  Cudd_RecursiveDeref( ddG, bG2 );
2021  Extra_StopManager( ddG );
2022 
2023  // re-enable variable ordering in ddF
2025 }
2026 
2027 
2028 ////////////////////////////////////////////////////////////////////////
2029 /// END OF FILE ///
2030 ////////////////////////////////////////////////////////////////////////
2031 
2032 
2034 
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define Cudd_T(node)
Definition: cudd.h:440
void Extra_TestAndPerm(DdManager *ddF, DdNode *bF, DdNode *bG)
#define CUDD_UNIQUE_SLOTS
Definition: cudd.h:97
#define cuddDeref(n)
Definition: cuddInt.h:604
#define Cudd_E(node)
Definition: cudd.h:455
#define cuddIZ(dd, index)
Definition: cuddInt.h:704
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
DdNode * Extra_bddCreateAnd(DdManager *dd, int nVars)
Definition: extraBddMisc.c:858
abctime TimeStop
Definition: cuddInt.h:489
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * Extra_bddRemapUp(DdManager *dd, DdNode *bF)
Definition: extraBddMisc.c:145
int Extra_bddSuppDifferentVars(DdManager *dd, DdNode *S1, DdNode *S2, int DiffMax)
Definition: extraBddMisc.c:393
int Cudd_bddPickOneCube(DdManager *ddm, DdNode *node, char *string)
Definition: cuddUtil.c:1221
void st__free_gen(st__generator *gen)
Definition: st.c:556
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
Definition: extraBddMisc.c:730
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:740
#define Cudd_ForeachCube(manager, f, gen, cube, value)
Definition: cudd.h:519
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
DdNode * Extra_bddComputeCube(DdManager *dd, DdNode **bXVars, int nVars)
int size
Definition: cuddInt.h:361
static DdNode * extraTransferPermute(DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute)
int var(Lit p)
Definition: SolverTypes.h:62
#define b1
Definition: extraBdd.h:76
#define Cudd_IsConstant(node)
Definition: cudd.h:352
DdNode * Extra_bddCreateExor(DdManager *dd, int nVars)
Definition: extraBddMisc.c:908
DdNode * Cudd_ReadLogicZero(DdManager *dd)
Definition: cuddAPI.c:1058
DdNode * extraBddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
DdNode * zero
Definition: cuddInt.h:346
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
Definition: extraBddMisc.c:321
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
static void ddSupportStep(DdNode *f, int *support)
int Extra_bddSuppContainVar(DdManager *dd, DdNode *bS, DdNode *bVar)
Definition: extraBddMisc.c:346
#define CUDD_CACHE_SLOTS
Definition: cudd.h:98
DdNode * Extra_bddFindOneCube(DdManager *dd, DdNode *bF)
Definition: extraBddMisc.c:605
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static DdNode * extraBddAndPermute(DdHashTable *table, DdManager *ddF, DdNode *bF, DdManager *ddG, DdNode *bG, int *pPermute)
int * Extra_VectorSupportArray(DdManager *dd, DdNode **F, int n, int *support)
Definition: extraBddMisc.c:572
Definition: cuddInt.h:204
static abctime Abc_Clock()
Definition: abc_global.h:279
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
Definition: cuddLCache.c:819
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * Extra_bddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
DdNode * Extra_TransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
Definition: extraBddMisc.c:87
int Extra_bddIsVar(DdNode *bFunc)
Definition: extraBddMisc.c:839
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
DdNode * extraComposeCover(DdManager *dd, DdNode *zC0, DdNode *zC1, DdNode *zC2, int TopVar)
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
int reordered
Definition: cuddInt.h:409
static int Abc_MinInt(int a, int b)
Definition: abc_global.h:239
static DdNode * extraZddPrimes(DdManager *dd, DdNode *F)
static DdNode * cuddBddPermuteRecur(DdManager *manager, DdHashTable *table, DdNode *node, int *permut)
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode * cuddZddDiff(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:717
static DdNode *cuddBddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut))
DdNode * Extra_bddCreateOr(DdManager *dd, int nVars)
Definition: extraBddMisc.c:883
DdNode * Extra_bddSupportNegativeCube(DdManager *dd, DdNode *f)
Definition: extraBddMisc.c:764
int Cudd_ShuffleHeap(DdManager *table, int *permutation)
Definition: cuddReorder.c:338
static DdNode * one
Definition: cuddDecomp.c:112
#define Code
Definition: deflate.h:76
ABC_PTRINT_T ptrint
Definition: cuddInt.h:260
DdNode * Cudd_bddPermute(DdManager *manager, DdNode *node, int *permut)
Definition: cuddCompose.c:332
Definition: st.h:52
DdNode * Extra_zddPrimes(DdManager *dd, DdNode *F)
Definition: extraBddMisc.c:933
DdNode * Extra_bddComputeRangeCube(DdManager *dd, int iStart, int iStop)
Definition: extraBddMisc.c:699
DdNode * next
Definition: cudd.h:281
void Extra_bddPrint(DdManager *dd, DdNode *F)
Definition: extraBddMisc.c:246
DdNode * Extra_bddMove(DdManager *dd, DdNode *bF, int nVars)
Definition: extraBddMisc.c:187
#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
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define ddMax(x, y)
Definition: cuddInt.h:832
if(last==0)
Definition: sparse_int.h:34
#define CUDD_CONST_INDEX
Definition: cudd.h:117
void Extra_StopManager(DdManager *dd)
Definition: extraBddMisc.c:223
static int size
Definition: cuddSign.c:86
static int Counter
DdNode * Extra_bddGetOneCube(DdManager *dd, DdNode *bFunc)
Definition: extraBddMisc.c:645
#define ddMin(x, y)
Definition: cuddInt.h:818
void extraDecomposeCover(DdManager *dd, DdNode *zC, DdNode **zC0, DdNode **zC1, DdNode **zC2)
void cuddHashTableQuit(DdHashTable *hash)
Definition: cuddLCache.c:595
DdNode * Cudd_bddOr(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:381
DdNode * Extra_TransferLevelByLevel(DdManager *ddSource, DdManager *ddDestination, DdNode *f)
Definition: extraBddMisc.c:112
#define cuddT(node)
Definition: cuddInt.h:636
st__generator * st__init_gen(st__table *table)
Definition: st.c:486
void Extra_bddPermuteArray(DdManager *manager, DdNode **bNodesIn, DdNode **bNodesOut, int nNodes, int *permut)
Definition: extraBddMisc.c:961
#define st__OUT_OF_MEM
Definition: st.h:113
int cuddHashTableInsert2(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)
Definition: cuddLCache.c:874
int * Extra_SupportArray(DdManager *dd, DdNode *f, int *support)
Definition: extraBddMisc.c:537
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int Cudd_CheckZeroRef(DdManager *manager)
Definition: cuddRef.c:466
void Cudd_AutodynDisable(DdManager *unique)
Definition: cuddAPI.c:708
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdNode * Cudd_ReadOne(DdManager *dd)
Definition: cuddAPI.c:987
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
Definition: cuddLCache.c:767
static ABC_NAMESPACE_IMPL_START DdNode * extraTransferPermuteRecur(DdManager *ddS, DdManager *ddD, DdNode *f, st__table *table, int *Permute)
#define b0
Definition: extraBdd.h:75
int sizeZ
Definition: cuddInt.h:362
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
enum keys key
static void ddClearFlag(DdNode *f)
DdNode * Cudd_bddIthVar(DdManager *dd, int i)
Definition: cuddAPI.c:416
DdNode * cuddHashTableLookup2(DdHashTable *hash, DdNode *f, DdNode *g)
Definition: cuddLCache.c:928
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:476
DdNode * one
Definition: cuddInt.h:345
DdNode * Extra_bddAndPermute(DdManager *ddF, DdNode *bF, DdManager *ddG, DdNode *bG, int *pPermute)
#define cuddE(node)
Definition: cuddInt.h:652
int st__add_direct(st__table *table, char *key, char *value)
Definition: st.c:205
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
void Extra_bddPrintSupport(DdManager *dd, DdNode *F)
Definition: extraBddMisc.c:302
int value
#define cuddSatDec(x)
Definition: cuddInt.h:896
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
Definition: cuddLCache.c:538
#define assert(ex)
Definition: util_old.h:213
int Extra_bddSuppOverlapping(DdManager *dd, DdNode *S1, DdNode *S2)
Definition: extraBddMisc.c:365
int * invperm
Definition: cuddInt.h:388
void Cudd_Quit(DdManager *unique)
Definition: cuddInit.c:225
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
#define DD_ONE(dd)
Definition: cuddInt.h:911
ABC_INT64_T abctime
Definition: abc_global.h:278
int Extra_bddSuppCheckContainment(DdManager *dd, DdNode *bL, DdNode *bH, DdNode **bLarge, DdNode **bSmall)
Definition: extraBddMisc.c:443
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
DdNode * extraBddMove(DdManager *dd, DdNode *bF, DdNode *bDist)
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int st__ptrhash(const char *, int)
Definition: st.c:468
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition: st.c:502
DdNode * cuddCacheLookup1Zdd(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:664
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
int Extra_bddVarIsInCube(DdNode *bCube, int iVar)
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633