summaryrefslogtreecommitdiff
path: root/src/bdd/extrab/extraBddSet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bdd/extrab/extraBddSet.c')
-rw-r--r--src/bdd/extrab/extraBddSet.c941
1 files changed, 941 insertions, 0 deletions
diff --git a/src/bdd/extrab/extraBddSet.c b/src/bdd/extrab/extraBddSet.c
new file mode 100644
index 0000000..882c474
--- /dev/null
+++ b/src/bdd/extrab/extraBddSet.c
@@ -0,0 +1,941 @@
+/**CFile***********************************************************************
+
+ FileName [zSubSet.c]
+
+ PackageName [extra]
+
+ Synopsis [Experimental version of some ZDD operators.]
+
+ Description [External procedures included in this module:
+ <ul>
+ <li> Extra_zddSubSet();
+ <li> Extra_zddSupSet();
+ <li> Extra_zddNotSubSet();
+ <li> Extra_zddNotSupSet();
+ <li> Extra_zddMaxNotSupSet();
+ <li> Extra_zddEmptyBelongs();
+ <li> Extra_zddIsOneSubset();
+ </ul>
+ Internal procedures included in this module:
+ <ul>
+ <li> extraZddSubSet();
+ <li> extraZddSupSet();
+ <li> extraZddNotSubSet();
+ <li> extraZddNotSupSet();
+ <li> extraZddMaxNotSupSet();
+ </ul>
+ Static procedures included in this module:
+ <ul>
+ </ul>
+
+ SubSet, SupSet, NotSubSet, NotSupSet were introduced
+ by O.Coudert to solve problems arising in two-level SOP
+ minimization. See O. Coudert, "Two-Level Logic Minimization:
+ An Overview", Integration. Vol. 17, No. 2, pp. 97-140, Oct 1994.
+ ]
+
+ SeeAlso []
+
+ Author [Alan Mishchenko]
+
+ Copyright []
+
+ Revision [$zSubSet.c, v.1.2, November 16, 2000, alanmi $]
+
+******************************************************************************/
+
+#include "extraBdd.h"
+
+ABC_NAMESPACE_IMPL_START
+
+/*---------------------------------------------------------------------------*/
+/* Constant declarations */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Stucture declarations */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Type declarations */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* Variable declarations */
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* Macro declarations */
+/*---------------------------------------------------------------------------*/
+
+
+/**AutomaticStart*************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Static function prototypes */
+/*---------------------------------------------------------------------------*/
+
+/**AutomaticEnd***************************************************************/
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of exported functions */
+/*---------------------------------------------------------------------------*/
+
+/**Function********************************************************************
+
+ Synopsis [Computes subsets in X that are contained in some of the subsets of Y.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso [Extra_zddNotSubSet, Extra_zddSupSet, Extra_zddNotSupSet]
+
+******************************************************************************/
+DdNode *
+Extra_zddSubSet(
+ DdManager * dd,
+ DdNode * X,
+ DdNode * Y)
+{
+ DdNode *res;
+ int autoDynZ;
+
+ autoDynZ = dd->autoDynZ;
+ dd->autoDynZ = 0;
+
+ do {
+ dd->reordered = 0;
+ res = extraZddSubSet(dd, X, Y);
+ } while (dd->reordered == 1);
+ dd->autoDynZ = autoDynZ;
+ return(res);
+
+} /* end of Extra_zddSubSet */
+
+
+/**Function********************************************************************
+
+ Synopsis [Computes subsets in X that contain some of the subsets of Y.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso [Extra_zddSubSet, Extra_zddNotSubSet, Extra_zddNotSupSet]
+
+******************************************************************************/
+DdNode *
+Extra_zddSupSet(
+ DdManager * dd,
+ DdNode * X,
+ DdNode * Y)
+{
+ DdNode *res;
+ int autoDynZ;
+
+ autoDynZ = dd->autoDynZ;
+ dd->autoDynZ = 0;
+
+ do {
+ dd->reordered = 0;
+ res = extraZddSupSet(dd, X, Y);
+ } while (dd->reordered == 1);
+ dd->autoDynZ = autoDynZ;
+ return(res);
+
+} /* end of Extra_zddSupSet */
+
+/**Function********************************************************************
+
+ Synopsis [Computes subsets in X that are not contained in any of the subsets of Y.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddNotSupSet]
+
+******************************************************************************/
+DdNode *
+Extra_zddNotSubSet(
+ DdManager * dd,
+ DdNode * X,
+ DdNode * Y)
+{
+ DdNode *res;
+ int autoDynZ;
+
+ autoDynZ = dd->autoDynZ;
+ dd->autoDynZ = 0;
+
+ do {
+ dd->reordered = 0;
+ res = extraZddNotSubSet(dd, X, Y);
+ } while (dd->reordered == 1);
+ dd->autoDynZ = autoDynZ;
+ return(res);
+
+} /* end of Extra_zddNotSubSet */
+
+
+/**Function********************************************************************
+
+ Synopsis [Computes subsets in X that do not contain any of the subsets of Y.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddNotSubSet]
+
+******************************************************************************/
+DdNode *
+Extra_zddNotSupSet(
+ DdManager * dd,
+ DdNode * X,
+ DdNode * Y)
+{
+ DdNode *res;
+ int autoDynZ;
+
+ autoDynZ = dd->autoDynZ;
+ dd->autoDynZ = 0;
+
+ do {
+ dd->reordered = 0;
+ res = extraZddNotSupSet(dd, X, Y);
+ } while (dd->reordered == 1);
+ dd->autoDynZ = autoDynZ;
+ return(res);
+
+} /* end of Extra_zddNotSupSet */
+
+
+
+/**Function********************************************************************
+
+ Synopsis [Computes the maximal of subsets in X not contained in any of the subsets of Y.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddSubSet, Extra_zddNotSupSet]
+
+******************************************************************************/
+DdNode *
+Extra_zddMaxNotSupSet(
+ DdManager * dd,
+ DdNode * X,
+ DdNode * Y)
+{
+ DdNode *res;
+ int autoDynZ;
+
+ autoDynZ = dd->autoDynZ;
+ dd->autoDynZ = 0;
+
+ do {
+ dd->reordered = 0;
+ res = extraZddMaxNotSupSet(dd, X, Y);
+ } while (dd->reordered == 1);
+ dd->autoDynZ = autoDynZ;
+ return(res);
+
+} /* end of Extra_zddMaxNotSupSet */
+
+
+/**Function********************************************************************
+
+ Synopsis [Returns 1 if ZDD contains the empty combination; 0 otherwise.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int
+Extra_zddEmptyBelongs(
+ DdManager *dd,
+ DdNode* zS )
+{
+ while ( zS->index != CUDD_MAXINDEX )
+ zS = cuddE( zS );
+ return (int)( zS == z1 );
+
+} /* end of Extra_zddEmptyBelongs */
+
+
+/**Function********************************************************************
+
+ Synopsis [Returns 1 if the set is empty or consists of one subset only.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int
+Extra_zddIsOneSubset(
+ DdManager * dd,
+ DdNode * zS )
+{
+ while ( zS->index != CUDD_MAXINDEX )
+ {
+ assert( cuddT(zS) != z0 );
+ if ( cuddE(zS) != z0 )
+ return 0;
+ zS = cuddT( zS );
+ }
+ return (int)( zS == z1 );
+
+} /* end of Extra_zddEmptyBelongs */
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of internal functions */
+/*---------------------------------------------------------------------------*/
+
+/**Function********************************************************************
+
+ Synopsis [Performs the recursive step of Extra_zddSubSet.]
+
+ Description []
+
+ SideEffects [None]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode* extraZddSubSet( DdManager *dd, DdNode *X, DdNode *Y )
+{
+ DdNode *zRes;
+ statLine(dd);
+ /* any comb is a subset of itself */
+ if ( X == Y )
+ return X;
+ /* if X is empty, the result is empty */
+ if ( X == z0 )
+ return z0;
+ /* combs in X are notsubsets of non-existant combs in Y */
+ if ( Y == z0 )
+ return z0;
+ /* the empty comb is contained in all combs of Y */
+ if ( X == z1 )
+ return z1;
+ /* only {()} is the subset of {()} */
+ if ( Y == z1 ) /* check whether the empty combination is present in X */
+ return ( Extra_zddEmptyBelongs( dd, X )? z1: z0 );
+
+ /* check cache */
+ zRes = cuddCacheLookup2Zdd(dd, extraZddSubSet, X, Y);
+ if (zRes)
+ return(zRes);
+ else
+ {
+ DdNode *zRes0, *zRes1, *zTemp;
+ int TopLevelX = dd->permZ[ X->index ];
+ int TopLevelY = dd->permZ[ Y->index ];
+
+ if ( TopLevelX < TopLevelY )
+ {
+ /* compute combs of X without var that are notsubsets of combs with Y */
+ zRes = extraZddSubSet( dd, cuddE( X ), Y );
+ if ( zRes == NULL ) return NULL;
+ }
+ else if ( TopLevelX == TopLevelY )
+ {
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL )
+ return NULL;
+ cuddRef( zTemp );
+
+ /* compute combs of X without var that are notsubsets of combs is Temp */
+ zRes0 = extraZddSubSet( dd, cuddE( X ), zTemp );
+ if ( zRes0 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+
+ /* combs of X with var that are notsubsets of combs in Y with var */
+ zRes1 = extraZddSubSet( dd, cuddT( X ), cuddT( Y ) );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else /* if ( TopLevelX > TopLevelY ) */
+ {
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL ) return NULL;
+ cuddRef( zTemp );
+
+ /* compute combs that are notsubsets of Temp */
+ zRes = extraZddSubSet( dd, X, zTemp );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ cuddDeref( zRes );
+ }
+
+ /* insert the result into cache */
+ cuddCacheInsert2(dd, extraZddSubSet, X, Y, zRes);
+ return zRes;
+ }
+} /* end of extraZddSubSet */
+
+
+/**Function********************************************************************
+
+ Synopsis [Performs the recursive step of Extra_zddSupSet.]
+
+ Description []
+
+ SideEffects [None]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode* extraZddSupSet( DdManager *dd, DdNode *X, DdNode *Y )
+{
+ DdNode *zRes;
+ statLine(dd);
+ /* any comb is a superset of itself */
+ if ( X == Y )
+ return X;
+ /* no comb in X is superset of non-existing combs */
+ if ( Y == z0 )
+ return z0;
+ /* any comb in X is the superset of the empty comb */
+ if ( Extra_zddEmptyBelongs( dd, Y ) )
+ return X;
+ /* if X is empty, the result is empty */
+ if ( X == z0 )
+ return z0;
+ /* if X is the empty comb (and Y does not contain it!), return empty */
+ if ( X == z1 )
+ return z0;
+
+ /* check cache */
+ zRes = cuddCacheLookup2Zdd(dd, extraZddSupSet, X, Y);
+ if (zRes)
+ return(zRes);
+ else
+ {
+ DdNode *zRes0, *zRes1, *zTemp;
+ int TopLevelX = dd->permZ[ X->index ];
+ int TopLevelY = dd->permZ[ Y->index ];
+
+ if ( TopLevelX < TopLevelY )
+ {
+ /* combinations of X without label that are supersets of combinations with Y */
+ zRes0 = extraZddSupSet( dd, cuddE( X ), Y );
+ if ( zRes0 == NULL ) return NULL;
+ cuddRef( zRes0 );
+
+ /* combinations of X with label that are supersets of combinations with Y */
+ zRes1 = extraZddSupSet( dd, cuddT( X ), Y );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else if ( TopLevelX == TopLevelY )
+ {
+ /* combs of X without var that are supersets of combs of Y without var */
+ zRes0 = extraZddSupSet( dd, cuddE( X ), cuddE( Y ) );
+ if ( zRes0 == NULL ) return NULL;
+ cuddRef( zRes0 );
+
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zTemp );
+
+ /* combs of X with label that are supersets of combs in Temp */
+ zRes1 = extraZddSupSet( dd, cuddT( X ), zTemp );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else /* if ( TopLevelX > TopLevelY ) */
+ {
+ /* combs of X that are supersets of combs of Y without label */
+ zRes = extraZddSupSet( dd, X, cuddE( Y ) );
+ if ( zRes == NULL ) return NULL;
+ }
+
+ /* insert the result into cache */
+ cuddCacheInsert2(dd, extraZddSupSet, X, Y, zRes);
+ return zRes;
+ }
+} /* end of extraZddSupSet */
+
+
+/**Function********************************************************************
+
+ Synopsis [Performs the recursive step of Extra_zddNotSubSet.]
+
+ Description []
+
+ SideEffects [None]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode* extraZddNotSubSet( DdManager *dd, DdNode *X, DdNode *Y )
+{
+ DdNode *zRes;
+ statLine(dd);
+ /* any comb is a subset of itself */
+ if ( X == Y )
+ return z0;
+ /* combs in X are notsubsets of non-existant combs in Y */
+ if ( Y == z0 )
+ return X;
+ /* only {()} is the subset of {()} */
+ if ( Y == z1 ) /* remove empty combination from X */
+ return cuddZddDiff( dd, X, z1 );
+ /* if X is empty, the result is empty */
+ if ( X == z0 )
+ return z0;
+ /* the empty comb is contained in all combs of Y */
+ if ( X == z1 )
+ return z0;
+
+ /* check cache */
+ zRes = cuddCacheLookup2Zdd(dd, extraZddNotSubSet, X, Y);
+ if (zRes)
+ return(zRes);
+ else
+ {
+ DdNode *zRes0, *zRes1, *zTemp;
+ int TopLevelX = dd->permZ[ X->index ];
+ int TopLevelY = dd->permZ[ Y->index ];
+
+ if ( TopLevelX < TopLevelY )
+ {
+ /* compute combs of X without var that are notsubsets of combs with Y */
+ zRes0 = extraZddNotSubSet( dd, cuddE( X ), Y );
+ if ( zRes0 == NULL )
+ return NULL;
+ cuddRef( zRes0 );
+
+ /* combs of X with var cannot be subsets of combs without var in Y */
+ zRes1 = cuddT( X );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ }
+ else if ( TopLevelX == TopLevelY )
+ {
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL )
+ return NULL;
+ cuddRef( zTemp );
+
+ /* compute combs of X without var that are notsubsets of combs is Temp */
+ zRes0 = extraZddNotSubSet( dd, cuddE( X ), zTemp );
+ if ( zRes0 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+
+ /* combs of X with var that are notsubsets of combs in Y with var */
+ zRes1 = extraZddNotSubSet( dd, cuddT( X ), cuddT( Y ) );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else /* if ( TopLevelX > TopLevelY ) */
+ {
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL )
+ return NULL;
+ cuddRef( zTemp );
+
+ /* compute combs that are notsubsets of Temp */
+ zRes = extraZddNotSubSet( dd, X, zTemp );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ cuddDeref( zRes );
+ }
+
+ /* insert the result into cache */
+ cuddCacheInsert2(dd, extraZddNotSubSet, X, Y, zRes);
+ return zRes;
+ }
+} /* end of extraZddNotSubSet */
+
+
+/**Function********************************************************************
+
+ Synopsis [Performs the recursive step of Extra_zddNotSupSet.]
+
+ Description []
+
+ SideEffects [None]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode* extraZddNotSupSet( DdManager *dd, DdNode *X, DdNode *Y )
+{
+ DdNode *zRes;
+ statLine(dd);
+ /* any comb is a superset of itself */
+ if ( X == Y )
+ return z0;
+ /* no comb in X is superset of non-existing combs */
+ if ( Y == z0 )
+ return X;
+ /* any comb in X is the superset of the empty comb */
+ if ( Extra_zddEmptyBelongs( dd, Y ) )
+ return z0;
+ /* if X is empty, the result is empty */
+ if ( X == z0 )
+ return z0;
+ /* if X is the empty comb (and Y does not contain it!), return it */
+ if ( X == z1 )
+ return z1;
+
+ /* check cache */
+ zRes = cuddCacheLookup2Zdd(dd, extraZddNotSupSet, X, Y);
+ if (zRes)
+ return(zRes);
+ else
+ {
+ DdNode *zRes0, *zRes1, *zTemp;
+ int TopLevelX = dd->permZ[ X->index ];
+ int TopLevelY = dd->permZ[ Y->index ];
+
+ if ( TopLevelX < TopLevelY )
+ {
+ /* combinations of X without label that are supersets of combinations of Y */
+ zRes0 = extraZddNotSupSet( dd, cuddE( X ), Y );
+ if ( zRes0 == NULL )
+ return NULL;
+ cuddRef( zRes0 );
+
+ /* combinations of X with label that are supersets of combinations of Y */
+ zRes1 = extraZddNotSupSet( dd, cuddT( X ), Y );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else if ( TopLevelX == TopLevelY )
+ {
+ /* combs of X without var that are not supersets of combs of Y without var */
+ zRes0 = extraZddNotSupSet( dd, cuddE( X ), cuddE( Y ) );
+ if ( zRes0 == NULL )
+ return NULL;
+ cuddRef( zRes0 );
+
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zTemp );
+
+ /* combs of X with label that are supersets of combs in Temp */
+ zRes1 = extraZddNotSupSet( dd, cuddT( X ), zTemp );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else /* if ( TopLevelX > TopLevelY ) */
+ {
+ /* combs of X that are supersets of combs of Y without label */
+ zRes = extraZddNotSupSet( dd, X, cuddE( Y ) );
+ if ( zRes == NULL ) return NULL;
+ }
+
+ /* insert the result into cache */
+ cuddCacheInsert2(dd, extraZddNotSupSet, X, Y, zRes);
+ return zRes;
+ }
+} /* end of extraZddNotSupSet */
+
+
+
+/**Function********************************************************************
+
+ Synopsis [Performs the recursive step of Extra_zddMaxNotSupSet.]
+
+ Description []
+
+ SideEffects [None]
+
+ SeeAlso []
+
+******************************************************************************/
+DdNode* extraZddMaxNotSupSet( DdManager *dd, DdNode *X, DdNode *Y )
+{
+ DdNode *zRes;
+ statLine(dd);
+ /* any comb is a superset of itself */
+ if ( X == Y )
+ return z0;
+ /* no comb in X is superset of non-existing combs */
+ if ( Y == z0 )
+ return extraZddMaximal( dd, X );
+ /* any comb in X is the superset of the empty comb */
+ if ( Extra_zddEmptyBelongs( dd, Y ) )
+ return z0;
+ /* if X is empty, the result is empty */
+ if ( X == z0 )
+ return z0;
+ /* if X is the empty comb (and Y does not contain it!), return it */
+ if ( X == z1 )
+ return z1;
+
+ /* check cache */
+ zRes = cuddCacheLookup2Zdd(dd, extraZddMaxNotSupSet, X, Y);
+ if (zRes)
+ return(zRes);
+ else
+ {
+ DdNode *zRes0, *zRes1, *zTemp;
+ int TopLevelX = dd->permZ[ X->index ];
+ int TopLevelY = dd->permZ[ Y->index ];
+
+ if ( TopLevelX < TopLevelY )
+ {
+ /* combinations of X without label that are supersets of combinations with Y */
+ zRes0 = extraZddMaxNotSupSet( dd, cuddE( X ), Y );
+ if ( zRes0 == NULL )
+ return NULL;
+ cuddRef( zRes0 );
+
+ /* combinations of X with label that are supersets of combinations with Y */
+ zRes1 = extraZddMaxNotSupSet( dd, cuddT( X ), Y );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+
+ /* ---------------------------------------------------- */
+ /* remove subsets without this element covered by subsets with this element */
+ zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1);
+ if ( zRes0 == NULL )
+ {
+ Cudd_RecursiveDerefZdd(dd, zTemp);
+ Cudd_RecursiveDerefZdd(dd, zRes1);
+ return NULL;
+ }
+ cuddRef( zRes0 );
+ Cudd_RecursiveDerefZdd(dd, zTemp);
+ /* ---------------------------------------------------- */
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else if ( TopLevelX == TopLevelY )
+ {
+ /* combs of X without var that are supersets of combs of Y without var */
+ zRes0 = extraZddMaxNotSupSet( dd, cuddE( X ), cuddE( Y ) );
+ if ( zRes0 == NULL )
+ return NULL;
+ cuddRef( zRes0 );
+
+ /* merge combs of Y with and without var */
+ zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) );
+ if ( zTemp == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ return NULL;
+ }
+ cuddRef( zTemp );
+
+ /* combs of X with label that are supersets of combs in Temp */
+ zRes1 = extraZddMaxNotSupSet( dd, cuddT( X ), zTemp );
+ if ( zRes1 == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+ return NULL;
+ }
+ cuddRef( zRes1 );
+ Cudd_RecursiveDerefZdd( dd, zTemp );
+
+ /* ---------------------------------------------------- */
+ /* remove subsets without this element covered by subsets with this element */
+ zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1);
+ if ( zRes0 == NULL )
+ {
+ Cudd_RecursiveDerefZdd(dd, zTemp);
+ Cudd_RecursiveDerefZdd(dd, zRes1);
+ return NULL;
+ }
+ cuddRef( zRes0 );
+ Cudd_RecursiveDerefZdd(dd, zTemp);
+ /* ---------------------------------------------------- */
+
+ /* compose Res0 and Res1 with the given ZDD variable */
+ zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 );
+ if ( zRes == NULL )
+ {
+ Cudd_RecursiveDerefZdd( dd, zRes0 );
+ Cudd_RecursiveDerefZdd( dd, zRes1 );
+ return NULL;
+ }
+ cuddDeref( zRes0 );
+ cuddDeref( zRes1 );
+ }
+ else /* if ( TopLevelX > TopLevelY ) */
+ {
+ /* combs of X that are supersets of combs of Y without label */
+ zRes = extraZddMaxNotSupSet( dd, X, cuddE( Y ) );
+ if ( zRes == NULL ) return NULL;
+ }
+
+ /* insert the result into cache */
+ cuddCacheInsert2(dd, extraZddMaxNotSupSet, X, Y, zRes);
+ return zRes;
+ }
+} /* end of extraZddMaxNotSupSet */
+
+
+/*---------------------------------------------------------------------------*/
+/* Definition of static functions */
+/*---------------------------------------------------------------------------*/
+
+
+ABC_NAMESPACE_IMPL_END