void reach_sat_loop(reach_proc_t reach_proc, vset_t visited, bitvector_t *reach_groups, long *eg_count, long *next_count, long *guard_count) { bitvector_t groups[max_sat_levels]; int empty_groups[max_sat_levels]; vset_t old_vis = vset_create(domain, -1, NULL); vset_t prev_vis[nGrps]; for (int k = 0; k < max_sat_levels; k++) bitvector_create(&groups[k], nGrps); initialize_levels(groups, empty_groups, NULL, reach_groups); for (int i = 0; i < max_sat_levels; i++) prev_vis[i] = save_sat_levels?vset_create(domain, -1, NULL):NULL; while (!vset_equal(old_vis, visited)) { vset_copy(old_vis, visited); for (int k = 0; k < max_sat_levels; k++) { if (empty_groups[k]) continue; Warning(infoLong, "Saturating level: %d", k); reach_proc(visited, prev_vis[k], &groups[k], eg_count, next_count,guard_count); check_invariants(visited, -1); if (save_sat_levels) vset_copy(prev_vis[k], visited); } } for (int k = 0; k < max_sat_levels; k++) bitvector_free(&groups[k]); vset_destroy(old_vis); if (save_sat_levels) for (int i = 0; i < max_sat_levels; i++) vset_destroy(prev_vis[i]); }
int dm_copy (const matrix_t *src, matrix_t *tgt) { tgt->rows = src->rows; tgt->cols = src->cols; tgt->bits_per_row = src->bits_per_row; tgt->row_perm.data = NULL; tgt->row_perm.count = NULL; tgt->col_perm.data = NULL; tgt->col_perm.count = NULL; tgt->bits.data = NULL; if (dm_copy_header (&(src->row_perm), &(tgt->row_perm))) { dm_free (tgt); return -1; } if (dm_copy_header (&(src->col_perm), &(tgt->col_perm))) { dm_free (tgt); return -1; } if (src->rows != 0 && src->cols != 0) { if (bitvector_copy (&(tgt->bits), &(src->bits))) { dm_free (tgt); return -1; } } else { bitvector_create(&(tgt->bits), 0); } return 0; }
int dm_create (matrix_t *m, const int rows, const int cols) { DMDBG (printf ("rows, cols: %d, %d\n", rows, cols)); m->rows = rows; m->cols = cols; m->row_perm.data = NULL; m->col_perm.data = NULL; m->bits.data = NULL; // calculate the number of bits needed per row, dword aligned size_t row_size = (cols % 32) ? cols - (cols % 32) + 32 : cols; m->bits_per_row = row_size; if (bitvector_create (&(m->bits), rows * row_size)) { dm_free (m); return -1; } // create row header if (dm_create_header (&(m->row_perm), rows)) { dm_free (m); return -1; } // create column header if (dm_create_header (&(m->col_perm), cols)) { dm_free (m); return -1; } return 0; }
void ndfs_local_setup (run_t *run, wctx_t *ctx) { alg_local_t *loc = ctx->local; size_t local_bits = 2; int res = bitvector_create (&loc->color_map, local_bits<<dbs_size); HREassert (res != -1, "Failure to allocate a color_map bitvector."); if (all_red) res = bitvector_create (&loc->stackbits, MAX_STACK); HREassert (res != -1, "Failure to allocate a all_red bitvector."); loc->rec_bits = 0; loc->strat = get_strategy (run->alg); loc->seed = state_info_create (); size_t len = state_info_serialize_int_size (ctx->state); //state_info_add_simple (ctx->state, sizeof(int), &loc->bits); //state_info_add_simple (ctx->local->seed, sizeof(int), &loc->seed_bits); loc->stack = dfs_stack_create (len); }
int test_create_destroy() { printf("test_create_destroy()... ");fflush(NULL); cbitvector a = NULL; a = bitvector_create(); if (a == NULL) { printf("\nERROR in test_create_destroy() creation seems to have failed\n"); return 1; } bitvector_destroy(&a); if (a != NULL) { printf("\nERROR in test_create_destroy() destruction seems to have failed\n"); return 1; } printf("success\n"); return 0; }
int main (void) { bitvector_t b1; bitvector_t b2; bitvector_create (&b1, 20); user_bitvector_print (&b1); bitvector_set (&b1, 4); user_bitvector_print (&b1); bitvector_copy (&b2, &b1); bitvector_unset (&b1, 4); user_bitvector_print (&b1); user_bitvector_print (&b2); // test is_empty printf ("is_empty b1? %c (should be t)\n", bitvector_is_empty(&b1)?'t':'f'); printf ("is_empty b2? %c (should be f)\n", bitvector_is_empty(&b2)?'t':'f'); // set even/odd bits in b1/b2 for(int i=0; i<20; ++i) { if (i%2) { bitvector_set(&b1,i); } else { bitvector_set(&b2,i); } } // print before union printf ("before union\n"); user_bitvector_print (&b1); user_bitvector_print (&b2); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); printf ("union\n"); bitvector_union(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after union user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("intersect\n"); bitvector_intersect(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after intersection user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("invert b1\n"); bitvector_invert(&b1); // print after inversion user_bitvector_print (&b1); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); bitvector_free (&b2); bitvector_free (&b1); matrix_t m1; matrix_t m2; dm_create (&m1, 10, 10); print_matrix (&m1); printf ("dm_set(4,4)\n"); dm_set (&m1, 4, 4); print_matrix (&m1); printf ("dm_unset(4,4)\n"); dm_unset (&m1, 4, 4); print_matrix (&m1); printf ("test shift permutation (3,4,5)(6,7)\n"); printf ("before\n"); dm_set (&m1, 3, 3); dm_set (&m1, 4, 4); dm_set (&m1, 5, 5); dm_set (&m1, 6, 6); dm_set (&m1, 7, 7); print_matrix (&m1); printf ("after\n"); // create permutation_group, apply permutation_group_t o1; dm_create_permutation_group (&o1, 2, NULL); dm_add_to_permutation_group (&o1, 3); dm_add_to_permutation_group (&o1, 4); dm_add_to_permutation_group (&o1, 5); dm_close_group (&o1); dm_add_to_permutation_group (&o1, 6); dm_add_to_permutation_group (&o1, 7); dm_permute_cols (&m1, &o1); print_matrix (&m1); dm_free_permutation_group (&o1); printf ("swap cols 6,7\n"); dm_swap_cols (&m1, 6, 7); print_matrix (&m1); printf ("swap rows 6,7\n"); dm_swap_rows (&m1, 6, 7); print_matrix (&m1); printf ("copy\n"); dm_create(&m2, dm_nrows(&m1), dm_ncols(&m1)); dm_copy (&m1, &m2); // TODO: needs some more work print_matrix (&m2); dm_sort_rows (&m1, &min_row_first); print_matrix (&m1); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("to nub rows added & resorted\n"); dm_set (&m1, 7, 3); dm_set (&m1, 8, 4); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); printf ("flatten \n"); dm_flatten (&m1); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("nub sorted\n"); //dm_nub_rows (&m1, &eq_rows, NULL); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); /* * printf("again, now to test row order & nub idx\n"); dm_free(&m1); * dm_create(&m1, 10, 10); dm_set(&m1, 0,0); dm_set(&m1, 1,0); * dm_set(&m1, 2,3); dm_set(&m1, 3,3); print_matrix(&m1); * * printf("nub sorted\n"); * * dm_nub_rows(&m1); * * print_matrix(&m1); * * dm_print_perm(&(m1.row_perm)); */ printf ("optimize sorted\n"); dm_set (&m1, 0, 7); dm_set (&m1, 1, 6); dm_set (&m1, 3, 9); printf ("before\n"); print_matrix (&m1); dm_optimize (&m1); printf ("after\n"); print_matrix (&m1); printf ("resorted\n"); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); /* dm_nub_cols(&m1); dm_ungroup_rows(&m1); dm_ungroup_cols(&m1); print_matrix (&m1); */ // get bitvector from matrix text bitvector_create (&b1, 6); bitvector_create (&b2, 10); printf ("bitvector of row 0\n"); user_bitvector_print (&b2); printf ("bitvector of col 8\n"); user_bitvector_print (&b1); bitvector_free (&b2); bitvector_free (&b1); printf ("count test\n"); for (int i = 0; i < dm_nrows (&m1); i++) printf ("ones in row %d: %d\n", i, dm_ones_in_row (&m1, i)); for (int i = 0; i < dm_ncols (&m1); i++) printf ("ones in col %d: %d\n", i, dm_ones_in_col (&m1, i)); printf ("iterator test\n"); dm_row_iterator_t mx; dm_col_iterator_t my; for (int i = 0; i < dm_nrows (&m1); i++) { printf ("iterator row: %d\n", i); dm_create_row_iterator (&mx, &m1, i); int r; while ((r = dm_row_next (&mx)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } for (int i = 0; i < dm_ncols (&m1); i++) { printf ("iterator col: %d\n", i); dm_create_col_iterator (&my, &m1, i); int r; while ((r = dm_col_next (&my)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } printf ("projection test\n"); int s0[10]; int src[10]; int prj[2]; int tgt[10]; // initialize for (int i = 0; i < 10; i++) { s0[i] = -i; src[i] = i; } // do projection int prj_n = dm_project_vector (&m1, 0, src, prj); // print projection printf ("projection:"); for (int i = 0; i < prj_n; i++) { printf (" %d", prj[i]); } printf ("\n"); printf ("expansion test\n"); // do expansion int exp_n = dm_expand_vector (&m1, 0, s0, prj, tgt); (void)exp_n; // print expansion printf ("expansion:"); for (int i = 0; i < 10; i++) { printf (" %d", tgt[i]); } printf ("\n"); // subsumption printf ("subsumption test:\n"); dm_swap_rows (&m1, 0, 3); dm_swap_rows (&m1, 1, 2); dm_flatten (&m1); print_matrix (&m1); dm_subsume_rows (&m1, &eq_rows, NULL); printf ("after subsumption:\n"); print_matrix (&m1); printf ("\n"); printf ("after ungrouping:\n"); dm_ungroup_rows (&m1); print_matrix (&m1); printf ("\n"); printf ("column sort test:\n"); dm_flatten (&m1); printf ("max col first:\n"); dm_sort_cols (&m1, &max_col_first); print_matrix (&m1); printf ("min col first:\n"); dm_sort_cols (&m1, &min_col_first); print_matrix (&m1); printf ("nub columns test:\n"); dm_set (&m1, 0, 1); dm_set (&m1, 3, 1); dm_set (&m1, 3, 4); dm_set (&m1, 3, 5); dm_sort_cols (&m1, &max_col_first); // dm_flatten(&m1); printf ("max col first:\n"); print_matrix (&m1); //printf ("subsume columns:\n"); //dm_subsume_cols (&m1, &eq_cols, NULL); //dm_subsume_rows (&m1, &eq_rows, NULL); print_matrix (&m1); printf ("column permutation:\n"); dm_print_perm (&(m1.col_perm)); printf ("optimize columns:\n"); dm_optimize (&m1); print_matrix (&m1); //printf ("ungroup columns:\n"); //dm_ungroup_cols (&m1); //print_matrix (&m1); //printf ("all permutations:\n"); //dm_set (&m1, 0, 9); //dm_nub_cols(&m1, &eq_cols, NULL); //print_matrix (&m1); //dm_all_perm (&m1); dm_free (&m2); dm_free (&m1); return 0; }
static void initialize_levels(bitvector_t *groups, int *empty_groups, int *back, bitvector_t *reach_groups) { int level[nGrps]; // groups: i = 0 .. nGrps - 1 // vars : j = 0 .. N - 1 // level[i] = first '+' in row (highest in BDD) of group i // recast 0 .. N - 1 down to equal groups 0 .. (N - 1) / sat_granularity for (int i = 0; i < nGrps; i++) { level[i] = -1; for (int j = 0; j < N; j++) { if (dm_is_set(GBgetDMInfo(model), i, j)) { level[i] = (N - j - 1) / sat_granularity; break; } } if (level[i] == -1) level[i] = 0; } for (int i = 0; i < nGrps; i++) bitvector_set(&groups[level[i]], i); // Limit the bit vectors to the groups we are interested in and establish // which saturation levels are not used. for (int k = 0; k < max_sat_levels; k++) { bitvector_intersect(&groups[k], reach_groups); empty_groups[k] = bitvector_is_empty(&groups[k]); } if (back == NULL) return; // back[k] = last + in any group of level k bitvector_t level_matrix[max_sat_levels]; for (int k = 0; k < max_sat_levels; k++) { bitvector_create(&level_matrix[k], N); back[k] = max_sat_levels; } for (int i = 0; i < nGrps; i++) { dm_row_union(&level_matrix[level[i]], GBgetDMInfo(model), i); } for (int k = 0; k < max_sat_levels; k++) { for (int j = 0; j < k; j++) { bitvector_t temp; int empty; bitvector_copy(&temp, &level_matrix[j]); bitvector_intersect(&temp, &level_matrix[k]); empty = bitvector_is_empty(&temp); bitvector_free(&temp); if (!empty) if (j < back[k]) back[k] = j; } if (back[k] == max_sat_levels && !bitvector_is_empty(&level_matrix[k])) back[k] = k + 1; } for (int k = 0; k < max_sat_levels; k++) bitvector_free(&level_matrix[k]); }
static void actual_main(void *arg) #endif { int argc = ((struct args_t*)arg)->argc; char **argv = ((struct args_t*)arg)->argv; /* initialize HRE */ HREinitBegin(argv[0]); HREaddOptions(options,"Perform a symbolic reachability analysis of <model>\n" "The optional output of this analysis is an ETF " "representation of the input\n\nOptions"); lts_lib_setup(); // add options for LTS library HREinitStart(&argc,&argv,1,2,files,"<model> [<etf>]"); /* initialize HRE on other workers */ init_hre(HREglobal()); /* check for unsupported options */ if (PINS_POR != PINS_POR_NONE) Abort("Partial-order reduction and symbolic model checking are not compatible."); if (inhibit_matrix != NULL && sat_strategy != NO_SAT) Abort("Maximal progress is incompatibale with saturation."); if (files[1] != NULL) { char *ext = strrchr(files[1], '.'); if (ext == NULL || ext == files[1]) { Abort("Output filename has no extension!"); } if (strcasecmp(ext, ".etf") != 0) { // not ETF if (!(vset_default_domain == VSET_Sylvan && strcasecmp(ext, ".bdd") == 0) && !(vset_default_domain == VSET_LDDmc && strcasecmp(ext, ".ldd") == 0)) { Abort("Only supported output formats are ETF, BDD (with --vset=sylvan) and LDD (with --vset=lddmc)"); } if (PINS_USE_GUARDS) { Abort("Exporting symbolic state space not comptabile with " "guard-splitting"); } } } #ifdef HAVE_SYLVAN if (!USE_PARALLELISM) { if (strategy == PAR_P) { strategy = BFS_P; Print(info, "Front-end not thread-safe; using --order=bfs-prev instead of --order=par-prev."); } else if (strategy == PAR) { strategy = BFS; Print(info, "Front-end not thread-safe; using --order=bfs instead of --order=par."); } } #endif /* turn off Lace for now to speed up while not using parallelism */ lace_suspend(); /* initialize the model and PINS wrappers */ init_model(files[0]); /* initialize action detection */ act_label = lts_type_find_edge_label_prefix (ltstype, LTSMIN_EDGE_TYPE_ACTION_PREFIX); if (act_label != -1) action_typeno = lts_type_get_edge_label_typeno(ltstype, act_label); if (act_detect != NULL) init_action_detection(); bitvector_create(&state_label_used, sLbls); if (inv_detect != NULL) init_invariant_detection(); else if (PINS_USE_GUARDS) { for (int i = 0; i < nGuards; i++) { bitvector_set(&state_label_used, i); } } init_maxsum(ltstype); /* turn on Lace again (for Sylvan) */ if (vset_default_domain==VSET_Sylvan || vset_default_domain==VSET_LDDmc) { lace_resume(); } if (next_union) vset_next_fn = vset_next_union_src; init_domain(VSET_IMPL_AUTOSELECT); vset_t initial = vset_create(domain, -1, NULL); int *src = RTmalloc (sizeof(int[N])); GBgetInitialState(model, src); vset_add(initial, src); Print(infoShort, "got initial state"); /* if writing .dot files, open directory first */ if (dot_dir != NULL) { DIR* dir = opendir(dot_dir); if (dir) { closedir(dir); } else if (ENOENT == errno) { Abort("Option 'dot-dir': directory '%s' does not exist", dot_dir); } else { Abort("Option 'dot-dir': failed opening directory '%s'", dot_dir); } } if (vset_dir != NULL) { DIR *dir = opendir(vset_dir); if (dir) { closedir(dir); } else if (errno == ENOENT) { Abort("Option 'save-levels': directory '%s' does not exist", vset_dir); } else { Abort("Option 'save-levels': failed opening directory '%s'", vset_dir); } } init_mu_calculus(); /* determine if we need to generate a symbolic parity game */ #ifdef LTSMIN_PBES bool spg = true; #else bool spg = GBhaveMucalc() ? true : false; #endif /* if spg, then initialize labeling stuff before reachability */ if (spg) { Print(infoShort, "Generating a Symbolic Parity Game (SPG)."); init_spg(model); } /* create timer */ reach_timer = RTcreateTimer(); /* fix level 0 */ visited = vset_create(domain, -1, NULL); vset_copy(visited, initial); /* check the invariants at level 0 */ check_invariants(visited, 0); /* run reachability */ run_reachability(visited, files[1]); /* report states */ final_stat_reporting(visited); /* save LTS */ if (files[1] != NULL) { char *ext = strrchr(files[1], '.'); if (strcasecmp(ext, ".etf") == 0) { do_output(files[1], visited); } else { // if not .etf, then the filename ends with .bdd or .ldd, symbolic LTS do_dd_output (initial, visited, files[1]); } } compute_maxsum(visited, domain); CHECK_MU(visited, src); if (max_mu_count > 0) { Print(info, "Mu-calculus peak nodes: %ld", max_mu_count); } /* optionally print counts of all group_next and group_explored sets */ final_final_stats_reporting (); if (spg) { // converting the LTS to a symbolic parity game, save and solve. lts_to_pg_solve (visited, src); } #ifdef HAVE_SYLVAN /* in case other Lace threads were still suspended... */ if (vset_default_domain!=VSET_Sylvan && vset_default_domain!=VSET_LDDmc) { lace_resume(); } else if (SYLVAN_STATS) { sylvan_stats_report(stderr); } #endif RTfree (src); GBExit(model); }