/**Function*************************************************************

  Synopsis    [Derives the truth table for one cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void * Fpga_TruthsCutBdd( void * dd, Fpga_Cut_t * pCut )
{
    Fpga_NodeVec_t * vVisited;
    DdNode * bFunc;
    int i;
    assert( pCut->nLeaves > 1 );
    // set the leaf variables
    for ( i = 0; i < pCut->nLeaves; i++ )
        pCut->ppLeaves[i]->pCuts->uSign = (unsigned)Cudd_bddIthVar( dd, i );
    // recursively compute the function
    vVisited = Fpga_NodeVecAlloc( 10 );
    bFunc = Fpga_TruthsCutBdd_rec( dd, pCut, vVisited );   Cudd_Ref( bFunc );
    // clean the intermediate BDDs
    for ( i = 0; i < pCut->nLeaves; i++ )
        pCut->ppLeaves[i]->pCuts->uSign = 0;
    for ( i = 0; i < vVisited->nSize; i++ )
    {
        pCut = (Fpga_Cut_t *)vVisited->pArray[i];
        Cudd_RecursiveDeref( dd, (DdNode*)pCut->uSign );
        pCut->uSign = 0;
    }
//    printf( "%d ", vVisited->nSize );
    Fpga_NodeVecFree( vVisited );
    Cudd_Deref( bFunc );
    return bFunc;
}
Ejemplo n.º 2
0
/**Function*************************************************************

  Synopsis    [Performs reordering of the function.]

  Description [Returns the DD minimized by variable reordering in the REO 
  engine. Takes the CUDD decision diagram manager (dd) and the function (Func) 
  represented as a BDD or ADD (MTBDD). If the variable array (pOrder) is not NULL, 
  returns the resulting  variable permutation. The permutation is such that if the resulting 
  function is permuted by Cudd_(add,bdd)Permute() using pOrder as the permutation 
  array, the initial function (Func) results.
  Several flag set by other interface functions specify reordering options: 
  - Remappig can be set by Extra_ReorderSetRemapping(). Then the resulting DD after 
  reordering is remapped into the topmost levels of the DD manager. Otherwise, 
  the resulting DD after reordering is mapped using the same variables, on which it 
  originally depended, only (possibly) permuted as a result of reordering.
  - Minimization type can be set by Extra_ReorderSetMinimizationType(). Note
  that when the BDD is minimized for the total width of the total APL, the number
  BDD nodes can increase. The total width is defines as sum total of widths on each 
  level. The width on one level is defined as the number of distinct BDD nodes 
  pointed by the nodes situated above the given level.
  - The number of iterations of sifting can be set by Extra_ReorderSetIterations().
  The decision diagram returned by this procedure is not referenced.]

  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_Reorder( reo_man * p, DdManager * dd, DdNode * Func, int * pOrder )
{
	DdNode * FuncRes;
	Extra_ReorderArray( p, dd, &Func, &FuncRes, 1, pOrder );
	Cudd_Deref( FuncRes );
	return FuncRes;
}
Ejemplo n.º 3
0
/**Function********************************************************************

  Synopsis    [Computes a complement cover for a ZDD node.]

  Description [Computes a complement cover for a ZDD node. For lack of a
  better method, we first extract the function BDD from the ZDD cover,
  then make the complement of the ZDD cover from the complement of the
  BDD node by using ISOP. Returns a pointer to the resulting cover if
  successful; NULL otherwise. The result depends on current variable
  order.]

  SideEffects [The result depends on current variable order.]

  SeeAlso     []

******************************************************************************/
DdNode  *
Cudd_zddComplement(
  DdManager *dd,
  DdNode *node)
{
    DdNode      *b, *isop, *zdd_I;

    /* Check cache */
    zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
    if (zdd_I)
        return(zdd_I);

    b = Cudd_MakeBddFromZddCover(dd, node);
    if (!b)
        return(NULL);
    Cudd_Ref(b);
    isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I);
    if (!isop) {
        Cudd_RecursiveDeref(dd, b);
        return(NULL);
    }
    Cudd_Ref(isop);
    Cudd_Ref(zdd_I);
    Cudd_RecursiveDeref(dd, b);
    Cudd_RecursiveDeref(dd, isop);

    cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
    Cudd_Deref(zdd_I);
    return(zdd_I);
} /* end of Cudd_zddComplement */
Ejemplo n.º 4
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * dsdTreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode, int fRemap ) 
{
	DdNode * bCof0,  * bCof1, * bCube0, * bCube1, * bNewFunc, * bTemp;
	int i;
	int fAllBuffs = 1;
	static int Permute[MAXINPUTS];

	assert( pNode );
	assert( !Dsd_IsComplement( pNode ) );
	assert( pNode->Type == DT_PRIME );

	// transform the function of this block to depend on inputs
	// corresponding to the formal inputs

	// first, substitute those inputs that have some blocks associated with them
	// second, remap the inputs to the top of the manager (then, it is easy to output them)

	// start the function
	bNewFunc = pNode->G;  Cudd_Ref( bNewFunc );
	// go over all primary inputs
	for ( i = 0; i < pNode->nDecs; i++ )
	if ( pNode->pDecs[i]->Type != DT_BUF ) // remap only if it is not the buffer
	{
		bCube0 = Extra_bddFindOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) );  Cudd_Ref( bCube0 );
		bCof0 = Cudd_Cofactor( dd, bNewFunc, bCube0 );                     Cudd_Ref( bCof0 );
		Cudd_RecursiveDeref( dd, bCube0 );

		bCube1 = Extra_bddFindOneCube( dd,          pNode->pDecs[i]->G  );  Cudd_Ref( bCube1 );
		bCof1 = Cudd_Cofactor( dd, bNewFunc, bCube1 );                     Cudd_Ref( bCof1 );
		Cudd_RecursiveDeref( dd, bCube1 );

		Cudd_RecursiveDeref( dd, bNewFunc );

		// use the variable in the i-th level of the manager
//		bNewFunc = Cudd_bddIte( dd, dd->vars[dd->invperm[i]],bCof1,bCof0 );     Cudd_Ref( bNewFunc );
		// use the first variale in the support of the component
		bNewFunc = Cudd_bddIte( dd, dd->vars[pNode->pDecs[i]->S->index],bCof1,bCof0 );     Cudd_Ref( bNewFunc );
		Cudd_RecursiveDeref( dd, bCof0 );
		Cudd_RecursiveDeref( dd, bCof1 );
	}

	if ( fRemap )
	{
		// remap the function to the top of the manager
		// remap the function to the first variables of the manager
		for ( i = 0; i < pNode->nDecs; i++ )
	//		Permute[ pNode->pDecs[i]->S->index ] = dd->invperm[i];
			Permute[ pNode->pDecs[i]->S->index ] = i;

		bNewFunc = Cudd_bddPermute( dd, bTemp = bNewFunc, Permute );   Cudd_Ref( bNewFunc );
		Cudd_RecursiveDeref( dd, bTemp );
	}

	Cudd_Deref( bNewFunc );
	return bNewFunc;
}
Ejemplo n.º 5
0
/**Function*************************************************************

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_bddSpaceReduce( DdManager * dd, DdNode * bFunc, DdNode * bCanonVars )
{
	DdNode * bNegCube;
	DdNode * bResult;
	bNegCube = Extra_bddSupportNegativeCube( dd, bCanonVars );  Cudd_Ref( bNegCube );
	bResult  = Cudd_Cofactor( dd, bFunc, bNegCube );            Cudd_Ref( bResult );
	Cudd_RecursiveDeref( dd, bNegCube );
	Cudd_Deref( bResult );
	return bResult;
}
Ejemplo n.º 6
0
/**Function*************************************************************

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_bddSpaceEquations( DdManager * dd, DdNode * bSpace )
{
    DdNode * zRes;
	DdNode * zEquPos;
	DdNode * zEquNeg;
	zEquPos = Extra_bddSpaceEquationsPos( dd, bSpace );  Cudd_Ref( zEquPos );
	zEquNeg = Extra_bddSpaceEquationsNeg( dd, bSpace );  Cudd_Ref( zEquNeg );
	zRes    = Cudd_zddUnion( dd, zEquPos, zEquNeg );     Cudd_Ref( zRes );
	Cudd_RecursiveDerefZdd( dd, zEquPos );
	Cudd_RecursiveDerefZdd( dd, zEquNeg );
	Cudd_Deref( zRes );
    return zRes;
}
Ejemplo n.º 7
0
/**Function*************************************************************

  Synopsis    [Derives the global BDD for one AIG node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Bbr_NodeGlobalBdds_rec( DdManager * dd, Aig_Obj_t * pNode, int nBddSizeMax, int fDropInternal, ProgressBar * pProgress, int * pCounter, int fVerbose )
{
    DdNode * bFunc, * bFunc0, * bFunc1;
    assert( !Aig_IsComplement(pNode) );
    if ( Cudd_ReadKeys(dd)-Cudd_ReadDead(dd) > (unsigned)nBddSizeMax )
    {
//        Extra_ProgressBarStop( pProgress );
        if ( fVerbose )
        printf( "The number of live nodes reached %d.\n", nBddSizeMax );
        fflush( stdout );
        return NULL;
    }
    // if the result is available return
    if ( Aig_ObjGlobalBdd(pNode) == NULL )
    {
        // compute the result for both branches
        bFunc0 = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin0(pNode), nBddSizeMax, fDropInternal, pProgress, pCounter, fVerbose ); 
        if ( bFunc0 == NULL )
            return NULL;
        Cudd_Ref( bFunc0 );
        bFunc1 = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin1(pNode), nBddSizeMax, fDropInternal, pProgress, pCounter, fVerbose ); 
        if ( bFunc1 == NULL )
            return NULL;
        Cudd_Ref( bFunc1 );
        bFunc0 = Cudd_NotCond( bFunc0, Aig_ObjFaninC0(pNode) );
        bFunc1 = Cudd_NotCond( bFunc1, Aig_ObjFaninC1(pNode) );
        // get the final result
        bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 );   Cudd_Ref( bFunc );
        Cudd_RecursiveDeref( dd, bFunc0 );
        Cudd_RecursiveDeref( dd, bFunc1 );
        // add the number of used nodes
        (*pCounter)++;
        // set the result
        assert( Aig_ObjGlobalBdd(pNode) == NULL );
        Aig_ObjSetGlobalBdd( pNode, bFunc );
        // increment the progress bar
//        if ( pProgress )
//            Extra_ProgressBarUpdate( pProgress, *pCounter, NULL );
    }
    // prepare the return value
    bFunc = Aig_ObjGlobalBdd(pNode);
    // dereference BDD at the node
    if ( --pNode->nRefs == 0 && fDropInternal )
    {
        Cudd_Deref( bFunc );
        Aig_ObjSetGlobalBdd( pNode, NULL );
    }
    return bFunc;
}
Ejemplo n.º 8
0
BFBdd BFBddManager::readBDDFromFile(const char *filename, std::vector<BFBdd> &vars) const {

    FILE *file = fopen (filename,"r");
    if (file == NULL){
        std::ostringstream os;
        os << "Error in BFBddManager::readBDDFromFile(const char *filename, std::vector<BFBdd> &vars) - Could not read a BDD from from file '" << filename << "'.";
        throw std::runtime_error(os.str().c_str());
    }

    int *idMatcher = new int[vars.size()];
    for (unsigned int i=0;i<vars.size();i++) {
        idMatcher[i] = vars[i].readNodeIndex();
    }
    DdNode *node = Dddmp_cuddBddLoad(mgr, DDDMP_VAR_COMPOSEIDS, NULL, NULL, idMatcher, DDDMP_MODE_DEFAULT,NULL,file);
    fclose(file);
    delete[] idMatcher;
    Cudd_Deref(node);
    return BFBdd(this,node);   
}
Ejemplo n.º 9
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars )
{
    DdNode * bCube, * bVar, * bTemp;
    int i;
    bCube = Cudd_ReadOne(dd);  Cudd_Ref( bCube );
    for ( i = 0; i < nVars; i++ )
    {
        if ( pLine[i] == '-' )
            continue;
        else if ( pLine[i] == '0' ) // 0
            bVar = Cudd_Not( Cudd_bddIthVar(dd, 29-i) );
        else if ( pLine[i] == '1' ) // 1
            bVar = Cudd_bddIthVar(dd, 29-i);
        else assert(0);
        bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar );  Cudd_Ref( bCube );
        Cudd_RecursiveDeref( dd, bTemp );
    }
    Cudd_Deref( bCube );
    return bCube;
}
Ejemplo n.º 10
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_dsdRemap( DdManager * dd, DdNode * bF, st_table * pCache,
    int * pVar2Form, int * pForm2Var, DdNode * pbCube0[], DdNode * pbCube1[] )
{
	DdNode * bFR, * bF0, * bF1;
    DdNode * bRes0, * bRes1, * bRes;
	int iForm;
	
	bFR = Cudd_Regular(bF);
	if ( cuddIsConstant(bFR) )
		return bF;

	// check the hash-table
	if ( bFR->ref != 1 )
	{
        if ( st_lookup( pCache, (char *)bF, (char **)&bRes ) )
            return bRes;
	}

    // get the formal input
    iForm = pVar2Form[bFR->index];

    // get the nodes pointed to by the cube
    bF0 = Extra_bddNodePointedByCube( dd, bF, pbCube0[iForm] );
    bF1 = Extra_bddNodePointedByCube( dd, bF, pbCube1[iForm] );

    // call recursively for these nodes
    bRes0 = Extra_dsdRemap( dd, bF0, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes0 );
    bRes1 = Extra_dsdRemap( dd, bF1, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes1 );

	// derive the result using ITE
	bRes = Cudd_bddIte( dd, dd->vars[ pForm2Var[iForm] ], bRes1, bRes0 ); Cudd_Ref( bRes );
    Cudd_RecursiveDeref( dd, bRes0 );
    Cudd_RecursiveDeref( dd, bRes1 );

	// add to the hash table
	if ( bFR->ref != 1 )
        st_insert( pCache, (char *)bF, (char *)bRes );
    Cudd_Deref( bRes );
    return bRes;
}
Ejemplo n.º 11
0
/**Function********************************************************************

  Synopsis    [Calculates the product of two matrices represented as
  ADDs.]

  Description [Calculates the product of two matrices, A and B,
  represented as ADDs, using the CMU matrix by matrix multiplication
  procedure by Clarke et al..  Matrix A has x's as row variables and z's
  as column variables, while matrix B has z's as row variables and y's
  as column variables. Returns the pointer to the result if successful;
  NULL otherwise. The resulting matrix has x's as row variables and y's
  as column variables.]

  SideEffects [None]

  SeeAlso     [Cudd_addMatrixMultiply]

******************************************************************************/
DdNode *
Cudd_addTimesPlus(
  DdManager * dd,
  DdNode * A,
  DdNode * B,
  DdNode ** z,
  int  nz)
{
    DdNode *w, *cube, *tmp, *res; 
    int i;
    tmp = Cudd_addApply(dd,Cudd_addTimes,A,B);
    if (tmp == NULL) return(NULL);
    Cudd_Ref(tmp);
    Cudd_Ref(cube = DD_ONE(dd));
    for (i = nz-1; i >= 0; i--) {
	 w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd));
	 if (w == NULL) {
	    Cudd_RecursiveDeref(dd,tmp);
	    return(NULL);
	 }
	 Cudd_Ref(w);
	 Cudd_RecursiveDeref(dd,cube);
	 cube = w;
    }
    res = Cudd_addExistAbstract(dd,tmp,cube);
    if (res == NULL) {
	Cudd_RecursiveDeref(dd,tmp);
	Cudd_RecursiveDeref(dd,cube);
	return(NULL);
    }
    Cudd_Ref(res);
    Cudd_RecursiveDeref(dd,cube);
    Cudd_RecursiveDeref(dd,tmp);
    Cudd_Deref(res);
    return(res);

} /* end of Cudd_addTimesPlus */
Ejemplo n.º 12
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_zddWeakDiv.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddWeakDiv]

