/**Function************************************************************* Synopsis [Computes the transition relation of the network.] Description [Assumes that the global BDDs are computed.] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) { DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs; Abc_Obj_t * pNode; int fReorder = 1; int i; // extand the BDD manager to represent NS variables assert( dd->size == Abc_NtkCiNum(pNtk) ); Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 ); // enable reordering if ( fReorder ) Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); else Cudd_AutodynDisable( dd ); // compute the transition relation bRel = b1; Cudd_Ref( bRel ); Abc_NtkForEachLatch( pNtk, pNode, i ) { bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); // bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd ); bProd = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( bProd ); bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bProd ); }
static YAP_Bool init_bdd(void) { mgr_ex = (DdManager **)realloc(mgr_ex, (ex + 1) * sizeof(DdManager *)); mgr_ex[ex] = Cudd_Init(0, 0, UNIQUE_SLOTS, CACHE_SLOTS, 5120); Cudd_AutodynEnable(mgr_ex[ex], CUDD_REORDER_GROUP_SIFT); Cudd_SetMaxCacheHard(mgr_ex[ex], 0); Cudd_SetLooseUpTo(mgr_ex[ex], 0); Cudd_SetMinHit(mgr_ex[ex], 15); bVar2mVar_ex = (int **)realloc(bVar2mVar_ex, (ex + 1) * sizeof(int *)); bVar2mVar_ex[ex] = NULL; vars_ex = (variable **)realloc(vars_ex, (ex + 1) * sizeof(variable *)); vars_ex[ex] = NULL; nVars_ex = (int *)realloc(nVars_ex, (ex + 1) * sizeof(int)); nVars_ex[ex] = 0; probs_ex = (double **)realloc(probs_ex, (ex + 1) * sizeof(double *)); probs_ex[ex] = NULL; boolVars_ex = (int *)realloc(boolVars_ex, (ex + 1) * sizeof(int)); boolVars_ex[ex] = 0; return 1; }
static YAP_Bool init_test(void) { YAP_Term arg1; arg1 = YAP_ARG1; nRules = YAP_IntOfTerm(arg1); ex = 0; mgr_ex = (DdManager **)malloc((ex + 1) * sizeof(DdManager *)); mgr_ex[ex] = Cudd_Init(0, 0, UNIQUE_SLOTS, CACHE_SLOTS, 5120); Cudd_AutodynEnable(mgr_ex[ex], CUDD_REORDER_GROUP_SIFT); Cudd_SetMaxCacheHard(mgr_ex[ex], 0); Cudd_SetLooseUpTo(mgr_ex[ex], 0); Cudd_SetMinHit(mgr_ex[ex], 15); bVar2mVar_ex = (int **)malloc((ex + 1) * sizeof(int *)); bVar2mVar_ex[ex] = NULL; vars_ex = (variable **)malloc((ex + 1) * sizeof(variable *)); vars_ex[ex] = NULL; nVars_ex = (int *)malloc((ex + 1) * sizeof(int)); nVars_ex[ex] = 0; probs_ex = (double **)malloc((ex + 1) * sizeof(double *)); probs_ex[ex] = NULL; boolVars_ex = (int *)malloc((ex + 1) * sizeof(int)); boolVars_ex[ex] = 0; rules = (int *)malloc(nRules * sizeof(int)); return 1; }
/** * Creates a new BDDManager. * * @param maxMemoryInMB The amount of memory to be used. Must be <4096 as CUDD does not support more * @param reorderingMaxBlowup The maximal allowed blowup during sifting steps in the reordering algorithm. Standard is 1.2 - use 1.1 to have less reordering done. A value of 1.0 results in greedy reordering. * @author ehlers */ BFBddManager::BFBddManager(unsigned int maxMemoryInMB, float reorderingMaxBlowup) { mgr = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, (long) maxMemoryInMB * 1024UL * 1024UL); // Configuring the manager Cudd_AutodynEnable(mgr, CUDD_REORDER_SIFT); Cudd_SetMaxGrowth(mgr, reorderingMaxBlowup); Cudd_SetMinHit(mgr, 1); setAutomaticOptimisation(true); }
/**Function******************************************************************** Synopsis [Starts the CUDD manager with the desired options.] Description [Starts the CUDD manager with the desired options. We start with 0 variables, because Ntr_buildDDs will create new variables rather than using whatever already exists.] SideEffects [None] SeeAlso [] *****************************************************************************/ static DdManager * startCudd( NtrOptions * option, int nvars) { DdManager *dd; int result; dd = Cudd_Init(0, 0, option->slots, option->cacheSize, option->maxMemory); if (dd == NULL) return(NULL); if (option->maxMemHard != 0) { Cudd_SetMaxMemory(dd,option->maxMemHard); } Cudd_SetMaxLive(dd,option->maxLive); Cudd_SetGroupcheck(dd,option->groupcheck); if (option->autoDyn & 1) { Cudd_AutodynEnable(dd,option->autoMethod); } dd->nextDyn = option->firstReorder; dd->countDead = (option->countDead == FALSE) ? ~0 : 0; dd->maxGrowth = 1.0 + ((float) option->maxGrowth / 100.0); dd->recomb = option->recomb; dd->arcviolation = option->arcviolation; dd->symmviolation = option->symmviolation; dd->populationSize = option->populationSize; dd->numberXovers = option->numberXovers; result = ntrReadTree(dd,option->treefile,nvars); if (result == 0) { Cudd_Quit(dd); return(NULL); } #ifndef DD_STATS result = Cudd_EnableReorderingReporting(dd); if (result == 0) { (void) fprintf(stderr, "Error reported by Cudd_EnableReorderingReporting\n"); Cudd_Quit(dd); return(NULL); } #endif return(dd); } /* end of startCudd */
void initc(int reorder) { int intBits; nVars=0; boolVars=0; mgr=Cudd_Init(nVars,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); if (reorder != CUDD_REORDER_NONE) Cudd_AutodynEnable(mgr,reorder); vars= (variable *) malloc(nVars * sizeof(variable)); probs=(double *) malloc(0); intBits=sizeof(unsigned int)*8; dividend=-1; /* dividend is a global variable used by my_hash it is equal to an unsigned int with binary representation 11..1 */ }
/**Function************************************************************* Synopsis [Recursively computes global BDDs for the AIG in the manager.] Description [On exit, BDDs are stored in the pNode->pData fields.] SideEffects [] SeeAlso [] ***********************************************************************/ DdManager * Aig_ManComputeGlobalBdds( Aig_Man_t * p, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose ) { ProgressBar * pProgress = NULL; Aig_Obj_t * pObj; DdManager * dd; DdNode * bFunc; int i, Counter; // start the manager dd = Cudd_Init( Aig_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); // set reordering if ( fReorder ) Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); // prepare to construct global BDDs Aig_ManCleanData( p ); // assign the constant node BDD Aig_ObjSetGlobalBdd( Aig_ManConst1(p), dd->one ); Cudd_Ref( dd->one ); // set the elementary variables Aig_ManForEachCi( p, pObj, i ) { Aig_ObjSetGlobalBdd( pObj, dd->vars[i] ); Cudd_Ref( dd->vars[i] ); }
BddBuilder::BddBuilder(){ __pddWireHead = __pddWireTail = NULL; __pddOutputWireHead = __pddOutputWireTail = NULL; __pddOutputNodes = NULL; __pddGateHead = __pddGateTail = NULL; __pddInputNodes = NULL; __pddManager = Cudd_Init(0, 0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS , 0); Cudd_ReduceHeap(__pddManager,CUDD_REORDER_RANDOM_PIVOT,0); Cudd_AutodynEnable(__pddManager,CUDD_REORDER_RANDOM_PIVOT); __Vcc = Cudd_ReadOne(__pddManager); __GND = Cudd_ReadLogicZero(__pddManager); char * name_vcc = new char[4]; char * name_gnd = new char[4]; sprintf(name_vcc, "Vcc"); sprintf(name_gnd, "GND"); __VccWire = new DdWire(__pddManager, name_vcc, 0, 0); __GNDWire = new DdWire(__pddManager, name_gnd, 0, 0); __VccWire->setDdNode(__Vcc); __GNDWire->setDdNode(__GND); Cudd_Ref(__Vcc); Cudd_Ref(__GND); if(__pddManager == NULL){ perror("DdManager initializing error."); } //__inputWireCnt = 2; // Vcc & GND __inputWireCnt = -1; __outputWireCnt = -1; __pddInputWireHead = __VccWire; __VccWire->setInputListNext(__GNDWire); __pddInputWireTail = __GNDWire; }
/**Function******************************************************************** Synopsis [Main function for testcudd.] Description [] SideEffects [None] SeeAlso [] ******************************************************************************/ int main(int argc, char **argv) { FILE *fp; /* pointer to input file */ char *file = (char *) ""; /* input file name */ FILE *dfp = NULL; /* pointer to dump file */ char *dfile; /* file for DD dump */ DdNode *dfunc[2]; /* addresses of the functions to be dumped */ DdManager *dd; /* pointer to DD manager */ DdNode *_true; /* fast access to constant function */ DdNode *M; DdNode **x; /* pointers to variables */ DdNode **y; /* pointers to variables */ DdNode **xn; /* complements of row variables */ DdNode **yn_; /* complements of column variables */ DdNode **xvars; DdNode **yvars; DdNode *C; /* result of converting from ADD to BDD */ DdNode *ess; /* cube of essential variables */ DdNode *shortP; /* BDD cube of shortest path */ DdNode *largest; /* BDD of largest cube */ DdNode *shortA; /* ADD cube of shortest path */ DdNode *constN; /* value returned by evaluation of ADD */ DdNode *ycube; /* cube of the negated y vars for c-proj */ DdNode *CP; /* C-Projection of C */ DdNode *CPr; /* C-Selection of C */ int length; /* length of the shortest path */ int nx; /* number of variables */ int ny; int maxnx; int maxny; int m; int n; int N; int cmu; /* use CMU multiplication */ int pr; /* verbose printout level */ int harwell; int multiple; /* read multiple matrices */ int ok; int c; /* variable to read in options */ int approach; /* reordering approach */ int autodyn; /* automatic reordering */ int groupcheck; /* option for group sifting */ int profile; /* print heap profile if != 0 */ int keepperm; /* keep track of permutation */ int clearcache; /* clear the cache after each matrix */ int blifOrDot; /* dump format: 0 -> dot, 1 -> blif, ... */ int retval; /* return value */ int i; /* loop index */ long startTime; /* initial time */ long lapTime; int size; unsigned int cacheSize, maxMemory; unsigned int nvars,nslots; startTime = util_cpu_time(); approach = CUDD_REORDER_NONE; autodyn = 0; pr = 0; harwell = 0; multiple = 0; profile = 0; keepperm = 0; cmu = 0; N = 4; nvars = 4; cacheSize = 127; maxMemory = 0; nslots = CUDD_UNIQUE_SLOTS; clearcache = 0; groupcheck = CUDD_GROUP_CHECK7; dfile = NULL; blifOrDot = 0; /* dot format */ /* Parse command line. */ while ((c = util_getopt(argc, argv, (char *) "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) != EOF) { switch(c) { case 'C': cmu = 1; break; case 'D': autodyn = 1; break; case 'H': harwell = 1; break; case 'M': #ifdef MNEMOSYNE (void) mnem_setrecording(0); #endif break; case 'P': profile = 1; break; case 'S': nslots = atoi(util_optarg); break; case 'X': maxMemory = atoi(util_optarg); break; case 'a': approach = atoi(util_optarg); break; case 'b': blifOrDot = 1; /* blif format */ break; case 'c': clearcache = 1; break; case 'd': dfile = util_optarg; break; case 'g': groupcheck = atoi(util_optarg); break; case 'k': keepperm = 1; break; case 'm': multiple = 1; break; case 'n': N = atoi(util_optarg); break; case 'p': pr = atoi(util_optarg); break; case 'v': nvars = atoi(util_optarg); break; case 'x': cacheSize = atoi(util_optarg); break; case 'h': default: usage(argv[0]); break; } } if (argc - util_optind == 0) { file = (char *) "-"; } else if (argc - util_optind == 1) { file = argv[util_optind]; } else { usage(argv[0]); } if ((approach<0) || (approach>17)) { (void) fprintf(stderr,"Invalid approach: %d \n",approach); usage(argv[0]); } if (pr >= 0) { (void) printf("# %s\n", TESTCUDD_VERSION); /* Echo command line and arguments. */ (void) printf("#"); for (i = 0; i < argc; i++) { (void) printf(" %s", argv[i]); } (void) printf("\n"); (void) fflush(stdout); } /* Initialize manager and provide easy reference to terminals. */ dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory); _true = DD_TRUE(dd); dd->groupcheck = (Cudd_AggregationType) groupcheck; if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); /* Open input file. */ fp = open_file(file, "r"); /* Open dump file if requested */ if (dfile != NULL) { dfp = open_file(dfile, "w"); } x = y = xn = yn_ = NULL; do { /* We want to start anew for every matrix. */ maxnx = maxny = 0; nx = maxnx; ny = maxny; if (pr>0) lapTime = util_cpu_time(); if (harwell) { if (pr >= 0) (void) printf(":name: "); ok = Cudd_addHarwell(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, &m, &n, 0, 2, 1, 2, pr); } else { ok = Cudd_addRead(fp, dd, &M, &x, &y, &xn, &yn_, &nx, &ny, &m, &n, 0, 2, 1, 2); if (pr >= 0) (void) printf(":name: %s: %d rows %d columns\n", file, m, n); } if (!ok) { (void) fprintf(stderr, "Error reading matrix\n"); exit(1); } if (nx > maxnx) maxnx = nx; if (ny > maxny) maxny = ny; /* Build cube of negated y's. */ ycube = DD_TRUE(dd); Cudd_Ref(ycube); for (i = maxny - 1; i >= 0; i--) { DdNode *tmpp; tmpp = Cudd_bddAnd(dd,Cudd_Not(dd->vars[y[i]->index]),ycube); if (tmpp == NULL) exit(2); Cudd_Ref(tmpp); Cudd_RecursiveDeref(dd,ycube); ycube = tmpp; } /* Initialize vectors of BDD variables used by priority func. */ xvars = ALLOC(DdNode *, nx); if (xvars == NULL) exit(2); for (i = 0; i < nx; i++) { xvars[i] = dd->vars[x[i]->index]; } yvars = ALLOC(DdNode *, ny); if (yvars == NULL) exit(2); for (i = 0; i < ny; i++) { yvars[i] = dd->vars[y[i]->index]; } /* Clean up */ for (i=0; i < maxnx; i++) { Cudd_RecursiveDeref(dd, x[i]); Cudd_RecursiveDeref(dd, xn[i]); } FREE(x); FREE(xn); for (i=0; i < maxny; i++) { Cudd_RecursiveDeref(dd, y[i]); Cudd_RecursiveDeref(dd, yn_[i]); } FREE(y); FREE(yn_); if (pr>0) {(void) printf(":1: M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} if (pr>0) (void) printf(":2: time to read the matrix = %s\n", util_print_time(util_cpu_time() - lapTime)); C = Cudd_addBddPattern(dd, M); if (C == 0) exit(2); Cudd_Ref(C); if (pr>0) {(void) printf(":3: C"); Cudd_PrintDebug(dd,C,nx+ny,pr);} /* Test iterators. */ retval = testIterators(dd,M,C,pr); if (retval == 0) exit(2); cuddCacheProfile(dd,stdout); /* Test XOR */ retval = testXor(dd,C,pr,nx+ny); if (retval == 0) exit(2); /* Test Hamming distance functions. */ retval = testHamming(dd,C,pr); if (retval == 0) exit(2); /* Test selection functions. */ CP = Cudd_CProjection(dd,C,ycube); if (CP == NULL) exit(2); Cudd_Ref(CP); if (pr>0) {(void) printf("ycube"); Cudd_PrintDebug(dd,ycube,nx+ny,pr);} if (pr>0) {(void) printf("CP"); Cudd_PrintDebug(dd,CP,nx+ny,pr);} if (nx == ny) { CPr = Cudd_PrioritySelect(dd,C,xvars,yvars,(DdNode **)NULL, (DdNode *)NULL,ny,Cudd_Xgty); if (CPr == NULL) exit(2); Cudd_Ref(CPr); if (pr>0) {(void) printf(":4: CPr"); Cudd_PrintDebug(dd,CPr,nx+ny,pr);} if (CP != CPr) { (void) printf("CP != CPr!\n"); } Cudd_RecursiveDeref(dd, CPr); } FREE(xvars); FREE(yvars); Cudd_RecursiveDeref(dd, CP); Cudd_RecursiveDeref(dd, ycube); /* Test functions for essential variables. */ ess = Cudd_FindEssential(dd,C); if (ess == NULL) exit(2); Cudd_Ref(ess); if (pr>0) {(void) printf(":4: ess"); Cudd_PrintDebug(dd,ess,nx+ny,pr);} Cudd_RecursiveDeref(dd, ess); /* Test functions for shortest paths. */ shortP = Cudd_ShortestPath(dd, M, NULL, NULL, &length); if (shortP == NULL) exit(2); Cudd_Ref(shortP); if (pr>0) { (void) printf(":5: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); } /* Test functions for largest cubes. */ largest = Cudd_LargestCube(dd, Cudd_Not(C), &length); if (largest == NULL) exit(2); Cudd_Ref(largest); if (pr>0) { (void) printf(":5b: largest"); Cudd_PrintDebug(dd,largest,nx+ny,pr); } Cudd_RecursiveDeref(dd, largest); /* Test Cudd_addEvalConst and Cudd_addIteConstant. */ shortA = Cudd_BddToAdd(dd,shortP); if (shortA == NULL) exit(2); Cudd_Ref(shortA); Cudd_RecursiveDeref(dd, shortP); constN = Cudd_addEvalConst(dd,shortA,M); if (constN == DD_NON_CONSTANT) exit(2); if (Cudd_addIteConstant(dd,shortA,M,constN) != constN) exit(2); if (pr>0) {(void) printf("The value of M along the chosen shortest path is %g\n", cuddV(constN));} Cudd_RecursiveDeref(dd, shortA); shortP = Cudd_ShortestPath(dd, C, NULL, NULL, &length); if (shortP == NULL) exit(2); Cudd_Ref(shortP); if (pr>0) { (void) printf(":6: shortP"); Cudd_PrintDebug(dd,shortP,nx+ny,pr); } /* Test Cudd_bddIteConstant and Cudd_bddLeq. */ if (!Cudd_bddLeq(dd,shortP,C)) exit(2); if (Cudd_bddIteConstant(dd,Cudd_Not(shortP),_true,C) != _true) exit(2); Cudd_RecursiveDeref(dd, shortP); if (profile) { retval = cuddHeapProfile(dd); } size = dd->size; if (pr>0) { (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); } /* Reorder if so requested. */ if (approach != CUDD_REORDER_NONE) { #ifndef DD_STATS retval = Cudd_EnableReorderingReporting(dd); if (retval == 0) { (void) fprintf(stderr,"Error reported by Cudd_EnableReorderingReporting\n"); exit(3); } #endif #ifdef DD_DEBUG retval = Cudd_DebugCheck(dd); if (retval != 0) { (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); exit(3); } retval = Cudd_CheckKeys(dd); if (retval != 0) { (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); exit(3); } #endif retval = Cudd_ReduceHeap(dd,(Cudd_ReorderingType)approach,5); if (retval == 0) { (void) fprintf(stderr,"Error reported by Cudd_ReduceHeap\n"); exit(3); } #ifndef DD_STATS retval = Cudd_DisableReorderingReporting(dd); if (retval == 0) { (void) fprintf(stderr,"Error reported by Cudd_DisableReorderingReporting\n"); exit(3); } #endif #ifdef DD_DEBUG retval = Cudd_DebugCheck(dd); if (retval != 0) { (void) fprintf(stderr,"Error reported by Cudd_DebugCheck\n"); exit(3); } retval = Cudd_CheckKeys(dd); if (retval != 0) { (void) fprintf(stderr,"Error reported by Cudd_CheckKeys\n"); exit(3); } #endif if (approach == CUDD_REORDER_SYMM_SIFT || approach == CUDD_REORDER_SYMM_SIFT_CONV) { Cudd_SymmProfile(dd,0,dd->size-1); } if (pr>0) { (void) printf("Average distance: %g\n", Cudd_AverageDistance(dd)); } if (keepperm) { /* Print variable permutation. */ (void) printf("Variable Permutation:"); for (i=0; i<size; i++) { if (i%20 == 0) (void) printf("\n"); (void) printf("%d ", dd->invperm[i]); } (void) printf("\n"); (void) printf("Inverse Permutation:"); for (i=0; i<size; i++) { if (i%20 == 0) (void) printf("\n"); (void) printf("%d ", dd->perm[i]); } (void) printf("\n"); } if (pr>0) {(void) printf("M"); Cudd_PrintDebug(dd,M,nx+ny,pr);} if (profile) { retval = cuddHeapProfile(dd); } } /* Dump DDs of C and M if so requested. */ if (dfile != NULL) { dfunc[0] = C; dfunc[1] = M; if (blifOrDot == 1) { /* Only dump C because blif cannot handle ADDs */ retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames, NULL,dfp); } else { retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); } if (retval != 1) { (void) fprintf(stderr,"abnormal termination\n"); exit(2); } } Cudd_RecursiveDeref(dd, C); Cudd_RecursiveDeref(dd, M); if (clearcache) { if (pr>0) {(void) printf("Clearing the cache... ");} for (i = dd->cacheSlots - 1; i>=0; i--) { dd->cache[i].data = NIL(DdNode); } if (pr>0) {(void) printf("done\n");} } if (pr>0) { (void) printf("Number of variables = %6d\t",dd->size); (void) printf("Number of slots = %6d\n",dd->slots); (void) printf("Number of keys = %6d\t",dd->keys); (void) printf("Number of min dead = %6d\n",dd->minDead); } } while (multiple && !feof(fp)); fclose(fp); if (dfile != NULL) { fclose(dfp); } /* Second phase: experiment with Walsh matrices. */ if (!testWalsh(dd,N,cmu,approach,pr)) { exit(2); } /* Check variable destruction. */ assert(cuddDestroySubtables(dd,3)); assert(Cudd_DebugCheck(dd) == 0); assert(Cudd_CheckKeys(dd) == 0); retval = Cudd_CheckZeroRef(dd); ok = retval != 0; /* ok == 0 means O.K. */ if (retval != 0) { (void) fprintf(stderr, "%d non-zero DD reference counts after dereferencing\n", retval); } if (pr >= 0) { (void) Cudd_PrintInfo(dd,stdout); } Cudd_Quit(dd); #ifdef MNEMOSYNE mnem_writestats(); #endif if (pr>0) (void) printf("total time = %s\n", util_print_time(util_cpu_time() - startTime)); if (pr >= 0) util_print_cpu_stats(stdout); exit(ok); /* NOTREACHED */ } /* end of main */
int main( int argc, char **argv ) { FILE *fp; FILE *stdin_backup = NULL; bool help_flag = False; bool ptdump_flag = False; bool logging_flag = False; unsigned char verbose = 0; int input_index = -1; int output_file_index = -1; /* For command-line flag "-o". */ char dumpfilename[64]; int i, j, var_index; ptree_t *tmppt; /* General purpose temporary ptree pointer */ int horizon = -1; DdNode *W, *etrans, *strans, **sgoals, **egoals; DdManager *manager; DdNode *T = NULL; anode_t *strategy = NULL; int num_env, num_sys; int original_num_env, original_num_sys; int max_sim_it; /* Number of simulation iterations */ anode_t *play; vartype *init_state; int *init_state_ints = NULL; char *all_vars = NULL, *metric_vars = NULL; int *offw, num_vars; int init_state_acc; /* Accumulate components of initial state before expanding into a (bool) bitvector. */ /* Look for flags in command-line arguments. */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { if (argv[i][1] == 'h') { help_flag = True; } else if (argv[i][1] == 'V') { printf( "grjit (experiment-related program, distributed with" " gr1c v" GR1C_VERSION ")\n\n" GR1C_COPYRIGHT "\n" ); return 0; } else if (argv[i][1] == 'v') { verbose = 1; j = 2; /* Only support up to "level 2" of verbosity */ while (argv[i][j] == 'v' && j <= 2) { verbose++; j++; } } else if (argv[i][1] == 'l') { logging_flag = True; } else if (argv[i][1] == 'p') { ptdump_flag = True; } else if (argv[i][1] == 'm') { if (i == argc-1) { fprintf( stderr, "Invalid flag given. Try \"-h\".\n" ); return 1; } all_vars = strtok( argv[i+1], "," ); max_sim_it = strtol( all_vars, NULL, 10 ); all_vars = strtok( NULL, "," ); if (all_vars == NULL) { fprintf( stderr, "Invalid use of -m flag.\n" ); return 1; } metric_vars = strdup( all_vars ); if (max_sim_it >= 0) { all_vars = strtok( NULL, "," ); if (all_vars == NULL) { fprintf( stderr, "Invalid use of -m flag.\n" ); return 1; } init_state_acc = read_state_str( all_vars, &init_state_ints, -1 ); all_vars = strtok( NULL, "," ); if (all_vars == NULL) { horizon = -1; /* The horizon was not given. */ } else { horizon = strtol( all_vars, NULL, 10 ); if (horizon < 1) { fprintf( stderr, "Invalid use of -m flag. Horizon must" " be positive.\n" ); return 1; } } } all_vars = NULL; i++; } else if (argv[i][1] == 'o') { if (i == argc-1) { fprintf( stderr, "Invalid flag given. Try \"-h\".\n" ); return 1; } output_file_index = i+1; i++; } else { fprintf( stderr, "Invalid flag given. Try \"-h\".\n" ); return 1; } } else if (input_index < 0) { /* Use first non-flag argument as filename whence to read specification. */ input_index = i; } } if (help_flag) { /* Split among printf() calls to conform with ISO C90 string length */ printf( "Usage: %s [-hVvlp] [-m ARG1,ARG2,...] [-o FILE] [FILE]\n\n" " -h this help message\n" " -V print version and exit\n" " -v be verbose; use -vv to be more verbose\n" " -l enable logging\n" " -p dump parse trees to DOT files, and echo formulas to screen\n" " -o FILE output results to FILE, rather than stdout (default)\n", argv[0] ); printf( " -m ARG1,... run simulation using comma-separated list of arguments:\n" " ARG1 is the max simulation duration; -1 to only compute horizon;\n" " ARG2 is a space-separated list of metric variables;\n" " ARG3 is a space-separated list of initial values;\n" " ARG3 is ignored and may be omitted if ARG1 equals -1.\n" " ARG4 is the horizon, if provided; otherwise compute it.\n" ); return 1; } if (logging_flag) { openlogfile( NULL ); /* Use default filename prefix */ /* Only change verbosity level if user did not specify it */ if (verbose == 0) verbose = 1; } else { setlogstream( stdout ); setlogopt( LOGOPT_NOTIME ); } if (verbose > 0) logprint( "Running with verbosity level %d.", verbose ); /* If filename for specification given at command-line, then use it. Else, read from stdin. */ if (input_index > 0) { fp = fopen( argv[input_index], "r" ); if (fp == NULL) { perror( "grjit, fopen" ); return -1; } stdin_backup = stdin; stdin = fp; } /* Parse the specification. */ if (verbose) logprint( "Parsing input..." ); SPC_INIT( spc ); if (yyparse()) return -1; if (verbose) logprint( "Done." ); if (stdin_backup != NULL) { stdin = stdin_backup; } /* Close input file, if opened. */ if (input_index > 0) fclose( fp ); /* Treat deterministic problem in which ETRANS or EINIT is omitted. */ if (spc.evar_list == NULL) { if (spc.et_array_len == 0) { spc.et_array_len = 1; spc.env_trans_array = malloc( sizeof(ptree_t *) ); if (spc.env_trans_array == NULL) { perror( "gr1c, malloc" ); return -1; } *spc.env_trans_array = init_ptree( PT_CONSTANT, NULL, 1 ); } if (spc.env_init == NULL) spc.env_init = init_ptree( PT_CONSTANT, NULL, 1 ); } /* Number of variables, before expansion of those that are nonboolean */ original_num_env = tree_size( spc.evar_list ); original_num_sys = tree_size( spc.svar_list ); /* Build list of variable names if needed for simulation, storing the result as a string in all_vars */ if (max_sim_it >= 0) { /* At this point, init_state_acc should contain the number of integers read by read_state_str() during command-line argument parsing. */ if (init_state_acc != original_num_env+original_num_sys) { fprintf( stderr, "Number of initial values given does not match number" " of problem variables.\n" ); return 1; } num_vars = 0; tmppt = spc.evar_list; while (tmppt) { num_vars += strlen( tmppt->name )+1; tmppt = tmppt->left; } tmppt = spc.svar_list; while (tmppt) { num_vars += strlen( tmppt->name )+1; tmppt = tmppt->left; } all_vars = malloc( num_vars*sizeof(char) ); if (all_vars == NULL) { perror( "main, malloc" ); return -1; } i = 0; tmppt = spc.evar_list; while (tmppt) { strncpy( all_vars+i, tmppt->name, num_vars-i ); i += strlen( tmppt->name )+1; *(all_vars+i-1) = ' '; tmppt = tmppt->left; } tmppt = spc.svar_list; while (tmppt) { strncpy( all_vars+i, tmppt->name, num_vars-i ); i += strlen( tmppt->name )+1; *(all_vars+i-1) = ' '; tmppt = tmppt->left; } *(all_vars+i-1) = '\0'; if (verbose) logprint( "String of all variables found to be \"%s\"", all_vars ); } if (ptdump_flag) { tree_dot_dump( spc.env_init, "env_init_ptree.dot" ); tree_dot_dump( spc.sys_init, "sys_init_ptree.dot" ); for (i = 0; i < spc.et_array_len; i++) { snprintf( dumpfilename, sizeof(dumpfilename), "env_trans%05d_ptree.dot", i ); tree_dot_dump( *(spc.env_trans_array+i), dumpfilename ); } for (i = 0; i < spc.st_array_len; i++) { snprintf( dumpfilename, sizeof(dumpfilename), "sys_trans%05d_ptree.dot", i ); tree_dot_dump( *(spc.sys_trans_array+i), dumpfilename ); } if (spc.num_egoals > 0) { for (i = 0; i < spc.num_egoals; i++) { snprintf( dumpfilename, sizeof(dumpfilename), "env_goal%05d_ptree.dot", i ); tree_dot_dump( *(spc.env_goals+i), dumpfilename ); } } if (spc.num_sgoals > 0) { for (i = 0; i < spc.num_sgoals; i++) { snprintf( dumpfilename, sizeof(dumpfilename), "sys_goal%05d_ptree.dot", i ); tree_dot_dump( *(spc.sys_goals+i), dumpfilename ); } } var_index = 0; printf( "Environment variables (indices; domains): " ); if (spc.evar_list == NULL) { printf( "(none)" ); } else { tmppt = spc.evar_list; while (tmppt) { if (tmppt->value == 0) { /* Boolean */ if (tmppt->left == NULL) { printf( "%s (%d; bool)", tmppt->name, var_index ); } else { printf( "%s (%d; bool), ", tmppt->name, var_index); } } else { if (tmppt->left == NULL) { printf( "%s (%d; {0..%d})", tmppt->name, var_index, tmppt->value ); } else { printf( "%s (%d; {0..%d}), ", tmppt->name, var_index, tmppt->value ); } } tmppt = tmppt->left; var_index++; } } printf( "\n\n" ); printf( "System variables (indices; domains): " ); if (spc.svar_list == NULL) { printf( "(none)" ); } else { tmppt = spc.svar_list; while (tmppt) { if (tmppt->value == 0) { /* Boolean */ if (tmppt->left == NULL) { printf( "%s (%d; bool)", tmppt->name, var_index ); } else { printf( "%s (%d; bool), ", tmppt->name, var_index ); } } else { if (tmppt->left == NULL) { printf( "%s (%d; {0..%d})", tmppt->name, var_index, tmppt->value ); } else { printf( "%s (%d; {0..%d}), ", tmppt->name, var_index, tmppt->value ); } } tmppt = tmppt->left; var_index++; } } printf( "\n\n" ); print_GR1_spec( spc.evar_list, spc.svar_list, spc.env_init, spc.sys_init, spc.env_trans_array, spc.et_array_len, spc.sys_trans_array, spc.st_array_len, spc.env_goals, spc.num_egoals, spc.sys_goals, spc.num_sgoals, stdout ); } if (expand_nonbool_GR1( spc.evar_list, spc.svar_list, &spc.env_init, &spc.sys_init, &spc.env_trans_array, &spc.et_array_len, &spc.sys_trans_array, &spc.st_array_len, &spc.env_goals, spc.num_egoals, &spc.sys_goals, spc.num_sgoals, verbose ) < 0) return -1; spc.nonbool_var_list = expand_nonbool_variables( &spc.evar_list, &spc.svar_list, verbose ); if (spc.et_array_len > 1) { spc.env_trans = merge_ptrees( spc.env_trans_array, spc.et_array_len, PT_AND ); } else if (spc.et_array_len == 1) { spc.env_trans = *spc.env_trans_array; } else { fprintf( stderr, "Syntax error: GR(1) specification is missing environment" " transition rules.\n" ); return -1; } if (spc.st_array_len > 1) { spc.sys_trans = merge_ptrees( spc.sys_trans_array, spc.st_array_len, PT_AND ); } else if (spc.st_array_len == 1) { spc.sys_trans = *spc.sys_trans_array; } else { fprintf( stderr, "Syntax error: GR(1) specification is missing system" " transition rules.\n" ); return -1; } if (verbose > 1) /* Dump the spec to show results of conversion (if any). */ print_GR1_spec( spc.evar_list, spc.svar_list, spc.env_init, spc.sys_init, spc.env_trans_array, spc.et_array_len, spc.sys_trans_array, spc.st_array_len, spc.env_goals, spc.num_egoals, spc.sys_goals, spc.num_sgoals, NULL ); num_env = tree_size( spc.evar_list ); num_sys = tree_size( spc.svar_list ); manager = Cudd_Init( 2*(num_env+num_sys), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); Cudd_SetMaxCacheHard( manager, (unsigned int)-1 ); Cudd_AutodynEnable( manager, CUDD_REORDER_SAME ); T = check_realizable( manager, EXIST_SYS_INIT, verbose ); if (verbose) { if (T != NULL) { logprint( "Realizable." ); } else { logprint( "Not realizable." ); } } if (T != NULL) { /* Print measure data and simulate. */ if (horizon < 0) { if (verbose) logprint( "Computing horizon with metric variables: %s", metric_vars ); horizon = compute_horizon( manager, &W, &etrans, &strans, &sgoals, metric_vars, verbose ); logprint( "horizon: %d", horizon ); if (getlogstream() != stdout) printf( "horizon: %d\n", horizon ); } else { W = compute_winning_set_saveBDDs( manager, &etrans, &strans, &egoals, &sgoals, verbose ); if (verbose) logprint( "Using given horizon: %d", horizon ); } if (max_sim_it >= 0 && horizon > -1) { /* Compute variable offsets and use it to get the initial state as a bitvector */ offw = get_offsets( all_vars, &num_vars ); if (num_vars != original_num_env+original_num_sys) { fprintf( stderr, "Error while computing bitwise variable offsets.\n" ); return -1; } free( all_vars ); init_state_acc = 0; if (verbose) { logprint_startline(); logprint_raw( "initial state for simulation:" ); } for (i = 0; i < original_num_env+original_num_sys; i++) { if (verbose) logprint_raw( " %d", *(init_state_ints+i) ); init_state_acc += *(init_state_ints+i) << *(offw + 2*i); } if (verbose) logprint_endline(); free( offw ); init_state = int_to_bitvec( init_state_acc, num_env+num_sys ); if (init_state == NULL) return -1; play = sim_rhc( manager, W, etrans, strans, sgoals, metric_vars, horizon, init_state, max_sim_it, verbose ); if (play == NULL) { fprintf( stderr, "Error while attempting receding horizon" " simulation.\n" ); return -1; } free( init_state ); logprint( "play length: %d", aut_size( play ) ); tmppt = spc.nonbool_var_list; while (tmppt) { aut_compact_nonbool( play, spc.evar_list, spc.svar_list, tmppt->name, tmppt->value ); tmppt = tmppt->left; } num_env = tree_size( spc.evar_list ); num_sys = tree_size( spc.svar_list ); /* Open output file if specified; else point to stdout. */ if (output_file_index >= 0) { fp = fopen( argv[output_file_index], "w" ); if (fp == NULL) { perror( "grjit, fopen" ); return -1; } } else { fp = stdout; } /* Print simulation trace */ dump_simtrace( play, spc.evar_list, spc.svar_list, fp ); if (fp != stdout) fclose( fp ); } Cudd_RecursiveDeref( manager, W ); Cudd_RecursiveDeref( manager, etrans ); Cudd_RecursiveDeref( manager, strans ); } /* Clean-up */ free( metric_vars ); delete_tree( spc.evar_list ); delete_tree( spc.svar_list ); delete_tree( spc.env_init ); delete_tree( spc.sys_init ); delete_tree( spc.env_trans ); delete_tree( spc.sys_trans ); for (i = 0; i < spc.num_egoals; i++) delete_tree( *(spc.env_goals+i) ); if (spc.num_egoals > 0) free( spc.env_goals ); for (i = 0; i < spc.num_sgoals; i++) delete_tree( *(spc.sys_goals+i) ); if (spc.num_sgoals > 0) free( spc.sys_goals ); if (T != NULL) Cudd_RecursiveDeref( manager, T ); if (strategy) delete_aut( strategy ); if (verbose > 1) logprint( "Cudd_CheckZeroRef -> %d", Cudd_CheckZeroRef( manager ) ); Cudd_Quit(manager); if (logging_flag) closelogfile(); /* Return 0 if realizable, -1 if not realizable. */ if (T != NULL) { return 0; } else { return -1; } return 0; }
anode_t *synthesize( DdManager *manager, unsigned char init_flags, unsigned char verbose ) { anode_t *strategy = NULL; anode_t *this_node_stack = NULL; anode_t *node, *new_node; bool initial; vartype *state; vartype **env_moves; int emoves_len; ptree_t *var_separator; DdNode *W; DdNode *strans_into_W; DdNode *einit, *sinit, *etrans, *strans, **egoals, **sgoals; DdNode *ddval; /* Store result of evaluating a BDD */ DdNode ***Y = NULL; DdNode *Y_i_primed; int *num_sublevels; DdNode ****X_ijr = NULL; DdNode *tmp, *tmp2; int i, j, r, k; /* Generic counters */ int offset; bool env_nogoal_flag = False; /* Indicate environment has no goals */ int loop_mode; int next_mode; int num_env, num_sys; int *cube; /* length will be twice total number of variables (to account for both variables and their primes). */ /* Variables used during CUDD generation (state enumeration). */ DdGen *gen; CUDD_VALUE_TYPE gvalue; int *gcube; /* Set environment goal to True (i.e., any state) if none was given. This simplifies the implementation below. */ if (spc.num_egoals == 0) { env_nogoal_flag = True; spc.num_egoals = 1; spc.env_goals = malloc( sizeof(ptree_t *) ); *spc.env_goals = init_ptree( PT_CONSTANT, NULL, 1 ); } num_env = tree_size( spc.evar_list ); num_sys = tree_size( spc.svar_list ); /* State vector (i.e., valuation of the variables) */ state = malloc( sizeof(vartype)*(num_env+num_sys) ); if (state == NULL) { perror( __FILE__ ", malloc" ); exit(-1); } /* Allocate cube array, used later for quantifying over variables. */ cube = (int *)malloc( sizeof(int)*2*(num_env+num_sys) ); if (cube == NULL) { perror( __FILE__ ", malloc" ); exit(-1); } /* Chain together environment and system variable lists for working with BDD library. */ if (spc.evar_list == NULL) { var_separator = NULL; spc.evar_list = spc.svar_list; /* that this is the deterministic case is indicated by var_separator = NULL. */ } else { var_separator = get_list_item( spc.evar_list, -1 ); if (var_separator == NULL) { fprintf( stderr, "Error: get_list_item failed on environment variables" " list.\n" ); free( state ); free( cube ); return NULL; } var_separator->left = spc.svar_list; } /* Generate BDDs for the various parse trees from the problem spec. */ if (spc.env_init != NULL) { einit = ptree_BDD( spc.env_init, spc.evar_list, manager ); } else { einit = Cudd_ReadOne( manager ); Cudd_Ref( einit ); } if (spc.sys_init != NULL) { sinit = ptree_BDD( spc.sys_init, spc.evar_list, manager ); } else { sinit = Cudd_ReadOne( manager ); Cudd_Ref( sinit ); } if (verbose > 1) logprint( "Building environment transition BDD..." ); etrans = ptree_BDD( spc.env_trans, spc.evar_list, manager ); if (verbose > 1) { logprint( "Done." ); logprint( "Building system transition BDD..." ); } strans = ptree_BDD( spc.sys_trans, spc.evar_list, manager ); if (verbose > 1) logprint( "Done." ); /* Build goal BDDs, if present. */ if (spc.num_egoals > 0) { egoals = malloc( spc.num_egoals*sizeof(DdNode *) ); for (i = 0; i < spc.num_egoals; i++) *(egoals+i) = ptree_BDD( *(spc.env_goals+i), spc.evar_list, manager ); } else { egoals = NULL; } if (spc.num_sgoals > 0) { sgoals = malloc( spc.num_sgoals*sizeof(DdNode *) ); for (i = 0; i < spc.num_sgoals; i++) *(sgoals+i) = ptree_BDD( *(spc.sys_goals+i), spc.evar_list, manager ); } else { sgoals = NULL; } if (var_separator == NULL) { spc.evar_list = NULL; } else { var_separator->left = NULL; } W = compute_winning_set_BDD( manager, etrans, strans, egoals, sgoals, verbose ); if (W == NULL) { fprintf( stderr, "Error synthesize: failed to construct winning set.\n" ); free( state ); free( cube ); return NULL; } Y = compute_sublevel_sets( manager, W, etrans, strans, egoals, spc.num_egoals, sgoals, spc.num_sgoals, &num_sublevels, &X_ijr, verbose ); if (Y == NULL) { fprintf( stderr, "Error synthesize: failed to construct sublevel sets.\n" ); free( state ); free( cube ); return NULL; } /* The sublevel sets are exactly as resulting from the vanilla fixed point formula. Thus for each system goal i, Y_0 = \emptyset, and Y_1 is a union of i-goal states and environment-blocking states. For the purpose of synthesis, it is enough to delete Y_0 and replace Y_1 with the intersection of i-goal states and the winning set, and then shift the indices down (so that Y_1 is now called Y_0, Y_2 is now called Y_1, etc.) */ for (i = 0; i < spc.num_sgoals; i++) { Cudd_RecursiveDeref( manager, *(*(Y+i)) ); Cudd_RecursiveDeref( manager, *(*(Y+i)+1) ); for (r = 0; r < spc.num_egoals; r++) Cudd_RecursiveDeref( manager, *(*(*(X_ijr+i))+r) ); free( *(*(X_ijr+i)) ); *(*(Y+i)+1) = Cudd_bddAnd( manager, *(sgoals+i), W ); Cudd_Ref( *(*(Y+i)+1) ); (*(num_sublevels+i))--; for (j = 0; j < *(num_sublevels+i); j++) { *(*(Y+i)+j) = *(*(Y+i)+j+1); *(*(X_ijr+i)+j) = *(*(X_ijr+i)+j+1); } assert( *(num_sublevels+i) > 0 ); *(Y+i) = realloc( *(Y+i), (*(num_sublevels+i))*sizeof(DdNode *) ); *(X_ijr+i) = realloc( *(X_ijr+i), (*(num_sublevels+i))*sizeof(DdNode **) ); if (*(Y+i) == NULL || *(X_ijr+i) == NULL) { perror( __FILE__ ", realloc" ); exit(-1); } } /* Make primed form of W and take conjunction with system transition (safety) formula, for use while stepping down Y_i sets. Note that we assume the variable map has been appropriately defined in the CUDD manager, after the call to compute_winning_set_BDD above. */ tmp = Cudd_bddVarMap( manager, W ); if (tmp == NULL) { fprintf( stderr, "Error synthesize: Error in swapping variables with primed" " forms.\n" ); free( state ); free( cube ); return NULL; } Cudd_Ref( tmp ); strans_into_W = Cudd_bddAnd( manager, strans, tmp ); Cudd_Ref( strans_into_W ); Cudd_RecursiveDeref( manager, tmp ); /* From each initial state, build strategy by propagating forward toward the next goal (current target goal specified by "mode" of a state), and iterating until every reached state and mode combination has already been encountered (whence the strategy already built). */ if (init_flags == ALL_INIT || (init_flags == ONE_SIDE_INIT && spc.sys_init == NULL)) { if (init_flags == ALL_INIT) { if (verbose > 1) logprint( "Enumerating initial states, given init_flags =" " ALL_INIT" ); tmp = Cudd_bddAnd( manager, einit, sinit ); } else { if (verbose > 1) logprint( "Enumerating initial states, given init_flags =" " ONE_SIDE_INIT and empty SYSINIT" ); tmp = einit; Cudd_Ref( tmp ); } Cudd_Ref( tmp ); Cudd_AutodynDisable( manager ); Cudd_ForeachCube( manager, tmp, gen, gcube, gvalue ) { initialize_cube( state, gcube, num_env+num_sys ); while (!saturated_cube( state, gcube, num_env+num_sys )) { this_node_stack = insert_anode( this_node_stack, 0, -1, False, state, num_env+num_sys ); if (this_node_stack == NULL) { fprintf( stderr, "Error synthesize: building list of initial" " states.\n" ); return NULL; } increment_cube( state, gcube, num_env+num_sys ); } this_node_stack = insert_anode( this_node_stack, 0, -1, False, state, num_env+num_sys ); if (this_node_stack == NULL) { fprintf( stderr, "Error synthesize: building list of initial" " states.\n" ); return NULL; } } Cudd_AutodynEnable( manager, CUDD_REORDER_SAME ); Cudd_RecursiveDeref( manager, tmp ); } else if (init_flags == ALL_ENV_EXIST_SYS_INIT) {
static int compute_prob(void) /* this is the function that implements the compute_prob predicate used in pp.pl */ { YAP_Term out,arg1,arg2,arg3,arg4; variables vars; expr expression; DdNode * function; DdManager * mgr; int nBVar,i,intBits,create_dot; FILE * file; DdNode * array[1]; double prob; char * onames[1]; char inames[1000][20]; char * names[1000]; tablerow * nodes; arg1=YAP_ARG1; arg2=YAP_ARG2; arg3=YAP_ARG3; arg4=YAP_ARG4; mgr=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); create_dot=YAP_IntOfTerm(arg4); vars=createVars(arg1,mgr,create_dot,inames); //Cudd_PrintInfo(mgr,stderr); /* automatic variable reordering, default method CUDD_REORDER_SIFT used */ //printf("status %d\n",Cudd_ReorderingStatus(mgr,&order)); //printf("order %d\n",order); Cudd_AutodynEnable(mgr,CUDD_REORDER_SAME); /* Cudd_AutodynEnable(mgr, CUDD_REORDER_RANDOM_PIVOT); printf("status %d\n",Cudd_ReorderingStatus(mgr,&order)); printf("order %d\n",order); printf("%d",CUDD_REORDER_RANDOM_PIVOT); */ expression=createExpression(arg2); function=retFunction(mgr,expression,vars); /* the BDD build by retFunction is converted to an ADD (algebraic decision diagram) because it is easier to interpret and to print */ //add=Cudd_BddToAdd(mgr,function); //Cudd_PrintInfo(mgr,stderr); if (create_dot) /* if specified by the user, a dot file for the BDD is written to cpl.dot */ { nBVar=vars.nBVar; for(i=0; i<nBVar; i++) names[i]=inames[i]; array[0]=function; onames[0]="Out"; file = open_file("cpl.dot", "w"); Cudd_DumpDot(mgr,1,array,names,onames,file); fclose(file); } nodes=init_table(vars.nBVar); intBits=sizeof(unsigned int)*8; prob=Prob(function,vars,nodes); out=YAP_MkFloatTerm(prob); destroy_table(nodes,vars.nBVar); Cudd_Quit(mgr); for(i=0; i<vars.nVar; i++) { free(vars.varar[i].probabilities); free(vars.varar[i].booleanVars); } free(vars.varar); free(vars.bVar2mVar); for(i=0; i<expression.nTerms; i++) { free(expression.terms[i].factors); } free(expression.terms); return(YAP_Unify(out,arg3)); }
/** * A function for switching automatic BDD optimisation (variable reordering) on and off * * @param enable Whether automatic optimisation should be enabled or not * @author ehlers */ void BFBddManager::setAutomaticOptimisation(bool enable) { if (enable) Cudd_AutodynEnable(mgr, CUDD_REORDER_SAME); else Cudd_AutodynDisable(mgr); }
static int compute_prob(void) /* this is the function that implements the compute_prob predicate used in pp.pl */ { YAP_Term out,arg1,arg2,arg3,arg4; array_t * variables,* expression, * bVar2mVar; DdNode * function, * add; DdManager * mgr; int nBVar,i,j,intBits,create_dot; FILE * file; DdNode * array[1]; char * onames[1]; char inames[1000][20]; char * names[1000]; GHashTable * nodes; /* hash table that associates nodes with their probability if already computed, it is defined in glib */ Cudd_ReorderingType order; arg1=YAP_ARG1; arg2=YAP_ARG2; arg3=YAP_ARG3; arg4=YAP_ARG4; mgr=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); variables=array_alloc(variable,0); bVar2mVar=array_alloc(int,0); create_dot=YAP_IntOfTerm(arg4); createVars(variables,arg1,mgr,bVar2mVar,create_dot,inames); //Cudd_PrintInfo(mgr,stderr); /* automatic variable reordering, default method CUDD_REORDER_SIFT used */ //printf("status %d\n",Cudd_ReorderingStatus(mgr,&order)); //printf("order %d\n",order); Cudd_AutodynEnable(mgr,CUDD_REORDER_SAME); /* Cudd_AutodynEnable(mgr, CUDD_REORDER_RANDOM_PIVOT); printf("status %d\n",Cudd_ReorderingStatus(mgr,&order)); printf("order %d\n",order); printf("%d",CUDD_REORDER_RANDOM_PIVOT); */ expression=array_alloc(array_t *,0); createExpression(expression,arg2); function=retFunction(mgr,expression,variables); /* the BDD build by retFunction is converted to an ADD (algebraic decision diagram) because it is easier to interpret and to print */ add=Cudd_BddToAdd(mgr,function); //Cudd_PrintInfo(mgr,stderr); if (create_dot) /* if specified by the user, a dot file for the BDD is written to cpl.dot */ { nBVar=array_n(bVar2mVar); for(i=0;i<nBVar;i++) names[i]=inames[i]; array[0]=add; onames[0]="Out"; file = open_file("cpl.dot", "w"); Cudd_DumpDot(mgr,1,array,names,onames,file); fclose(file); } nodes=g_hash_table_new(my_hash,my_equal); intBits=sizeof(unsigned int)*8; /* dividend is a global variable used by my_hash it is equal to an unsigned int with binary representation 11..1 */ dividend=1; for(j=1;j<intBits;j++) { dividend=(dividend<<1)+1; } out=YAP_MkFloatTerm(Prob(add,variables,bVar2mVar,nodes)); g_hash_table_foreach (nodes,dealloc,NULL); g_hash_table_destroy(nodes); Cudd_Quit(mgr); array_free(variables); array_free(bVar2mVar); array_free(expression); return(YAP_Unify(out,arg3)); }