ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
extraBddMisc.c
Go to the documentation of this file.
1
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
48
49/*---------------------------------------------------------------------------*/
50/* Static function prototypes */
51/*---------------------------------------------------------------------------*/
52
53// file "extraDdTransfer.c"
54static DdNode * extraTransferPermuteRecur( DdManager * ddS, DdManager * ddD, DdNode * f, st__table * table, int * Permute );
55static DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute );
56static DdNode * cuddBddPermuteRecur ARGS( ( DdManager * manager, DdHashTable * table, DdNode * node, int *permut ) );
57
58static DdNode * extraBddAndPermute( DdHashTable * table, DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute );
59
60// file "cuddUtils.c"
61void ddSupportStep2(DdNode *f, int *support);
62void ddClearFlag2(DdNode *f);
63
64static DdNode* extraZddPrimes( DdManager *dd, DdNode* F );
65
67
68/*---------------------------------------------------------------------------*/
69/* Definition of exported functions */
70/*---------------------------------------------------------------------------*/
71
87DdNode * 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
112DdNode * 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
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
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
223void Extra_StopManager( DdManager * dd )
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
246void 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
302void Extra_bddPrintSupport( DdManager * dd, DdNode * F )
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
321int 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
346int 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
365int Extra_bddSuppOverlapping( DdManager * dd, DdNode * S1, DdNode * S2 )
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
393int 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
443int 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
536int *
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 ddSupportStep2(Cudd_Regular(f),support);
551 ddClearFlag2(Cudd_Regular(f));
552
553 return(support);
554
555} /* end of Extra_SupportArray */
556
571int *
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 ddSupportStep2( Cudd_Regular(F[i]), support );
588 for ( i = 0; i < n; i++ )
589 ddClearFlag2( Cudd_Regular(F[i]) );
590
591 return support;
592}
593
605DdNode * Extra_bddFindOneCube( DdManager * dd, DdNode * bF )
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
645DdNode * Extra_bddGetOneCube( DdManager * dd, DdNode * bFunc )
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
699DdNode * 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
730DdNode * 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
764DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f )
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 {
776 dd->errorCode = CUDD_MEMORY_OUT;
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 ddSupportStep2( Cudd_Regular( f ), support );
786 ddClearFlag2( 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 ) );
801 var = Cudd_Not(var);
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
839int 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
858DdNode * 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
883DdNode * 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
908DdNode * Extra_bddCreateExor( DdManager * dd, int nVars )
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
933DdNode * Extra_zddPrimes( DdManager * dd, DdNode * F )
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
961void 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
1001DdNode * 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
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
1056int 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
1090DdNode * 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
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
1216void
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
1262static DdNode * extraBddCountCubes( DdManager * dd, DdNode * L, DdNode * U, st__table *table, int * pnCubes, int Limit )
1263{
1264 DdNode *one = DD_ONE(dd);
1265 DdNode *zero = Cudd_Not(one);
1266 int v, top_l, top_u;
1267 DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
1268 DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
1269 DdNode *Isub0, *Isub1, *Id;
1270 DdNode *x;
1271 DdNode *term0, *term1, *sum;
1272 DdNode *Lv, *Uv, *Lnv, *Unv;
1273 DdNode *r;
1274 int index;
1275 int Count0 = 0, Count1 = 0, Count2 = 0;
1276
1277 statLine(dd);
1278 if (L == zero)
1279 {
1280 *pnCubes = 0;
1281 return(zero);
1282 }
1283 if (U == one)
1284 {
1285 *pnCubes = 1;
1286 return(one);
1287 }
1288
1289 /* Check cache */
1290 r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
1291 if (r)
1292 {
1293 int nCubes = 0;
1294 if ( st__lookup_int( table, (char *)r, &nCubes ) )
1295 *pnCubes = nCubes;
1296 else assert( 0 );
1297 return r;
1298 }
1299
1300 top_l = dd->perm[Cudd_Regular(L)->index];
1301 top_u = dd->perm[Cudd_Regular(U)->index];
1302 v = ddMin(top_l, top_u);
1303
1304 /* Compute cofactors */
1305 if (top_l == v) {
1306 index = Cudd_Regular(L)->index;
1307 Lv = Cudd_T(L);
1308 Lnv = Cudd_E(L);
1309 if (Cudd_IsComplement(L)) {
1310 Lv = Cudd_Not(Lv);
1311 Lnv = Cudd_Not(Lnv);
1312 }
1313 }
1314 else {
1315 index = Cudd_Regular(U)->index;
1316 Lv = Lnv = L;
1317 }
1318
1319 if (top_u == v) {
1320 Uv = Cudd_T(U);
1321 Unv = Cudd_E(U);
1322 if (Cudd_IsComplement(U)) {
1323 Uv = Cudd_Not(Uv);
1324 Unv = Cudd_Not(Unv);
1325 }
1326 }
1327 else {
1328 Uv = Unv = U;
1329 }
1330
1331 Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
1332 if (Lsub0 == NULL)
1333 return(NULL);
1334 Cudd_Ref(Lsub0);
1335 Usub0 = Unv;
1336 Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
1337 if (Lsub1 == NULL) {
1338 Cudd_RecursiveDeref(dd, Lsub0);
1339 return(NULL);
1340 }
1341 Cudd_Ref(Lsub1);
1342 Usub1 = Uv;
1343
1344 Isub0 = extraBddCountCubes(dd, Lsub0, Usub0, table, &Count0, Limit);
1345 if (Isub0 == NULL) {
1346 Cudd_RecursiveDeref(dd, Lsub0);
1347 Cudd_RecursiveDeref(dd, Lsub1);
1348 return(NULL);
1349 }
1350 Cudd_Ref(Isub0);
1351 Isub1 = extraBddCountCubes(dd, Lsub1, Usub1, table, &Count1, Limit);
1352 if (Isub1 == NULL) {
1353 Cudd_RecursiveDeref(dd, Lsub0);
1354 Cudd_RecursiveDeref(dd, Lsub1);
1355 Cudd_RecursiveDeref(dd, Isub0);
1356 return(NULL);
1357 }
1358 Cudd_Ref(Isub1);
1359 Cudd_RecursiveDeref(dd, Lsub0);
1360 Cudd_RecursiveDeref(dd, Lsub1);
1361
1362 Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
1363 if (Lsuper0 == NULL) {
1364 Cudd_RecursiveDeref(dd, Isub0);
1365 Cudd_RecursiveDeref(dd, Isub1);
1366 return(NULL);
1367 }
1368 Cudd_Ref(Lsuper0);
1369 Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
1370 if (Lsuper1 == NULL) {
1371 Cudd_RecursiveDeref(dd, Isub0);
1372 Cudd_RecursiveDeref(dd, Isub1);
1373 Cudd_RecursiveDeref(dd, Lsuper0);
1374 return(NULL);
1375 }
1376 Cudd_Ref(Lsuper1);
1377 Usuper0 = Unv;
1378 Usuper1 = Uv;
1379
1380 /* Ld = Lsuper0 + Lsuper1 */
1381 Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
1382 Ld = Cudd_NotCond(Ld, Ld != NULL);
1383 if (Ld == NULL) {
1384 Cudd_RecursiveDeref(dd, Isub0);
1385 Cudd_RecursiveDeref(dd, Isub1);
1386 Cudd_RecursiveDeref(dd, Lsuper0);
1387 Cudd_RecursiveDeref(dd, Lsuper1);
1388 return(NULL);
1389 }
1390 Cudd_Ref(Ld);
1391 Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
1392 if (Ud == NULL) {
1393 Cudd_RecursiveDeref(dd, Isub0);
1394 Cudd_RecursiveDeref(dd, Isub1);
1395 Cudd_RecursiveDeref(dd, Lsuper0);
1396 Cudd_RecursiveDeref(dd, Lsuper1);
1397 Cudd_RecursiveDeref(dd, Ld);
1398 return(NULL);
1399 }
1400 Cudd_Ref(Ud);
1401 Cudd_RecursiveDeref(dd, Lsuper0);
1402 Cudd_RecursiveDeref(dd, Lsuper1);
1403
1404 Id = extraBddCountCubes(dd, Ld, Ud, table, &Count2, Limit);
1405 if (Id == NULL) {
1406 Cudd_RecursiveDeref(dd, Isub0);
1407 Cudd_RecursiveDeref(dd, Isub1);
1408 Cudd_RecursiveDeref(dd, Ld);
1409 Cudd_RecursiveDeref(dd, Ud);
1410 return(NULL);
1411 }
1412 Cudd_Ref(Id);
1413 Cudd_RecursiveDeref(dd, Ld);
1414 Cudd_RecursiveDeref(dd, Ud);
1415
1416 x = cuddUniqueInter(dd, index, one, zero);
1417 if (x == NULL) {
1418 Cudd_RecursiveDeref(dd, Isub0);
1419 Cudd_RecursiveDeref(dd, Isub1);
1420 Cudd_RecursiveDeref(dd, Id);
1421 return(NULL);
1422 }
1423 Cudd_Ref(x);
1424 term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
1425 if (term0 == NULL) {
1426 Cudd_RecursiveDeref(dd, Isub0);
1427 Cudd_RecursiveDeref(dd, Isub1);
1428 Cudd_RecursiveDeref(dd, Id);
1429 Cudd_RecursiveDeref(dd, x);
1430 return(NULL);
1431 }
1432 Cudd_Ref(term0);
1433 Cudd_RecursiveDeref(dd, Isub0);
1434 term1 = cuddBddAndRecur(dd, x, Isub1);
1435 if (term1 == NULL) {
1436 Cudd_RecursiveDeref(dd, Isub1);
1437 Cudd_RecursiveDeref(dd, Id);
1438 Cudd_RecursiveDeref(dd, x);
1439 Cudd_RecursiveDeref(dd, term0);
1440 return(NULL);
1441 }
1442 Cudd_Ref(term1);
1443 Cudd_RecursiveDeref(dd, x);
1444 Cudd_RecursiveDeref(dd, Isub1);
1445 /* sum = term0 + term1 */
1446 sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
1447 sum = Cudd_NotCond(sum, sum != NULL);
1448 if (sum == NULL) {
1449 Cudd_RecursiveDeref(dd, Id);
1450 Cudd_RecursiveDeref(dd, term0);
1451 Cudd_RecursiveDeref(dd, term1);
1452 return(NULL);
1453 }
1454 Cudd_Ref(sum);
1455 Cudd_RecursiveDeref(dd, term0);
1456 Cudd_RecursiveDeref(dd, term1);
1457 /* r = sum + Id */
1458 r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
1459 r = Cudd_NotCond(r, r != NULL);
1460 if (r == NULL) {
1461 Cudd_RecursiveDeref(dd, Id);
1462 Cudd_RecursiveDeref(dd, sum);
1463 return(NULL);
1464 }
1465 Cudd_Ref(r);
1466 Cudd_RecursiveDeref(dd, sum);
1467 Cudd_RecursiveDeref(dd, Id);
1468
1469 cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
1470 *pnCubes = Count0 + Count1 + Count2;
1471 if ( st__add_direct( table, (char *)r, (char *)(ABC_PTRINT_T)*pnCubes ) == st__OUT_OF_MEM )
1472 {
1473 Cudd_RecursiveDeref( dd, r );
1474 return NULL;
1475 }
1476 if ( *pnCubes > Limit )
1477 {
1478 Cudd_RecursiveDeref( dd, r );
1479 return NULL;
1480 }
1481 //printf( "%d ", *pnCubes );
1482 Cudd_Deref(r);
1483 return r;
1484}
1485int Extra_bddCountCubes( DdManager * dd, DdNode ** pFuncs, int nFuncs, int fMode, int nLimit, int * pGuide )
1486{
1487 DdNode * pF0, * pF1;
1488 int i, Count, Count0, Count1, CounterAll = 0;
1490 unsigned int saveLimit = dd->maxLive;
1491 dd->maxLive = dd->keys - dd->dead + 1000000; // limit on intermediate BDD nodes
1492 for ( i = 0; i < nFuncs; i++ )
1493 {
1494 if ( !pFuncs[i] )
1495 continue;
1496 pF1 = pF0 = NULL;
1497 Count0 = Count1 = nLimit;
1498 if ( fMode == -1 || fMode == 1 ) // both or pos
1499 pF1 = extraBddCountCubes( dd, pFuncs[i], pFuncs[i], table, &Count1, nLimit );
1500 pFuncs[i] = Cudd_Not( pFuncs[i] );
1501 if ( fMode == -1 || fMode == 0 ) // both or neg
1502 pF0 = extraBddCountCubes( dd, pFuncs[i], pFuncs[i], table, &Count0, Count1 );
1503 pFuncs[i] = Cudd_Not( pFuncs[i] );
1504 if ( !pF1 && !pF0 )
1505 break;
1506 if ( !pF0 ) pGuide[i] = 1, Count = Count1; // use pos
1507 else if ( !pF1 ) pGuide[i] = 0, Count = Count0; // use neg
1508 else if ( Count1 <= Count0 ) pGuide[i] = 1, Count = Count1; // use pos
1509 else pGuide[i] = 0, Count = Count0; // use neg
1510 CounterAll += Count;
1511 //printf( "Output %5d has %5d cubes (%d) (%5d and %5d)\n", nOuts++, Count, pGuide[i], Count1, Count0 );
1512 }
1513 dd->maxLive = saveLimit;
1514 st__free_table( table );
1515 return i == nFuncs ? CounterAll : -1;
1516} /* end of Extra_bddCountCubes */
1517
1518/*---------------------------------------------------------------------------*/
1519/* Definition of static Functions */
1520/*---------------------------------------------------------------------------*/
1521
1535DdNode * extraTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute )
1536{
1537 DdNode *res;
1538 st__table *table = NULL;
1539 st__generator *gen = NULL;
1540 DdNode *key, *value;
1541
1543 if ( table == NULL )
1544 goto failure;
1545 res = extraTransferPermuteRecur( ddS, ddD, f, table, Permute );
1546 if ( res != NULL )
1547 cuddRef( res );
1548
1549 /* Dereference all elements in the table and dispose of the table.
1550 ** This must be done also if res is NULL to avoid leaks in case of
1551 ** reordering. */
1552 gen = st__init_gen( table );
1553 if ( gen == NULL )
1554 goto failure;
1555 while ( st__gen( gen, ( const char ** ) &key, ( char ** ) &value ) )
1556 {
1557 Cudd_RecursiveDeref( ddD, value );
1558 }
1559 st__free_gen( gen );
1560 gen = NULL;
1561 st__free_table( table );
1562 table = NULL;
1563
1564 if ( res != NULL )
1565 cuddDeref( res );
1566 return ( res );
1567
1568 failure:
1569 if ( table != NULL )
1570 st__free_table( table );
1571 if ( gen != NULL )
1572 st__free_gen( gen );
1573 return ( NULL );
1574
1575} /* end of extraTransferPermute */
1576
1577
1590static DdNode *
1591extraTransferPermuteRecur(
1592 DdManager * ddS,
1593 DdManager * ddD,
1594 DdNode * f,
1595 st__table * table,
1596 int * Permute )
1597{
1598 DdNode *ft, *fe, *t, *e, *var, *res;
1599 DdNode *one, *zero;
1600 int index;
1601 int comple = 0;
1602
1603 statLine( ddD );
1604 one = DD_ONE( ddD );
1605 comple = Cudd_IsComplement( f );
1606
1607 /* Trivial cases. */
1608 if ( Cudd_IsConstant( f ) )
1609 return ( Cudd_NotCond( one, comple ) );
1610
1611
1612 /* Make canonical to increase the utilization of the cache. */
1613 f = Cudd_NotCond( f, comple );
1614 /* Now f is a regular pointer to a non-constant node. */
1615
1616 /* Check the cache. */
1617 if ( st__lookup( table, ( char * ) f, ( char ** ) &res ) )
1618 return ( Cudd_NotCond( res, comple ) );
1619
1620 if ( ddS->TimeStop && Abc_Clock() > ddS->TimeStop )
1621 return NULL;
1622 if ( ddD->TimeStop && Abc_Clock() > ddD->TimeStop )
1623 return NULL;
1624
1625 /* Recursive step. */
1626 if ( Permute )
1627 index = Permute[f->index];
1628 else
1629 index = f->index;
1630
1631 ft = cuddT( f );
1632 fe = cuddE( f );
1633
1634 t = extraTransferPermuteRecur( ddS, ddD, ft, table, Permute );
1635 if ( t == NULL )
1636 {
1637 return ( NULL );
1638 }
1639 cuddRef( t );
1640
1641 e = extraTransferPermuteRecur( ddS, ddD, fe, table, Permute );
1642 if ( e == NULL )
1643 {
1644 Cudd_RecursiveDeref( ddD, t );
1645 return ( NULL );
1646 }
1647 cuddRef( e );
1648
1649 zero = Cudd_Not(ddD->one);
1650 var = cuddUniqueInter( ddD, index, one, zero );
1651 if ( var == NULL )
1652 {
1653 Cudd_RecursiveDeref( ddD, t );
1654 Cudd_RecursiveDeref( ddD, e );
1655 return ( NULL );
1656 }
1657 res = cuddBddIteRecur( ddD, var, t, e );
1658
1659 if ( res == NULL )
1660 {
1661 Cudd_RecursiveDeref( ddD, t );
1662 Cudd_RecursiveDeref( ddD, e );
1663 return ( NULL );
1664 }
1665 cuddRef( res );
1666 Cudd_RecursiveDeref( ddD, t );
1667 Cudd_RecursiveDeref( ddD, e );
1668
1669 if ( st__add_direct( table, ( char * ) f, ( char * ) res ) ==
1671 {
1672 Cudd_RecursiveDeref( ddD, res );
1673 return ( NULL );
1674 }
1675 return ( Cudd_NotCond( res, comple ) );
1676
1677} /* end of extraTransferPermuteRecur */
1678
1692void
1694 DdNode * f,
1695 int * support)
1696{
1697 if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
1698 return;
1699 }
1700
1701 support[f->index] = 1;
1702 ddSupportStep2(cuddT(f),support);
1703 ddSupportStep2(Cudd_Regular(cuddE(f)),support);
1704 /* Mark as visited. */
1705 f->next = Cudd_Not(f->next);
1706 return;
1707
1708} /* end of ddSupportStep */
1709
1710
1723void
1725 DdNode * f)
1726{
1727 if (!Cudd_IsComplement(f->next)) {
1728 return;
1729 }
1730 /* Clear visited flag. */
1731 f->next = Cudd_Regular(f->next);
1732 if (cuddIsConstant(f)) {
1733 return;
1734 }
1735 ddClearFlag2(cuddT(f));
1736 ddClearFlag2(Cudd_Regular(cuddE(f)));
1737 return;
1738
1739} /* end of ddClearFlag */
1740
1741
1753DdNode *
1755 DdManager* dd, /* the manager */
1756 DdNode* zC0, /* the pointer to the negative var cofactor */
1757 DdNode* zC1, /* the pointer to the positive var cofactor */
1758 DdNode* zC2, /* the pointer to the cofactor without var */
1759 int TopVar) /* the index of the positive ZDD var */
1760{
1761 DdNode * zRes, * zTemp;
1762 /* compose with-neg-var and without-var using the neg ZDD var */
1763 zTemp = cuddZddGetNode( dd, 2*TopVar + 1, zC0, zC2 );
1764 if ( zTemp == NULL )
1765 {
1766 Cudd_RecursiveDerefZdd(dd, zC0);
1767 Cudd_RecursiveDerefZdd(dd, zC1);
1768 Cudd_RecursiveDerefZdd(dd, zC2);
1769 return NULL;
1770 }
1771 cuddRef( zTemp );
1772 cuddDeref( zC0 );
1773 cuddDeref( zC2 );
1774
1775 /* compose with-pos-var and previous result using the pos ZDD var */
1776 zRes = cuddZddGetNode( dd, 2*TopVar, zC1, zTemp );
1777 if ( zRes == NULL )
1778 {
1779 Cudd_RecursiveDerefZdd(dd, zC1);
1780 Cudd_RecursiveDerefZdd(dd, zTemp);
1781 return NULL;
1782 }
1783 cuddDeref( zC1 );
1784 cuddDeref( zTemp );
1785 return zRes;
1786} /* extraComposeCover */
1787
1799DdNode* extraZddPrimes( DdManager *dd, DdNode* F )
1800{
1801 DdNode *zRes;
1802
1803 if ( F == Cudd_Not( dd->one ) )
1804 return dd->zero;
1805 if ( F == dd->one )
1806 return dd->one;
1807
1808 /* check cache */
1809 zRes = cuddCacheLookup1Zdd(dd, extraZddPrimes, F);
1810 if (zRes)
1811 return(zRes);
1812 {
1813 /* temporary variables */
1814 DdNode *bF01, *zP0, *zP1;
1815 /* three components of the prime set */
1816 DdNode *zResE, *zResP, *zResN;
1817 int fIsComp = Cudd_IsComplement( F );
1818
1819 /* find cofactors of F */
1820 DdNode * bF0 = Cudd_NotCond( Cudd_E( F ), fIsComp );
1821 DdNode * bF1 = Cudd_NotCond( Cudd_T( F ), fIsComp );
1822
1823 /* find the intersection of cofactors */
1824 bF01 = cuddBddAndRecur( dd, bF0, bF1 );
1825 if ( bF01 == NULL ) return NULL;
1826 cuddRef( bF01 );
1827
1828 /* solve the problems for cofactors */
1829 zP0 = extraZddPrimes( dd, bF0 );
1830 if ( zP0 == NULL )
1831 {
1832 Cudd_RecursiveDeref( dd, bF01 );
1833 return NULL;
1834 }
1835 cuddRef( zP0 );
1836
1837 zP1 = extraZddPrimes( dd, bF1 );
1838 if ( zP1 == NULL )
1839 {
1840 Cudd_RecursiveDeref( dd, bF01 );
1841 Cudd_RecursiveDerefZdd( dd, zP0 );
1842 return NULL;
1843 }
1844 cuddRef( zP1 );
1845
1846 /* check for local unateness */
1847 if ( bF01 == bF0 ) /* unate increasing */
1848 {
1849 /* intersection is useless */
1850 cuddDeref( bF01 );
1851 /* the primes of intersection are the primes of F0 */
1852 zResE = zP0;
1853 /* there are no primes with negative var */
1854 zResN = dd->zero;
1855 cuddRef( zResN );
1856 /* primes with positive var are primes of F1 that are not primes of F01 */
1857 zResP = cuddZddDiff( dd, zP1, zP0 );
1858 if ( zResP == NULL )
1859 {
1860 Cudd_RecursiveDerefZdd( dd, zResE );
1861 Cudd_RecursiveDerefZdd( dd, zResN );
1862 Cudd_RecursiveDerefZdd( dd, zP1 );
1863 return NULL;
1864 }
1865 cuddRef( zResP );
1866 Cudd_RecursiveDerefZdd( dd, zP1 );
1867 }
1868 else if ( bF01 == bF1 ) /* unate decreasing */
1869 {
1870 /* intersection is useless */
1871 cuddDeref( bF01 );
1872 /* the primes of intersection are the primes of F1 */
1873 zResE = zP1;
1874 /* there are no primes with positive var */
1875 zResP = dd->zero;
1876 cuddRef( zResP );
1877 /* primes with negative var are primes of F0 that are not primes of F01 */
1878 zResN = cuddZddDiff( dd, zP0, zP1 );
1879 if ( zResN == NULL )
1880 {
1881 Cudd_RecursiveDerefZdd( dd, zResE );
1882 Cudd_RecursiveDerefZdd( dd, zResP );
1883 Cudd_RecursiveDerefZdd( dd, zP0 );
1884 return NULL;
1885 }
1886 cuddRef( zResN );
1887 Cudd_RecursiveDerefZdd( dd, zP0 );
1888 }
1889 else /* not unate */
1890 {
1891 /* primes without the top var are primes of F10 */
1892 zResE = extraZddPrimes( dd, bF01 );
1893 if ( zResE == NULL )
1894 {
1895 Cudd_RecursiveDerefZdd( dd, bF01 );
1896 Cudd_RecursiveDerefZdd( dd, zP0 );
1897 Cudd_RecursiveDerefZdd( dd, zP1 );
1898 return NULL;
1899 }
1900 cuddRef( zResE );
1901 Cudd_RecursiveDeref( dd, bF01 );
1902
1903 /* primes with the negative top var are those of P0 that are not in F10 */
1904 zResN = cuddZddDiff( dd, zP0, zResE );
1905 if ( zResN == NULL )
1906 {
1907 Cudd_RecursiveDerefZdd( dd, zResE );
1908 Cudd_RecursiveDerefZdd( dd, zP0 );
1909 Cudd_RecursiveDerefZdd( dd, zP1 );
1910 return NULL;
1911 }
1912 cuddRef( zResN );
1913 Cudd_RecursiveDerefZdd( dd, zP0 );
1914
1915 /* primes with the positive top var are those of P1 that are not in F10 */
1916 zResP = cuddZddDiff( dd, zP1, zResE );
1917 if ( zResP == NULL )
1918 {
1919 Cudd_RecursiveDerefZdd( dd, zResE );
1920 Cudd_RecursiveDerefZdd( dd, zResN );
1921 Cudd_RecursiveDerefZdd( dd, zP1 );
1922 return NULL;
1923 }
1924 cuddRef( zResP );
1925 Cudd_RecursiveDerefZdd( dd, zP1 );
1926 }
1927
1928 zRes = extraComposeCover( dd, zResN, zResP, zResE, Cudd_Regular(F)->index );
1929 if ( zRes == NULL ) return NULL;
1930
1931 /* insert the result into cache */
1932 cuddCacheInsert1(dd, extraZddPrimes, F, zRes);
1933 return zRes;
1934 }
1935} /* end of extraZddPrimes */
1936
1957static DdNode *
1958cuddBddPermuteRecur( DdManager * manager /* DD manager */ ,
1959 DdHashTable * table /* computed table */ ,
1960 DdNode * node /* BDD to be reordered */ ,
1961 int *permut /* permutation array */ )
1962{
1963 DdNode *N, *T, *E;
1964 DdNode *res;
1965 int index;
1966
1967 statLine( manager );
1968 N = Cudd_Regular( node );
1969
1970 /* Check for terminal case of constant node. */
1971 if ( cuddIsConstant( N ) )
1972 {
1973 return ( node );
1974 }
1975
1976 /* If problem already solved, look up answer and return. */
1977 if ( N->ref != 1 && ( res = cuddHashTableLookup1( table, N ) ) != NULL )
1978 {
1979 return ( Cudd_NotCond( res, N != node ) );
1980 }
1981
1982 /* Split and recur on children of this node. */
1983 T = cuddBddPermuteRecur( manager, table, cuddT( N ), permut );
1984 if ( T == NULL )
1985 return ( NULL );
1986 cuddRef( T );
1987 E = cuddBddPermuteRecur( manager, table, cuddE( N ), permut );
1988 if ( E == NULL )
1989 {
1990 Cudd_IterDerefBdd( manager, T );
1991 return ( NULL );
1992 }
1993 cuddRef( E );
1994
1995 /* Move variable that should be in this position to this position
1996 ** by retrieving the single var BDD for that variable, and calling
1997 ** cuddBddIteRecur with the T and E we just created.
1998 */
1999 index = permut[N->index];
2000 res = cuddBddIteRecur( manager, manager->vars[index], T, E );
2001 if ( res == NULL )
2002 {
2003 Cudd_IterDerefBdd( manager, T );
2004 Cudd_IterDerefBdd( manager, E );
2005 return ( NULL );
2006 }
2007 cuddRef( res );
2008 Cudd_IterDerefBdd( manager, T );
2009 Cudd_IterDerefBdd( manager, E );
2010
2011 /* Do not keep the result if the reference count is only 1, since
2012 ** it will not be visited again.
2013 */
2014 if ( N->ref != 1 )
2015 {
2016 ptrint fanout = ( ptrint ) N->ref;
2017 cuddSatDec( fanout );
2018 if ( !cuddHashTableInsert1( table, N, res, fanout ) )
2019 {
2020 Cudd_IterDerefBdd( manager, res );
2021 return ( NULL );
2022 }
2023 }
2024 cuddDeref( res );
2025 return ( Cudd_NotCond( res, N != node ) );
2026
2027} /* end of cuddBddPermuteRecur */
2028
2029
2042 DdManager * dd, /* the DD manager */
2043 DdNode * bFunc,
2044 DdNode * bVars)
2045{
2046 DdNode * bRes;
2047
2048 if ( bVars == b1 )
2049 return bFunc;
2050 if ( Cudd_IsConstant(bFunc) )
2051 return bFunc;
2052
2053 if ( (bRes = cuddCacheLookup2(dd, extraBddChangePolarity, bFunc, bVars)) )
2054 return bRes;
2055 else
2056 {
2057 DdNode * bFR = Cudd_Regular(bFunc);
2058 int LevelF = dd->perm[bFR->index];
2059 int LevelV = dd->perm[bVars->index];
2060
2061 if ( LevelV < LevelF )
2062 bRes = extraBddChangePolarity( dd, bFunc, cuddT(bVars) );
2063 else // if ( LevelF <= LevelV )
2064 {
2065 DdNode * bRes0, * bRes1;
2066 DdNode * bF0, * bF1;
2067 DdNode * bVarsNext;
2068
2069 // cofactor the functions
2070 if ( bFR != bFunc ) // bFunc is complemented
2071 {
2072 bF0 = Cudd_Not( cuddE(bFR) );
2073 bF1 = Cudd_Not( cuddT(bFR) );
2074 }
2075 else
2076 {
2077 bF0 = cuddE(bFR);
2078 bF1 = cuddT(bFR);
2079 }
2080
2081 if ( LevelF == LevelV )
2082 bVarsNext = cuddT(bVars);
2083 else
2084 bVarsNext = bVars;
2085
2086 bRes0 = extraBddChangePolarity( dd, bF0, bVarsNext );
2087 if ( bRes0 == NULL )
2088 return NULL;
2089 cuddRef( bRes0 );
2090
2091 bRes1 = extraBddChangePolarity( dd, bF1, bVarsNext );
2092 if ( bRes1 == NULL )
2093 {
2094 Cudd_RecursiveDeref( dd, bRes0 );
2095 return NULL;
2096 }
2097 cuddRef( bRes1 );
2098
2099 if ( LevelF == LevelV )
2100 { // swap the cofactors
2101 DdNode * bTemp;
2102 bTemp = bRes0;
2103 bRes0 = bRes1;
2104 bRes1 = bTemp;
2105 }
2106
2107 /* only aRes0 and aRes1 are referenced at this point */
2108
2109 /* consider the case when Res0 and Res1 are the same node */
2110 if ( bRes0 == bRes1 )
2111 bRes = bRes1;
2112 /* consider the case when Res1 is complemented */
2113 else if ( Cudd_IsComplement(bRes1) )
2114 {
2115 bRes = cuddUniqueInter(dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
2116 if ( bRes == NULL )
2117 {
2118 Cudd_RecursiveDeref(dd,bRes0);
2119 Cudd_RecursiveDeref(dd,bRes1);
2120 return NULL;
2121 }
2122 bRes = Cudd_Not(bRes);
2123 }
2124 else
2125 {
2126 bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 );
2127 if ( bRes == NULL )
2128 {
2129 Cudd_RecursiveDeref(dd,bRes0);
2130 Cudd_RecursiveDeref(dd,bRes1);
2131 return NULL;
2132 }
2133 }
2134 cuddDeref( bRes0 );
2135 cuddDeref( bRes1 );
2136 }
2137
2138 /* insert the result into cache */
2139 cuddCacheInsert2(dd, extraBddChangePolarity, bFunc, bVars, bRes);
2140 return bRes;
2141 }
2142} /* end of extraBddChangePolarity */
2143
2144
2145
2146static int Counter = 0;
2147
2159DdNode * extraBddAndPermute( DdHashTable * table, DdManager * ddF, DdNode * bF, DdManager * ddG, DdNode * bG, int * pPermute )
2160{
2161 DdNode * bF0, * bF1, * bG0, * bG1, * bRes0, * bRes1, * bRes, * bVar;
2162 int LevF, LevG, Lev;
2163
2164 // if F == 0, return 0
2165 if ( bF == Cudd_Not(ddF->one) )
2166 return Cudd_Not(ddF->one);
2167 // if G == 0, return 0
2168 if ( bG == Cudd_Not(ddG->one) )
2169 return Cudd_Not(ddF->one);
2170 // if G == 1, return F
2171 if ( bG == ddG->one )
2172 return bF;
2173 // cannot use F == 1, because the var order of G has to be changed
2174
2175 // check cache
2176 if ( //(Cudd_Regular(bF)->ref != 1 || Cudd_Regular(bG)->ref != 1) &&
2177 (bRes = cuddHashTableLookup2(table, bF, bG)) )
2178 return bRes;
2179 Counter++;
2180
2181 if ( ddF->TimeStop && Abc_Clock() > ddF->TimeStop )
2182 return NULL;
2183 if ( ddG->TimeStop && Abc_Clock() > ddG->TimeStop )
2184 return NULL;
2185
2186 // find the topmost variable in F and G using var order of F
2187 LevF = cuddI( ddF, Cudd_Regular(bF)->index );
2188 LevG = cuddI( ddF, pPermute ? pPermute[Cudd_Regular(bG)->index] : Cudd_Regular(bG)->index );
2189 Lev = Abc_MinInt( LevF, LevG );
2190 assert( Lev < ddF->size );
2191 bVar = ddF->vars[ddF->invperm[Lev]];
2192
2193 // cofactor
2194 bF0 = (Lev < LevF) ? bF : Cudd_NotCond( cuddE(Cudd_Regular(bF)), Cudd_IsComplement(bF) );
2195 bF1 = (Lev < LevF) ? bF : Cudd_NotCond( cuddT(Cudd_Regular(bF)), Cudd_IsComplement(bF) );
2196 bG0 = (Lev < LevG) ? bG : Cudd_NotCond( cuddE(Cudd_Regular(bG)), Cudd_IsComplement(bG) );
2197 bG1 = (Lev < LevG) ? bG : Cudd_NotCond( cuddT(Cudd_Regular(bG)), Cudd_IsComplement(bG) );
2198
2199 // call for cofactors
2200 bRes0 = extraBddAndPermute( table, ddF, bF0, ddG, bG0, pPermute );
2201 if ( bRes0 == NULL )
2202 return NULL;
2203 cuddRef( bRes0 );
2204 // call for cofactors
2205 bRes1 = extraBddAndPermute( table, ddF, bF1, ddG, bG1, pPermute );
2206 if ( bRes1 == NULL )
2207 {
2208 Cudd_IterDerefBdd( ddF, bRes0 );
2209 return NULL;
2210 }
2211 cuddRef( bRes1 );
2212
2213 // compose the result
2214 bRes = cuddBddIteRecur( ddF, bVar, bRes1, bRes0 );
2215 if ( bRes == NULL )
2216 {
2217 Cudd_IterDerefBdd( ddF, bRes0 );
2218 Cudd_IterDerefBdd( ddF, bRes1 );
2219 return NULL;
2220 }
2221 cuddRef( bRes );
2222 Cudd_IterDerefBdd( ddF, bRes0 );
2223 Cudd_IterDerefBdd( ddF, bRes1 );
2224
2225 // cache the result
2226// if ( Cudd_Regular(bF)->ref != 1 || Cudd_Regular(bG)->ref != 1 )
2227 {
2228 ptrint fanout = (ptrint)Cudd_Regular(bF)->ref * Cudd_Regular(bG)->ref;
2229 cuddSatDec(fanout);
2230 cuddHashTableInsert2( table, bF, bG, bRes, fanout );
2231 }
2232 cuddDeref( bRes );
2233 return bRes;
2234}
2235
2250void Extra_TestAndPerm( DdManager * ddF, DdNode * bF, DdNode * bG )
2251{
2252 DdManager * ddG;
2253 DdNode * bG2, * bRes1, * bRes2;
2254 abctime clk;
2255 // disable variable ordering in ddF
2256 Cudd_AutodynDisable( ddF );
2257
2258 // create new BDD manager
2259 ddG = Cudd_Init( ddF->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
2260 // transfer BDD into it
2261 Cudd_ShuffleHeap( ddG, ddF->invperm );
2262 bG2 = Extra_TransferLevelByLevel( ddF, ddG, bG ); Cudd_Ref( bG2 );
2263 // reorder the new manager
2264 Cudd_ReduceHeap( ddG, CUDD_REORDER_SYMM_SIFT, 1 );
2265
2266 // compute the result
2267clk = Abc_Clock();
2268 bRes1 = Cudd_bddAnd( ddF, bF, bG ); Cudd_Ref( bRes1 );
2269Abc_PrintTime( 1, "Runtime of Cudd_bddAnd ", Abc_Clock() - clk );
2270
2271 // compute the result
2272Counter = 0;
2273clk = Abc_Clock();
2274 bRes2 = Extra_bddAndPermute( ddF, bF, ddG, bG2, NULL ); Cudd_Ref( bRes2 );
2275Abc_PrintTime( 1, "Runtime of new procedure", Abc_Clock() - clk );
2276printf( "Recursive calls = %d\n", Counter );
2277printf( "|F| =%6d |G| =%6d |H| =%6d |F|*|G| =%9d ",
2278 Cudd_DagSize(bF), Cudd_DagSize(bG), Cudd_DagSize(bRes2),
2279 Cudd_DagSize(bF) * Cudd_DagSize(bG) );
2280
2281 if ( bRes1 == bRes2 )
2282 printf( "Result verified.\n\n" );
2283 else
2284 printf( "Result is incorrect.\n\n" );
2285
2286 Cudd_RecursiveDeref( ddF, bRes1 );
2287 Cudd_RecursiveDeref( ddF, bRes2 );
2288 // quit the new manager
2289 Cudd_RecursiveDeref( ddG, bG2 );
2290 Extra_StopManager( ddG );
2291
2292 // re-enable variable ordering in ddF
2293 Cudd_AutodynEnable( ddF, CUDD_REORDER_SYMM_SIFT );
2294}
2295
2307void Extra_zddDumpPla( DdManager * dd, DdNode * F, int nVars, char * pFileName )
2308{
2309 DdGen *gen;
2310 char * pCube;
2311 int * pPath, i;
2312 FILE * pFile = fopen( pFileName, "wb" );
2313 if ( pFile == NULL )
2314 {
2315 printf( "Cannot open file \"%s\" for writing.\n", pFileName );
2316 return;
2317 }
2318 fprintf( pFile, "# PLA file dumped by Extra_zddDumpPla() in ABC\n" );
2319 fprintf( pFile, ".i %d\n", nVars );
2320 fprintf( pFile, ".o 1\n" );
2321 pCube = ABC_CALLOC( char, dd->sizeZ );
2322 Cudd_zddForeachPath( dd, F, gen, pPath )
2323 {
2324 for ( i = 0; i < nVars; i++ )
2325 pCube[i] = '-';
2326 for ( i = 0; i < nVars; i++ )
2327 if ( pPath[2*i] == 1 || pPath[2*i+1] == 1 )
2328 pCube[i] = '0' + (pPath[2*i] == 1);
2329 fprintf( pFile, "%s 1\n", pCube );
2330 }
2331 fprintf( pFile, ".e\n\n" );
2332 fclose( pFile );
2333 ABC_FREE( pCube );
2334}
2335
2348{
2349 int Edges[5][5] = {
2350 {1, 3, 4},
2351 {1, 5},
2352 {2, 3, 5},
2353 {2, 4}
2354 };
2355 int e, n;
2356
2357 DdManager * dd = Cudd_Init( 0, 6, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
2358
2359 // create the edges
2360 DdNode * zGraph, * zEdge, * zVar, * zTemp;
2361 zGraph = DD_ZERO(dd); Cudd_Ref( zGraph );
2362 for ( e = 0; Edges[e][0]; e++ )
2363 {
2364 zEdge = DD_ONE(dd); Cudd_Ref( zEdge );
2365 for ( n = 0; Edges[e][n]; n++ )
2366 {
2367 zVar = cuddZddGetNode( dd, Edges[e][n], DD_ONE(dd), DD_ZERO(dd) ); Cudd_Ref( zVar );
2368 zEdge = Cudd_zddUnateProduct( dd, zTemp = zEdge, zVar ); Cudd_Ref( zEdge );
2369 Cudd_RecursiveDerefZdd( dd, zTemp );
2370 Cudd_RecursiveDerefZdd( dd, zVar );
2371 }
2372 zGraph = Cudd_zddUnion( dd, zTemp = zGraph, zEdge ); Cudd_Ref( zGraph );
2373 Cudd_RecursiveDerefZdd( dd, zTemp );
2374 Cudd_RecursiveDerefZdd( dd, zEdge );
2375 }
2376
2377 Cudd_zddPrintMinterm( dd, zGraph );
2378
2379 Cudd_RecursiveDerefZdd( dd, zGraph );
2380 Cudd_Quit(dd);
2381}
2382
2383
2384
2385
2400 DdManager* dd,
2401 int* VarValues,
2402 int nVars )
2403{
2404 int lev, index;
2405 DdNode *zRes, *zTemp;
2406
2407 /* transform the combination from the array VarValues into a ZDD cube. */
2408 zRes = dd->one;
2409 cuddRef(zRes);
2410
2411 /* go through levels starting bottom-up and create nodes
2412 * if these variables are present in the comb
2413 */
2414 for (lev = nVars - 1; lev >= 0; lev--)
2415 {
2416 index = (lev >= dd->sizeZ) ? lev : dd->invpermZ[lev];
2417 if (VarValues[index] == 1)
2418 {
2419 /* compose zRes with ZERO for the given ZDD variable */
2420 zRes = cuddZddGetNode( dd, index, zTemp = zRes, dd->zero );
2421 if ( zRes == NULL )
2422 {
2423 Cudd_RecursiveDerefZdd( dd, zTemp );
2424 return NULL;
2425 }
2426 cuddRef( zRes );
2427 cuddDeref( zTemp );
2428 }
2429 }
2430 cuddDeref( zRes );
2431 return zRes;
2432
2433} /* end of extraZddCombination */
2434
2452 DdManager *dd,
2453 int* VarValues,
2454 int nVars )
2455{
2456 DdNode *res;
2457 do {
2458 dd->reordered = 0;
2459 res = extraZddCombination(dd, VarValues, nVars);
2460 } while (dd->reordered == 1);
2461 return(res);
2462
2463} /* end of Extra_zddCombination */
2464
2481 DdManager * dd, /* the DD manager */
2482 int n, /* the number of elements */
2483 int k, /* the number of combinations (subsets) */
2484 double d) /* average density of elements in combinations */
2485{
2486 DdNode *Result, *TempComb, *Aux;
2487 int c, v, Limit, *VarValues;
2488
2489 /* sanity check the parameters */
2490 if ( n <= 0 || k <= 0 || d < 0.0 || d > 1.0 )
2491 return NULL;
2492
2493 /* allocate temporary storage for variable values */
2494 VarValues = ABC_ALLOC( int, n );
2495 if (VarValues == NULL)
2496 {
2497 dd->errorCode = CUDD_MEMORY_OUT;
2498 return NULL;
2499 }
2500
2501 /* start the new set */
2502 Result = dd->zero;
2503 Cudd_Ref( Result );
2504
2505 /* seed random number generator */
2506 Cudd_Srandom( time(NULL) );
2507// Cudd_Srandom( 4 );
2508 /* determine the limit below which var belongs to the combination */
2509 Limit = (int)(d * 2147483561.0);
2510
2511 /* add combinations one by one */
2512 for ( c = 0; c < k; c++ )
2513 {
2514 for ( v = 0; v < n; v++ )
2515 if ( Cudd_Random() <= Limit )
2516 VarValues[v] = 1;
2517 else
2518 VarValues[v] = 0;
2519
2520 TempComb = Extra_zddCombination( dd, VarValues, n );
2521 Cudd_Ref( TempComb );
2522
2523 /* make sure that this combination is not already in the set */
2524 if ( c )
2525 { /* at least one combination is already included */
2526
2527 Aux = Cudd_zddDiff( dd, Result, TempComb );
2528 Cudd_Ref( Aux );
2529 if ( Aux != Result )
2530 {
2531 Cudd_RecursiveDerefZdd( dd, Aux );
2532 Cudd_RecursiveDerefZdd( dd, TempComb );
2533 c--;
2534 continue;
2535 }
2536 else
2537 { /* Aux is the same node as Result */
2538 Cudd_Deref( Aux );
2539 }
2540 }
2541
2542 Result = Cudd_zddUnion( dd, Aux = Result, TempComb );
2543 Cudd_Ref( Result );
2544 Cudd_RecursiveDerefZdd( dd, Aux );
2545 Cudd_RecursiveDerefZdd( dd, TempComb );
2546 }
2547
2548 ABC_FREE( VarValues );
2549 Cudd_Deref( Result );
2550 return Result;
2551
2552} /* end of Extra_zddRandomSet */
2553
2566{
2567 int N = 64;
2568 int K0 = 1000;
2569 int i, Size;
2570 DdManager * dd = Cudd_Init( 0, 32, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
2571 for ( i = 1; i <= 10; i++ )
2572 {
2573 int K = K0 * i;
2574 DdNode * zRandSet = Extra_zddRandomSet( dd, N, K, 0.5 ); Cudd_Ref(zRandSet);
2575 Size = Cudd_zddDagSize(zRandSet);
2576 //Cudd_zddPrintMinterm( dd, zRandSet );
2577 printf( "N = %5d K = %5d BddSize = %6d MemBdd = %8.3f MB MemBit = %8.3f MB Ratio = %8.3f %%\n",
2578 N, K, Size, 20.0*Size/(1<<20), 0.125 * N * K /(1<<20), 100.0*(0.125 * N * K)/(20.0*Size) );
2579 Cudd_RecursiveDerefZdd( dd, zRandSet );
2580 }
2581 Cudd_Quit(dd);
2582}
2583
2584
2598 DdManager * dd, /* the DD manager */
2599 DdNode * bVarsK, /* the number of variables in tuples */
2600 DdNode * bVarsN) /* the set of all variables */
2601{
2602 DdNode *bRes, *bRes0, *bRes1;
2603 statLine(dd);
2604
2605 /* terminal cases */
2606/* if ( k < 0 || k > n )
2607 * return dd->zero;
2608 * if ( n == 0 )
2609 * return dd->one;
2610 */
2611 if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) )
2612 return b0;
2613 if ( bVarsN == b1 )
2614 return b1;
2615
2616 /* check cache */
2617 bRes = cuddCacheLookup2(dd, extraBddTuples, bVarsK, bVarsN);
2618 if (bRes)
2619 return(bRes);
2620
2621 /* ZDD in which is variable is 0 */
2622/* bRes0 = extraBddTuples( dd, k, n-1 ); */
2623 bRes0 = extraBddTuples( dd, bVarsK, cuddT(bVarsN) );
2624 if ( bRes0 == NULL )
2625 return NULL;
2626 cuddRef( bRes0 );
2627
2628 /* ZDD in which is variable is 1 */
2629/* bRes1 = extraBddTuples( dd, k-1, n-1 ); */
2630 if ( bVarsK == b1 )
2631 {
2632 bRes1 = b0;
2633 cuddRef( bRes1 );
2634 }
2635 else
2636 {
2637 bRes1 = extraBddTuples( dd, cuddT(bVarsK), cuddT(bVarsN) );
2638 if ( bRes1 == NULL )
2639 {
2640 Cudd_RecursiveDeref( dd, bRes0 );
2641 return NULL;
2642 }
2643 cuddRef( bRes1 );
2644 }
2645
2646 /* consider the case when Res0 and Res1 are the same node */
2647 if ( bRes0 == bRes1 )
2648 bRes = bRes1;
2649 /* consider the case when Res1 is complemented */
2650 else if ( Cudd_IsComplement(bRes1) )
2651 {
2652 bRes = cuddUniqueInter(dd, bVarsN->index, Cudd_Not(bRes1), Cudd_Not(bRes0));
2653 if ( bRes == NULL )
2654 {
2655 Cudd_RecursiveDeref(dd,bRes0);
2656 Cudd_RecursiveDeref(dd,bRes1);
2657 return NULL;
2658 }
2659 bRes = Cudd_Not(bRes);
2660 }
2661 else
2662 {
2663 bRes = cuddUniqueInter( dd, bVarsN->index, bRes1, bRes0 );
2664 if ( bRes == NULL )
2665 {
2666 Cudd_RecursiveDeref(dd,bRes0);
2667 Cudd_RecursiveDeref(dd,bRes1);
2668 return NULL;
2669 }
2670 }
2671 cuddDeref( bRes0 );
2672 cuddDeref( bRes1 );
2673
2674 /* insert the result into cache */
2675 cuddCacheInsert2(dd, extraBddTuples, bVarsK, bVarsN, bRes);
2676 return bRes;
2677
2678} /* end of extraBddTuples */
2679
2692 DdManager * dd, /* the DD manager */
2693 int K, /* the number of variables in tuples */
2694 DdNode * VarsN) /* the set of all variables represented as a BDD */
2695{
2696 DdNode *res;
2697 int autoDyn;
2698
2699 /* it is important that reordering does not happen,
2700 otherwise, this methods will not work */
2701
2702 autoDyn = dd->autoDyn;
2703 dd->autoDyn = 0;
2704
2705 do {
2706 /* transform the numeric arguments (K) into a DdNode * argument;
2707 * this allows us to use the standard internal CUDD cache */
2708 DdNode *VarSet = VarsN, *VarsK = VarsN;
2709 int nVars = 0, i;
2710
2711 /* determine the number of variables in VarSet */
2712 while ( VarSet != b1 )
2713 {
2714 nVars++;
2715 /* make sure that the VarSet is a cube */
2716 if ( cuddE( VarSet ) != b0 )
2717 return NULL;
2718 VarSet = cuddT( VarSet );
2719 }
2720 /* make sure that the number of variables in VarSet is less or equal
2721 that the number of variables that should be present in the tuples
2722 */
2723 if ( K > nVars )
2724 return NULL;
2725
2726 /* the second argument in the recursive call stands for <n>;
2727 * create the first argument, which stands for <k>
2728 * as when we are talking about the tuple of <k> out of <n> */
2729 for ( i = 0; i < nVars-K; i++ )
2730 VarsK = cuddT( VarsK );
2731
2732 dd->reordered = 0;
2733 res = extraBddTuples(dd, VarsK, VarsN );
2734
2735 } while (dd->reordered == 1);
2736 dd->autoDyn = autoDyn;
2737 return(res);
2738
2739} /* end of Extra_bddTuples */
2740
2741
2745
2746
2748
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define ARGS(protos)
Definition avl.h:20
#define b0
Definition bbrImage.c:96
#define b1
Definition bbrImage.c:97
ABC_NAMESPACE_IMPL_START typedef signed char value
#define Code
Definition deflate.h:76
struct cube Cube
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
DdNode * extraBddMove(DdManager *dd, DdNode *bF, DdNode *bDist)
DdNode * Extra_zddCombination(DdManager *dd, int *VarValues, int nVars)
void extraDecomposeCover(DdManager *dd, DdNode *zC, DdNode **zC0, DdNode **zC1, DdNode **zC2)
int * Extra_SupportArray(DdManager *dd, DdNode *f, int *support)
void ddClearFlag2(DdNode *f)
void Extra_bddPermuteArray(DdManager *manager, DdNode **bNodesIn, DdNode **bNodesOut, int nNodes, int *permut)
void Extra_StopManager(DdManager *dd)
DdNode * Extra_bddComputeCube(DdManager *dd, DdNode **bXVars, int nVars)
DdNode * extraZddCombination(DdManager *dd, int *VarValues, int nVars)
DdNode * Extra_bddCreateOr(DdManager *dd, int nVars)
int Extra_bddSuppSize(DdManager *dd, DdNode *bSupp)
void ddSupportStep2(DdNode *f, int *support)
DdNode * Extra_zddPrimes(DdManager *dd, DdNode *F)
int Extra_bddVarIsInCube(DdNode *bCube, int iVar)
int Extra_bddSuppOverlapping(DdManager *dd, DdNode *S1, DdNode *S2)
DdNode * Extra_bddCreateAnd(DdManager *dd, int nVars)
int Extra_bddIsVar(DdNode *bFunc)
DdNode * Extra_bddSupportNegativeCube(DdManager *dd, DdNode *f)
int Extra_bddSuppContainVar(DdManager *dd, DdNode *bS, DdNode *bVar)
DdNode * Extra_TransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
void Extra_zddDumpPla(DdManager *dd, DdNode *F, int nVars, char *pFileName)
DdNode * Extra_bddCreateExor(DdManager *dd, int nVars)
void Extra_bddPrint(DdManager *dd, DdNode *F)
DdNode * extraBddTuples(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
DdNode * Extra_bddRemapUp(DdManager *dd, DdNode *bF)
DdNode * Extra_bddComputeRangeCube(DdManager *dd, int iStart, int iStop)
DdNode * Extra_bddFindOneCube(DdManager *dd, DdNode *bF)
DdNode * Extra_bddMove(DdManager *dd, DdNode *bF, int nVars)
DdNode * Extra_zddRandomSet(DdManager *dd, int n, int k, double d)
int Extra_bddSuppDifferentVars(DdManager *dd, DdNode *S1, DdNode *S2, int DiffMax)
int * Extra_VectorSupportArray(DdManager *dd, DdNode **F, int n, int *support)
void Extra_GraphExperiment()
DdNode * Extra_bddAndPermute(DdManager *ddF, DdNode *bF, DdManager *ddG, DdNode *bG, int *pPermute)
DdNode * Extra_TransferLevelByLevel(DdManager *ddSource, DdManager *ddDestination, DdNode *f)
void Extra_ZddTest()
int Extra_bddCountCubes(DdManager *dd, DdNode **pFuncs, int nFuncs, int fMode, int nLimit, int *pGuide)
DdNode * extraComposeCover(DdManager *dd, DdNode *zC0, DdNode *zC1, DdNode *zC2, int TopVar)
DdNode * Extra_bddGetOneCube(DdManager *dd, DdNode *bFunc)
DdNode * extraBddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
int Extra_bddSuppCheckContainment(DdManager *dd, DdNode *bL, DdNode *bH, DdNode **bLarge, DdNode **bSmall)
DdNode * Extra_bddTuples(DdManager *dd, int K, DdNode *VarsN)
void Extra_bddPrintSupport(DdManager *dd, DdNode *F)
void Extra_TestAndPerm(DdManager *ddF, DdNode *bF, DdNode *bG)
DdNode * Extra_bddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
DdNode * extraBddTuples(DdManager *dd, DdNode *bVarsK, DdNode *bVarsN)
DdNode * extraBddMove(DdManager *dd, DdNode *bF, DdNode *bFlag)
DdNode * extraBddChangePolarity(DdManager *dd, DdNode *bFunc, DdNode *bVars)
enum keys key
Definition main.h:25
unsigned short var
Definition giaNewBdd.h:35
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition st.c:501
int st__lookup_int(st__table *table, char *key, int *value)
Definition st.c:134
int st__ptrhash(const char *, int)
Definition st.c:467
int st__ptrcmp(const char *, const char *)
Definition st.c:479
void st__free_gen(st__generator *gen)
Definition st.c:555
int st__lookup(st__table *table, const char *key, char **value)
Definition st.c:114
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition st.c:72
st__generator * st__init_gen(st__table *table)
Definition st.c:485
int st__add_direct(st__table *table, char *key, char *value)
Definition st.c:205
void st__free_table(st__table *table)
Definition st.c:81
#define st__OUT_OF_MEM
Definition st.h:113
Definition st.h:52
#define assert(ex)
Definition util_old.h:213