Beispiel #1
0
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;
}
Beispiel #2
0
/* 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);
        }
    }
}
Beispiel #3
0
static inline void
set_all_red2 (wctx_t *ctx, state_info_t *state)
{
    if (update_color(ctx, state->ref, CRED, 1)) {
        ctx->local->counters.allred++;
        if ( pins_state_is_accepting(ctx->model, state_info_state(state)) )
            ctx->local->counters.accepting++; /* count accepting states */
    } else {
        ctx->local->red.allred++;
    }
}
Beispiel #4
0
static inline int
on_stack_accepting_up (wctx_t *ctx, int *accepting)
{
    cndfs_alg_local_t      *cloc = (cndfs_alg_local_t *) ctx->local;
    size_t                 *depth;
    int                     on_stack;
    on_stack = fset_find (cloc->pink, NULL, &ctx->state->ref, (void**)&depth, true);
    HREassert (on_stack != FSET_FULL);
    if (!on_stack) {
        *accepting = pins_state_is_accepting(ctx->model, state_info_state(ctx->state)) != 0;
        Debug ("Added state %zu %s with depth %zu accepting depth",
               ctx->state->ref, (*accepting ? "(accepting)" : ""), cloc->accepting_depth);
        *depth = cloc->accepting_depth; // write currect accepting depth
        cloc->accepting_depth += *accepting;
    }
    return on_stack;
}
Beispiel #5
0
static void
ta_handle (void *arg, state_info_t *successor, transition_info_t *ti, int seen)
{
    wctx_t             *ctx = (wctx_t*) arg;
    ta_alg_shared_t    *shared = (ta_alg_shared_t *) ctx->run->shared;
    alg_local_t        *loc = ctx->local;
    ta_alg_local_t     *ta_loc = (ta_alg_local_t *) ctx->local;
    ta_alg_global_t    *sm = (ta_alg_global_t *) ctx->global;
    ta_loc->done = 0;
    ta_loc->subsumes = 0; // if a successor subsumes one in the set, it cannot be subsumed itself (see invariant paper)
    ta_loc->work = 0;
    ta_loc->added_at = LM_NULL_LOC;
    ta_loc->last = LM_NULL_LOC;
    ta_loc->successor = successor;
    lm_lock (shared->lmap, successor->ref);
    lm_loc_t last = lm_iterate (shared->lmap, successor->ref, ta_covered, ctx);
    if (!ta_loc->done) {
        last = (LM_NULL_LOC == ta_loc->last ? last : ta_loc->last);
        sm->lloc = lm_insert_from (shared->lmap, successor->ref,
                                   successor->lattice, TA_WAITING, &last);
        lm_unlock (shared->lmap, successor->ref);
        ta_loc->counters.inserts++;
        if (0) { // quite costly: flops
            if (ta_loc->work > 0)
                statistics_unrecord (&ta_loc->counters.lattice_ratio, ta_loc->work);
            statistics_record (&ta_loc->counters.lattice_ratio, ta_loc->work+1);
        }
        ta_queue_state (ctx, successor);
        ta_loc->counters.updates += LM_NULL_LOC != ta_loc->last;
        loc->counters.level_size++;
    } else {
        lm_unlock (shared->lmap, successor->ref);
    }
    action_detect (ctx, ti, successor);
    if (EXPECT_FALSE(loc->lts != NULL)) {
        int             src = ctx->counters->explored;
        int            *tgt = state_info_state (successor);
        int             tgt_owner = ref_hash (successor->ref) % W;
        lts_write_edge (loc->lts, ctx->id, &src, tgt_owner, tgt, ti->labels);
    }
    ctx->counters->trans++;
    (void) seen;
}
Beispiel #6
0
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;
}
Beispiel #7
0
void
timed_run (run_t *run, wctx_t *ctx)
{
    transition_info_t       ti = GB_NO_TRANSITION;

    if ( Strat_PBFS & strategy[0] ) {
        ta_queue_state = pbfs_queue_state;
    }

    if (0 == ctx->id) { // only w1 receives load, as it is propagated later
        if ( Strat_PBFS & strategy[0] ) {
            if (ctx->local->lts != NULL) {
                state_data_t    initial = state_info_state(ctx->initial);
                int             src_owner = ref_hash(ctx->initial->ref) % W;
                lts_write_init (ctx->local->lts, src_owner, initial);
            }
        }
        ta_handle (ctx, ctx->initial, &ti, 0);
        ctx->counters->trans = 0; //reset trans count
    }

    HREbarrier (HREglobal());

    switch (get_strategy(run->alg)) {
        case Strat_TA_PBFS:
            ta_pbfs (ctx);
            break;
        case Strat_TA_SBFS:
            ta_sbfs (ctx);
            break;
        case Strat_TA_BFS:
            ta_bfs (ctx);
            break;
        case Strat_TA_DFS:
            ta_dfs (ctx);
            break;
        default: Abort ("Missing case in timed_run");
    }
}
Beispiel #8
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," ");
    }
}
Beispiel #9
0
/* 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);
    }
}