void lts_to_pg_solve (vset_t visited, int* src) { // converting the LTS to a symbolic parity game, save and solve. vset_destroy (true_states); vset_destroy (false_states); if (pg_output || pgsolve_flag) { rt_timer_t compute_pg_timer = RTcreateTimer (); RTstartTimer (compute_pg_timer); parity_game* g = compute_symbolic_parity_game (visited, src); RTstopTimer (compute_pg_timer); RTprintTimer (info, compute_pg_timer, "computing symbolic parity game took"); if (pg_output) { Print(info, "Writing symbolic parity game to %s.", pg_output); FILE* f = fopen (pg_output, "w"); spg_save (f, g); fclose (f); } if (pgsolve_flag) { spgsolver_options* spg_options = spg_get_solver_options (); rt_timer_t pgsolve_timer = RTcreateTimer (); Print(info, "Solving symbolic parity game for player %d.", spg_options->player); RTstartTimer (pgsolve_timer); recursive_result strategy; parity_game* copy = NULL; if (spg_options->check_strategy) { copy = spg_copy (g); } _Bool result = spg_solve (g, &strategy, spg_options); Print(info, " "); Print(info, "The result is: %s.", result ? "true" : "false"); RTstopTimer (pgsolve_timer); Print(info, " "); RTprintTimer (info, reach_timer, "reachability took "); RTprintTimer (info, compute_pg_timer, "computing game took "); RTprintTimer (info, pgsolve_timer, "solving took "); if (spg_options->strategy_filename != NULL) { Print(info, "Writing winning strategies to %s", spg_options->strategy_filename); FILE* f = fopen (spg_options->strategy_filename, "w"); result_save (f, strategy); fclose (f); } if (spg_options->check_strategy) { check_strategy (copy, &strategy, spg_options->player, result, 10); } } else { spg_destroy (g); } } if (player != 0) { RTfree (player); RTfree (priority); } }
void trc_find_and_write (trc_env_t *env, char *trc_output, ref_t dst_idx, int level, ref_t *parent_ofs, ref_t start_idx) { rt_timer_t timer = RTcreateTimer (); RTstartTimer (timer); /* Other workers may have influenced the trace, writing to parent_ofs. * we artificially limit the length of the trace to 10 times that of the * found one */ size_t max_length = level * 10; ref_t *trace = RTmalloc(sizeof(ref_t) * max_length); if (trace == NULL) Abort("unable to allocate memory for trace"); int i = max_length - 1; ref_t curr_idx = dst_idx; trace[i] = curr_idx; while(curr_idx != start_idx) { i--; if (i < 0) Abort("Trace length 10x longer than initially found trace. Giving up."); curr_idx = parent_ofs[curr_idx]; trace[i] = curr_idx; } Warning (info, "reconstructed trace length: %zu", max_length - i); RTstopTimer (timer); RTprintTimer (info, timer, "constructing the trace took"); trc_write_trace (env, trc_output, &trace[i], max_length - i); RTfree (trace); }
void do_output(char *etf_output, vset_t visited) { FILE *tbl_file; rt_timer_t timer = RTcreateTimer(); RTstartTimer(timer); Warning(info, "writing output"); tbl_file = fopen(etf_output, "w"); if (tbl_file == NULL) AbortCall("could not open %s", etf_output); if (vdom_separates_rw(domain)) { /* * This part is necessary because the ETF format does not yet support * read, write and copy. This part should thus be removed when ETF is * extended. */ Warning(info, "Note: ETF format does not yet support read, write and copy."); transitions_short = GBgetTransitionsShort; RTfree (r_projs); RTfree (w_projs); w_projs = r_projs = (ci_list **) dm_rows_to_idx_table (GBgetDMInfo(model)); for (int i = 0; i < nGrps; i++) { vset_destroy(group_explored[i]); group_explored[i] = vset_create(domain, r_projs[i]->count, r_projs[i]->data); vset_project(group_explored[i], visited); } } output_init(tbl_file); output_trans(tbl_file); output_lbls(tbl_file, visited); output_types(tbl_file); fclose(tbl_file); RTstopTimer(timer); RTprintTimer(info, timer, "writing output took"); }
void final_stat_reporting(vset_t visited) { RTprintTimer(info, reach_timer, "reachability took"); if (dlk_detect) Warning(info, "No deadlocks found"); if (act_detect != NULL) { Warning(info, "%d different actions with prefix \"%s\" are found", ErrorActions, act_detect); } long n_count; Print(infoShort, "counting visited states..."); rt_timer_t t = RTcreateTimer(); RTstartTimer(t); char states[128]; long double e_count; int digs = vset_count_fn(visited, &n_count, &e_count); snprintf(states, 128, "%.*Lg", digs, e_count); RTstopTimer(t); RTprintTimer(infoShort, t, "counting took"); RTresetTimer(t); int is_precise = strstr(states, "e") == NULL && strstr(states, "inf") == NULL; Print(infoShort, "state space has%s %s states, %ld nodes", precise && is_precise ? " precisely" : "", states, n_count); if (!is_precise && precise) { if (vdom_supports_precise_counting(domain)) { Print(infoShort, "counting visited states precisely..."); RTstartTimer(t); bn_int_t e_count; vset_count_precise(visited, n_count, &e_count); RTstopTimer(t); RTprintTimer(infoShort, t, "counting took"); size_t len = bn_strlen(&e_count); char e_str[len]; bn_int2string(e_str, len, &e_count); bn_clear(&e_count); Print(infoShort, "state space has precisely %s states (%zu digits)", e_str, strlen(e_str)); } else Warning(info, "vset implementation does not support precise counting"); } RTdeleteTimer(t); if (log_active (infoLong) || peak_nodes) { log_t l; if (peak_nodes) l = info; else l = infoLong; if (max_lev_count == 0) { Print(l, "( %ld final BDD nodes; %ld peak nodes )", n_count, max_vis_count); } else { Print(l, "( %ld final BDD nodes; %ld peak nodes; %ld peak nodes per level )", n_count, max_vis_count, max_lev_count); } if (log_active (debug)) { Debug("( peak transition cache: %ld nodes; peak group explored: " "%ld nodes )\n", max_trans_count, max_grp_count); } } }
int main (int argc, char **argv) { dlts_t lts; rt_timer_t timer; int oldN, oldM, tauN, tauM, N, M, i, j; char *files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Perform a distributed cycle elimination on the input.\n\nOptions"); lts_lib_setup(); HREselectMPI(); HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]"); MPI_Comm_size (MPI_COMM_WORLD, &nodes); MPI_Comm_rank (MPI_COMM_WORLD, &me); timer = RTcreateTimer (); if (me == 0) Warning (info, "(tau)SCC elimination"); if (me == 0) RTstartTimer (timer); MPI_Barrier (MPI_COMM_WORLD); lts = dlts_read(MPI_COMM_WORLD,files[0]); oldN = lts->state_count[me]; oldM = 0; for (i = 0; i < lts->segment_count; i++) oldM += lts->transition_count[me][i]; MPI_Reduce (&oldN, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&oldM, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); if (me == 0) { oldN = i; oldM = j; Warning (info, "%d states and %d transitions", oldN, oldM); RTstopTimer (timer); RTprintTimer (info, timer, "***** reading the LTS took"); RTresetTimer (timer); RTstartTimer (timer); } MPI_Barrier (MPI_COMM_WORLD); switch (action) { case SCC_COLOR: dlts_elim_tauscc_colours (lts); break; case SCC_GROUP: if (!dlts_elim_tauscc_groups (lts)) { if (me == 0) Abort("cannot get it small enough!"); } MPI_Barrier (MPI_COMM_WORLD); break; default: if (me == 0) Abort("bad action %d", action); MPI_Barrier (MPI_COMM_WORLD); } MPI_Barrier (lts->comm); if (me == 0) { RTstopTimer (timer); RTprintTimer (info, timer, "***** SCC reduction took"); RTresetTimer (timer); RTstartTimer (timer); } // statistics... N = lts->state_count[me]; M = 0; for (i = 0; i < lts->segment_count; i++) M += lts->transition_count[me][i]; MPI_Reduce (&N, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&M, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); if (me == 0) { Warning (info, "LTS initial:%10d states and %10d transitions", oldN, oldM); Warning (info, "LTS reduced:%10d states [%3.3f] and %10d [%3.3f] transitions", i, 100 * i / (float)oldN, j, 100 * j / (float)oldM); } N = Nfinal + Nleft + Nhooked; M = Mfinal + Mhooked; MPI_Reduce (&N, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&M, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); tauN = i; tauM = j; N = Nfinal + Nleft; M = Mfinal; MPI_Reduce (&N, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&M, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); if (me == 0) { Warning (info, "TAU initial:%10d states [%3.3f] and %10d [%3.3f] transitions", tauN, 100 * tauN / (float)oldN, tauM, 100 * tauM / (float)oldM); Warning (info, "TAU reduced:%10d states [%3.3f] and %10d [%3.3f] transitions", i, 100 * i / (float)tauN, j, 100 * j / (float)tauM); } if (files[1]) { if (me == 0) Warning (info, "NOW WRITING"); dlts_writedir (lts, files[1]); } // if (lts != NULL) dlts_free(lts); HREexit(HRE_EXIT_SUCCESS); }