/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Extra_bddImageCompute2( Extra_ImageTree2_t * pTree, DdNode * bCare ) { if ( pTree->bImage ) Cudd_RecursiveDeref( pTree->dd, pTree->bImage ); pTree->bImage = Cudd_bddAndAbstract( pTree->dd, pTree->bRel, bCare, pTree->bCube ); Cudd_Ref( pTree->bImage ); return pTree->bImage; }
/**Function************************************************************* Synopsis [Merges two nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Extra_ImageNode_t * Extra_CombineTwoNodes( DdManager * dd, DdNode * bCube, Extra_ImageNode_t * pNode1, Extra_ImageNode_t * pNode2 ) { Extra_ImageNode_t * pNode; Extra_ImagePart_t * pPart; // create a new partition pPart = ABC_ALLOC( Extra_ImagePart_t, 1 ); memset( pPart, 0, sizeof(Extra_ImagePart_t) ); // create the function pPart->bFunc = Cudd_bddAndAbstract( dd, pNode1->pPart->bFunc, pNode2->pPart->bFunc, bCube ); Cudd_Ref( pPart->bFunc ); // update the support the partition pPart->bSupp = Cudd_bddAndAbstract( dd, pNode1->pPart->bSupp, pNode2->pPart->bSupp, bCube ); Cudd_Ref( pPart->bSupp ); // update the numbers pPart->nSupp = Extra_bddSuppSize( dd, pPart->bSupp ); pPart->nNodes = Cudd_DagSize( pPart->bFunc ); pPart->iPart = -1; /* ABC_PRB( dd, pNode1->pPart->bSupp ); ABC_PRB( dd, pNode2->pPart->bSupp ); ABC_PRB( dd, pPart->bSupp ); */ // create a new node pNode = ABC_ALLOC( Extra_ImageNode_t, 1 ); memset( pNode, 0, sizeof(Extra_ImageNode_t) ); pNode->dd = dd; pNode->pPart = pPart; pNode->pNode1 = pNode1; pNode->pNode2 = pNode2; // compute the image pNode->bImage = Cudd_bddAndAbstract( dd, pNode1->bImage, pNode2->bImage, bCube ); Cudd_Ref( pNode->bImage ); // save the cube if ( bCube != b1 ) { pNode->bCube = bCube; Cudd_Ref( bCube ); } return pNode; }
/**Function************************************************************* Synopsis [Recompute the image.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Extra_bddImageCompute_rec( Extra_ImageTree_t * pTree, Extra_ImageNode_t * pNode ) { DdManager * dd = pNode->dd; DdNode * bTemp; int nNodes; // trivial case if ( pNode->pNode1 == NULL ) { if ( pNode->bCube ) { pNode->bImage = Cudd_bddExistAbstract( dd, bTemp = pNode->bImage, pNode->bCube ); Cudd_Ref( pNode->bImage ); Cudd_RecursiveDeref( dd, bTemp ); } return; } // compute the children if ( pNode->pNode1 ) Extra_bddImageCompute_rec( pTree, pNode->pNode1 ); if ( pNode->pNode2 ) Extra_bddImageCompute_rec( pTree, pNode->pNode2 ); // clean the old image if ( pNode->bImage ) Cudd_RecursiveDeref( dd, pNode->bImage ); pNode->bImage = NULL; // compute the new image if ( pNode->bCube ) pNode->bImage = Cudd_bddAndAbstract( dd, pNode->pNode1->bImage, pNode->pNode2->bImage, pNode->bCube ); else pNode->bImage = Cudd_bddAnd( dd, pNode->pNode1->bImage, pNode->pNode2->bImage ); Cudd_Ref( pNode->bImage ); if ( pTree->fVerbose ) { nNodes = Cudd_DagSize( pNode->bImage ); if ( pTree->nNodesMax < nNodes ) pTree->nNodesMax = nNodes; } }
DdNode* compute_EX(DdManager* m, pos* postab, DdNode* R, DdNode* p) { DdNode* tmp; /* rename variables */ int perm[2*(postab->num_procs*postab->pc_size+postab->num_vars)]; int i, j, k; for (i=0; i<postab->num_vars; i++) { perm[i] = i+postab->num_vars; perm[i+postab->num_vars] = i; } for (j=0; j<postab->num_procs; j++) { for (k=0; k<postab->pc_size; k++) { perm[postab->num_vars+i] = postab->pc_[j][k]; perm[postab->num_vars+postab->num_procs*postab->pc_size+i++] = postab->pc[j][k]; } } p = Cudd_bddPermute(m, p, perm); /* construct cube of next state variables */ DdNode* cube = Cudd_ReadOne(m); for (i=0; i<postab->num_vars; i++) { tmp = Cudd_bddAnd(m, cube, Cudd_bddIthVar(m, postab->num_vars+i)); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, cube); cube = tmp; } for (i=0; i<postab->num_procs*postab->pc_size; i++) { tmp = Cudd_bddAnd(m, cube, Cudd_bddIthVar(m, 2*postab->num_vars+postab->num_procs*postab->pc_size+i)); Cudd_Ref(tmp); Cudd_RecursiveDeref(m, cube); cube = tmp; } DdNode* EX_p = Cudd_bddAndAbstract(m, R, p, cube); Cudd_Ref(EX_p); Cudd_RecursiveDeref(m, p); Cudd_RecursiveDeref(m, cube); return EX_p; }
/**Function******************************************************************** Synopsis [Selects pairs from R using a priority function.] Description [Selects pairs from a relation R(x,y) (given as a BDD) in such a way that a given x appears in one pair only. Uses a priority function to determine which y should be paired to a given x. Cudd_PrioritySelect returns a pointer to the selected function if successful; NULL otherwise. Three of the arguments--x, y, and z--are vectors of BDD variables. The first two are the variables on which R depends. The third vectore is a vector of auxiliary variables, used during the computation. This vector is optional. If a NULL value is passed instead, Cudd_PrioritySelect will create the working variables on the fly. The sizes of x and y (and z if it is not NULL) should equal n. The priority function Pi can be passed as a BDD, or can be built by Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the priority function. (Pifunc is a pointer to a C function.) If Pi is not NULL, then Pifunc is ignored. Pifunc should have the same interface as the standard priority functions (e.g., Cudd_Dxygtdxz). Cudd_PrioritySelect and Cudd_CProjection can sometimes be used interchangeably. Specifically, calling Cudd_PrioritySelect with Cudd_Xgty as Pifunc produces the same result as calling Cudd_CProjection with the all-zero minterm as reference minterm. However, depending on the application, one or the other may be preferable: <ul> <li> When extracting representatives from an equivalence relation, Cudd_CProjection has the advantage of nor requiring the auxiliary variables. <li> When computing matchings in general bipartite graphs, Cudd_PrioritySelect normally obtains better results because it can use more powerful matching schemes (e.g., Cudd_Dxygtdxz). </ul> ] SideEffects [If called with z == NULL, will create new variables in the manager.] SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX Cudd_CProjection] ******************************************************************************/ DdNode * Cudd_PrioritySelect( DdManager * dd /* manager */, DdNode * R /* BDD of the relation */, DdNode ** x /* array of x variables */, DdNode ** y /* array of y variables */, DdNode ** z /* array of z variables (optional: may be NULL) */, DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, int n /* size of x, y, and z */, DdNode * (*Pifunc)(DdManager *, int, DdNode **, DdNode **, DdNode **) /* function used to build Pi if it is NULL */) { DdNode *res = NULL; DdNode *zcube = NULL; DdNode *Rxz, *Q; int createdZ = 0; int createdPi = 0; int i; /* Create z variables if needed. */ if (z == NULL) { if (Pi != NULL) return(NULL); z = ALLOC(DdNode *,n); if (z == NULL) { dd->errorCode = CUDD_MEMORY_OUT; return(NULL); } createdZ = 1; for (i = 0; i < n; i++) { if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); if (z[i] == NULL) goto endgame; } } /* Create priority function BDD if needed. */ if (Pi == NULL) { Pi = Pifunc(dd,n,x,y,z); if (Pi == NULL) goto endgame; createdPi = 1; cuddRef(Pi); } /* Initialize abstraction cube. */ zcube = DD_ONE(dd); cuddRef(zcube); for (i = n - 1; i >= 0; i--) { DdNode *tmpp; tmpp = Cudd_bddAnd(dd,z[i],zcube); if (tmpp == NULL) goto endgame; cuddRef(tmpp); Cudd_RecursiveDeref(dd,zcube); zcube = tmpp; } /* Compute subset of (x,y) pairs. */ Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); if (Rxz == NULL) goto endgame; cuddRef(Rxz); Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); if (Q == NULL) { Cudd_RecursiveDeref(dd,Rxz); goto endgame; } cuddRef(Q); Cudd_RecursiveDeref(dd,Rxz); res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); if (res == NULL) { Cudd_RecursiveDeref(dd,Q); goto endgame; } cuddRef(res); Cudd_RecursiveDeref(dd,Q); endgame: if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); if (createdZ) { FREE(z); } if (createdPi) { Cudd_RecursiveDeref(dd,Pi); } if (res != NULL) cuddDeref(res); return(res); } /* Cudd_PrioritySelect */