示例#1
0
static keyvalue_table_ptr cudd_shift(shadow_mgr mgr, set_ptr roots,
				     keyvalue_table_ptr vmap) {
    DdNode **vector = calloc_or_fail(mgr->nvars, sizeof(DdNode *), "cudd_shift");
    size_t i;
    /* Must build up vector of composition functions */
    for (i = 0; i < mgr->nvars; i++) {
	ref_t vref = shadow_get_variable(mgr, i);
	word_t wv;
	ref_t nvref = vref;
	if (keyvalue_find(vmap, (word_t) vref, &wv))
	    nvref = (ref_t) wv;
	DdNode *nv = get_ddnode(mgr, nvref);
	vector[i] = nv;
    }
    keyvalue_table_ptr stable = word_keyvalue_new();
    word_t w;
    set_iterstart(roots);
    while (set_iternext(roots, &w)) {
	ref_t r = (ref_t) w;
	DdNode *n = get_ddnode(mgr, r);
	DdNode *ns = Cudd_bddVectorCompose(mgr->bdd_manager, n, vector);
	reference_dd(mgr, ns);
	keyvalue_insert(stable, w, (word_t) ns);
    }
    free_array(vector, mgr->nvars, sizeof(DdNode *));
    return stable;
}
示例#2
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;
}