******************************************************************************/
DdNode  *
cuddZddWeakDiv(
  DdManager * dd,
  DdNode * f,
  DdNode * g)
{
    int         v;
    DdNode      *one = DD_ONE(dd);
    DdNode      *zero = DD_ZERO(dd);
    DdNode      *f0, *f1, *fd, *g0, *g1, *gd;
    DdNode      *q, *tmp;
    DdNode      *r;
    int         flag;

    statLine(dd);
    if (g == one)
        return(f);
    if (f == zero || f == one)
        return(zero);
    if (f == g)
        return(one);

    /* Check cache. */
    r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g);
    if (r)
        return(r);

    v = g->index;

    flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
    if (flag == 1)
        return(NULL);
    Cudd_Ref(f1);
    Cudd_Ref(f0);
    Cudd_Ref(fd);
    flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
    if (flag == 1) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        return(NULL);
    }
    Cudd_Ref(g1);
    Cudd_Ref(g0);
    Cudd_Ref(gd);

    q = g;

    if (g0 != zero) {
        q = cuddZddWeakDiv(dd, f0, g0);
        if (q == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, f0);
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, g1);
            Cudd_RecursiveDerefZdd(dd, g0);
            Cudd_RecursiveDerefZdd(dd, gd);
            return(NULL);
        }
        Cudd_Ref(q);
    }
    else
        Cudd_Ref(q);
    Cudd_RecursiveDerefZdd(dd, f0);
    Cudd_RecursiveDerefZdd(dd, g0);

    if (q == zero) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
        cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero);
        Cudd_Deref(q);
        return(zero);
    }

    if (g1 != zero) {
        Cudd_RecursiveDerefZdd(dd, q);
        tmp = cuddZddWeakDiv(dd, f1, g1);
        if (tmp == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, g1);
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, gd);
            return(NULL);
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, g1);
        if (q == g)
            q = tmp;
        else {
            q = cuddZddIntersect(dd, q, tmp);
            if (q == NULL) {
                Cudd_RecursiveDerefZdd(dd, fd);
                Cudd_RecursiveDerefZdd(dd, gd);
                return(NULL);
            }
            Cudd_Ref(q);
            Cudd_RecursiveDerefZdd(dd, tmp);
        }
    }
    else {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, g1);
    }

    if (q == zero) {
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
        cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero);
        Cudd_Deref(q);
        return(zero);
    }

    if (gd != zero) {
        Cudd_RecursiveDerefZdd(dd, q);
        tmp = cuddZddWeakDiv(dd, fd, gd);
        if (tmp == NULL) {
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, gd);
            return(NULL);
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
        if (q == g)
            q = tmp;
        else {
            q = cuddZddIntersect(dd, q, tmp);
            if (q == NULL) {
                Cudd_RecursiveDerefZdd(dd, tmp);
                return(NULL);
            }
            Cudd_Ref(q);
            Cudd_RecursiveDerefZdd(dd, tmp);
        }
    }
    else {
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
    }

    cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q);
    Cudd_Deref(q);
    return(q);

} /* end of cuddZddWeakDiv */
Ejemplo n.º 13
0
/**Function********************************************************************

  Synopsis [Converts a ZDD cover to a BDD graph.]

  Description [Converts a ZDD cover to a BDD graph. If successful, it
  returns a BDD node, otherwise it returns NULL. It is a recursive
  algorithm as the following. First computes 3 cofactors of a ZDD cover;
  f1, f0 and fd. Second, compute BDDs(b1, b0 and bd) of f1, f0 and fd.
  Third, compute T=b1+bd and E=b0+bd. Fourth, compute ITE(v,T,E) where v
  is the variable which has the index of the top node of the ZDD cover.
  In this case, since the index of v can be larger than either one of T or
  one of E, cuddUniqueInterIVO is called, here IVO stands for
  independent variable ordering.]

  SideEffects []

  SeeAlso     [Cudd_MakeBddFromZddCover]

******************************************************************************/
DdNode	*
cuddMakeBddFromZddCover(
  DdManager * dd,
  DdNode * node)
{
    DdNode	*neW;
    int		v;
    DdNode	*f1, *f0, *fd;
    DdNode	*b1, *b0, *bd;
    DdNode	*T, *E;

    statLine(dd);
    if (node == dd->one)
	return(dd->one);
    if (node == dd->zero)
	return(Cudd_Not(dd->one));

    /* Check cache */
    neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node);
    if (neW)
	return(neW);

    v = Cudd_Regular(node)->index;	/* either yi or zi */
    cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd);
    Cudd_Ref(f1);
    Cudd_Ref(f0);
    Cudd_Ref(fd);

    b1 = cuddMakeBddFromZddCover(dd, f1);
    if (!b1) {
	Cudd_RecursiveDerefZdd(dd, f1);
	Cudd_RecursiveDerefZdd(dd, f0);
	Cudd_RecursiveDerefZdd(dd, fd);
	return(NULL);
    }
    Cudd_Ref(b1);
    b0 = cuddMakeBddFromZddCover(dd, f0);
    if (!b1) {
	Cudd_RecursiveDerefZdd(dd, f1);
	Cudd_RecursiveDerefZdd(dd, f0);
	Cudd_RecursiveDerefZdd(dd, fd);
	Cudd_RecursiveDeref(dd, b1);
	return(NULL);
    }
    Cudd_Ref(b0);
    Cudd_RecursiveDerefZdd(dd, f1);
    Cudd_RecursiveDerefZdd(dd, f0);
    if (fd != dd->zero) {
	bd = cuddMakeBddFromZddCover(dd, fd);
	if (!bd) {
	    Cudd_RecursiveDerefZdd(dd, fd);
	    Cudd_RecursiveDeref(dd, b1);
	    Cudd_RecursiveDeref(dd, b0);
	    return(NULL);
	}
	Cudd_Ref(bd);
	Cudd_RecursiveDerefZdd(dd, fd);

	T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd));
	if (!T) {
	    Cudd_RecursiveDeref(dd, b1);
	    Cudd_RecursiveDeref(dd, b0);
	    Cudd_RecursiveDeref(dd, bd);
	    return(NULL);
	}
	T = Cudd_NotCond(T, T != NULL);
	Cudd_Ref(T);
	Cudd_RecursiveDeref(dd, b1);
	E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd));
	if (!E) {
	    Cudd_RecursiveDeref(dd, b0);
	    Cudd_RecursiveDeref(dd, bd);
	    Cudd_RecursiveDeref(dd, T);
	    return(NULL);
	}
	E = Cudd_NotCond(E, E != NULL);
	Cudd_Ref(E);
	Cudd_RecursiveDeref(dd, b0);
	Cudd_RecursiveDeref(dd, bd);
    }
    else {
	Cudd_RecursiveDerefZdd(dd, fd);
	T = b1;
	E = b0;
    }

    if (Cudd_IsComplement(T)) {
	neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E));
	if (!neW) {
	    Cudd_RecursiveDeref(dd, T);
	    Cudd_RecursiveDeref(dd, E);
	    return(NULL);
	}
	neW = Cudd_Not(neW);
    }
    else {
	neW = cuddUniqueInterIVO(dd, v / 2, T, E);
	if (!neW) {
	    Cudd_RecursiveDeref(dd, T);
	    Cudd_RecursiveDeref(dd, E);
	    return(NULL);
	}
    }
    Cudd_Ref(neW);
    Cudd_RecursiveDeref(dd, T);
    Cudd_RecursiveDeref(dd, E);

    cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW);
    Cudd_Deref(neW);
    return(neW);

} /* end of cuddMakeBddFromZddCover */
Ejemplo n.º 14
0
/**Function********************************************************************

  Synopsis [Performs the recursive step of Cudd_bddIsop.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_bddIsop]

******************************************************************************/
DdNode	*
cuddBddIsop(
  DdManager * dd,
  DdNode * L,
  DdNode * U)
{
    DdNode	*one = DD_ONE(dd);
    DdNode	*zero = Cudd_Not(one);
    int		v, top_l, top_u;
    DdNode	*Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
    DdNode	*Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
    DdNode	*Isub0, *Isub1, *Id;
    DdNode	*x;
    DdNode	*term0, *term1, *sum;
    DdNode	*Lv, *Uv, *Lnv, *Unv;
    DdNode	*r;
    int		index;

    statLine(dd);
    if (L == zero)
    	return(zero);
    if (U == one)
    	return(one);

    /* Check cache */
    r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
    if (r)
    	return(r);

    top_l = dd->perm[Cudd_Regular(L)->index];
    top_u = dd->perm[Cudd_Regular(U)->index];
    v = ddMin(top_l, top_u);

    /* Compute cofactors */
    if (top_l == v) {
	index = Cudd_Regular(L)->index;
    	Lv = Cudd_T(L);
    	Lnv = Cudd_E(L);
    	if (Cudd_IsComplement(L)) {
    	    Lv = Cudd_Not(Lv);
    	    Lnv = Cudd_Not(Lnv);
    	}
    }
    else {
	index = Cudd_Regular(U)->index;
        Lv = Lnv = L;
    }

    if (top_u == v) {
    	Uv = Cudd_T(U);
    	Unv = Cudd_E(U);
    	if (Cudd_IsComplement(U)) {
    	    Uv = Cudd_Not(Uv);
    	    Unv = Cudd_Not(Unv);
    	}
    }
    else {
        Uv = Unv = U;
    }

    Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
    if (Lsub0 == NULL)
	return(NULL);
    Cudd_Ref(Lsub0);
    Usub0 = Unv;
    Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
    if (Lsub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	return(NULL);
    }
    Cudd_Ref(Lsub1);
    Usub1 = Uv;

    Isub0 = cuddBddIsop(dd, Lsub0, Usub0);
    if (Isub0 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	return(NULL);
    }
    Cudd_Ref(Isub0);
    Isub1 = cuddBddIsop(dd, Lsub1, Usub1);
    if (Isub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	Cudd_RecursiveDeref(dd, Isub0);
	return(NULL);
    }
    Cudd_Ref(Isub1);
    Cudd_RecursiveDeref(dd, Lsub0);
    Cudd_RecursiveDeref(dd, Lsub1);

    Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
    if (Lsuper0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	return(NULL);
    }
    Cudd_Ref(Lsuper0);
    Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
    if (Lsuper1 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	return(NULL);
    }
    Cudd_Ref(Lsuper1);
    Usuper0 = Unv;
    Usuper1 = Uv;

    /* Ld = Lsuper0 + Lsuper1 */
    Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
    Ld = Cudd_NotCond(Ld, Ld != NULL);
    if (Ld == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	return(NULL);
    }
    Cudd_Ref(Ld);
    Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
    if (Ud == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	Cudd_RecursiveDeref(dd, Ld);
	return(NULL);
    }
    Cudd_Ref(Ud);
    Cudd_RecursiveDeref(dd, Lsuper0);
    Cudd_RecursiveDeref(dd, Lsuper1);

    Id = cuddBddIsop(dd, Ld, Ud);
    if (Id == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Ld);
	Cudd_RecursiveDeref(dd, Ud);
	return(NULL);
    }
    Cudd_Ref(Id);
    Cudd_RecursiveDeref(dd, Ld);
    Cudd_RecursiveDeref(dd, Ud);

    x = cuddUniqueInter(dd, index, one, zero);
    if (x == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Id);
	return(NULL);
    }
    Cudd_Ref(x);
    term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
    if (term0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, x);
	return(NULL);
    }
    Cudd_Ref(term0);
    Cudd_RecursiveDeref(dd, Isub0);
    term1 = cuddBddAndRecur(dd, x, Isub1);
    if (term1 == NULL) {
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, x);
	Cudd_RecursiveDeref(dd, term0);
	return(NULL);
    }
    Cudd_Ref(term1);
    Cudd_RecursiveDeref(dd, x);
    Cudd_RecursiveDeref(dd, Isub1);
    /* sum = term0 + term1 */
    sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
    sum = Cudd_NotCond(sum, sum != NULL);
    if (sum == NULL) {
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, term0);
	Cudd_RecursiveDeref(dd, term1);
	return(NULL);
    }
    Cudd_Ref(sum);
    Cudd_RecursiveDeref(dd, term0);
    Cudd_RecursiveDeref(dd, term1);
    /* r = sum + Id */
    r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
    r = Cudd_NotCond(r, r != NULL);
    if (r == NULL) {
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDeref(dd, sum);
	return(NULL);
    }
    Cudd_Ref(r);
    Cudd_RecursiveDeref(dd, sum);
    Cudd_RecursiveDeref(dd, Id);

    cuddCacheInsert2(dd, cuddBddIsop, L, U, r);

    Cudd_Deref(r);
    return(r);

} /* end of cuddBddIsop */
Ejemplo n.º 15
0
/**Function********************************************************************

  Synopsis [Performs the recursive step of Cudd_zddIsop.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddIsop]

******************************************************************************/
DdNode	*
cuddZddIsop(
  DdManager * dd,
  DdNode * L,
  DdNode * U,
  DdNode ** zdd_I)
{
    DdNode	*one = DD_ONE(dd);
    DdNode	*zero = Cudd_Not(one);
    DdNode	*zdd_one = DD_ONE(dd);
    DdNode	*zdd_zero = DD_ZERO(dd);
    int		v, top_l, top_u;
    DdNode	*Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
    DdNode	*Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
    DdNode	*Isub0, *Isub1, *Id;
    DdNode	*zdd_Isub0, *zdd_Isub1, *zdd_Id;
    DdNode	*x;
    DdNode	*term0, *term1, *sum;
    DdNode	*Lv, *Uv, *Lnv, *Unv;
    DdNode	*r, *y, *z;
    int		index;
    DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *);

    statLine(dd);
    if (L == zero) {
	*zdd_I = zdd_zero;
    	return(zero);
    }
    if (U == one) {
	*zdd_I = zdd_one;
    	return(one);
    }

    if (U == zero || L == one) {
	printf("*** ERROR : illegal condition for ISOP (U < L).\n");
	exit(1);
    }

    /* Check the cache. We store two results for each recursive call.
    ** One is the BDD, and the other is the ZDD. Both are needed.
    ** Hence we need a double hit in the cache to terminate the
    ** recursion. Clearly, collisions may evict only one of the two
    ** results. */
    cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) cuddZddIsop;
    r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
    if (r) {
	*zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U);
	if (*zdd_I)
	    return(r);
	else {
	    /* The BDD result may have been dead. In that case
	    ** cuddCacheLookup2 would have called cuddReclaim,
	    ** whose effects we now have to undo. */
	    cuddRef(r);
	    Cudd_RecursiveDeref(dd, r);
	}
    }

    top_l = dd->perm[Cudd_Regular(L)->index];
    top_u = dd->perm[Cudd_Regular(U)->index];
    v = ddMin(top_l, top_u);

    /* Compute cofactors. */
    if (top_l == v) {
	index = Cudd_Regular(L)->index;
    	Lv = Cudd_T(L);
    	Lnv = Cudd_E(L);
    	if (Cudd_IsComplement(L)) {
    	    Lv = Cudd_Not(Lv);
    	    Lnv = Cudd_Not(Lnv);
    	}
    }
    else {
	index = Cudd_Regular(U)->index;
        Lv = Lnv = L;
    }

    if (top_u == v) {
    	Uv = Cudd_T(U);
    	Unv = Cudd_E(U);
    	if (Cudd_IsComplement(U)) {
    	    Uv = Cudd_Not(Uv);
    	    Unv = Cudd_Not(Unv);
    	}
    }
    else {
        Uv = Unv = U;
    }

    Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
    if (Lsub0 == NULL)
	return(NULL);
    Cudd_Ref(Lsub0);
    Usub0 = Unv;
    Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
    if (Lsub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	return(NULL);
    }
    Cudd_Ref(Lsub1);
    Usub1 = Uv;

    Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0);
    if (Isub0 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	return(NULL);
    }
    /*
    if ((!cuddIsConstant(Cudd_Regular(Isub0))) &&
	(Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 ||
	dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) {
	printf("*** ERROR : illegal permutation in ZDD. ***\n");
    }
    */
    Cudd_Ref(Isub0);
    Cudd_Ref(zdd_Isub0);
    Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1);
    if (Isub1 == NULL) {
	Cudd_RecursiveDeref(dd, Lsub0);
	Cudd_RecursiveDeref(dd, Lsub1);
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	return(NULL);
    }
    /*
    if ((!cuddIsConstant(Cudd_Regular(Isub1))) &&
	(Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 ||
	dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) {
	printf("*** ERROR : illegal permutation in ZDD. ***\n");
    }
    */
    Cudd_Ref(Isub1);
    Cudd_Ref(zdd_Isub1);
    Cudd_RecursiveDeref(dd, Lsub0);
    Cudd_RecursiveDeref(dd, Lsub1);

    Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
    if (Lsuper0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	return(NULL);
    }
    Cudd_Ref(Lsuper0);
    Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
    if (Lsuper1 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	return(NULL);
    }
    Cudd_Ref(Lsuper1);
    Usuper0 = Unv;
    Usuper1 = Uv;

    /* Ld = Lsuper0 + Lsuper1 */
    Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
    if (Ld == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	return(NULL);
    }
    Ld = Cudd_Not(Ld);
    Cudd_Ref(Ld);
    /* Ud = Usuper0 * Usuper1 */
    Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
    if (Ud == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Lsuper0);
	Cudd_RecursiveDeref(dd, Lsuper1);
	Cudd_RecursiveDeref(dd, Ld);
	return(NULL);
    }
    Cudd_Ref(Ud);
    Cudd_RecursiveDeref(dd, Lsuper0);
    Cudd_RecursiveDeref(dd, Lsuper1);

    Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id);
    if (Id == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Ld);
	Cudd_RecursiveDeref(dd, Ud);
	return(NULL);
    }
    /*
    if ((!cuddIsConstant(Cudd_Regular(Id))) &&
	(Cudd_Regular(Id)->index != zdd_Id->index / 2 ||
	dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) {
	printf("*** ERROR : illegal permutation in ZDD. ***\n");
    }
    */
    Cudd_Ref(Id);
    Cudd_Ref(zdd_Id);
    Cudd_RecursiveDeref(dd, Ld);
    Cudd_RecursiveDeref(dd, Ud);

    x = cuddUniqueInter(dd, index, one, zero);
    if (x == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	return(NULL);
    }
    Cudd_Ref(x);
    /* term0 = x * Isub0 */
    term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
    if (term0 == NULL) {
	Cudd_RecursiveDeref(dd, Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, x);
	return(NULL);
    }
    Cudd_Ref(term0);
    Cudd_RecursiveDeref(dd, Isub0);
    /* term1 = x * Isub1 */
    term1 = cuddBddAndRecur(dd, x, Isub1);
    if (term1 == NULL) {
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDeref(dd, Isub1);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, x);
	Cudd_RecursiveDeref(dd, term0);
	return(NULL);
    }
    Cudd_Ref(term1);
    Cudd_RecursiveDeref(dd, x);
    Cudd_RecursiveDeref(dd, Isub1);
    /* sum = term0 + term1 */
    sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
    if (sum == NULL) {
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, term0);
	Cudd_RecursiveDeref(dd, term1);
	return(NULL);
    }
    sum = Cudd_Not(sum);
    Cudd_Ref(sum);
    Cudd_RecursiveDeref(dd, term0);
    Cudd_RecursiveDeref(dd, term1);
    /* r = sum + Id */
    r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
    r = Cudd_NotCond(r, r != NULL);
    if (r == NULL) {
	Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	Cudd_RecursiveDeref(dd, Id);
	Cudd_RecursiveDerefZdd(dd, zdd_Id);
	Cudd_RecursiveDeref(dd, sum);
	return(NULL);
    }
    Cudd_Ref(r);
    Cudd_RecursiveDeref(dd, sum);
    Cudd_RecursiveDeref(dd, Id);

    if (zdd_Isub0 != zdd_zero) {
	z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id);
	if (z == NULL) {
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	    Cudd_RecursiveDerefZdd(dd, zdd_Id);
	    Cudd_RecursiveDeref(dd, r);
	    return(NULL);
	}
    }
    else {
	z = zdd_Id;
    }
    Cudd_Ref(z);
    if (zdd_Isub1 != zdd_zero) {
	y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z);
	if (y == NULL) {
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
	    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
	    Cudd_RecursiveDerefZdd(dd, zdd_Id);
	    Cudd_RecursiveDeref(dd, r);
	    Cudd_RecursiveDerefZdd(dd, z);
	    return(NULL);
	}
    }
    else
	y = z;
    Cudd_Ref(y);

    Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
    Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
    Cudd_RecursiveDerefZdd(dd, zdd_Id);
    Cudd_RecursiveDerefZdd(dd, z);

    cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
    cuddCacheInsert2(dd, cacheOp, L, U, y);

    Cudd_Deref(r);
    Cudd_Deref(y);
    *zdd_I = y;
    /*
    if (Cudd_Regular(r)->index != y->index / 2) {
	printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
    }
    */
    return(r);

} /* end of cuddZddIsop */
Ejemplo n.º 16
0
/**Function*************************************************************

  Synopsis    [Returns the local function of the DSD node. ]

  Description [The local function is computed using the global function 
  of the node and the global functions of the formal inputs. The resulting
  local function is mapped using the topmost N variables of the manager.
  The number of variables N is equal to the number of formal inputs.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Dsd_TreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode ) 
{
    int * pForm2Var;   // the mapping of each formal input into its first var
    int * pVar2Form;   // the mapping of each var into its formal inputs
    int i, iVar, iLev, * pPermute;
    DdNode ** pbCube0, ** pbCube1;
    DdNode * bFunc, * bRes, * bTemp;
    st_table * pCache;
    
    pPermute  = ALLOC( int, dd->size );
    pVar2Form = ALLOC( int, dd->size );
    pForm2Var = ALLOC( int, dd->size );

    pbCube0 = ALLOC( DdNode *, dd->size );
    pbCube1 = ALLOC( DdNode *, dd->size );

    // remap the global function in such a way that
    // the support variables of each formal input are adjacent
    iLev = 0;
	for ( i = 0; i < pNode->nDecs; i++ )
    {
        pForm2Var[i] = dd->invperm[i];
        for ( bTemp = pNode->pDecs[i]->S; bTemp != b1; bTemp = cuddT(bTemp) )
        {
            iVar = dd->invperm[iLev];
            pPermute[bTemp->index] = iVar;
            pVar2Form[iVar] = i;
            iLev++;
        }

        // collect the cubes representing each assignment
        pbCube0[i] = Extra_bddGetOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) );
        Cudd_Ref( pbCube0[i] );
        pbCube1[i] = Extra_bddGetOneCube( dd, pNode->pDecs[i]->G );
        Cudd_Ref( pbCube1[i] );
    }

    // remap the function
    bFunc = Cudd_bddPermute( dd, pNode->G, pPermute ); Cudd_Ref( bFunc );
    // remap the cube
	for ( i = 0; i < pNode->nDecs; i++ )
    {
        pbCube0[i] = Cudd_bddPermute( dd, bTemp = pbCube0[i], pPermute ); Cudd_Ref( pbCube0[i] );
        Cudd_RecursiveDeref( dd, bTemp );
        pbCube1[i] = Cudd_bddPermute( dd, bTemp = pbCube1[i], pPermute ); Cudd_Ref( pbCube1[i] );
        Cudd_RecursiveDeref( dd, bTemp );
    }

    // remap the function
    pCache = st_init_table(st_ptrcmp,st_ptrhash);
    bRes = Extra_dsdRemap( dd, bFunc, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 );  Cudd_Ref( bRes );
    st_free_table( pCache );

    Cudd_RecursiveDeref( dd, bFunc );
	for ( i = 0; i < pNode->nDecs; i++ )
    {
        Cudd_RecursiveDeref( dd, pbCube0[i] );
        Cudd_RecursiveDeref( dd, pbCube1[i] );
    }
/*
////////////
    // permute the function once again
    // in such a way that i-th var stood for i-th formal input
	for ( i = 0; i < dd->size; i++ )
        pPermute[i] = -1;
	for ( i = 0; i < pNode->nDecs; i++ )
        pPermute[dd->invperm[i]] = i;
    bRes = Cudd_bddPermute( dd, bTemp = bRes, pPermute ); Cudd_Ref( bRes );
    Cudd_RecursiveDeref( dd, bTemp );
////////////
*/
    FREE(pPermute);
    FREE(pVar2Form);
    FREE(pForm2Var);
    FREE(pbCube0);
    FREE(pbCube1);

    Cudd_Deref( bRes );
    return bRes;
}
Ejemplo n.º 17
0
/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_SolveEqn.]

  Description [Implements the recursive step of Cudd_SolveEqn. 
  Returns NULL if the intermediate solution blows up
  or reordering occurs. The parametric solutions are
  stored in the array G.]

  SideEffects [none]

  SeeAlso     [Cudd_SolveEqn, Cudd_VerifySol]

