Ejemplo n.º 1
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addOrAbstract.]

  Description [Performs the recursive step of Cudd_addOrAbstract.
  Returns the ADD obtained by abstracting the variables of cube from f,
  if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
DdNode *
cuddAddOrAbstractRecur(
  DdManager * manager,
  DdNode * f,
  DdNode * cube)
{
    DdNode	*T, *E, *res, *res1, *res2, *one;

    statLine(manager);
    one = DD_ONE(manager);

    /* Cube is guaranteed to be a cube at this point. */
    if (cuddIsConstant(f) || cube == one) {  
	return(f);
    }

    /* Abstract a variable that does not appear in f. */
    if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
	res = cuddAddOrAbstractRecur(manager, f, cuddT(cube));
	return(res);
    }

    if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) {
	return(res);
    }

    T = cuddT(f);
    E = cuddE(f);

    /* If the two indices are the same, so are their levels. */
    if (f->index == cube->index) {
	res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube));
	if (res1 == NULL) return(NULL);
        cuddRef(res1);
	if (res1 != one) {
	    res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube));
	    if (res2 == NULL) {
		Cudd_RecursiveDeref(manager,res1);
		return(NULL);
	    }
	    cuddRef(res2);
	    res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2);
	    if (res == NULL) {
		Cudd_RecursiveDeref(manager,res1);
		Cudd_RecursiveDeref(manager,res2);
		return(NULL);
	    }
	    cuddRef(res);
	    Cudd_RecursiveDeref(manager,res1);
	    Cudd_RecursiveDeref(manager,res2);
	} else {
	    res = res1;
	}
	cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
	cuddDeref(res);
        return(res);
    } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
	res1 = cuddAddOrAbstractRecur(manager, T, cube);
	if (res1 == NULL) return(NULL);
        cuddRef(res1);
	res2 = cuddAddOrAbstractRecur(manager, E, cube);
	if (res2 == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    return(NULL);
	}
        cuddRef(res2);
	res = (res1 == res2) ? res1 :
	    cuddUniqueInter(manager, (int) f->index, res1, res2);
	if (res == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    Cudd_RecursiveDeref(manager,res2);
	    return(NULL);
	}
	cuddDeref(res1);
	cuddDeref(res2);
	cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
        return(res);
    }

} /* end of cuddAddOrAbstractRecur */
Ejemplo n.º 2
0
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addUnivAbstract.]

  Description [Performs the recursive step of Cudd_addUnivAbstract.
  Returns the ADD obtained by abstracting the variables of cube from f,
  if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
DdNode *
cuddAddUnivAbstractRecur(
  DdManager * manager,
  DdNode * f,
  DdNode * cube)
{
    DdNode	*T, *E, *res, *res1, *res2, *one, *zero;

    statLine(manager);
    one = DD_ONE(manager);
    zero = DD_ZERO(manager);

    /* Cube is guaranteed to be a cube at this point.
    ** zero and one are the only constatnts c such that c*c=c.
    */
    if (f == zero || f == one || cube == one) {  
	return(f);
    }

    /* Abstract a variable that does not appear in f. */
    if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
	res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube));
	if (res1 == NULL) return(NULL);
	cuddRef(res1);
	/* Use the "internal" procedure to be alerted in case of
	** dynamic reordering. If dynamic reordering occurs, we
	** have to abort the entire abstraction.
	*/
	res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1);
	if (res == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    return(NULL);
	}
	cuddRef(res);
	Cudd_RecursiveDeref(manager,res1);
	cuddDeref(res);
	return(res);
    }

    if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) {
	return(res);
    }

    T = cuddT(f);
    E = cuddE(f);

    /* If the two indices are the same, so are their levels. */
    if (f->index == cube->index) {
	res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube));
	if (res1 == NULL) return(NULL);
        cuddRef(res1);
	res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube));
	if (res2 == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    return(NULL);
	}
        cuddRef(res2);
	res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2);
	if (res == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    Cudd_RecursiveDeref(manager,res2);
	    return(NULL);
	}
	cuddRef(res);
	Cudd_RecursiveDeref(manager,res1);
	Cudd_RecursiveDeref(manager,res2);
	cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
	cuddDeref(res);
        return(res);
    } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
	res1 = cuddAddUnivAbstractRecur(manager, T, cube);
	if (res1 == NULL) return(NULL);
        cuddRef(res1);
	res2 = cuddAddUnivAbstractRecur(manager, E, cube);
	if (res2 == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    return(NULL);
	}
        cuddRef(res2);
	res = (res1 == res2) ? res1 :
	    cuddUniqueInter(manager, (int) f->index, res1, res2);
	if (res == NULL) {
	    Cudd_RecursiveDeref(manager,res1);
	    Cudd_RecursiveDeref(manager,res2);
	    return(NULL);
	}
	cuddDeref(res1);
	cuddDeref(res2);
	cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
        return(res);
    }

} /* end of cuddAddUnivAbstractRecur */
Ejemplo n.º 3
0
/**Function********************************************************************

  Synopsis    [Performs the reordering-sensitive step of Extra_bddReedMuller().]

  Description [Generates in a bottom-up fashion an ADD for all spectral
               coefficients of the functions represented by a BDD.]

  SideEffects []

  SeeAlso     []

******************************************************************************/
DdNode* extraBddReedMuller( 
  DdManager * dd,    /* the manager */
  DdNode * bFunc,    /* the function whose spectrum is being computed */
  DdNode * bVars)    /* the variables on which the function depends */
{
	DdNode * aRes;
    statLine(dd); 

	/* terminal cases */
	if ( bVars == b1 )
	{
		assert( Cudd_IsConstant(bFunc) );
		if ( bFunc == b0 )
			return a0;
		else
			return a1;
	}

    /* check cache */
  if ( ( aRes = cuddCacheLookup2(dd, extraBddReedMuller, bFunc, bVars) ) )
    	return aRes;
	else
	{
		DdNode * bFunc0, * bFunc1;   /* cofactors of the function */
		DdNode * aRes0,  * aRes1;    /* partial results to be composed by ITE */
		DdNode * bFuncR = Cudd_Regular(bFunc); /* the regular pointer to the function */
		DdNode * aTemp;

		/* bFunc cannot depend on a variable that is not in bVars */
		assert( cuddI(dd,bFuncR->index) >= cuddI(dd,bVars->index) );


		/* cofactor the BDD */
		if ( bFuncR->index == bVars->index )
		{
			if ( bFuncR != bFunc ) /* bFunc is complemented */
			{
				bFunc0 = Cudd_Not( cuddE(bFuncR) );
				bFunc1 = Cudd_Not( cuddT(bFuncR) );
			}
			else
			{
				bFunc0 = cuddE(bFuncR);
				bFunc1 = cuddT(bFuncR);
			}
		}
		else /* bVars is higher in the variable order */
			bFunc0 = bFunc1 = bFunc;


		/* solve subproblems */
		aRes0 = extraBddReedMuller( dd, bFunc0, cuddT(bVars) );
		if ( aRes0 == NULL )
			return NULL;
		cuddRef( aRes0 );

		aRes1 = extraBddReedMuller( dd, bFunc1, cuddT(bVars) );
		if ( aRes1 == NULL )
		{
			Cudd_RecursiveDeref( dd, aRes0 );
			return NULL;
		}
		cuddRef( aRes1 );

		/* compute  aRes1 = aRes1 (+) aRes0 */
		aRes1 = cuddAddApplyRecur( dd, Cudd_addXor, aTemp = aRes1, aRes0 );
		if ( aRes1 == NULL )
		{
			Cudd_RecursiveDeref( dd, aRes0 );
			Cudd_RecursiveDeref( dd, aTemp );
			return NULL;
		}
		cuddRef( aRes1 );
		Cudd_RecursiveDeref(dd, aTemp);


		/* only aRes0 and aRes1 are referenced at this point */

		/* consider the case when Res0 and Res1 are the same node */
		aRes = (aRes1 == aRes0) ? aRes1 : cuddUniqueInter( dd, bVars->index, aRes1, aRes0 );
		if (aRes == NULL) 
		{
			Cudd_RecursiveDeref(dd, aRes1);
			Cudd_RecursiveDeref(dd, aRes0);
			return NULL;
		}
		cuddDeref(aRes1);
		cuddDeref(aRes0);

		/* insert the result into cache */
		cuddCacheInsert2(dd, extraBddReedMuller, bFunc, bVars, aRes);
		return aRes;
	}
} /* end of extraBddReedMuller */
Ejemplo n.º 4
0
/**Function********************************************************************

  Synopsis    [Performs the reordering-sensitive step of Extra_bddHaarInverse().]

  Description [Generates in a bottom-up fashion an ADD for the inverse Haar.]

  SideEffects [The third cached argument (bSteps) is the BDD of the elementary variable
  whose index equal to the number of lazy steps made thus far plus one. On the top-most
  level it is 0, next it is 1, etc.]

  SeeAlso     []

******************************************************************************/
DdNode * extraBddHaarInverse( 
  DdManager * dd,    /* the manager */
  DdNode * aFunc,    /* the function whose spectrum is being computed */
  DdNode * aSteps,   /* the index of this variable indicates the number of previous lazy recursive calls */
  DdNode * bVars,    /* the variables, on which the function depends */
  DdNode * bVarsAll, /* the set of all variables, which will never change through the calls */
  int      nVarsAll, /* the number of vars in the set */
  int    * InverseMap ) /* the variable map mapping the var index into its inverse var index */
{
	DdNode * aRes;
	DdNode * bCacheCube;
    statLine(dd); 

	/* terminal cases */
	if ( bVars == b1 )
	{ // return a terminal node with a value equal to cuddV(aFunc) * 2^(nSteps-1)
		if ( cuddV(aSteps) == 0.0 )
			return cuddUniqueConst( dd, cuddV(aFunc) ); 
		else
			return cuddUniqueConst( dd, cuddV(aFunc) * Extra_Power2( (int)(cuddV(aSteps)-1) ) ); 
	}

    /* check cache */
    /* the last two arguments are derivitives, therefore there are useless for caching */
	/* the other two arguments (bVars and bVarsAll) can be combined into one argument */
	bCacheCube = extraCachingCube( dd, bVarsAll, bVars );  Cudd_Ref( bCacheCube );
    if ( aRes = cuddCacheLookup(dd, DD_ADD_HAAR_INVERSE_TAG, aFunc, aSteps, bCacheCube) )
	{
		Cudd_RecursiveDeref( dd, bCacheCube );
   		return aRes;
	}
	else
	{
		DdNode * aFunc0, * aFunc1;   /* cofactors of the function */
		DdNode * aInvH0, * aInvH1;   /* partial solutions of the problem */
		DdNode * aRes0,  * aRes1;    /* partial results to be composed by ITE */
		DdNode * aStepNext;

		/* aFunc cannot depend on a variable that is not in bVars */
		assert( cuddI(dd,aFunc->index) >= cuddI(dd,bVars->index) );

		/* cofactor the ADD */
		if ( aFunc->index == bVars->index )
		{
			aFunc0 = cuddE(aFunc);
			aFunc1 = cuddT(aFunc);
		}
		else /* bVars is higher in the variable order */
			aFunc0 = aFunc1 = aFunc;


		if ( cuddV(aSteps) > 0.0 ) /* meaning that it is a lazy call */
		{
			/* solve subproblems */
			aStepNext = cuddUniqueConst( dd, cuddV(aSteps)+1 );
			if ( aStepNext == NULL )
				return NULL;
			cuddRef( aStepNext );

			aInvH0 = extraBddHaarInverse( dd, aFunc0, aStepNext, cuddT(bVars), bVarsAll, nVarsAll, InverseMap );
			if ( aInvH0 == NULL )
			{
				Cudd_RecursiveDeref( dd, aStepNext );
				return NULL;
			}
			cuddRef( aInvH0 );

			aInvH1 = extraBddHaarInverse( dd, aFunc1, aStepNext, cuddT(bVars), bVarsAll, nVarsAll, InverseMap );
			if ( aInvH1 == NULL )
			{
				Cudd_RecursiveDeref( dd, aStepNext );
				Cudd_RecursiveDeref( dd, aInvH0 );
				return NULL;
			}
			cuddRef( aInvH1 );
			Cudd_RecursiveDeref( dd, aStepNext );

			aRes0 = aInvH0;
			aRes1 = aInvH1;
		}
		else // if ( cuddV(aSteps) == 0.0 )
		{
			/* solve subproblems */
			aInvH0 = extraBddHaarInverse( dd, aFunc0, aSteps, cuddT(bVars), bVarsAll, nVarsAll, InverseMap );
			if ( aInvH0 == NULL )
				return NULL;
			cuddRef( aInvH0 );

			aStepNext = cuddUniqueConst( dd, 1.0 );
			if ( aStepNext == NULL )
			{
				Cudd_RecursiveDeref( dd, aInvH0 );
				return NULL;
			}
			cuddRef( aStepNext );

			aInvH1 = extraBddHaarInverse( dd, aFunc1, aStepNext, cuddT(bVars), bVarsAll, nVarsAll, InverseMap );
			if ( aInvH1 == NULL )
			{
				Cudd_RecursiveDeref( dd, aStepNext );
				Cudd_RecursiveDeref( dd, aInvH0 );
				return NULL;
			}
			cuddRef( aInvH1 );
			Cudd_RecursiveDeref( dd, aStepNext );


			/* compute  aRes0 = aWalsh0 + aWalsh1 */
			aRes0 = cuddAddApplyRecur( dd, Cudd_addPlus, aInvH0, aInvH1 );
			if ( aRes0 == NULL )
			{
				Cudd_RecursiveDeref( dd, aInvH0 );
				Cudd_RecursiveDeref( dd, aInvH1 );
				return NULL;
			}
			cuddRef( aRes0 );

			/* compute  aRes1 = aWalsh0 - aWalsh1 */
			aRes1 = cuddAddApplyRecur( dd, Cudd_addMinus, aInvH0, aInvH1 );
			if ( aRes1 == NULL )
			{
				Cudd_RecursiveDeref( dd, aInvH0 );
				Cudd_RecursiveDeref( dd, aInvH1 );
				Cudd_RecursiveDeref( dd, aRes0 );
				return NULL;
			}
			cuddRef( aRes1 );

			Cudd_RecursiveDeref(dd, aInvH0);
			Cudd_RecursiveDeref(dd, aInvH1);
		}

		/* only aRes0 and aRes1 are referenced at this point */

		/* consider the case when Res0 and Res1 are the same node */
		aRes = extraAddIteRecurGeneral( dd, dd->vars[ InverseMap[bVars->index] ], aRes1, aRes0 );
		if (aRes == NULL) 
		{
			Cudd_RecursiveDeref(dd, aRes1);
			Cudd_RecursiveDeref(dd, aRes0);
			return NULL;
		}
		cuddRef( aRes );
		Cudd_RecursiveDeref(dd, aRes1);
		Cudd_RecursiveDeref(dd, aRes0);
		cuddDeref( aRes );

		/* insert the result into cache */
		cuddCacheInsert(dd, DD_ADD_HAAR_INVERSE_TAG, aFunc, aSteps, bCacheCube, aRes);
		Cudd_RecursiveDeref( dd, bCacheCube );
		return aRes;
	}
} /* end of extraBddHaarInverse */
Ejemplo n.º 5
0
/**Function********************************************************************

  Synopsis    [Performs the reordering-sensitive step of Extra_bddWalsh().]

  Description [Generates in a bottom-up fashion an ADD for all spectral
               coefficients of the functions represented by a BDD.]

  SideEffects []

  SeeAlso     []

******************************************************************************/
DdNode* extraBddWalsh( 
  DdManager * dd,    /* the manager */
  DdNode * bFunc,    /* the function whose spectrum is being computed */
  DdNode * bVars)    /* the variables on which the function depends */
{
	DdNode * aRes;
    statLine(dd); 

	if ( clock() > s_TimeLimit )
		return NULL;

	/* terminal cases */
	if ( bVars == b1 )
	{
		assert( Cudd_IsConstant(bFunc) );
		if ( bFunc == b0 )
			return a1;
		else
			return Cudd_addConst(dd,-1.0);
	}

    /* check cache */
//	if ( bFunc->ref != 1 )
  if ( ( aRes = cuddCacheLookup2(dd, extraBddWalsh, bFunc, bVars) ) )
	{
	    s_CacheHit++;
    	return aRes;
	}
	else
	{
		DdNode * bFunc0,  * bFunc1;   /* cofactors of the function */
		DdNode * aWalsh0, * aWalsh1;   /* partial solutions of the problem */
		DdNode * aRes0,   * aRes1;    /* partial results to be composed by ITE */
		DdNode * bFuncR = Cudd_Regular(bFunc); /* the regular pointer to the function */

	    s_CacheMiss++;

	    /* bFunc cannot depend on a variable that is not in bVars */
		assert( cuddI(dd,bFuncR->index) >= cuddI(dd,bVars->index) );


		/* cofactor the BDD */
		if ( bFuncR->index == bVars->index )
		{
			if ( bFuncR != bFunc ) /* bFunc is complemented */
			{
				bFunc0 = Cudd_Not( cuddE(bFuncR) );
				bFunc1 = Cudd_Not( cuddT(bFuncR) );
			}
			else
			{
				bFunc0 = cuddE(bFuncR);
				bFunc1 = cuddT(bFuncR);
			}
		}
		else /* bVars is higher in the variable order */
			bFunc0 = bFunc1 = bFunc;


		/* solve subproblems */
		aWalsh0 = extraBddWalsh( dd, bFunc0, cuddT(bVars) );
		if ( aWalsh0 == NULL )
			return NULL;
		cuddRef( aWalsh0 );

		aWalsh1 = extraBddWalsh( dd, bFunc1, cuddT(bVars) );
		if ( aWalsh1 == NULL )
		{
			Cudd_RecursiveDeref( dd, aWalsh0 );
			return NULL;
		}
		cuddRef( aWalsh1 );


		/* compute  aRes0 = aWalsh0 + aWalsh1 */
		aRes0 = cuddAddApplyRecur( dd, Cudd_addPlus, aWalsh0, aWalsh1 );
		if ( aRes0 == NULL )
		{
			Cudd_RecursiveDeref( dd, aWalsh0 );
			Cudd_RecursiveDeref( dd, aWalsh1 );
			return NULL;
		}
		cuddRef( aRes0 );

		/* compute  aRes1 = aWalsh0 - aWalsh1 */
		aRes1 = cuddAddApplyRecur( dd, Cudd_addMinus, aWalsh0, aWalsh1 );
		if ( aRes1 == NULL )
		{
			Cudd_RecursiveDeref( dd, aWalsh0 );
			Cudd_RecursiveDeref( dd, aWalsh1 );
			Cudd_RecursiveDeref( dd, aRes0 );
			return NULL;
		}
		cuddRef( aRes1 );

		Cudd_RecursiveDeref(dd, aWalsh0);
		Cudd_RecursiveDeref(dd, aWalsh1);


		/* only aRes0 and aRes1 are referenced at this point */

		/* consider the case when Res0 and Res1 are the same node */
		aRes = (aRes1 == aRes0) ? aRes1 : cuddUniqueInter( dd, bVars->index, aRes1, aRes0 );
		if (aRes == NULL) 
		{
			Cudd_RecursiveDeref(dd, aRes1);
			Cudd_RecursiveDeref(dd, aRes0);
			return NULL;
		}
		cuddDeref(aRes1);
		cuddDeref(aRes0);

		/* insert the result into cache */
//		if ( bFunc->ref != 1 )
		cuddCacheInsert2(dd, extraBddWalsh, bFunc, bVars, aRes);
		return aRes;
	}
} /* end of extraBddWalsh */