Ejemplo n.º 1
0
Archivo: pg.c Proyecto: Meijuh/ltsmin
/**
 * \brief Initialises the data structures for generating symbolic parity games.
 */
void
init_spg(model_t model)
{
    lts_type_t type = GBgetLTStype(model);
    var_pos = 0;
    var_type_no = 0;
    for(int i=0; i<N; i++)
    {
        //Printf(infoLong, "%d: %s (%d [%s])\n", i, lts_type_get_state_name(type, i), lts_type_get_state_typeno(type, i), lts_type_get_state_type(type, i));
#ifdef LTSMIN_PBES
        char* str1 = "string"; // for the PBES language module
#else
        char* str1 = "mu"; // for the mu-calculus PINS layer
#endif
        size_t strlen1 = strlen(str1);
        char* str2 = lts_type_get_state_type(type, i);
        size_t strlen2 = strlen(str2);
        if (strlen1==strlen2 && strncmp(str1, str2, strlen1)==0)
        {
            var_pos = i;
            var_type_no = lts_type_get_state_typeno(type, i);
            if (GBhaveMucalc()) {
                true_index = 0; // enforced by mucalc parser (mucalc-grammar.lemon / mucalc-syntax.c)
                false_index = 1;
            } else { // required for the PBES language module.
                true_index = pins_chunk_put (model, var_type_no, chunk_str("true"));
                false_index = pins_chunk_put (model, var_type_no, chunk_str("false"));
            }
        }
    }
    int p_len = 1;
    int proj[1] = {var_pos}; // position 0 encodes the variable
    variable_projection = vproj_create(domain, p_len, proj);

    num_vars = pins_chunk_count (model, var_type_no); // number of propositional variables
    if (GBhaveMucalc()) {
        num_vars = GBgetMucalcNodeCount(); // number of mu-calculus subformulae
    }
    Print(infoLong, "init_spg: var_type_no=%d, num_vars=%zu", var_type_no, num_vars);
    priority = RTmalloc(num_vars * sizeof(int)); // priority of variables
    player = RTmalloc(num_vars * sizeof(int)); // player of variables
    for(size_t i=0; i<num_vars; i++)
    {
        lts_type_t type = GBgetLTStype(model);
        int state_length = lts_type_get_state_length(type);
        // create dummy state with variable i:
        int state[state_length];
        for(int j=0; j < state_length; j++)
        {
            state[j] = 0;
        }
        state[var_pos] = i;
        int label = GBgetStateLabelLong(model, PG_PRIORITY, state); // priority
        priority[i] = label;
        if (label < min_priority) {
            min_priority = label;
        }
        if (label > max_priority) {
            max_priority = label;
        }
        //Print(infoLong, "  label %d (priority): %d", 0, label);
        label = GBgetStateLabelLong(model, PG_PLAYER, state); // player
        player[i] = label;
        //Print(infoLong, "  label %d (player): %d", 1, label);
    }
    true_states = vset_create(domain, -1, NULL);
    false_states = vset_create(domain, -1, NULL);
}
Ejemplo n.º 2
0
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);
}