******************************************************************************/
DdNode *
cuddSolveEqnRecur(
  DdManager * bdd,
  DdNode * F /* the left-hand side of the equation */,
  DdNode * Y /* the cube of remaining y variables */,
  DdNode ** G /* the array of solutions */,
  int  n /* number of unknowns */,
  int * yIndex /* array holding the y variable indices */,
  int  i /* level of recursion */)
{
    DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one;
    DdNodePtr *variables;

    int j;

    statLine(bdd);
    variables = bdd->vars;
    one = DD_ONE(bdd);

    /* Base condition. */
    if (Y == one) {
	return F;
    }

    /* Cofactor of Y. */
    yIndex[i] = Y->index;
    nextY = Cudd_T(Y);

    /* Universal abstraction of F with respect to the top variable index. */
    Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]);
    if (Fm1) {
	Fm1 = Cudd_Not(Fm1);
	cuddRef(Fm1);
    } else {
	return(NULL);
    }

    Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
    if (Fn) {
	cuddRef(Fn);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	return(NULL);
    }

    Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
    if (Fv) {
	cuddRef(Fv);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	return(NULL);
    }

    Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
    if (Fvbar) {
	cuddRef(Fvbar);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	Cudd_RecursiveDeref(bdd, Fv);
	return(NULL);
    }

    /* Build i-th component of the solution. */
    w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar);
    if (w) {
	cuddRef(w);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	Cudd_RecursiveDeref(bdd, Fv);
	Cudd_RecursiveDeref(bdd, Fvbar);
	return(NULL);
    }

    T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1));
    if(T) {
	cuddRef(T);
    } else {
	Cudd_RecursiveDeref(bdd, Fm1);
	Cudd_RecursiveDeref(bdd, Fn);
	Cudd_RecursiveDeref(bdd, Fv);
	Cudd_RecursiveDeref(bdd, Fvbar);
	Cudd_RecursiveDeref(bdd, w);
	return(NULL);
    }

    Cudd_RecursiveDeref(bdd,Fm1);
    Cudd_RecursiveDeref(bdd,w);
    Cudd_RecursiveDeref(bdd,Fv);
    Cudd_RecursiveDeref(bdd,Fvbar);

    /* Substitute components of solution already found into solution. */
    for (j = n-1; j > i; j--) {
	w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
	if(w) {
	    cuddRef(w);
	} else {
	    Cudd_RecursiveDeref(bdd, Fn);
	    Cudd_RecursiveDeref(bdd, T);
	    return(NULL);
	}
	Cudd_RecursiveDeref(bdd,T);
	T = w;
    }
    G[i] = T;

    Cudd_Deref(Fn);

    return(Fn);

} /* end of cuddSolveEqnRecur */
Ejemplo n.º 18
0
ABC_NAMESPACE_IMPL_START


