/**Function******************************************************************** Synopsis [Creates the symmetry information structure from ZDD.] Description [ZDD representation of symmetries is the set of cubes, each of which has two variables in the positive polarity. These variables correspond to the symmetric variable pair.] SideEffects [] SeeAlso [] ******************************************************************************/ Extra_SymmInfo_t * Extra_SymmPairsCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bSupp ) { int i; int nSuppSize; Extra_SymmInfo_t * p; int * pMapVars2Nums; DdNode * bTemp; DdNode * zSet, * zCube, * zTemp; int iVar1, iVar2; nSuppSize = Extra_bddSuppSize( dd, bSupp ); // allocate and clean the storage for symmetry info p = Extra_SymmPairsAllocate( nSuppSize ); // allocate the storage for the temporary map pMapVars2Nums = ABC_ALLOC( int, dd->size ); memset( pMapVars2Nums, 0, dd->size * sizeof(int) ); // assign the variables p->nVarsMax = dd->size; // p->nNodes = Cudd_DagSize( zPairs ); p->nNodes = 0; for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ ) { p->pVars[i] = bTemp->index; pMapVars2Nums[bTemp->index] = i; } // write the symmetry info into the structure zSet = zPairs; Cudd_Ref( zSet ); while ( zSet != z0 ) { // get the next cube zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube ); // add these two variables to the data structure assert( cuddT( cuddT(zCube) ) == z1 ); iVar1 = zCube->index/2; iVar2 = cuddT(zCube)->index/2; if ( pMapVars2Nums[iVar1] < pMapVars2Nums[iVar2] ) p->pSymms[ pMapVars2Nums[iVar1] ][ pMapVars2Nums[iVar2] ] = 1; else p->pSymms[ pMapVars2Nums[iVar2] ][ pMapVars2Nums[iVar1] ] = 1; // count the symmetric pairs p->nSymms ++; // update the cuver and deref the cube zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet ); Cudd_RecursiveDerefZdd( dd, zTemp ); Cudd_RecursiveDerefZdd( dd, zCube ); } // for each cube Cudd_RecursiveDerefZdd( dd, zSet ); ABC_FREE( pMapVars2Nums ); return p; } /* end of Extra_SymmPairsCreateFromZdd */
/** * @brief Basic test of ZDDs. * @return 0 if successful; -1 otherwise. */ static int testZdd(int verbosity) { DdManager *manager; DdNode *f, *var, *tmp; int i, ret; manager = Cudd_Init(0,4,CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS,0); if (!manager) { if (verbosity) { printf("initialization failed\n"); } return -1; } tmp = Cudd_ReadZddOne(manager,0); Cudd_Ref(tmp); for (i = 3; i >= 0; i--) { var = Cudd_zddIthVar(manager,i); Cudd_Ref(var); f = Cudd_zddIntersect(manager,var,tmp); Cudd_Ref(f); Cudd_RecursiveDerefZdd(manager,tmp); Cudd_RecursiveDerefZdd(manager,var); tmp = f; } f = Cudd_zddDiff(manager,Cudd_ReadZddOne(manager,0),tmp); Cudd_Ref(f); Cudd_RecursiveDerefZdd(manager,tmp); if (verbosity) { Cudd_zddPrintMinterm(manager,f); printf("\n"); } Cudd_RecursiveDerefZdd(manager,f); ret = Cudd_CheckZeroRef(manager); if (ret != 0 && verbosity) { printf("%d unexpected non-zero references\n", ret); } Cudd_Quit(manager); return 0; }
/* Compute negation. Creates CUDD reference. For ZDDs, records as reference */ ref_t shadow_negate(shadow_mgr mgr, ref_t a) { ref_t r = REF_INVALID; if (REF_IS_INVALID(a)) return a; if (do_ref(mgr)) r = REF_NEGATE(a); else { DdNode *an = get_ddnode(mgr, a); if (is_zdd(mgr, a)) { DdNode *zone = Cudd_ReadZddOne(mgr->bdd_manager, 0); reference_dd(mgr, zone); DdNode *ann = Cudd_zddDiff(mgr->bdd_manager, zone, an); reference_dd(mgr, ann); unreference_dd(mgr, zone, IS_ZDD); r = dd2ref(ann, IS_ZDD); // For ZDDs, don't already have negated values recorded add_ref(mgr, r, ann); } else if (is_add(mgr, a)) { DdNode *ann = Cudd_addCmpl(mgr->bdd_manager, an); reference_dd(mgr, ann); r = dd2ref(ann, IS_ADD); // For ADDs, don't already have negated values recorded add_ref(mgr, r, ann); } else { DdNode *ann = Cudd_Not(an); reference_dd(mgr, ann); r = dd2ref(ann, IS_BDD); } } #if RPT >= 5 char buf[24], nbuf[24]; shadow_show(mgr, a, buf); shadow_show(mgr, r, nbuf); report(5, "Negated %s to get %s", buf, nbuf); #endif return r; }