/* NDFS dfs_blue */ void ndfs_blue (run_t *run, wctx_t *ctx) { alg_local_t *loc = ctx->local; transition_info_t ti = GB_NO_TRANSITION; ndfs_blue_handle (ctx, ctx->initial, &ti, 0); ctx->counters->trans = 0; //reset trans count while ( !run_is_stopped(run) ) { raw_data_t state_data = dfs_stack_top (loc->stack); if (NULL != state_data) { state_info_deserialize (ctx->state, state_data); nndfs_color_t color = nn_get_color (&loc->color_map, ctx->state->ref); if ( nn_color_eq(color, NNWHITE) ) { if (all_red) bitvector_set ( &loc->stackbits, ctx->counters->level_cur ); nn_set_color (&loc->color_map, ctx->state->ref, NNCYAN); ndfs_explore_state_blue (ctx); } else { if ( all_red && ctx->counters->level_cur != 0 && !nn_color_eq(color, NNPINK) ) bitvector_unset ( &loc->stackbits, ctx->counters->level_cur - 1); dfs_stack_pop (loc->stack); } } else { //backtrack if (0 == dfs_stack_nframes (loc->stack)) return; dfs_stack_leave (loc->stack); ctx->counters->level_cur--; state_data = dfs_stack_top (loc->stack); state_info_deserialize (loc->seed, state_data); if ( all_red && bitvector_is_set(&loc->stackbits, ctx->counters->level_cur) ) { /* exit if backtrack hits seed, leave stack the way it was */ nn_set_color (&loc->color_map, loc->seed->ref, NNPINK); loc->counters.allred++; if ( GBbuchiIsAccepting(ctx->model, state_info_state(loc->seed)) ) loc->counters.accepting++; } else if ( GBbuchiIsAccepting(ctx->model, state_info_state(loc->seed)) ) { /* call red DFS for accepting states */ ndfs_red (ctx, loc->seed->ref); nn_set_color (&loc->color_map, loc->seed->ref, NNPINK); } else { if (all_red && ctx->counters->level_cur > 0) bitvector_unset (&loc->stackbits, ctx->counters->level_cur - 1); nn_set_color (&loc->color_map, loc->seed->ref, NNBLUE); } dfs_stack_pop (loc->stack); } } }
static inline void set_proviso_stack (wctx_t* ctx, alg_local_t* loc, cndfs_alg_local_t* cloc) { switch (cloc->successors) { case NONEC: bitvector_set (&loc->stackbits, pred(ctx, NOCYCLE)); break; case CYCLE: bitvector_unset (&loc->stackbits, pred(ctx, NOCYCLE)); break; case SRCINV: bitvector_set (&loc->stackbits, pred(ctx, INVOL)); break; default: HREassert (false); } }
int dm_bitvector_col(bitvector_t *bv, const matrix_t *m, int col) { // check size if (bitvector_size (bv) != (size_t)dm_nrows (m)) return -1; // copy row for (int i = 0; i < dm_nrows (m); i++) { if (dm_is_set (m, i, col)) { bitvector_set(bv, i); } else { bitvector_unset(bv, i); } } return 0; }
void dm_unset (matrix_t *m, int row, int col) { // get permutation int rowp = m->row_perm.data[row].becomes; int colp = m->col_perm.data[col].becomes; // calculate bit number int bitnr = rowp * (m->bits_per_row) + colp; // counts if (bitvector_is_set (&(m->bits), bitnr)) { m->row_perm.count[rowp]--; m->col_perm.count[colp]--; } bitvector_unset (&(m->bits), bitnr); }
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; }
/* ENDFS dfs_blue */ void endfs_blue (run_t *run, wctx_t *ctx) { HREassert (ecd, "CNDFS's correctness depends crucially on ECD"); alg_local_t *loc = ctx->local; cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; transition_info_t ti = GB_NO_TRANSITION; uint32_t global_color; int accepting; cloc->successors = NONEC; endfs_handle_blue (ctx, ctx->initial, &ti, 0); ctx->counters->trans = 0; //reset trans count cloc->accepting_depth = 0; alg_global_t *sm = ctx->global; while ( !run_is_stopped(ctx->run) ) { raw_data_t state_data = dfs_stack_top (loc->stack); if (NULL != state_data) { state_info_deserialize (ctx->state, state_data); global_color = state_store_get_colors (ctx->state->ref); if (global_color < CBLUE && !on_stack_accepting_up(ctx, &accepting)) { if (global_color == CWHITE) update_color (ctx, ctx->state->ref, CCYAN, 0); if (all_red) bitvector_set (&loc->stackbits, cur(ctx,REDALL)); bitvector_unset (&loc->stackbits, cur(ctx,INVOL)); endfs_explore_state_blue (ctx); } else { if ( all_red && ctx->counters->level_cur != 0 && global_color != CRED ) bitvector_unset (&loc->stackbits, pred(ctx,REDALL)); dfs_stack_pop (loc->stack); } } else { //backtrack if (0 == dfs_stack_nframes(loc->stack)) break; dfs_stack_leave (loc->stack); ctx->counters->level_cur--; /* call red DFS for accepting states */ state_data = dfs_stack_top (loc->stack); state_info_deserialize (loc->seed, state_data); if (check_cndfs_proviso(ctx)) { reach_explore_all (ctx, loc->seed); continue; } accepting = pins_state_is_accepting(ctx->model, state_info_state(loc->seed)) != 0; /* Mark state GGREEN on backtrack */ update_color (ctx, loc->seed->ref, CBLUE, 1); if ( all_red && bitvector_is_set(&loc->stackbits, cur(ctx,REDALL)) ) { /* all successors are red */ //permute_trans (loc->permute, ctx->state, check, ctx); set_all_red2 (ctx, loc->seed); } else if ( accepting ) { sm->work = loc->seed->ref; endfs_red (ctx); if (Strat_ENDFS == loc->strat) endfs_handle_dangerous (ctx); else cndfs_handle_nonseed_accepting (ctx); sm->work = SIZE_MAX; } else if (all_red && ctx->counters->level_cur > 0 && state_store_get_colors (loc->seed->ref) != CRED) { /* unset the all-red flag (only for non-initial nodes) */ bitvector_unset (&loc->stackbits, pred(ctx,REDALL)); } accepting_down (ctx, loc->seed, accepting); dfs_stack_pop (loc->stack); } } HREassert (run_is_stopped(ctx->run) || fset_count(cloc->pink) == 0); // if the recursive strategy uses global bits (global pruning) // then do simple load balancing (only for the top-level strategy) if ( Strat_ENDFS == loc->strat && run == run->shared->top_level && (Strat_LTLG & sm->rec->local->strat) ) { endfs_lb (ctx); } if (global->exit_status == LTSMIN_EXIT_SUCCESS && ctx->id == 0) { Warning(info," "); Warning(info,"Empty product with LTL!"); Warning(info," "); } }
/* ENDFS dfs_red */ static void endfs_red (wctx_t *ctx) { alg_local_t *loc = ctx->local; cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; size_t seed_level = dfs_stack_nframes (loc->stack); int accepting = 0; int on_stack; size_t count = fset_count(cloc->pink); size_t *level; while ( !run_is_stopped(ctx->run) ) { raw_data_t state_data = dfs_stack_top (loc->stack); if (NULL != state_data) { state_info_deserialize (ctx->state, state_data); // seed is only state on both cyan and pink stack on_stack = ctx->state->ref == loc->seed->ref; if (!on_stack) { on_stack = fset_find (cloc->pink, NULL, &ctx->state->ref, (void**)&level, false); HREassert (on_stack != FSET_FULL); } if (!on_stack && state_store_get_colors(ctx->state->ref) != CRED) { on_stack_accepting_up (ctx, &accepting); //add to stack bitvector_unset (&loc->stackbits, cur(ctx,INVOL)); dfs_stack_push (cloc->in_stack, state_data); if ( Strat_CNDFS == loc->strat && ctx->state->ref != loc->seed->ref && accepting) dfs_stack_push (cloc->out_stack, state_data); endfs_explore_state_red (ctx); } else { if (seed_level == dfs_stack_nframes (loc->stack)) break; dfs_stack_pop (loc->stack); } } else { //backtrack dfs_stack_leave (loc->stack); ctx->counters->level_cur--; /* exit search if backtrack hits seed, leave stack the way it was */ if (seed_level == dfs_stack_nframes(loc->stack)) break; state_data = dfs_stack_top (loc->stack); state_info_deserialize (ctx->state, state_data); if (check_cndfs_proviso(ctx)) { reach_explore_all (ctx, ctx->state); continue; } accepting = pins_state_is_accepting (ctx->model, state_info_state(ctx->state)) != 0; accepting_down (ctx, ctx->state, accepting); dfs_stack_pop (loc->stack); } } if (!run_is_stopped(ctx->run)) { HREassert (fset_count(cloc->pink) == count); } }