/*---------------------------------------------------------------------------*/
/* Constant declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Stucture declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Type declarations                                                         */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Variable declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Macro declarations                                                        */
/*---------------------------------------------------------------------------*/


/**AutomaticStart*************************************************************/

/*---------------------------------------------------------------------------*/
/* Static function prototypes                                                */
/*---------------------------------------------------------------------------*/

/**AutomaticEnd***************************************************************/


/*
    LinearSpace(f) = Space(f,f)

    Space(f,g)
	{
		if ( f = const )
		{ 
		    if ( f = g )  return 1;
			else          return 0;
		}
		if ( g = const )  return 0;
		return x' * Space(fx',gx') * Space(fx,gx) + x * Space(fx',gx) * Space(fx,gx');
	}

	Equations(s) = Pos(s) + Neg(s);

	Pos(s)
	{
		if ( s  = 0 )   return 1;
		if ( s  = 1 )   return 0;
		if ( sx'= 0 )   return Pos(sx) + x;
		if ( sx = 0 )   return Pos(sx');
		return 1 * [Pos(sx') & Pos(sx)] + x * [Pos(sx') & Neg(sx)];
	}

	Neg(s)
	{
		if ( s  = 0 )   return 1;
		if ( s  = 1 )   return 0;
		if ( sx'= 0 )   return Neg(sx);
		if ( sx = 0 )   return Neg(sx') + x;
		return 1 * [Neg(sx') & Neg(sx)] + x * [Neg(sx') & Pos(sx)];
	}


    SpaceP(A)
	{
		if ( A = 0 )    return 1;
		if ( A = 1 )    return 1;
		return x' * SpaceP(Ax') * SpaceP(Ax) + x * SpaceP(Ax') * SpaceN(Ax);
	}

    SpaceN(A)
	{
		if ( A = 0 )    return 1;
		if ( A = 1 )    return 0;
		return x' * SpaceN(Ax') * SpaceN(Ax) + x * SpaceN(Ax') * SpaceP(Ax);
	}


    LinInd(A)
	{
		if ( A = const )     return 1;
		if ( !LinInd(Ax') )  return 0;
		if ( !LinInd(Ax)  )  return 0;
		if (  LinSumOdd(Ax')  & LinSumEven(Ax) != 0 )  return 0;
		if (  LinSumEven(Ax') & LinSumEven(Ax) != 0 )  return 0;
		return 1;
	}

	LinSumOdd(A)
	{
		if ( A = 0 )    return 0;                 // Odd0  ---e-- Odd1
		if ( A = 1 )    return 1;                 //       \   o
		Odd0  = LinSumOdd(Ax');  // x is absent   //         \ 
		Even0 = LinSumEven(Ax'); // x is absent   //       /   o  
		Odd1  = LinSumOdd(Ax);   // x is present  // Even0 ---e-- Even1 
		Even1 = LinSumEven(Ax);  // x is absent
		return 1 * [Odd0 + ExorP(Odd0, Even1)] + x * [Odd1 + ExorP(Odd1, Even0)];
	}

	LinSumEven(A)
	{
		if ( A = 0 )    return 0;
		if ( A = 1 )    return 0;
		Odd0  = LinSumOdd(Ax');  // x is absent
		Even0 = LinSumEven(Ax'); // x is absent
		Odd1  = LinSumOdd(Ax);   // x is present
		Even1 = LinSumEven(Ax);  // x is absent
		return 1 * [Even0 + Even1 + ExorP(Even0, Even1)] + x * [ExorP(Odd0, Odd1)];
	}
	
*/

