/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_MvPrintStats( Mv_Man_t * p ) { int i, v; for ( i = 0; i < 15; i++ ) { printf( "%2d : ", i ); printf( "%3d (%2d) ", Cudd_DagSize(p->bFuncs[i])-1, Cudd_SupportSize(p->dd, p->bFuncs[i]) ); for ( v = 0; v < 4; v++ ) printf( "%d = %3d (%2d) ", v, Cudd_DagSize(p->bValues[i][v])-1, Cudd_SupportSize(p->dd, p->bValues[i][v]) ); printf( "\n" ); } }
/**Function************************************************************* Synopsis [Reorders the DD using REO and CUDD.] Description [This function can be used to test the performance of the reordering package.] SideEffects [] SeeAlso [] ***********************************************************************/ void Extra_ReorderTest( DdManager * dd, DdNode * Func ) { reo_man * pReo; DdNode * Temp, * Temp1; int pOrder[1000]; pReo = Extra_ReorderInit( 100, 100 ); //Extra_DumpDot( dd, &Func, 1, "beforReo.dot", 0 ); Temp = Extra_Reorder( pReo, dd, Func, pOrder ); Cudd_Ref( Temp ); //Extra_DumpDot( dd, &Temp, 1, "afterReo.dot", 0 ); Temp1 = Extra_ReorderCudd(dd, Func, NULL ); Cudd_Ref( Temp1 ); printf( "Initial = %d. Final = %d. Cudd = %d.\n", Cudd_DagSize(Func), Cudd_DagSize(Temp), Cudd_DagSize(Temp1) ); Cudd_RecursiveDeref( dd, Temp1 ); Cudd_RecursiveDeref( dd, Temp ); Extra_ReorderQuit( pReo ); }
/**Function******************************************************************** Synopsis [Finds the number of variables on which a DD depends, using Cuddaux_Support.] Description [] SideEffects [None] SeeAlso [Cudd_SupportSize] ******************************************************************************/ int Cuddaux_SupportSize(DdManager* dd, DdNode* f) { DdNode* res; int size; res = Cuddaux_Support(dd,f); cuddRef(res); size = Cudd_DagSize(res) - 1; assert(size>=0); Cudd_IterDerefBdd(dd,res); return size; }
static YAP_Bool dag_size(void) { int size; YAP_Term arg1, arg2, out; DdNode *node; arg1 = YAP_ARG1; arg2 = YAP_ARG2; node = (DdNode *)YAP_IntOfTerm(arg1); size = Cudd_DagSize(node); out = YAP_MkIntTerm(size); return (YAP_Unify(out, arg2)); }
/**Function************************************************************* Synopsis [Reorders BDDs of the local functions.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose ) { reo_man * p; Abc_Obj_t * pNode; int i; Abc_NtkRemoveDupFanins( pNtk ); Abc_NtkMinimumBase( pNtk ); p = Extra_ReorderInit( Abc_NtkGetFaninMax(pNtk), 100 ); Abc_NtkForEachNode( pNtk, pNode, i ) { if ( Abc_ObjFaninNum(pNode) < 3 ) continue; if ( fVerbose ) fprintf( stdout, "%10s: ", Abc_ObjName(pNode) ); if ( fVerbose ) fprintf( stdout, "Before = %5d BDD nodes. ", Cudd_DagSize((DdNode *)pNode->pData) ); Abc_NodeBddReorder( p, pNode ); if ( fVerbose ) fprintf( stdout, "After = %5d BDD nodes.\n", Cudd_DagSize((DdNode *)pNode->pData) ); } Extra_ReorderQuit( p ); }
/**Function************************************************************* Synopsis [Computes the cost based on the BDD size after reordering.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkRenodeEvalBdd( If_Cut_t * pCut ) { int pOrder[IF_MAX_LUTSIZE]; DdNode * bFunc, * bFuncNew; int i, k, nNodes; for ( i = 0; i < If_CutLeaveNum(pCut); i++ ) pCut->pPerm[i] = pOrder[i] = -100; bFunc = Kit_TruthToBdd( s_pDd, If_CutTruth(pCut), If_CutLeaveNum(pCut), 0 ); Cudd_Ref( bFunc ); bFuncNew = Extra_Reorder( s_pReo, s_pDd, bFunc, pOrder ); Cudd_Ref( bFuncNew ); for ( i = k = 0; i < If_CutLeaveNum(pCut); i++ ) if ( pOrder[i] >= 0 ) pCut->pPerm[pOrder[i]] = ++k; // double-check this! nNodes = -1 + Cudd_DagSize( bFuncNew ); Cudd_RecursiveDeref( s_pDd, bFuncNew ); Cudd_RecursiveDeref( s_pDd, bFunc ); return nNodes; }
/**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; } }
/**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; }
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; }
/**Function************************************************************* Synopsis [Extracts sequential DCs of the network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose ) { int fReorder = 1; DdManager * dd; DdNode * bRelation, * bInitial, * bUnreach; // remove EXDC network if present if ( pNtk->pExdc ) { Abc_NtkDelete( pNtk->pExdc ); pNtk->pExdc = NULL; } // compute the global BDDs of the latches dd = Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); if ( dd == NULL ) return 0; if ( fVerbose ) printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); // create the transition relation (dereferenced global BDDs) bRelation = Abc_NtkTransitionRelation( dd, pNtk, fVerbose ); Cudd_Ref( bRelation ); // create the initial state and the variable map bInitial = Abc_NtkInitStateAndVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial ); // compute the unreachable states bUnreach = Abc_NtkComputeUnreachable( dd, pNtk, bRelation, bInitial, fVerbose ); Cudd_Ref( bUnreach ); Cudd_RecursiveDeref( dd, bRelation ); Cudd_RecursiveDeref( dd, bInitial ); // reorder and disable reordering if ( fReorder ) { if ( fVerbose ) fprintf( stdout, "BDD nodes in the unreachable states before reordering %d.\n", Cudd_DagSize(bUnreach) ); Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 ); Cudd_AutodynDisable( dd ); if ( fVerbose ) fprintf( stdout, "BDD nodes in the unreachable states after reordering %d.\n", Cudd_DagSize(bUnreach) ); } // allocate ZDD variables Cudd_zddVarsFromBddVars( dd, 2 ); // create the EXDC network representing the unreachable states if ( pNtk->pExdc ) Abc_NtkDelete( pNtk->pExdc ); pNtk->pExdc = Abc_NtkConstructExdc( dd, pNtk, bUnreach ); Cudd_RecursiveDeref( dd, bUnreach ); Extra_StopManager( dd ); // pNtk->pManGlob = NULL; // make sure that everything is okay if ( pNtk->pExdc && !Abc_NtkCheck( pNtk->pExdc ) ) { printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" ); Abc_NtkDelete( pNtk->pExdc ); return 0; } return 1; }
int DumpDot(DdManager *dd, DdNode *add, rnum *vars, onum *orig_vars, char ** lnames, FILE *fp) { int i; // first, we must apply an ordering in which all the orig_vars's //corresponding binary variables are together // so we just re-apply the original ordering // we'll also save the initial ordering so we can re-apply it after the dump. int *list = new int[2*numvars]; int *orig_list = new int[2*numvars]; for (i=0; i<numvars*2; i++) { // this is the original ordering list[i] = i; orig_list[i] = Cudd_ReadInvPerm(dd,i); } /* fprintf(stderr,"ordering passed into dumpdot is "); for (i=0; i<numvars*2; i++) fprintf(stderr,"%d ",orig_list[i]); fprintf(stderr,"\nnew ordering is "); for (i=0; i<numvars*2; i++) fprintf(stderr,"%d ",list[i]); fprintf(stderr,"\n"); */ int res = Cudd_ShuffleHeap(dd,list); // write out the header and global attributes fprintf(fp,"digraph \"DD\" {\n"); fprintf(fp,"size = \"7.5,10\"\nratio=1.0;\ncenter = true;\nedge [dir = none];\n"); // write the links to a different file name (temporary) // and the nodes to the original file int howmanynodes(0); int dagCount = Cudd_DagSize(add); int dagLeafCount = Cudd_CountLeaves(add); numbranches = 0; numexpbranches = dagCount; branches = new DdNode*[numexpbranches]; branchnodenames = new char*[numexpbranches]; FILE *nodes_fp = fopen("/tmp/spudd.dat","w"); DumpDoth(gbm,add,orig_vars,0,lnames,fp,nodes_fp,&howmanynodes); fclose(nodes_fp); //now transfer all of nodes_fp over to fp nodes_fp = fopen("/tmp/spudd.dat","r"); char tmp; while (!feof(nodes_fp)) { tmp = fgetc(nodes_fp); //?? why?? if (!feof(nodes_fp)) fputc(tmp,fp); } fprintf(fp,"}\n"); for (i=0; i<numbranches; i++) Cudd_RecursiveDeref(gbm,branches[i]); // reapply the original ordering res = Cudd_ShuffleHeap(dd,orig_list); delete [] branches; delete [] list; delete [] orig_list; return(1); }
int BDD::numNodes(void) const { return Cudd_DagSize(node); }