/** * \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); }
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); }