/** * @brief Basic test of Cudd_CountMinterm(). * @return 0 if successful; -1 otherwise. */ static int testCount(int verbosity) { DdManager *dd; DdNode *h; int i, ret; int const N = 2044; /* number of variables */ dd = Cudd_Init(N, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!dd) { if (verbosity) { printf("initialization failed\n"); } return -1; } /* Build a cube with N/2 variables. */ h = Cudd_ReadOne(dd); Cudd_Ref(h); for (i = 0; i < N; i += 2) { DdNode *var, *tmp; var = Cudd_bddIthVar(dd, N-i-1); tmp = Cudd_bddAnd(dd, h, var); if (!tmp) { Cudd_Quit(dd); return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, h); h = tmp; } if (verbosity) { printf("h (dbl) "); Cudd_PrintDebug(dd, h, N, 1); printf("h (apa) "); Cudd_PrintSummary(dd, h, N, 1); } Cudd_RecursiveDeref(dd, h); if (verbosity) { printf("one[%d] (dbl) ", N); Cudd_PrintDebug(dd, Cudd_ReadOne(dd), N, 1); printf("one[%d] (apa) ", N); Cudd_PrintSummary(dd, Cudd_ReadOne(dd), N, 1); ret = Cudd_CheckZeroRef(dd); printf("one[%d] (dbl) ", N+1); Cudd_PrintDebug(dd, Cudd_ReadOne(dd), N+1, 1); printf("one[%d] (apa) ", N+1); Cudd_PrintSummary(dd, Cudd_ReadOne(dd), N+1, 1); ret = Cudd_CheckZeroRef(dd); } if (verbosity && ret != 0) { printf("%d non-zero references\n", ret); } Cudd_Quit(dd); return 0; }
BFBddManager::~BFBddManager() { int nofLeft = Cudd_CheckZeroRef(mgr); if (nofLeft != 0) { std::cerr << "Warning: " << nofLeft << " referenced nodes in the BDD manager left on destruction!\n"; } Cudd_Quit(mgr); }
/*************************************************************************************************************************** Main Function( write all new functions in user.c only and call them in main.c) Compile Command: make Execution Command: ./proj2 "input file" "path file" "output file" ****************************************************************************************************************************/ int main(int argc, char **argv) { FILE *fisc, *path, *fout; //file pointers used for .isc file, .path file, and output file int Max,Bound; //maxnode id,Max nodes in a bdd of cct NODE *graph; //structure used to store the cct information in .isc file //Read the .isc file and store the information in graph structure fisc=fopen(argv[1],"r"); //file pointer to open .isc file graph=(NODE *) malloc(Mnod * sizeof(NODE)); //dynamic memory allocation for graph structure Max=0; Max=ReadIsc(fisc,graph); //read .isc file and return index of last node in graph formed fclose(fisc); //close file pointer for .isc file PrintCircuit(graph,Max); //print all members of graph structure test (graph, Max, manager); //BDD user.c function declaration manager=Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); //intializing CUDD package manger path=fopen(argv[2],"r"); //File pointer to open .path file fout=fopen(argv[3],"w"); //File pointer to open .out file printf("\nNo of Unreferenced Bdds %d\n", Cudd_CheckZeroRef(manager)); Cudd_Quit(manager); //closing the cudd package manager ClearCircuit(graph,Mnod); //clear memeory for all members of graph fclose(path); //close the path file fclose(fout); //close the output file return 0; }//end of main
ACCExpr *cleanupBool(ACCExpr *expr) { if (!expr) return expr; inBool++; // can be invoked recursively! walkReplaceBuiltin(expr); inBool--; int varIndex = 0; VarMap varMap; DdManager * mgr = Cudd_Init(MAX_NAME_COUNT,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); varIndex = 0; varMap.clear(); DdNode *bdd = tree2BDD(mgr, expr, varMap); char const *inames[MAX_NAME_COUNT]; for (auto item: varMap) inames[item.second->index] = strdup(item.first.c_str()); char * fform = Cudd_FactoredFormString(mgr, bdd, inames); Cudd_RecursiveDeref(mgr, bdd); int err = Cudd_CheckZeroRef(mgr); if (trace_bool) printf("%s: expr '%s' val = %s\n", __FUNCTION__, tree2str(expr).c_str(), fform); assert(err == 0 && "Reference counting"); ACCExpr *ret = str2tree(fform); free(fform); Cudd_Quit(mgr); return ret; }
static YAP_Bool end(void) { int r, i; for (i = 0; i < ex; i++) { Cudd_Quit(mgr_ex[i]); free(bVar2mVar_ex[i]); free(vars_ex[i]); free(probs_ex[i]); fflush(stdout); } free(mgr_ex); free(bVar2mVar_ex); free(vars_ex); free(probs_ex); free(nVars_ex); free(boolVars_ex); for (r = 0; r < nRules; r++) { for (i = 0; i < rules[r] - 1; i++) { free(eta[r][i]); free(eta_temp[r][i]); } free(eta[r]); free(eta_temp[r]); } free(eta); free(eta_temp); for (r = 0; r < nRules; r++) { free(arrayprob[r]); } free(arrayprob); free(rules); return 1; }
/**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 free_shadow_mgr(shadow_mgr mgr) { if (mgr->do_cudd) { Cudd_Quit(mgr->bdd_manager); } if (do_ref(mgr)) free_ref_mgr(mgr->ref_mgr); keyvalue_free(mgr->c2r_table); keyvalue_free(mgr->r2c_table); free_block((void *) mgr, sizeof(shadow_ele)); }
static YAP_Bool end_test(void) { free(bVar2mVar_ex[ex]); free(vars_ex[ex]); Cudd_Quit(mgr_ex[ex]); free(probs_ex[ex]); free(rules); free(mgr_ex); free(bVar2mVar_ex); free(vars_ex); free(probs_ex); free(nVars_ex); free(boolVars_ex); return 1; }
// construct the BDDs // pProgress = Extra_ProgressBarStart( stdout, Aig_ManNodeNum(p) ); Aig_ManForEachCo( p, pObj, i ) { bFunc = Bbr_NodeGlobalBdds_rec( dd, Aig_ObjFanin0(pObj), nBddSizeMax, fDropInternal, pProgress, &Counter, fVerbose ); if ( bFunc == NULL ) { if ( fVerbose ) printf( "Constructing global BDDs is aborted.\n" ); Aig_ManFreeGlobalBdds( p, dd ); Cudd_Quit( dd ); // reset references Aig_ManResetRefs( p ); return NULL; } bFunc = Cudd_NotCond( bFunc, Aig_ObjFaninC0(pObj) ); Cudd_Ref( bFunc ); Aig_ObjSetGlobalBdd( pObj, bFunc ); }
/** * @brief Basic ADD test. * @return 0 if successful; -1 otherwise. */ static int testAdd(int verbosity) { DdManager *manager; DdNode *f, *var, *tmp, *bg; int i, ret; CUDD_VALUE_TYPE pinf; manager = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!manager) { if (verbosity) { printf("initialization failed\n"); } return -1; } pinf = Cudd_V(Cudd_ReadPlusInfinity(manager)); if (verbosity) { printf("Plus infinity is %g\n", pinf); } f = Cudd_addConst(manager,5); Cudd_Ref(f); for (i = 3; i >= 0; i--) { var = Cudd_addIthVar(manager,i); Cudd_Ref(var); tmp = Cudd_addApply(manager,Cudd_addTimes,var,f); Cudd_Ref(tmp); Cudd_RecursiveDeref(manager,f); Cudd_RecursiveDeref(manager,var); f = tmp; } if (verbosity) { Cudd_PrintMinterm(manager, f); printf("\n"); } Cudd_RecursiveDeref(manager, f); bg = Cudd_ReadBackground(manager); if (verbosity) { printf("background (%g) minterms : ", Cudd_V(bg)); Cudd_ApaPrintMinterm(Cudd_ReadStdout(manager), manager, bg, 0); } ret = Cudd_CheckZeroRef(manager); if (ret != 0 && verbosity) { printf("%d non-zero ADD reference counts after dereferencing\n", ret); } Cudd_Quit(manager); return ret != 0; }
/** * @brief Basic BDD test. * @return 0 if successful; -1 otherwise. */ static int testBdd(int verbosity) { DdManager *dd; DdNode *f, *var, *tmp; int i, ret; dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!dd) { if (verbosity) { printf("initialization failed\n"); } return -1; } if (verbosity) { printf("Started CUDD version "); Cudd_PrintVersion(stdout); } f = Cudd_ReadOne(dd); Cudd_Ref(f); for (i = 3; i >= 0; i--) { var = Cudd_bddIthVar(dd, i); tmp = Cudd_bddAnd(dd, Cudd_Not(var), f); if (!tmp) { if (verbosity) { printf("computation failed\n"); } return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, f); f = tmp; } if (verbosity) { Cudd_bddPrintCover(dd, f, f); } Cudd_RecursiveDeref(dd, f); ret = Cudd_CheckZeroRef(dd); if (ret != 0 && verbosity) { printf("%d unexpected non-zero references\n", ret); } Cudd_Quit(dd); return 0; }
/** * @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; }
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; }
int main(int argc, char** argv) { unsigned int i; Biddy_Boolean complete; Biddy_Edge tmp; Biddy_Edge r1,r2; unsigned int n1,n2; char *userinput; #ifdef USA_YES unsigned int usaSize = 0; unsigned int **usaEdge; unsigned int *usaOrder; char *usaCodes; Biddy_Edge *usaState; Biddy_Edge *usaGraph; #endif #ifdef EUROPE_YES unsigned int europeSize = 0; unsigned int **europeEdge; unsigned int *europeOrder; char *europeCodes; Biddy_Edge *europeState; Biddy_Edge *europeGraph; #endif setbuf(stdout, NULL); #ifdef USA_YES setDataUSA(&usaSize,&usaEdge,&usaOrder,&usaCodes); #endif #ifdef EUROPE_YES setDataEurope(&europeSize,&europeEdge,&europeOrder,&europeCodes); #endif #ifdef USE_BIDDY /* There is only one unique table in Biddy */ /* There are three caches in Biddy */ /* Unique table grows over the time */ /* The max number of variables is hardcoded in biddyInt. h */ /* biddyVariableTable.usaSize = BIDDYVARMAX = 2048 */ /* The following constants are hardcoded in biddyMain.c */ /* biddyIteCache.usaSize = MEDIUM_TABLE = 262143 */ /* biddyEACache.usaSize = SMALL_TABLE = 65535 */ /* biddyRCCache.usaSize = SMALL_TABLE = 65535 */ /* DEFAULT INIT CALL: Biddy_Init() */ Biddy_Init(); #endif #ifdef USE_CUDD /* In CUDD each variable has its own subtable in the unique table */ /* There is only one cache in CUDD */ /* Subtables grow over the time, you can set limit for fast unique table growth */ /* Cudd_SetLooseUpTo(manager,1048576) */ /* Cache can grow over the time, you can set the max usaSize */ /* Cudd_SetMaxCacheHard(manager,262144) */ /* These two constants are hardcoded in v3.0.0 */ /* CUDD_UNIQUE_SLOTS = 256 (default initial usaSize of each subtable) */ /* CUDD_CACHE_SLOTS = 262144 (default initial usaSize of cache table) */ /* DEFAULT INIT CALL: Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0) */ manager = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); Cudd_SetMaxCacheHard(manager,262144); #endif #ifdef USA_YES usaGraph = (Biddy_Edge *) malloc(usaSize*sizeof(Biddy_Edge *)); usaState = (Biddy_Edge *) malloc(usaSize*sizeof(Biddy_Edge *)); #endif #ifdef EUROPE_YES europeGraph = (Biddy_Edge *) malloc(europeSize*sizeof(Biddy_Edge *)); europeState = (Biddy_Edge *) malloc(europeSize*sizeof(Biddy_Edge *)); #endif i = 0; complete = FALSE; while (!complete) { complete = TRUE; tmp = Biddy_AddVariable(); #ifdef USA_YES if (i < usaSize) { usaState[usaOrder[i]] = tmp; } complete = complete && (i >= (usaSize-1)); #endif #ifdef EUROPE_YES if (i < europeSize) { europeState[europeOrder[i]] = tmp; } complete = complete && (i >= (europeSize-1)); #endif i++; } #ifdef USA_YES createGraph(usaSize,usaEdge,usaState,usaGraph); #endif #ifdef EUROPE_YES createGraph(europeSize,europeEdge,europeState,europeGraph); #endif #ifdef USE_BIDDY Biddy_Clean(); #endif r1 = Biddy_GetConstantZero(); r2 = Biddy_GetConstantZero(); #ifdef USE_CUDD Cudd_Ref(r1); Cudd_Ref(r2); #endif #ifdef USA_YES if (!CALCULATE_KERNELS) { /* CALCULATING INDEPENDENCE SETS FOR USA */ #ifdef USE_CUDD Cudd_RecursiveDeref(manager,r1); #endif r1 = calculateIndependence(usaSize,usaState,usaGraph); } else { /* CALCULATING KERNELS (MAXIMUM INDEPENDENCE SETS) FOR USA */ #ifdef USE_CUDD Cudd_RecursiveDeref(manager,r1); #endif r1 = calculateKernels(usaSize,usaState,usaGraph); } #ifdef USE_BIDDY Biddy_AddPersistentFormula((Biddy_String)"usa",r1); Biddy_Clean(); #endif #ifdef USE_CUDD for (i=0; i<usaSize; i++) { Cudd_RecursiveDeref(manager,usaGraph[i]); } #endif #endif #ifdef EUROPE_YES if (!CALCULATE_KERNELS) { /* CALCULATING INDEPENDENCE SETS FOR EUROPE */ #ifdef USE_CUDD Cudd_RecursiveDeref(manager,r2); #endif r2 = calculateIndependence(europeSize,europeState,europeGraph); } else { /* CALCULATING KERNELS (MAXIMUM INDEPENDENCE SETS) FOR EUROPE */ #ifdef USE_CUDD Cudd_RecursiveDeref(manager,r2); #endif r2 = calculateKernels(europeSize,europeState,europeGraph); } #ifdef USE_BIDDY Biddy_AddPersistentFormula((Biddy_String)"europe",r2); Biddy_Clean(); #endif #ifdef USE_CUDD for (i=0; i<europeSize; i++) { Cudd_RecursiveDeref(manager,europeGraph[i]); } #endif #endif userinput = strdup("..."); while (userinput[0] != 'x') { /* We have problems with passing stdout in the case you compile this file */ /* with MINGW and use biddy.dll generated with Visual Studio. */ /* In such cases, please, use Biddy_PrintInfo(NULL) */ if (userinput[0] == 'r') Biddy_PrintInfo(stdout); /* SIFTING */ #ifdef USE_BIDDY #ifdef CONVERGE if (userinput[0] == 's') Biddy_PurgeAndReorder(NULL,TRUE); #ifdef USA_YES if (userinput[0] == 'u') Biddy_PurgeAndReorder(r1,TRUE); #endif #ifdef EUROPE_YES if (userinput[0] == 'e') Biddy_PurgeAndReorder(r2,TRUE); #endif #else if (userinput[0] == 's') Biddy_PurgeAndReorder(NULL,FALSE); #ifdef USA_YES if (userinput[0] == 'u') Biddy_PurgeAndReorder(r1,FALSE); #endif #ifdef EUROPE_YES if (userinput[0] == 'e') Biddy_PurgeAndReorder(r2,FALSE); #endif #endif #endif #ifdef USE_CUDD #ifdef CONVERGE if (userinput[0] == 's') Cudd_ReduceHeap(manager,CUDD_REORDER_SIFT_CONVERGE,0); #else if (userinput[0] == 's') Cudd_ReduceHeap(manager,CUDD_REORDER_SIFT,0); #endif #endif n1 = Biddy_VariableNumber(r1); n2 = Biddy_VariableNumber(r2); if ((userinput[0] == 's') #ifdef USA_YES || (userinput[0] == 'u') #endif #ifdef EUROPE_YES || (userinput[0] == 'e') #endif ) { #ifdef CONVERGE printf("(CONVERGING SIFTING"); #ifdef USE_BIDDY if (userinput[0] == 'u') { printf(" ON FUNCTION FOR USA"); } if (userinput[0] == 'e') { printf(" ON FUNCTION FOR EUROPE"); } #endif printf(") "); #else printf("(SIFTING"); #ifdef USE_BIDDY if (userinput[0] == 'u') { printf(" ON FUNCTION FOR USA"); } if (userinput[0] == 'e') { printf(" ON FUNCTION FOR EUROPE"); } #endif printf(") "); #endif } printf("Resulting function r1/r2 depends on %u/%u variables.\n",n1,n2); printf("Resulting function r1/r2 has %.0f/%.0f minterms.\n",Biddy_CountMinterm(r1,n1),Biddy_CountMinterm(r2,n2)); #ifdef USE_BIDDY printf("BDD for resulting function r1/r2 has %u/%u nodes (%u/%u nodes if using complement edges).\n", Biddy_NodeNumberPlain(r1),Biddy_NodeNumberPlain(r2),Biddy_NodeNumber(r1),Biddy_NodeNumber(r2)); #endif #ifdef USE_CUDD printf("BDD for resulting function r1/r2 has %u/%u nodes (using complement edges).\n",Biddy_NodeNumber(r1),Biddy_NodeNumber(r2)); #endif #ifdef USE_BIDDY printf("Variable swaps performed so far: %u\n",Biddy_NodeTableSwapNumber()); #endif #ifdef USE_CUDD printf("Variable swaps performed so far: %.0f\n",Cudd_ReadSwapSteps(manager)); #endif #ifdef USA_YES printf("Order for USA: "); writeOrder(r1,usaCodes,usaOrder,usaSize); #endif #ifdef EUROPE_YES printf("Order for Europe: "); writeOrder(r2,europeCodes,europeOrder,europeSize); #endif #ifdef USE_BIDDY printf("E[x]it or [r]eport or "); #ifdef CONVERGE printf("Converging sifting "); #else printf("Sifting "); #endif #if (defined USA_YES) || (defined EUROPE_YES) printf("on [s]ystem or Sifting on function for"); #ifdef USA_YES printf(" [u]SA"); #endif #ifdef EUROPE_YES printf(" [e]urope"); #endif #endif printf(": "); if (!scanf("%s",userinput)) printf("ERROR\n"); #endif #ifdef USE_CUDD printf("E[x]it or [r]eport or "); #ifdef CONVERGE printf("Converging sifting "); #else printf("Sifting "); #endif printf("on [s]ystem: "); if (!scanf("%s",userinput)) printf("ERROR\n"); #endif } free(userinput); /* EXIT */ #ifdef USE_BIDDY Biddy_Exit(); #endif #ifdef USE_CUDD Cudd_RecursiveDeref(manager,r1); Cudd_RecursiveDeref(manager,r2); printf("CUDD: nodes with non-zero reference counts: %d\n",Cudd_CheckZeroRef(manager)); Cudd_Quit(manager); #endif return 0; }
void endc(void) { Cudd_Quit(mgr); free(vars); free(probs); }
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)); }
/**Function******************************************************************** Synopsis [Main program for ntr.] Description [Main program for ntr. Performs initialization. Reads command line options and network(s). Builds BDDs with reordering, and optionally does reachability analysis. Prints stats.] SideEffects [None] SeeAlso [] ******************************************************************************/ int main( int argc, char ** argv) { NtrOptions *option; /* options */ FILE *fp1; /* first network file pointer */ BnetNetwork *net1 = NULL; /* first network */ FILE *fp2; /* second network file pointer */ BnetNetwork *net2 = NULL; /* second network */ DdManager *dd; /* pointer to DD manager */ int exitval; /* return value of Cudd_CheckZeroRef */ int ok; /* overall return value from main() */ int result; /* stores the return value of functions */ BnetNode *node; /* auxiliary pointer to network node */ int i; /* loop index */ int j; /* loop index */ double *signatures; /* array of signatures */ int pr; /* verbosity level */ int reencoded; /* linear transformations attempted */ /* Initialize. */ option = mainInit(); ntrReadOptions(argc,argv,option); pr = option->verb; reencoded = option->reordering == CUDD_REORDER_LINEAR || option->reordering == CUDD_REORDER_LINEAR_CONVERGE || option->autoMethod == CUDD_REORDER_LINEAR || option->autoMethod == CUDD_REORDER_LINEAR_CONVERGE; /* Currently traversal requires global BDDs. Override whatever ** was specified for locGlob. */ if (option->traverse == TRUE || option->envelope == TRUE || option->scc == TRUE) { option->locGlob = BNET_GLOBAL_DD; } /* Read the first network... */ fp1 = open_file(option->file1, "r"); net1 = Bnet_ReadNetwork(fp1,pr); (void) fclose(fp1); if (net1 == NULL) { (void) fprintf(stderr,"Syntax error in %s.\n",option->file1); exit(2); } /* ... and optionally echo it to the standard output. */ if (pr > 2) { Bnet_PrintNetwork(net1); } /* Read the second network... */ if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0 || option->dontcares) { fp2 = open_file(option->file2, "r"); net2 = Bnet_ReadNetwork(fp2,pr); (void) fclose(fp2); if (net2 == NULL) { (void) fprintf(stderr,"Syntax error in %s.\n",option->file2); exit(2); } /* ... and optionally echo it to the standard output. */ if (pr > 2) { Bnet_PrintNetwork(net2); } } /* Initialize manager. We start with 0 variables, because ** Ntr_buildDDs will create new variables rather than using ** whatever already exists. */ dd = startCudd(option,net1->ninputs); if (dd == NULL) { exit(2); } /* Build the BDDs for the nodes of the first network. */ result = Ntr_buildDDs(net1,dd,option,NULL); if (result == 0) { exit(2); } /* Build the BDDs for the nodes of the second network if requested. */ if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0 || option->dontcares == TRUE) { char *nodesave = option->node; option->node = NULL; result = Ntr_buildDDs(net2,dd,option,net1); option->node = nodesave; if (result == 0) { exit(2); } } if (option->noBuild == TRUE) { Bnet_FreeNetwork(net1); if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0) { Bnet_FreeNetwork(net2); } freeOption(option); exit(0); } if (option->locGlob != BNET_LOCAL_DD) { /* Print the order before the final reordering. */ (void) printf("Order before final reordering\n"); result = Bnet_PrintOrder(net1,dd); if (result == 0) exit(2); } /* Perform final reordering */ if (option->zddtest == FALSE) { result = reorder(net1,dd,option); if (result == 0) exit(2); /* Print final order. */ if ((option->reordering != CUDD_REORDER_NONE || option->gaOnOff) && option->locGlob != BNET_LOCAL_DD) { (void) printf("New order\n"); result = Bnet_PrintOrder(net1,dd); if (result == 0) exit(2); } /* Print the re-encoded inputs. */ if (pr >= 1 && reencoded == 1) { for (i = 0; i < net1->npis; i++) { if (!st_lookup(net1->hash,net1->inputs[i],&node)) { exit(2); } (void) fprintf(stdout,"%s:",node->name); Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); } for (i = 0; i < net1->nlatches; i++) { if (!st_lookup(net1->hash,net1->latches[i][1],&node)) { exit(2); } (void) fprintf(stdout,"%s:",node->name); Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr); } if (pr >= 3) { result = Cudd_PrintLinear(dd); if (result == 0) exit(2); } } } /* Verify (combinational) equivalence. */ if (option->verify == TRUE) { result = Ntr_VerifyEquivalence(dd,net1,net2,option); if (result == 0) { (void) printf("Verification abnormally terminated\n"); exit(2); } else if (result == -1) { (void) printf("Combinational verification failed\n"); } else { (void) printf("Verification succeeded\n"); } } /* Traverse if requested and if the circuit is sequential. */ result = Ntr_Trav(dd,net1,option); if (result == 0) exit(2); /* Traverse with trasitive closure. */ result = Ntr_ClosureTrav(dd,net1,option); if (result == 0) exit(2); /* Compute outer envelope if requested and if the circuit is sequential. */ if (option->envelope == TRUE && net1->nlatches > 0) { NtrPartTR *T; T = Ntr_buildTR(dd,net1,option,option->image); result = Ntr_Envelope(dd,T,NULL,option); Ntr_freeTR(dd,T); } /* Compute SCCs if requested and if the circuit is sequential. */ result = Ntr_SCC(dd,net1,option); if (result == 0) exit(2); /* Test Constrain Decomposition. */ if (option->partition == TRUE && net1->nlatches > 0) { NtrPartTR *T; DdNode *product; DdNode **decomp; int sharingSize; T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO); decomp = Cudd_bddConstrainDecomp(dd,T->part[0]); if (decomp == NULL) exit(2); sharingSize = Cudd_SharingSize(decomp, Cudd_ReadSize(dd)); (void) fprintf(stdout, "Decomposition Size: %d components %d nodes\n", Cudd_ReadSize(dd), sharingSize); product = Cudd_ReadOne(dd); Cudd_Ref(product); for (i = 0; i < Cudd_ReadSize(dd); i++) { DdNode *intermediate = Cudd_bddAnd(dd, product, decomp[i]); if (intermediate == NULL) { exit(2); } Cudd_Ref(intermediate); Cudd_IterDerefBdd(dd, product); product = intermediate; } if (product != T->part[0]) exit(2); Cudd_IterDerefBdd(dd, product); for (i = 0; i < Cudd_ReadSize(dd); i++) { Cudd_IterDerefBdd(dd, decomp[i]); } FREE(decomp); Ntr_freeTR(dd,T); } /* Test char-to-vect conversion. */ result = Ntr_TestCharToVect(dd,net1,option); if (result == 0) exit(2); /* Test extraction of two-literal clauses. */ result = Ntr_TestTwoLiteralClauses(dd,net1,option); if (result == 0) exit(2); /* Test BDD minimization functions. */ result = Ntr_TestMinimization(dd,net1,net2,option); if (result == 0) exit(2); /* Test density-related functions. */ result = Ntr_TestDensity(dd,net1,option); if (result == 0) exit(2); /* Test decomposition functions. */ result = Ntr_TestDecomp(dd,net1,option); if (result == 0) exit(2); /* Test cofactor estimation functions. */ result = Ntr_TestCofactorEstimate(dd,net1,option); if (result == 0) exit(2); /* Test BDD clipping functions. */ result = Ntr_TestClipping(dd,net1,net2,option); if (result == 0) exit(2); /* Test BDD equivalence and containment under DC functions. */ result = Ntr_TestEquivAndContain(dd,net1,net2,option); if (result == 0) exit(2); /* Test BDD Cudd_bddClosestCube. */ result = Ntr_TestClosestCube(dd,net1,option); if (result == 0) exit(2); /* Test ZDDs if requested. */ if (option->stateOnly == FALSE && option->zddtest == TRUE) { result = Ntr_testZDD(dd,net1,option); if (result == 0) (void) fprintf(stdout,"ZDD test failed.\n"); result = Ntr_testISOP(dd,net1,option); if (result == 0) (void) fprintf(stdout,"ISOP test failed.\n"); } /* Compute maximum flow if requested and if the circuit is sequential. */ if (option->maxflow == TRUE && net1->nlatches > 0) { result = Ntr_maxflow(dd,net1,option); if (result == 0) (void) fprintf(stdout,"Maxflow computation failed.\n"); } /* Compute shortest paths if requested and if the circuit is sequential. */ if (option->shortPath != NTR_SHORT_NONE && net1->nlatches > 0) { result = Ntr_ShortestPaths(dd,net1,option); if (result == 0) (void) fprintf(stdout,"Shortest paths computation failed.\n"); } /* Compute output signatures if so requested. */ if (option->signatures) { (void) printf("Positive cofactor measures\n"); for (i = 0; i < net1->noutputs; i++) { if (!st_lookup(net1->hash,net1->outputs[i],&node)) { exit(2); } signatures = Cudd_CofMinterm(dd, node->dd); if (signatures) { (void) printf("%s:\n", node->name); for (j = 0; j < Cudd_ReadSize(dd); j++) { if((j%5 == 0)&&i) (void) printf("\n"); (void) printf("%5d: %-#8.4g ", j, signatures[j]); } (void) printf("\n"); FREE(signatures); } else { (void) printf("Signature computation failed.\n"); } } } /* Dump BDDs if so requested. */ if (option->bdddump && option->second == FALSE && option->density == FALSE && option->decomp == FALSE && option->cofest == FALSE && option->clip < 0.0 && option->scc == FALSE) { (void) printf("Dumping BDDs to %s\n", option->dumpfile); if (option->node != NULL) { if (!st_lookup(net1->hash,option->node,&node)) { exit(2); } result = Bnet_bddArrayDump(dd,net1,option->dumpfile,&(node->dd), &(node->name),1,option->dumpFmt); } else { result = Bnet_bddDump(dd, net1, option->dumpfile, option->dumpFmt, reencoded); } if (result != 1) { (void) printf("BDD dump failed.\n"); } } /* Print stats and clean up. */ if (pr >= 0) { result = Cudd_PrintInfo(dd,stdout); if (result != 1) { (void) printf("Cudd_PrintInfo failed.\n"); } } #if defined(DD_DEBUG) && !defined(DD_NO_DEATH_ROW) (void) fprintf(dd->err,"%d empty slots in death row\n", cuddTimesInDeathRow(dd,NULL)); #endif (void) printf("Final size: %ld\n", Cudd_ReadNodeCount(dd)); /* Dispose of node BDDs. */ node = net1->nodes; while (node != NULL) { if (node->dd != NULL && node->type != BNET_INPUT_NODE && node->type != BNET_PRESENT_STATE_NODE) { Cudd_IterDerefBdd(dd,node->dd); } node = node->next; } /* Dispose of network. */ Bnet_FreeNetwork(net1); /* Do the same cleanup for the second network if it was created. */ if (option->verify == TRUE || option->second == TRUE || option->clip > 0.0 || option->dontcares == TRUE) { node = net2->nodes; while (node != NULL) { if (node->dd != NULL && node->type != BNET_INPUT_NODE && node->type != BNET_PRESENT_STATE_NODE) { Cudd_IterDerefBdd(dd,node->dd); } node = node->next; } Bnet_FreeNetwork(net2); } /* Check reference counts: At this point we should have dereferenced ** everything we had, except in the case of re-encoding. */ exitval = Cudd_CheckZeroRef(dd); ok = exitval != 0; /* ok == 0 means O.K. */ if (exitval != 0) { (void) fflush(stdout); (void) fprintf(stderr, "%d non-zero DD reference counts after dereferencing\n", exitval); } #ifdef DD_DEBUG Cudd_CheckKeys(dd); #endif Cudd_Quit(dd); if (pr >= 0) (void) printf("total time = %s\n", util_print_time(util_cpu_time() - option->initialTime)); freeOption(option); if (pr >= 0) util_print_cpu_stats(stdout); #ifdef MNEMOSYNE mnem_writestats(); #endif exit(ok); /* NOTREACHED */ } /* end of main */
/**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 */
/**Function************************************************************* Synopsis [Deriving the functionality of the gates.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Mio_GateParseFormula( Mio_Gate_t * pGate ) { DdManager * dd = pGate->pLib->dd; char * pPinNames[100]; char * pPinNamesCopy[100]; Mio_Pin_t * pPin, ** ppPin; int nPins, iPin, i; // set the maximum delay of the gate; count pins pGate->dDelayMax = 0.0; nPins = 0; Mio_GateForEachPin( pGate, pPin ) { // set the maximum delay of the gate if ( pGate->dDelayMax < pPin->dDelayBlockMax ) pGate->dDelayMax = pPin->dDelayBlockMax; // count the pin nPins++; } // check for the gate with const function if ( nPins == 0 ) { if ( strcmp( pGate->pForm, MIO_STRING_CONST0 ) == 0 ) { pGate->bFunc = b0; pGate->pSop = Abc_SopRegister( pGate->pLib->pMmFlex, " 0\n" ); pGate->pLib->pGate0 = pGate; } else if ( strcmp( pGate->pForm, MIO_STRING_CONST1 ) == 0 ) { pGate->bFunc = b1; pGate->pSop = Abc_SopRegister( pGate->pLib->pMmFlex, " 1\n" ); pGate->pLib->pGate1 = pGate; } else { printf( "Cannot parse formula \"%s\" of gate \"%s\".\n", pGate->pForm, pGate->pName ); return 1; } Cudd_Ref( pGate->bFunc ); return 0; } // collect the names as they appear in the formula nPins = Mio_GateCollectNames( pGate->pForm, pPinNames ); if ( nPins == 0 ) { printf( "Cannot read formula \"%s\" of gate \"%s\".\n", pGate->pForm, pGate->pName ); return 1; } // set the number of inputs pGate->nInputs = nPins; // consider the case when all the pins have identical pin info if ( strcmp( pGate->pPins->pName, "*" ) == 0 ) { // get the topmost (generic) pin pPin = pGate->pPins; FREE( pPin->pName ); // create individual pins from the generic pin ppPin = &pPin->pNext; for ( i = 1; i < nPins; i++ ) { // get the new pin *ppPin = Mio_PinDup( pPin ); // set its name (*ppPin)->pName = pPinNames[i]; // prepare the next place in the list ppPin = &((*ppPin)->pNext); } *ppPin = NULL; // set the name of the topmost pin pPin->pName = pPinNames[0]; } else { // reorder the variable names to appear the save way as the pins iPin = 0; Mio_GateForEachPin( pGate, pPin ) { // find the pin with the name pPin->pName for ( i = 0; i < nPins; i++ ) { if ( pPinNames[i] && strcmp( pPinNames[i], pPin->pName ) == 0 ) { // free pPinNames[i] because it is already available as pPin->pName // setting pPinNames[i] to NULL is useful to make sure that // this name is not assigned to two pins in the list FREE( pPinNames[i] ); pPinNamesCopy[iPin++] = pPin->pName; break; } if ( i == nPins ) { printf( "Cannot find pin name \"%s\" in the formula \"%s\" of gate \"%s\".\n", pPin->pName, pGate->pForm, pGate->pName ); return 1; } } } // check for the remaining names for ( i = 0; i < nPins; i++ ) if ( pPinNames[i] ) { printf( "Name \"%s\" appears in the formula \"%s\" of gate \"%s\" but there is no such pin.\n", pPinNames[i], pGate->pForm, pGate->pName ); return 1; } // copy the names back memcpy( pPinNames, pPinNamesCopy, nPins * sizeof(char *) ); } // expand the manager if necessary if ( dd->size < nPins ) { Cudd_Quit( dd ); dd = Cudd_Init( nPins + 10, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); Cudd_zddVarsFromBddVars( dd, 2 ); } // derive the formula as the BDD pGate->bFunc = Parse_FormulaParser( stdout, pGate->pForm, nPins, 0, pPinNames, dd, dd->vars ); Cudd_Ref( pGate->bFunc ); // derive the cover (SOP) pGate->pSop = Abc_ConvertBddToSop( pGate->pLib->pMmFlex, dd, pGate->bFunc, pGate->bFunc, nPins, 0, pGate->pLib->vCube, -1 ); return 0; }
/** * @brief Basic test of long double and EPD minterm computation. * @return 0 if successful; -1 otherwise. */ static int testLdbl(int verbosity) { DdManager *dd; DdNode *f, *g; int i, ret; int const N = 12; /* half the number of variables */ long double cnt; dd = Cudd_Init(2*N, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!dd) { if (verbosity) { printf("initialization failed\n"); } return -1; } f = g = Cudd_ReadOne(dd); Cudd_Ref(f); Cudd_Ref(g); for (i = 0; i < N; i++) { DdNode *var1, *var2, *clause, *tmp; var1 = Cudd_bddIthVar(dd, i); var2 = Cudd_bddIthVar(dd, i+N); clause = Cudd_bddOr(dd, var1, var2); if (!clause) { Cudd_Quit(dd); return -1; } Cudd_Ref(clause); tmp = Cudd_bddAnd(dd, f, clause); if (!tmp) { Cudd_Quit(dd); return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, clause); Cudd_RecursiveDeref(dd, f); f = tmp; clause = Cudd_bddOr(dd, Cudd_Not(var1), Cudd_Not(var2)); if (!clause) { Cudd_Quit(dd); return -1; } Cudd_Ref(clause); tmp = Cudd_bddAnd(dd, g, clause); if (!tmp) { Cudd_Quit(dd); return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, clause); Cudd_RecursiveDeref(dd, g); g = tmp; } if (verbosity) { printf("f"); Cudd_PrintSummary(dd, f, 2*N, 0); } cnt = Cudd_LdblCountMinterm(dd, f, 2*N); if (verbosity) { printf("f has %Lg minterms\n", cnt); } if (verbosity) { printf("EPD count for f = "); ret = Cudd_EpdPrintMinterm(dd, f, 2*N); printf("\n"); if (!ret) { printf("problem with EPD\n"); } } Cudd_RecursiveDeref(dd, f); if (verbosity) { printf("g"); Cudd_PrintSummary(dd, g, 2*N, 0); } cnt = Cudd_LdblCountMinterm(dd, g, 2*N); if (verbosity) { printf("g has %Lg minterms\n", cnt); } if (verbosity) { printf("EPD count for g = "); ret = Cudd_EpdPrintMinterm(dd, g, 2*N); printf("\n"); if (!ret) { printf("problem with EPD\n"); } } Cudd_RecursiveDeref(dd, g); ret = Cudd_CheckZeroRef(dd); if (verbosity && ret != 0) { printf("%d non-zero references\n", ret); } Cudd_Quit(dd); return 0; }
/** * @brief Basic test of timeout handler. * * @details Sets a short timeout and then tries to build a function * with a large BDD. Strives to avoid leaking nodes. * * @return 0 if successful; -1 otherwise. */ static int testTimeout(int verbosity) { DdManager *dd; /* Declare these "volatile" to prevent clobbering by longjmp. */ DdNode * volatile f; DdNode * volatile clause = NULL; DdNode * var1, * var2; int i, ret, count; int const N = 20; /* half the number of variables in f */ unsigned long timeout = 100UL; /* in milliseconds */ jmp_buf timeoutEnv; dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); if (!dd) { if (verbosity) { printf("initialization failed\n"); } return -1; } /* Set up timeout handling. */ if (setjmp(timeoutEnv) > 0) { if (verbosity) { printf("caught timeout\n"); } /* The nodes of clause may be leaked if the timeout was * detected while conjoining the clause to f. We set * clause to NULL when it's not in use to be able to * detect this case. */ if (clause) Cudd_RecursiveDeref(dd, clause); goto finally; } (void) Cudd_RegisterTimeoutHandler(dd, timeoutHandler, (void *) &timeoutEnv); (void) Cudd_SetTimeLimit(dd, timeout); /* Try to build function. This is expected to run out of time. */ f = Cudd_ReadOne(dd); Cudd_Ref(f); for (i = 0; i < N; i++) { DdNode * tmp; var1 = Cudd_bddIthVar(dd, i); if (!var1) { if (verbosity) { printf("computation failed\n"); return -1; } } var2 = Cudd_bddIthVar(dd, i+N); if (!var2) { if (verbosity) { printf("computation failed\n"); return -1; } } clause = Cudd_bddOr(dd, var1, var2); if (!clause) { if (verbosity) { printf("computation failed\n"); } return -1; } Cudd_Ref(clause); tmp = Cudd_bddAnd(dd, f, clause); if (!tmp) { if (verbosity) { printf("computation failed\n"); } return -1; } Cudd_Ref(tmp); Cudd_RecursiveDeref(dd, clause); clause = NULL; Cudd_RecursiveDeref(dd, f); f = tmp; } if (verbosity > 1) { Cudd_bddPrintCover(dd, f, f); } finally: if (verbosity) { printf("so far"); Cudd_PrintSummary(dd, f, 2*N, 0); } count = 0; for (i = 0; i < N-1; i += 2) { var1 = Cudd_bddIthVar(dd, i); if (!var1) { printf("computation failed\n"); return -1; } var2 = Cudd_bddIthVar(dd, i+1); if (!var2) { printf("computation failed\n"); return -1; } clause = Cudd_bddOr(dd, var1, var2); if (!clause) { printf("computation failed\n"); return -1; } Cudd_Ref(clause); if (Cudd_bddLeq(dd, f, clause)) { count++; } Cudd_RecursiveDeref(dd, clause); } if (verbosity) { printf("f implies %d clauses\n", count); } Cudd_RecursiveDeref(dd, f); ret = Cudd_CheckZeroRef(dd); if (verbosity) { Cudd_PrintInfo(dd, stdout); if (ret != 0) { printf("%d non-zero references\n", ret); } } Cudd_Quit(dd); return 0; }
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)); }