/*---------------------------------------------------------------------------*/
/* Definition of exported functions                                          */
/*---------------------------------------------------------------------------*/

/**Function*************************************************************

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
DdNode * Extra_bddSpaceFromFunctionFast( DdManager * dd, DdNode * bFunc )
{
	int * pSupport;
	int * pPermute;
	int * pPermuteBack;
	DdNode ** pCompose;
	DdNode * bCube, * bTemp;
	DdNode * bSpace, * bFunc1, * bFunc2, * bSpaceShift;
	int nSupp, Counter;
	int i, lev;

	// get the support
	pSupport = ABC_ALLOC( int, ddMax(dd->size,dd->sizeZ) );
	Extra_SupportArray( dd, bFunc, pSupport );
	nSupp = 0;
	for ( i = 0; i < dd->size; i++ )
		if ( pSupport[i] )
			nSupp++;

	// make sure the manager has enough variables
	if ( 2*nSupp > dd->size )
	{
		printf( "Cannot derive linear space, because DD manager does not have enough variables.\n" );
		fflush( stdout );
		ABC_FREE( pSupport );
		return NULL;
	}

	// create the permutation arrays
	pPermute     = ABC_ALLOC( int, dd->size );
	pPermuteBack = ABC_ALLOC( int, dd->size );
	pCompose     = ABC_ALLOC( DdNode *, dd->size );
	for ( i = 0; i < dd->size; i++ )
	{
		pPermute[i]     = i;
		pPermuteBack[i] = i;
		pCompose[i]     = dd->vars[i];   Cudd_Ref( pCompose[i] );
	}

	// remap the function in such a way that the variables are interleaved
	Counter = 0;
	bCube = b1;  Cudd_Ref( bCube );
	for ( lev = 0; lev < dd->size; lev++ )
		if ( pSupport[ dd->invperm[lev] ] )
		{   // var "dd->invperm[lev]" on level "lev" should go to level 2*Counter;
			pPermute[ dd->invperm[lev] ] = dd->invperm[2*Counter];
			// var from level 2*Counter+1 should go back to the place of this var
			pPermuteBack[ dd->invperm[2*Counter+1] ] = dd->invperm[lev];
			// the permutation should be defined in such a way that variable
			// on level 2*Counter is replaced by an EXOR of itself and var on the next level
			Cudd_Deref( pCompose[ dd->invperm[2*Counter] ] );
			pCompose[ dd->invperm[2*Counter] ] = 
				Cudd_bddXor( dd, dd->vars[ dd->invperm[2*Counter] ], dd->vars[ dd->invperm[2*Counter+1] ] );  
			Cudd_Ref( pCompose[ dd->invperm[2*Counter] ] );
			// add this variable to the cube
			bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[ dd->invperm[2*Counter] ] );  Cudd_Ref( bCube );
			Cudd_RecursiveDeref( dd, bTemp );
			// increment the counter
			Counter ++;
		}

	// permute the functions
	bFunc1 = Cudd_bddPermute( dd, bFunc, pPermute );         Cudd_Ref( bFunc1 );
	// compose to gate the function depending on both vars
	bFunc2 = Cudd_bddVectorCompose( dd, bFunc1, pCompose );  Cudd_Ref( bFunc2 );
	// gate the vector space
	// L(a) = ForAll x [ F(x) = F(x+a) ] = Not( Exist x [ F(x) (+) F(x+a) ] )
	bSpaceShift = Cudd_bddXorExistAbstract( dd, bFunc1, bFunc2, bCube );  Cudd_Ref( bSpaceShift );
	bSpaceShift = Cudd_Not( bSpaceShift );
	// permute the space back into the original mapping
	bSpace = Cudd_bddPermute( dd, bSpaceShift, pPermuteBack ); Cudd_Ref( bSpace );
	Cudd_RecursiveDeref( dd, bFunc1 );
	Cudd_RecursiveDeref( dd, bFunc2 );
	Cudd_RecursiveDeref( dd, bSpaceShift );
	Cudd_RecursiveDeref( dd, bCube );

	for ( i = 0; i < dd->size; i++ )
		Cudd_RecursiveDeref( dd, pCompose[i] );
	ABC_FREE( pPermute );
	ABC_FREE( pPermuteBack );
	ABC_FREE( pCompose );
    ABC_FREE( pSupport );

	Cudd_Deref( bSpace );
	return bSpace;
}
Ejemplo n.º 19
0
/**Function********************************************************************

  Synopsis    [Repeated squaring algorithm for all-pairs shortest paths.]

  Description []

  SideEffects []

  SeeAlso     []

******************************************************************************/
static DdNode *
ntrSquare(
  DdManager *dd /* manager */,
  DdNode *D /* D(z,y): distance matrix */,
  DdNode **x /* array of x variables */,
  DdNode **y /* array of y variables */,
  DdNode **z /* array of z variables */,
  int vars /* number of variables in each of the three arrays */,
  int pr /* verbosity level */,
  int st /* use the selective trace algorithm */)
{
    DdNode *zero;
    DdNode *I;              /* identity matirix */
    DdNode *w, *V, *P, *M, *R, *RT;
    DdNode *diff, *min, *minDiag;
    int n;
    int neg;
    long start_time;

    zero = Cudd_ReadZero(dd);
    /* Make a working copy of the original matrix. */
    R = D;
    Cudd_Ref(R);
    I = Cudd_addXeqy(dd,vars,z,y);    /* identity matrix */
    Cudd_Ref(I);

    /* Make a copy of the matrix for the selective trace algorithm. */
    diff = R;
    Cudd_Ref(diff);

    start_time = util_cpu_time();
    for (n = vars; n >= 0; n--) {
	printf("Starting iteration %d at time %s\n",vars-n,
	       util_print_time(util_cpu_time() - start_time));

	/* Check for negative cycles: They are identified by negative
	** elements on the diagonal.
	*/

	/* Extract values from the diagonal. */
        Cudd_Ref(w = Cudd_addIte(dd,I,R,zero));
	minDiag = Cudd_addFindMin(dd,w);	/* no need to ref */
	neg = Cudd_V(minDiag) < 0;
	Cudd_RecursiveDeref(dd,w);
	if (neg) {
	    Cudd_RecursiveDeref(dd,diff);
            (void) printf("Negative cycle after %d iterations!\n",vars-n);
            break;
        }

	/* Prepare the first operand of matrix multiplication:
	**   diff(z,y) -> RT(x,y) -> V(x,z)
	*/

	/* RT(x,y) */
	Cudd_Ref(RT = Cudd_addSwapVariables(dd,diff,x,z,vars));
	Cudd_RecursiveDeref(dd,diff);
	/* V(x,z) */
	Cudd_Ref(V = Cudd_addSwapVariables(dd,RT,y,z,vars));
	Cudd_RecursiveDeref(dd,RT);
	if (pr > 0) {
	    double pathcount;
	    (void) printf("V"); Cudd_PrintDebug(dd,V,2*vars,pr);
	    pathcount = Cudd_CountPath(V);
	    (void) printf("Path count = %g\n", pathcount);
	}

	/* V(x,z) * R(z,y) -> P(x,y) */
	Cudd_Ref(P = Cudd_addTriangle(dd,V,R,z,vars));
	Cudd_RecursiveDeref(dd,V);
	/* P(x,y) => M(z,y) */
	Cudd_Ref(M = Cudd_addSwapVariables(dd,P,x,z,vars));
	Cudd_RecursiveDeref(dd,P);
	if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,2*vars,pr);}

	/* min(z,y) */
	Cudd_Ref(min = Cudd_addApply(dd,Cudd_addMinimum,R,M));
	Cudd_RecursiveDeref(dd,M);

	if (R == min) {
	    Cudd_RecursiveDeref(dd,min);
	    if (pr>0) {printf("Done after %d iterations\n",vars-n+1); }
	    break;
	}
	/* diff(z,y) */
	if (st) {
	    Cudd_Ref(diff = Cudd_addApply(dd,Cudd_addDiff,min,R));
	} else {
	    Cudd_Ref(diff = min);
	}
	Cudd_RecursiveDeref(dd,R);
	R = min;                  /* keep a copy of matrix at current iter. */
	if (pr > 0) {
	    double pathcount;
	    (void) printf("R"); Cudd_PrintDebug(dd,R,2*vars,pr);
	    pathcount = Cudd_CountPath(R);
	    (void) printf("Path count = %g\n", pathcount);
	}

	if (n == 0) {
	    (void) printf("Negative cycle!\n");
	    break;
	}

    }
    Cudd_RecursiveDeref(dd,I);
    Cudd_Deref(R);
    return(R);

} /* end of ntrSquare */
Ejemplo n.º 20
0
/**Function********************************************************************

  Synopsis    [Floyd-Warshall algorithm for all-pair shortest paths.]

  Description []

  SideEffects []

  SeeAlso     []

******************************************************************************/
static DdNode *
ntrWarshall(
  DdManager *dd,
  DdNode *D,
  DdNode **x,
  DdNode **y,
  int vars,
  int pr)
{
    DdNode *one, *zero;
    DdNode *xminterm,  *w, *V, *V2;
    DdNode *P, *R;
    int i;
    int nodes;
    int k,u;
    long start_time;
    if (vars > 30)
	nodes = 1000000000;
    else
	nodes = 1 << vars;

    one = DD_ONE(dd);
    zero = DD_ZERO(dd);
    Cudd_Ref(R = D);                        /* make copy of original matrix */

    /* Extract pivot row and column from D */
    start_time = util_cpu_time();
    for (k = 0; k < nodes; k++) {
        if (k % 10000 == 0) {
	    (void) printf("Starting iteration  %d  at time %s\n",
			  k,util_print_time(util_cpu_time() - start_time));
        }
        Cudd_Ref(xminterm = one);
        u = k;
	for (i = vars-1; i >= 0; i--) {
	    if (u&1) {
	        Cudd_Ref(w = Cudd_addIte(dd,x[i],xminterm,zero));
	    } else {
	        Cudd_Ref(w = Cudd_addIte(dd,x[i],zero,xminterm));
	    }
	    Cudd_RecursiveDeref(dd,xminterm);
	    xminterm = w;
	    u >>= 1;
	}

	Cudd_Ref(V = Cudd_Cofactor(dd,R,xminterm));
	Cudd_RecursiveDeref(dd,xminterm);
	if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);}


	Cudd_Ref(xminterm = one);
	u = k;
	for (i = vars-1; i >= 0; i--) {
	    if (u&1) {
	        Cudd_Ref(w = Cudd_addIte(dd,y[i],xminterm,zero));
	    } else {
	        Cudd_Ref(w = Cudd_addIte(dd,y[i],zero,xminterm));
	    }
	    Cudd_RecursiveDeref(dd,xminterm);
	    xminterm = w;
	    u >>= 1;
	}

	Cudd_Ref(V2 = Cudd_Cofactor(dd,R,xminterm));
	Cudd_RecursiveDeref(dd,xminterm);
	if (pr>2) {(void) printf("V2"); Cudd_PrintDebug(dd,V2,vars,pr);}

	Cudd_Ref(P = Cudd_addOuterSum(dd,R,V,V2));

	Cudd_RecursiveDeref(dd,V);
	Cudd_RecursiveDeref(dd,V2);
	Cudd_RecursiveDeref(dd,R);
	R = P;
	if (pr>2) {(void) printf("R"); Cudd_PrintDebug(dd,R,vars,pr);}
    }

    Cudd_Deref(R);
    return(R);

} /* end of ntrWarshall */
Ejemplo n.º 21
0
/**Function********************************************************************

  Synopsis    [Bellman-Ford algorithm for single-source shortest paths.]

  Description [Bellman-Ford algorithm for single-source shortest
  paths.  Returns the vector of the distances of all states from the
  initial states.  In case of multiple initial states the distance for
  each state is from the nearest initial state.  Negative-weight
  cycles are detected, though only in the naive way.  (Lack of
  convergence after nodes-1 iterations.)  In such a case, a constant
  ADD with value minus infinity is returned.  Bellman-Ford is based on
  matrix-vector multiplication.  The matrix is the distance matrix
  D(x,y), such that D(a,b) is the length of the arc connecting state a
  to state b.  The vector V(x) stores the distances of all states from
  the initial states.  The actual vector used in the matrix-vector
  multiplication is diff(x), that holds those distances that have
  changed during the last update.]

  SideEffects []

  SeeAlso     [ntrWarshall ntrSquare]

******************************************************************************/
static DdNode *
ntrBellman(
  DdManager *dd,
  DdNode *D,
  DdNode *source,
  DdNode **x,
  DdNode **y,
  int vars,
  int pr)
{
    DdNode *u, *w, *V, *min, *diff;
    DdApaNumber i, nodes, one;
    int digits = vars + 1;

    /* To avoid overflow when there are many variables, use APA. */
    nodes = Cudd_NewApaNumber(digits);
    Cudd_ApaPowerOfTwo(digits,nodes,vars);
    i = Cudd_NewApaNumber(digits);
    one = Cudd_NewApaNumber(digits);
    Cudd_ApaSetToLiteral(digits,one,1);

#if 0
    /* Find the distances from the initial state along paths using one
    ** arc. */
    w = Cudd_Cofactor(dd,D,source); /* works only if source is a cube */
    Cudd_Ref(w);
    V = Cudd_addSwapVariables(dd,w,x,y,vars);
    Cudd_Ref(V);
    Cudd_RecursiveDeref(dd,w);
#endif

    /* The initial states are at distance 0. The other states are
    ** initially at infinite distance. */
    V = Cudd_addIte(dd,source,Cudd_ReadZero(dd),Cudd_ReadPlusInfinity(dd));
    Cudd_Ref(V);

    /* Selective trace algorithm.  For the next update, only consider the
    ** nodes whose distance has changed in the last update. */
    diff = V;
    Cudd_Ref(diff);

    for (Cudd_ApaSetToLiteral(digits,i,1);
	 Cudd_ApaCompare(digits,i,digits,nodes) < 0;
	 Cudd_ApaAdd(digits,i,one,i)) {
	if (pr>2) {(void) printf("V"); Cudd_PrintDebug(dd,V,vars,pr);}
	/* Compute the distances via triangulation as a function of x. */
	w = Cudd_addTriangle(dd,diff,D,x,vars);
	Cudd_Ref(w);
	Cudd_RecursiveDeref(dd,diff);
	u = Cudd_addSwapVariables(dd,w,x,y,vars);
	Cudd_Ref(u);
	Cudd_RecursiveDeref(dd,w);
	if (pr>2) {(void) printf("u"); Cudd_PrintDebug(dd,u,vars,pr);}

	/* Take the minimum of the previous distances and those just
	** computed. */
	min = Cudd_addApply(dd,Cudd_addMinimum,V,u);
	Cudd_Ref(min);
	Cudd_RecursiveDeref(dd,u);
	if (pr>2) {(void) printf("min"); Cudd_PrintDebug(dd,min,vars,pr);}

	if (V == min) {		/* convergence */
	    Cudd_RecursiveDeref(dd,min);
	    if (pr>0) {
		(void) printf("Terminating after ");
		Cudd_ApaPrintDecimal(stdout,digits,i);
		(void) printf(" iterations\n");
	    }
	    break;
	}
	/* Find the distances that decreased. */
	diff = Cudd_addApply(dd,Cudd_addDiff,V,min);
	Cudd_Ref(diff);
	if (pr>2) {(void) printf("diff"); Cudd_PrintDebug(dd,diff,vars,pr);}
	Cudd_RecursiveDeref(dd,V);
	V = min;
    }
    /* Negative cycle detection. */
    if (Cudd_ApaCompare(digits,i,digits,nodes) == 0 &&
	diff != Cudd_ReadPlusInfinity(dd)) {
	(void) printf("Negative cycle\n");
	Cudd_RecursiveDeref(dd,diff);
	Cudd_RecursiveDeref(dd,V);
	V = Cudd_ReadMinusInfinity(dd);
	Cudd_Ref(V);
    }

    Cudd_Deref(V);
    FREE(i);
    FREE(nodes);
    FREE(one);
    return(V);

} /* end of ntrBellman */
Ejemplo n.º 22
0
ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                    FUNCTION DEFINITIONS                          ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [This procedure is similar to Cudd_ShuffleHeap() and Cudd_bddPermute().]

  Description [The first argument is the REO manager. The 2nd/3d
  arguments are the function and its CUDD manager. The last argument
  is the permutation to be implemented. The i-th entry of the permutation 
  array contains the index of the variable that should be brought to the 
  i-th level.  The size of the array should be equal or greater to 
  the number of variables currently in use (that is, the size of CUDD
  manager and the size of REO manager).]

  SideEffects [Note that the resulting BDD is not referenced.]

  SeeAlso     []

