void ndfs_blue_handle (void *arg, state_info_t *successor, transition_info_t *ti, int seen) { wctx_t *ctx = (wctx_t *) arg; alg_local_t *loc = ctx->local; nndfs_color_t color = nn_get_color (&loc->color_map, successor->ref); if (proviso == Proviso_Stack) ti->por_proviso = !nn_color_eq(color, NNCYAN); /** * The following lines bear little resemblance to the algorithms in the * respective papers (NNDFS / LNDFS), but we must store all non-red states * on the stack here, in order to calculate all-red correctly later. */ if ( ecd && nn_color_eq(color, NNCYAN) && (GBbuchiIsAccepting(ctx->model, state_info_state(ctx->state)) || GBbuchiIsAccepting(ctx->model, state_info_state(successor))) ) { /* Found cycle in blue search */ ndfs_report_cycle (ctx->run, ctx->model, loc->stack, successor); } else if ((loc->strat == Strat_LNDFS && !state_store_has_color(ctx->state->ref, GRED, loc->rec_bits)) || (loc->strat != Strat_LNDFS && !nn_color_eq(color, NNPINK))) { raw_data_t stack_loc = dfs_stack_push (loc->stack, NULL); state_info_serialize (successor, stack_loc); } (void) ti; (void) seen; }
static void ta_queue_state_normal (wctx_t *ctx, state_info_t *successor) { alg_global_t *sm = ctx->global; raw_data_t stack_loc = dfs_stack_push (sm->stack, NULL); state_info_serialize (successor, stack_loc); }
static void endfs_handle_all (void *arg, state_info_t *successor, transition_info_t *ti, int seen) { wctx_t *ctx = (wctx_t *) arg; alg_local_t *loc = ctx->local; raw_data_t stack_loc = dfs_stack_push (loc->stack, NULL); state_info_serialize (successor, stack_loc); ti->por_proviso = 0; (void) seen; }
void rec_ndfs_call (wctx_t *ctx, ref_t state) { cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; alg_global_t *sm = ctx->global; strategy_t rec_strat = get_strategy (ctx->run->shared->rec->alg); dfs_stack_push (sm->rec->local->stack, (int*)&state); cloc->counters.rec++; switch (rec_strat) { case Strat_ENDFS: endfs_blue (sm->rec->run, sm->rec); break; case Strat_LNDFS: lndfs_blue (sm->rec->run, sm->rec); break; case Strat_NDFS: ndfs_blue (sm->rec->run, sm->rec); break; default: Abort ("Invalid recursive strategy."); } }
static void tarjan_handle (void *arg, state_info_t *successor, transition_info_t *ti, int seen) { // parent state is ctx->state wctx_t *ctx = (wctx_t *) arg; alg_local_t *loc = ctx->local; raw_data_t *addr; hash32_t hash; int found; ctx->counters->trans++; // self-loop if (ctx->state->ref == successor->ref) return; // completed SCC if (state_store_has_color (successor->ref, SCC_STATE, 0)) return; hash = ref_hash (successor->ref); found = fset_find (loc->visited_states, &hash, &successor->ref, (void **)&addr, false); if (found) { // previously visited state ==> update lowlink state_info_deserialize (loc->target, *addr); if (loc->state_tarjan.lowlink > loc->target_tarjan.lowlink) loc->state_tarjan.lowlink = loc->target_tarjan.lowlink; } else { // unseen state ==> push to search_stack raw_data_t stack_loc = dfs_stack_push (loc->search_stack, NULL); state_info_serialize (successor, stack_loc); } (void) ti; (void) seen; }
static void endfs_handle_red (void *arg, state_info_t *successor, transition_info_t *ti, int seen) { wctx_t *ctx = (wctx_t *) arg; alg_local_t *loc = ctx->local; cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; int onstack; /* Find cycle back to the seed */ HREassert (cloc->accepting_depth > 0); size_t *level; onstack = ctx->state->ref == loc->seed->ref; if (!onstack) { onstack = fset_find (cloc->pink, NULL, &successor->ref, (void**)&level, false); HREassert (onstack != FSET_FULL); } if ( onstack && *level < cloc->accepting_depth ) ndfs_report_cycle (ctx, ctx->model, loc->stack, successor); /* Mark states dangerous if necessary */ if ( Strat_ENDFS == loc->strat && pins_state_is_accepting(ctx->model, state_info_state(successor)) && state_store_get_colors (successor->ref) != CRED ) state_store_try_color(successor->ref, GDANGEROUS, loc->rec_bits); if ( !onstack && state_store_get_colors (successor->ref) != CRED ) { raw_data_t stack_loc = dfs_stack_push (loc->stack, NULL); state_info_serialize (successor, stack_loc); } // check proviso if (PINS_POR && proviso == Proviso_CNDFS && cloc->successors == NONEC) { if (ti->por_proviso != 0) { // state already fully expanded cloc->successors = SRCINV; } else if (onstack) { // cycle check if (onstack) cloc->successors = CYCLE; } // avoid full exploration (proviso is enforced later in backtrack) ti->por_proviso = 1; // avoid full exploration } (void) seen; }
/** * move a search_stack state to the tarjan_stack */ static void move_tarjan (wctx_t *ctx, state_info_t *state, raw_data_t state_data) { alg_local_t *loc = ctx->local; raw_data_t *addr; hash32_t hash; int found; // add state to tarjan_stack raw_data_t tarjan_loc = dfs_stack_push (loc->tarjan_stack, NULL); state_info_serialize (state, tarjan_loc); // Update reference to the new stack hash = ref_hash (state->ref); found = fset_find (loc->visited_states, &hash, &state->ref, (void**) &addr, false); HREassert (*addr == state_data, "Wrong addr?"); HREassert (found, "Could not find key in set"); *addr = tarjan_loc; }
int main() { dfs_stack_t stack = dfs_stack_create (ARRAY_SIZE); size_t x; printf("Filling stack\n"); for (x = 0; x<NUM; x++) { int ar[ARRAY_SIZE]; ar[0] = x; ar[ARRAY_SIZE-1] = -x; dfs_stack_push(stack, ar); if (x%(NUM/FRAMES)==0) { printf("entered frame after: %zu - %zu\n", x, -x); dfs_stack_enter(stack); } } char tmp[256]; ssize_t tmpsz = sizeof tmp; printf("%s\n", dfs_stack_to_string(stack, tmp, &tmpsz)); for (x = 0; x<=FRAMES; x++) { int* ar = dfs_stack_peek_top(stack, x); printf("peek_top(%zu): %d - %d\n", x, ar[0], ar[ARRAY_SIZE-1]); } printf("Emptying stack stack\n"); for (x = 0; x<NUM; x++) { int* ar; if ((ar = dfs_stack_top(stack))==NULL) { dfs_stack_leave(stack); ar = dfs_stack_top(stack); printf("leave frame before: %d - %d\n", ar[0], ar[ARRAY_SIZE-1]); } ar = dfs_stack_pop(stack); } printf("DONE\n"); //pop(stack); dfs_stack_destroy(stack); return 0; }
static void ndfs_red_handle (void *arg, state_info_t *successor, transition_info_t *ti, int seen) { wctx_t *ctx = (wctx_t *) arg; alg_local_t *loc = ctx->local; nndfs_color_t color = nn_get_color(&loc->color_map, successor->ref); ti->por_proviso = 1; // only visit blue states to stay in reduced search space if (proviso != Proviso_None && !nn_color_eq(color, NNBLUE)) return; // only revisit blue states to determinize POR if ( nn_color_eq(color, NNCYAN) ) { /* Found cycle back to the stack */ ndfs_report_cycle (ctx->run, ctx->model, loc->stack, successor); } else if ( nn_color_eq(color, NNBLUE) && (loc->strat != Strat_LNDFS || !state_store_has_color(ctx->state->ref, GRED, loc->rec_bits)) ) { raw_data_t stack_loc = dfs_stack_push (loc->stack, NULL); state_info_serialize (successor, stack_loc); } (void) ti; (void) seen; }
static void endfs_handle_blue (void *arg, state_info_t *successor, transition_info_t *ti, int seen) { wctx_t *ctx = (wctx_t *) arg; alg_local_t *loc = ctx->local; cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; size_t *level; int onstack = fset_find (cloc->pink, NULL, &successor->ref, (void**)&level, false); HREassert (onstack != FSET_FULL); /** * The following lines bear little resemblance to the algorithms in the * respective papers (Evangelista et al./ Laarman et al.), but we must * store all non-red states on the stack in order to calculate * all-red correctly later. Red states are also stored as optimization. */ if ( ecd && onstack && *level < cloc->accepting_depth) { /* Found cycle in blue search */ ndfs_report_cycle (ctx, ctx->model, loc->stack, successor); } else if ( all_red || (!onstack && state_store_get_colors (successor->ref) != CBLUE) ) { raw_data_t stack_loc = dfs_stack_push (loc->stack, NULL); state_info_serialize (successor, stack_loc); } // check proviso if (PINS_POR && proviso == Proviso_CNDFS && cloc->successors == NONEC) { if (ti->por_proviso != 0) { // state already fully expanded cloc->successors = SRCINV; } else if (onstack) { // check cycle cloc->successors = CYCLE; } // avoid full exploration (proviso is enforced later in backtrack) ti->por_proviso = 1; } (void) seen; }
/* 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); } }