***********************************************************************/
DdNode * reoShuffle( reo_man * p, DdManager * dd, DdNode * bFunc, int * pPerm, int * pPermInv )
{
    DdNode * bFuncRes = NULL;
    int i, k, v;

    if ( Cudd_IsConstant(bFunc) )
        return bFunc;

	// set the initial parameters
	p->dd    = dd;
    p->nSupp = Cudd_SupportSize( dd, bFunc );
	p->nTops = 1;
//    p->nNodesBeg = Cudd_DagSize( bFunc );

    // set the starting permutation
	for ( i = 0; i < p->nSupp; i++ )
    {
        p->pOrderInt[i] = i;
		p->pMapToPlanes[ dd->invperm[i] ] = i;
		p->pMapToDdVarsFinal[i] = dd->invperm[i];
    }

	// set the initial parameters
	p->nUnitsUsed = 0;
	p->nNodesCur  = 0;
	p->fThisIsAdd = 0;
	p->Signature++;

	// transfer the function from the CUDD package into REO's internal data structure
    p->pTops[0] = reoTransferNodesToUnits_rec( p, bFunc );
//	assert( p->nNodesBeg == p->nNodesCur );

    // reorder one variable at a time
    for ( i = 0; i < p->nSupp; i++ )
    {
        if ( p->pOrderInt[i] == pPerm[i] )
            continue;
        // find where is variable number pPerm[i]
        for ( k = i + 1; k < p->nSupp; k++ )
            if ( pPerm[i] == p->pOrderInt[k] )
                break;
        if ( k == p->nSupp )
        {
            printf( "reoShuffle() Error: Cannot find a variable.\n" );
            goto finish;
        }
        // move the variable up
        for ( v = k - 1; v >= i; v-- )
        {
            reoReorderSwapAdjacentVars( p, v, 1 );
            // check if the number of nodes is not too large
            if ( p->nNodesCur > 10000 )
            {
                printf( "reoShuffle() Error: BDD size is too large.\n" );
                goto finish;
            }
        }
        assert( p->pOrderInt[i] == pPerm[i] );
    }

	// set the initial parameters
	p->nRefNodes  = 0;
	p->nNodesCur  = 0;
	p->Signature++;
	// transfer the BDDs from REO's internal data structure to CUDD
    bFuncRes = reoTransferUnitsToNodes_rec( p, p->pTops[0] ); Cudd_Ref( bFuncRes );
	// undo the DDs referenced for storing in the cache
	for ( i = 0; i < p->nRefNodes; i++ )
		Cudd_RecursiveDeref( dd, p->pRefNodes[i] );

	// verify zero refs of the terminal nodes
//    assert( reoRecursiveDeref( p->pTops[0] ) );
//    assert( reoCheckZeroRefs( &(p->pPlanes[p->nSupp]) ) );

    // perform verification
	if ( p->fVerify )
	{
		DdNode * bFuncPerm;
		bFuncPerm = Cudd_bddPermute( dd, bFunc, pPermInv );  Cudd_Ref( bFuncPerm );
		if ( bFuncPerm != bFuncRes )
		{
			printf( "REO: Internal verification has failed!\n" );
			fflush( stdout );
		}
		Cudd_RecursiveDeref( dd, bFuncPerm );
	}

	// recycle the data structure
	for ( i = 0; i <= p->nSupp; i++ )
		reoUnitsRecycleUnitList( p, p->pPlanes + i );

finish :
    if ( bFuncRes )
        Cudd_Deref( bFuncRes );
    return bFuncRes;
}
Ejemplo n.º 23
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_zddDivideF.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddDivideF]

******************************************************************************/
DdNode  *
cuddZddDivideF(
  DdManager * dd,
  DdNode * f,
  DdNode * g)
{
    int         v;
    DdNode      *one = DD_ONE(dd);
    DdNode      *zero = DD_ZERO(dd);
    DdNode      *f0, *f1, *g0, *g1;
    DdNode      *q, *r, *tmp;
    int         flag;

    statLine(dd);
    if (g == one)
        return(f);
    if (f == zero || f == one)
        return(zero);
    if (f == g)
        return(one);

    /* Check cache. */
    r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g);
    if (r)
        return(r);

    v = g->index;

    flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
    if (flag == 1)
        return(NULL);
    Cudd_Ref(f1);
    Cudd_Ref(f0);
    flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0);    /* g1 != zero */
    if (flag == 1) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        return(NULL);
    }
    Cudd_Ref(g1);
    Cudd_Ref(g0);

    r = cuddZddDivideF(dd, f1, g1);
    if (r == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        return(NULL);
    }
    Cudd_Ref(r);

    if (r != zero && g0 != zero) {
        tmp = r;
        q = cuddZddDivideF(dd, f0, g0);
        if (q == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, f0);
            Cudd_RecursiveDerefZdd(dd, g1);
            Cudd_RecursiveDerefZdd(dd, g0);
            return(NULL);
        }
        Cudd_Ref(q);
        r = cuddZddIntersect(dd, r, q);
        if (r == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, f0);
            Cudd_RecursiveDerefZdd(dd, g1);
            Cudd_RecursiveDerefZdd(dd, g0);
            Cudd_RecursiveDerefZdd(dd, q);
            return(NULL);
        }
        Cudd_Ref(r);
        Cudd_RecursiveDerefZdd(dd, q);
        Cudd_RecursiveDerefZdd(dd, tmp);
    }

    Cudd_RecursiveDerefZdd(dd, f1);
    Cudd_RecursiveDerefZdd(dd, f0);
    Cudd_RecursiveDerefZdd(dd, g1);
    Cudd_RecursiveDerefZdd(dd, g0);
    
    cuddCacheInsert2(dd, cuddZddDivideF, f, g, r);
    Cudd_Deref(r);
    return(r);

} /* end of cuddZddDivideF */
Ejemplo n.º 24
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_zddUnateProduct.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddUnateProduct]

******************************************************************************/
DdNode  *
cuddZddUnateProduct(
  DdManager * dd,
  DdNode * f,
  DdNode * g)
{
    int         v, top_f, top_g;
    DdNode      *term1, *term2, *term3, *term4;
    DdNode      *sum1, *sum2;
    DdNode      *f0, *f1, *g0, *g1;
    DdNode      *r;
    DdNode      *one = DD_ONE(dd);
    DdNode      *zero = DD_ZERO(dd);
    int         flag;

    statLine(dd);
    if (f == zero || g == zero)
        return(zero);
    if (f == one)
        return(g);
    if (g == one)
        return(f);

    top_f = dd->permZ[f->index];
    top_g = dd->permZ[g->index];

    if (top_f > top_g)
        return(cuddZddUnateProduct(dd, g, f));

    /* Check cache */
    r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g);
    if (r)
        return(r);

    v = f->index;       /* either yi or zi */
    flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
    if (flag == 1)
        return(NULL);
    Cudd_Ref(f1);
    Cudd_Ref(f0);
    flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0);
    if (flag == 1) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        return(NULL);
    }
    Cudd_Ref(g1);
    Cudd_Ref(g0);

    term1 = cuddZddUnateProduct(dd, f1, g1);
    if (term1 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        return(NULL);
    }
    Cudd_Ref(term1);
    term2 = cuddZddUnateProduct(dd, f1, g0);
    if (term2 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, term1);
        return(NULL);
    }
    Cudd_Ref(term2);
    term3 = cuddZddUnateProduct(dd, f0, g1);
    if (term3 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        return(NULL);
    }
    Cudd_Ref(term3);
    term4 = cuddZddUnateProduct(dd, f0, g0);
    if (term4 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        Cudd_RecursiveDerefZdd(dd, term3);
        return(NULL);
    }
    Cudd_Ref(term4);
    Cudd_RecursiveDerefZdd(dd, f1);
    Cudd_RecursiveDerefZdd(dd, f0);
    Cudd_RecursiveDerefZdd(dd, g1);
    Cudd_RecursiveDerefZdd(dd, g0);
    sum1 = cuddZddUnion(dd, term1, term2);
    if (sum1 == NULL) {
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        Cudd_RecursiveDerefZdd(dd, term3);
        Cudd_RecursiveDerefZdd(dd, term4);
        return(NULL);
    }
    Cudd_Ref(sum1);
    Cudd_RecursiveDerefZdd(dd, term1);
    Cudd_RecursiveDerefZdd(dd, term2);
    sum2 = cuddZddUnion(dd, sum1, term3);
    if (sum2 == NULL) {
        Cudd_RecursiveDerefZdd(dd, term3);
        Cudd_RecursiveDerefZdd(dd, term4);
        Cudd_RecursiveDerefZdd(dd, sum1);
        return(NULL);
    }
    Cudd_Ref(sum2);
    Cudd_RecursiveDerefZdd(dd, sum1);
    Cudd_RecursiveDerefZdd(dd, term3);
    r = cuddZddGetNode(dd, v, sum2, term4);
    if (r == NULL) {
        Cudd_RecursiveDerefZdd(dd, term4);
        Cudd_RecursiveDerefZdd(dd, sum2);
        return(NULL);
    }
    Cudd_Ref(r);
    Cudd_RecursiveDerefZdd(dd, sum2);
    Cudd_RecursiveDerefZdd(dd, term4);

    cuddCacheInsert2(dd, cuddZddUnateProduct, f, g, r);
    Cudd_Deref(r);
    return(r);

} /* end of cuddZddUnateProduct */
Ejemplo n.º 25
0
/**Function********************************************************************

  Synopsis [Performs the recursive step of Cudd_zddProduct.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddProduct]

******************************************************************************/
DdNode  *
cuddZddProduct(
  DdManager * dd,
  DdNode * f,
  DdNode * g)
{
    int         v, top_f, top_g;
    DdNode      *tmp, *term1, *term2, *term3;
    DdNode      *f0, *f1, *fd, *g0, *g1, *gd;
    DdNode      *R0, *R1, *Rd, *N0, *N1;
    DdNode      *r;
    DdNode      *one = DD_ONE(dd);
    DdNode      *zero = DD_ZERO(dd);
    int         flag;
    int         pv, nv;

    statLine(dd);
    if (f == zero || g == zero)
        return(zero);
    if (f == one)
        return(g);
    if (g == one)
        return(f);

    top_f = dd->permZ[f->index];
    top_g = dd->permZ[g->index];

    if (top_f > top_g)
        return(cuddZddProduct(dd, g, f));

    /* Check cache */
    r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g);
    if (r)
        return(r);

    v = f->index;       /* either yi or zi */
    flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
    if (flag == 1)
        return(NULL);
    Cudd_Ref(f1);
    Cudd_Ref(f0);
    Cudd_Ref(fd);
    flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
    if (flag == 1) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        return(NULL);
    }
    Cudd_Ref(g1);
    Cudd_Ref(g0);
    Cudd_Ref(gd);
    pv = cuddZddGetPosVarIndex(dd, v);
    nv = cuddZddGetNegVarIndex(dd, v);

    Rd = cuddZddProduct(dd, fd, gd);
    if (Rd == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, gd);
        return(NULL);
    }
    Cudd_Ref(Rd);

    term1 = cuddZddProduct(dd, f0, g0);
    if (term1 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, Rd);
        return(NULL);
    }
    Cudd_Ref(term1);
    term2 = cuddZddProduct(dd, f0, gd);
    if (term2 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, Rd);
        Cudd_RecursiveDerefZdd(dd, term1);
        return(NULL);
    }
    Cudd_Ref(term2);
    term3 = cuddZddProduct(dd, fd, g0);
    if (term3 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, g0);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, Rd);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        return(NULL);
    }
    Cudd_Ref(term3);
    Cudd_RecursiveDerefZdd(dd, f0);
    Cudd_RecursiveDerefZdd(dd, g0);
    tmp = cuddZddUnion(dd, term1, term2);
    if (tmp == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, Rd);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        Cudd_RecursiveDerefZdd(dd, term3);
        return(NULL);
    }
    Cudd_Ref(tmp);
    Cudd_RecursiveDerefZdd(dd, term1);
    Cudd_RecursiveDerefZdd(dd, term2);
    R0 = cuddZddUnion(dd, tmp, term3);
    if (R0 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, Rd);
        Cudd_RecursiveDerefZdd(dd, term3);
        Cudd_RecursiveDerefZdd(dd, tmp);
        return(NULL);
    }
    Cudd_Ref(R0);
    Cudd_RecursiveDerefZdd(dd, tmp);
    Cudd_RecursiveDerefZdd(dd, term3);
    N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */
    if (N0 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, Rd);
        Cudd_RecursiveDerefZdd(dd, R0);
        return(NULL);
    }
    Cudd_Ref(N0);
    Cudd_RecursiveDerefZdd(dd, R0);
    Cudd_RecursiveDerefZdd(dd, Rd);

    term1 = cuddZddProduct(dd, f1, g1);
    if (term1 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, N0);
        return(NULL);
    }
    Cudd_Ref(term1);
    term2 = cuddZddProduct(dd, f1, gd);
    if (term2 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, N0);
        Cudd_RecursiveDerefZdd(dd, term1);
        return(NULL);
    }
    Cudd_Ref(term2);
    term3 = cuddZddProduct(dd, fd, g1);
    if (term3 == NULL) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, gd);
        Cudd_RecursiveDerefZdd(dd, N0);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        return(NULL);
    }
    Cudd_Ref(term3);
    Cudd_RecursiveDerefZdd(dd, f1);
    Cudd_RecursiveDerefZdd(dd, g1);
    Cudd_RecursiveDerefZdd(dd, fd);
    Cudd_RecursiveDerefZdd(dd, gd);
    tmp = cuddZddUnion(dd, term1, term2);
    if (tmp == NULL) {
        Cudd_RecursiveDerefZdd(dd, N0);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, term2);
        Cudd_RecursiveDerefZdd(dd, term3);
        return(NULL);
    }
    Cudd_Ref(tmp);
    Cudd_RecursiveDerefZdd(dd, term1);
    Cudd_RecursiveDerefZdd(dd, term2);
    R1 = cuddZddUnion(dd, tmp, term3);
    if (R1 == NULL) {
        Cudd_RecursiveDerefZdd(dd, N0);
        Cudd_RecursiveDerefZdd(dd, term3);
        Cudd_RecursiveDerefZdd(dd, tmp);
        return(NULL);
    }
    Cudd_Ref(R1);
    Cudd_RecursiveDerefZdd(dd, tmp);
    Cudd_RecursiveDerefZdd(dd, term3);
    N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */
    if (N1 == NULL) {
        Cudd_RecursiveDerefZdd(dd, N0);
        Cudd_RecursiveDerefZdd(dd, R1);
        return(NULL);
    }
    Cudd_Ref(N1);
    Cudd_RecursiveDerefZdd(dd, R1);
    Cudd_RecursiveDerefZdd(dd, N0);

    cuddCacheInsert2(dd, cuddZddProduct, f, g, N1);
    Cudd_Deref(N1);
    return(N1);

} /* end of cuddZddProduct */
Ejemplo n.º 26
0
/**Function********************************************************************

  Synopsis    [Computes the three-way decomposition of f w.r.t. v.]

  Description [Computes the three-way decomposition of function f (represented
  by a ZDD) wit respect to variable v.  Returns 0 if successful; 1 otherwise.]

  SideEffects [The results are returned in f1, f0, and fd.]

  SeeAlso     [cuddZddGetCofactors2]

******************************************************************************/
int
cuddZddGetCofactors3(
  DdManager * dd,
  DdNode * f,
  int  v,
  DdNode ** f1,
  DdNode ** f0,
  DdNode ** fd)
{
    DdNode      *pc, *nc;
    DdNode      *zero = DD_ZERO(dd);
    int         top, hv, ht, pv, nv;
    int         level;

    top = dd->permZ[f->index];
    level = dd->permZ[v];
    hv = level >> 1;
    ht = top >> 1;

    if (hv < ht) {
        *f1 = zero;
        *f0 = zero;
        *fd = f;
    }
    else {
        pv = cuddZddGetPosVarIndex(dd, v);
        nv = cuddZddGetNegVarIndex(dd, v);

        /* not to create intermediate ZDD node */
        if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) {
            pc = cuddZddSubset1(dd, f, pv);
            if (pc == NULL)
                return(1);
            Cudd_Ref(pc);
            nc = cuddZddSubset0(dd, f, pv);
            if (nc == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                return(1);
            }
            Cudd_Ref(nc);

            *f1 = cuddZddSubset0(dd, pc, nv);
            if (*f1 == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                Cudd_RecursiveDerefZdd(dd, nc);
                return(1);
            }
            Cudd_Ref(*f1);
            *f0 = cuddZddSubset1(dd, nc, nv);
            if (*f0 == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                Cudd_RecursiveDerefZdd(dd, nc);
                Cudd_RecursiveDerefZdd(dd, *f1);
                return(1);
            }
            Cudd_Ref(*f0);

            *fd = cuddZddSubset0(dd, nc, nv);
            if (*fd == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                Cudd_RecursiveDerefZdd(dd, nc);
                Cudd_RecursiveDerefZdd(dd, *f1);
                Cudd_RecursiveDerefZdd(dd, *f0);
                return(1);
            }
            Cudd_Ref(*fd);
        } else {
            pc = cuddZddSubset1(dd, f, nv);
            if (pc == NULL)
                return(1);
            Cudd_Ref(pc);
            nc = cuddZddSubset0(dd, f, nv);
            if (nc == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                return(1);
            }
            Cudd_Ref(nc);

            *f0 = cuddZddSubset0(dd, pc, pv);
            if (*f0 == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                Cudd_RecursiveDerefZdd(dd, nc);
                return(1);
            }
            Cudd_Ref(*f0);
            *f1 = cuddZddSubset1(dd, nc, pv);
            if (*f1 == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                Cudd_RecursiveDerefZdd(dd, nc);
                Cudd_RecursiveDerefZdd(dd, *f0);
                return(1);
            }
            Cudd_Ref(*f1);

            *fd = cuddZddSubset0(dd, nc, pv);
            if (*fd == NULL) {
                Cudd_RecursiveDerefZdd(dd, pc);
                Cudd_RecursiveDerefZdd(dd, nc);
                Cudd_RecursiveDerefZdd(dd, *f1);
                Cudd_RecursiveDerefZdd(dd, *f0);
                return(1);
            }
            Cudd_Ref(*fd);
        }

        Cudd_RecursiveDerefZdd(dd, pc);
        Cudd_RecursiveDerefZdd(dd, nc);
        Cudd_Deref(*f1);
        Cudd_Deref(*f0);
        Cudd_Deref(*fd);
    }
    return(0);

} /* end of cuddZddGetCofactors3 */
Ejemplo n.º 27
0
bool qbf_skizzo_coret::get_certificate(void)
{
  std::string result_tmp_file="ozziKs.out";
  std::string options="-dump qbm=bdd";
  std::string log_file = qbf_tmp_file + ".sKizzo.log";

  system(("ozziKs " + options + " " + log_file +
          " > "+result_tmp_file).c_str());

  // read result
  bool result=false;
  {
    std::ifstream in(result_tmp_file.c_str());
    std::string key="  [OK, VALID,";

    while(in)
    {
      std::string line;

      std::getline(in, line);

      if(line!="" && line[line.size()-1]=='\r')
        line.resize(line.size()-1);

      if(line.compare(0, key.size(), key)==0)
      {
        result=true;
        break;
      }
    }
  }

  if(!result)
  {
    messaget::error("Skizzo failed: unknown result");
    return true;
  }

  remove(result_tmp_file.c_str());
  remove(log_file.c_str());

  // certificate reconstruction done, now let's load it from the .qbm file

  int n_e;
  std::vector<int> e_list;
  int e_max=0;

  // check header
  result=false;
  {
    std::ifstream in((qbf_tmp_file+".qbm").c_str());
    std::string key="# existentials[";

    std::string line;
    std::getline(in, line);

    assert(line=="# QBM file, 1.3");

    while(in)
    {
      std::getline(in, line);

      if(line!="" && line[line.size()-1]=='\r')
        line.resize(line.size()-1);

      if(line.compare(0, key.size(), key)==0)
      {
        result=true;
        break;
      }
    }

    size_t ob=line.find('[');
    std::string n_es=line.substr(ob+1, line.find(']')-ob-1);
    n_e=atoi(n_es.c_str());
    assert(n_e!=0);

    e_list.resize(n_e);
    std::string e_lists=line.substr(line.find(':')+2);

    for(int i=0; i<n_e; i++)
    {
      size_t space=e_lists.find(' ');

      int cur=atoi(e_lists.substr(0, space).c_str());
      assert(cur!=0);

      e_list[i]=cur;
      if(cur>e_max) e_max=cur;

      e_lists = e_lists.substr(space+1);
    }

    if(!result)
      throw ("Existential mapping from sKizzo missing");

    in.close();

    // workaround for long comments
    system(("sed -e \"s/^#.*$/# no comment/\" -i "+qbf_tmp_file+".qbm").c_str());
  }


  {
    DdNode **bdds;
    std::string bdd_file=qbf_tmp_file+".qbm";

    // dddmp insists on a non-const string here...
    char filename[bdd_file.size()+1];
    strcpy(filename, bdd_file.c_str());

    bdd_manager->AutodynEnable(CUDD_REORDER_SIFT);

    int nroots =
    Dddmp_cuddBddArrayLoad(bdd_manager->getManager(),
                           DDDMP_ROOT_MATCHLIST, NULL,
                           DDDMP_VAR_MATCHIDS, NULL, NULL, NULL,
                           DDDMP_MODE_DEFAULT,
                           filename,
                           NULL,
                           &bdds);

    assert(nroots=2*n_e); // ozziKs documentation guarantees that.

    model_bdds.resize(e_max+1, NULL);

    for(unsigned i=0; i<e_list.size(); i++)
    {
      int cur=e_list[i];
      DdNode *posNode = bdds[2*i];
      DdNode *negNode = bdds[2*i+1];

      if(Cudd_DagSize(posNode) <= Cudd_DagSize(negNode))
        model_bdds[cur]=new BDD(bdd_manager, posNode);
      else
        model_bdds[cur]=new BDD(bdd_manager, Cudd_Not(negNode));
    }

    // tell CUDD that we don't need those BDDs anymore.
    for(int i=0; i<nroots; i++)
      Cudd_Deref(bdds[i]);

    free(bdds);
    bdds=NULL;
    remove(bdd_file.c_str());
    remove((qbf_tmp_file+".qbm").c_str());
  }


  return false;
}
Ejemplo n.º 28
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_zddWeakDivF.]

  Description []

  SideEffects [None]

  SeeAlso     [Cudd_zddWeakDivF]

******************************************************************************/
DdNode  *
cuddZddWeakDivF(
  DdManager * dd,
  DdNode * f,
  DdNode * g)
{
    int         v, top_f, top_g, vf, vg;
    DdNode      *one = DD_ONE(dd);
    DdNode      *zero = DD_ZERO(dd);
    DdNode      *f0, *f1, *fd, *g0, *g1, *gd;
    DdNode      *q, *tmp;
    DdNode      *r;
    DdNode      *term1, *term0, *termd;
    int         flag;
    int         pv, nv;

    statLine(dd);
    if (g == one)
        return(f);
    if (f == zero || f == one)
        return(zero);
    if (f == g)
        return(one);

    /* Check cache. */
    r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g);
    if (r)
        return(r);

    top_f = dd->permZ[f->index];
    top_g = dd->permZ[g->index];
    vf = top_f >> 1;
    vg = top_g >> 1;
    v = ddMin(top_f, top_g);

    if (v == top_f && vf < vg) {
        v = f->index;
        flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
        if (flag == 1)
            return(NULL);
        Cudd_Ref(f1);
        Cudd_Ref(f0);
        Cudd_Ref(fd);

        pv = cuddZddGetPosVarIndex(dd, v);
        nv = cuddZddGetNegVarIndex(dd, v);

        term1 = cuddZddWeakDivF(dd, f1, g);
        if (term1 == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, f0);
            Cudd_RecursiveDerefZdd(dd, fd);
            return(NULL);
        }
        Cudd_Ref(term1);
        Cudd_RecursiveDerefZdd(dd, f1);
        term0 = cuddZddWeakDivF(dd, f0, g);
        if (term0 == NULL) {
            Cudd_RecursiveDerefZdd(dd, f0);
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, term1);
            return(NULL);
        }
        Cudd_Ref(term0);
        Cudd_RecursiveDerefZdd(dd, f0);
        termd = cuddZddWeakDivF(dd, fd, g);
        if (termd == NULL) {
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, term1);
            Cudd_RecursiveDerefZdd(dd, term0);
            return(NULL);
        }
        Cudd_Ref(termd);
        Cudd_RecursiveDerefZdd(dd, fd);

        tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */
        if (tmp == NULL) {
            Cudd_RecursiveDerefZdd(dd, term1);
            Cudd_RecursiveDerefZdd(dd, term0);
            Cudd_RecursiveDerefZdd(dd, termd);
            return(NULL);
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDerefZdd(dd, term0);
        Cudd_RecursiveDerefZdd(dd, termd);
        q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */
        if (q == NULL) {
            Cudd_RecursiveDerefZdd(dd, term1);
            Cudd_RecursiveDerefZdd(dd, tmp);
            return(NULL);
        }
        Cudd_Ref(q);
        Cudd_RecursiveDerefZdd(dd, term1);
        Cudd_RecursiveDerefZdd(dd, tmp);

        cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
        Cudd_Deref(q);
        return(q);
    }

    if (v == top_f)
        v = f->index;
    else
        v = g->index;

    flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
    if (flag == 1)
        return(NULL);
    Cudd_Ref(f1);
    Cudd_Ref(f0);
    Cudd_Ref(fd);
    flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
    if (flag == 1) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, f0);
        Cudd_RecursiveDerefZdd(dd, fd);
        return(NULL);
    }
    Cudd_Ref(g1);
    Cudd_Ref(g0);
    Cudd_Ref(gd);

    q = g;

    if (g0 != zero) {
        q = cuddZddWeakDivF(dd, f0, g0);
        if (q == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, f0);
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, g1);
            Cudd_RecursiveDerefZdd(dd, g0);
            Cudd_RecursiveDerefZdd(dd, gd);
            return(NULL);
        }
        Cudd_Ref(q);
    }
    else
        Cudd_Ref(q);
    Cudd_RecursiveDerefZdd(dd, f0);
    Cudd_RecursiveDerefZdd(dd, g0);

    if (q == zero) {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, g1);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
        cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero);
        Cudd_Deref(q);
        return(zero);
    }

    if (g1 != zero) {
        Cudd_RecursiveDerefZdd(dd, q);
        tmp = cuddZddWeakDivF(dd, f1, g1);
        if (tmp == NULL) {
            Cudd_RecursiveDerefZdd(dd, f1);
            Cudd_RecursiveDerefZdd(dd, g1);
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, gd);
            return(NULL);
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, g1);
        if (q == g)
            q = tmp;
        else {
            q = cuddZddIntersect(dd, q, tmp);
            if (q == NULL) {
                Cudd_RecursiveDerefZdd(dd, fd);
                Cudd_RecursiveDerefZdd(dd, gd);
                return(NULL);
            }
            Cudd_Ref(q);
            Cudd_RecursiveDerefZdd(dd, tmp);
        }
    }
    else {
        Cudd_RecursiveDerefZdd(dd, f1);
        Cudd_RecursiveDerefZdd(dd, g1);
    }

    if (q == zero) {
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
        cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero);
        Cudd_Deref(q);
        return(zero);
    }

    if (gd != zero) {
        Cudd_RecursiveDerefZdd(dd, q);
        tmp = cuddZddWeakDivF(dd, fd, gd);
        if (tmp == NULL) {
            Cudd_RecursiveDerefZdd(dd, fd);
            Cudd_RecursiveDerefZdd(dd, gd);
            return(NULL);
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
        if (q == g)
            q = tmp;
        else {
            q = cuddZddIntersect(dd, q, tmp);
            if (q == NULL) {
                Cudd_RecursiveDerefZdd(dd, tmp);
                return(NULL);
            }
            Cudd_Ref(q);
            Cudd_RecursiveDerefZdd(dd, tmp);
        }
    }
    else {
        Cudd_RecursiveDerefZdd(dd, fd);
        Cudd_RecursiveDerefZdd(dd, gd);
    }

    cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
    Cudd_Deref(q);
    return(q);

} /* end of cuddZddWeakDivF */