コード例 #1
0
ファイル: sat.c プロジェクト: Meijuh/ltsmin
void
reach_sat_loop(reach_proc_t reach_proc, vset_t visited,
               bitvector_t *reach_groups, long *eg_count, long *next_count, long *guard_count)
{
    bitvector_t groups[max_sat_levels];
    int empty_groups[max_sat_levels];
    vset_t old_vis = vset_create(domain, -1, NULL);
    vset_t prev_vis[nGrps];

    for (int k = 0; k < max_sat_levels; k++)
        bitvector_create(&groups[k], nGrps);

    initialize_levels(groups, empty_groups, NULL, reach_groups);

    for (int i = 0; i < max_sat_levels; i++)
        prev_vis[i] = save_sat_levels?vset_create(domain, -1, NULL):NULL;

    while (!vset_equal(old_vis, visited)) {
        vset_copy(old_vis, visited);
        for (int k = 0; k < max_sat_levels; k++) {
            if (empty_groups[k]) continue;
            Warning(infoLong, "Saturating level: %d", k);
            reach_proc(visited, prev_vis[k], &groups[k], eg_count, next_count,guard_count);
            check_invariants(visited, -1);
            if (save_sat_levels) vset_copy(prev_vis[k], visited);
        }
    }

    for (int k = 0; k < max_sat_levels; k++)
        bitvector_free(&groups[k]);

    vset_destroy(old_vis);
    if (save_sat_levels)
        for (int i = 0; i < max_sat_levels; i++) vset_destroy(prev_vis[i]);
}
コード例 #2
0
ファイル: sat.c プロジェクト: Meijuh/ltsmin
void
reach_sat_fix(reach_proc_t reach_proc, vset_t visited,
              bitvector_t *reach_groups, long *eg_count, long *next_count, long *guard_count)
{
    (void) reach_proc;
    (void) guard_count;

    if (PINS_USE_GUARDS)
        Abort("guard-splitting not supported with saturation=sat-fix");

    int level = 0;
    vset_t old_vis = vset_create(domain, -1, NULL);
    vset_t deadlocks = dlk_detect?vset_create(domain, -1, NULL):NULL;
    vset_t dlk_temp = dlk_detect?vset_create(domain, -1, NULL):NULL;

    LACE_ME;
    while (!vset_equal(visited, old_vis)) {
        if (trc_output != NULL) save_level(visited);
        vset_copy(old_vis, visited);
        stats_and_progress_report(NULL, visited, level);
        level++;
        for(int i = 0; i < nGrps; i++){
            if (!bitvector_is_set(reach_groups, i)) continue;
            expand_group_next(i, visited);
            reach_chain_stop();
            (*eg_count)++;
        }
        if (dlk_detect) vset_copy(deadlocks, visited);
        if (USE_PARALLELISM) vset_least_fixpoint_par(visited, visited, group_next, nGrps);
        else vset_least_fixpoint(visited, visited, group_next, nGrps);
        (*next_count)++;
        check_invariants(visited, level);
        if (dlk_detect) {
            for (int i = 0; i < nGrps; i++) {
                vset_prev(dlk_temp, visited, group_next[i],deadlocks);
                reduce(i, dlk_temp);
                vset_minus(deadlocks, dlk_temp);
                vset_clear(dlk_temp);
            }
            deadlock_check(deadlocks, reach_groups);
        }
        vset_reorder(domain);
    }

    vset_destroy(old_vis);
    if (dlk_detect) {
        vset_destroy(deadlocks);
        vset_destroy(dlk_temp);
    }
}
コード例 #3
0
ファイル: sat.c プロジェクト: Meijuh/ltsmin
void
reach_sat(reach_proc_t reach_proc, vset_t visited,
          bitvector_t *reach_groups, long *eg_count, long *next_count, long *guard_count)
{
    (void) reach_proc;
    (void) next_count;
    (void) guard_count;

    if (PINS_USE_GUARDS)
        Abort("guard-splitting not supported with saturation=sat");

    if (act_detect != NULL && trc_output != NULL)
        Abort("Action detection with trace generation not supported");

    for (int i = 0; i < nGrps; i++) {
        if (bitvector_is_set(reach_groups, i)) {
            struct expand_info *ctx = RTmalloc(sizeof(struct expand_info));
            ctx->group = i;
            ctx->group_explored = group_explored[i];
            ctx->eg_count = eg_count;

            vrel_set_expand(group_next[i], expand_group_next_projected, ctx);
        }
    }

    if (trc_output != NULL) save_level(visited);
    stats_and_progress_report(NULL, visited, 0);
    if (USE_PARALLELISM) vset_least_fixpoint_par(visited, visited, group_next, nGrps);
    else vset_least_fixpoint(visited, visited, group_next, nGrps);
    stats_and_progress_report(NULL, visited, 1);

    check_invariants(visited, -1);

    if (dlk_detect) {
        vset_t deadlocks = vset_create(domain, -1, NULL);
        vset_t dlk_temp = vset_create(domain, -1, NULL);
        vset_copy(deadlocks, visited);
        for (int i = 0; i < nGrps; i++) {
            vset_prev(dlk_temp, visited, group_next[i],deadlocks);
            reduce(i, dlk_temp);
            vset_minus(deadlocks, dlk_temp);
            vset_clear(dlk_temp);
        }
        deadlock_check(deadlocks, reach_groups);
        vset_destroy(deadlocks);
        vset_destroy(dlk_temp);
    }
}
コード例 #4
0
ファイル: spg-strategy.c プロジェクト: Meijuh/ltsmin
/**
 * \brief Adds level for player to strategy.
 */
void update_strategy_levels(recursive_result* result, int player, vset_t level)
{
    if (result->strategy_levels_count[player]==result->strategy_levels_max[player]) {
        result->strategy_levels_max[player] += INIT_STRATEGY_MAX;
        result->strategy_levels[player] = RTrealloc(result->strategy_levels[player], (result->strategy_levels_max[player])*sizeof(vset_t));
    }
    result->strategy_levels[player][result->strategy_levels_count[player]] = vset_create(result->dom, -1, NULL);
    vset_copy(result->strategy_levels[player][result->strategy_levels_count[player]], level);
    //printf("update_strategy_levels: player=%d, index=%d.\n", player, result->strategy_levels_count[player]);
    result->strategy_levels_count[player]++;
    result->strategy_boundaries[player][result->strategy_boundary_count[player]-1]++;
    //printf("update_strategy_levels: levels_count=%d, boundary[boundary_count-1=%d]=%d.\n",
    //       result->strategy_levels_count[player], result->strategy_boundary_count[player]-1,
    //       result->strategy_boundaries[player][result->strategy_boundary_count[player]-1]);
    assert(result->strategy_boundaries[player][result->strategy_boundary_count[player]-1] == result->strategy_levels_count[player]);
}
コード例 #5
0
ファイル: pg.c プロジェクト: Meijuh/ltsmin
/**
 * \brief Creates a symbolic parity game from the generated LTS.
 */
parity_game *
compute_symbolic_parity_game(vset_t visited, int *src)
{
    Print(infoShort, "Computing symbolic parity game.");
    debug_output_enabled = true;

    // num_vars and player have been pre-computed by init_pbes.
    parity_game* g = spg_create(domain, N, nGrps, min_priority, max_priority);
    for(int i=0; i < N; i++)
    {
        g->src[i] = src[i];
    }
    vset_copy(g->v, visited);
    for(size_t i = 0; i < num_vars; i++)
    {
        // players
        Print(infoLong, "Adding nodes for var %zu (player %d).", i, player[i]);
        add_variable_subset(g->v_player[player[i]], g->v, g->domain, i);
        // priorities
        add_variable_subset(g->v_priority[priority[i]], g->v, g->domain, i);
    }
    if (log_active(infoLong))
    {
        for(int p = 0; p < 2; p++)
        {
            long   n_count;
            double elem_count;
            vset_count(g->v_player[p], &n_count, &elem_count);
            Print(infoLong, "player %d: %ld nodes, %.*g elements.", p, n_count, DBL_DIG, elem_count);
        }
        for(int p = min_priority; p <= max_priority; p++)
        {
            long   n_count;
            double elem_count;
            vset_count(g->v_priority[p], &n_count, &elem_count);
            Print(infoLong, "priority %d: %ld nodes, %.*g elements.", p, n_count, DBL_DIG, elem_count);
        }
    }
    for(int i = 0; i < nGrps; i++)
    {
        g->e[i] = group_next[i];
    }
    return g;
}
コード例 #6
0
ファイル: spg-strategy.c プロジェクト: Meijuh/ltsmin
/**
 * \brief Combines strategy levels for player.
 */
void
concat_strategy_levels_player (int player, vdom_t domain, vset_t** dst,
                               int* dst_count, int** dst_boundaries,
                               int* dst_boundary_count, vset_t** src,
                               int* src_count, int** src_boundaries,
                               int* src_boundary_count)
{
    //printf("concat_strategy_levels: player=%d, dst_count=%d, src_count=%d, dst_boundary_count=%d, src_boundary_count=%d.\n",
    //       player, dst_count[player], src_count[player], dst_boundary_count[player], src_boundary_count[player]);
    dst[player] = RTrealloc(dst[player], (dst_count[player]+src_count[player])*sizeof(vset_t));
    for (int i = 0; i < src_count[player]; i++) {
        dst[player][dst_count[player] + i] = vset_create(domain, -1, NULL);
        vset_copy(dst[player][dst_count[player] + i], src[player][i]);
    }
    dst_boundaries[player] = RTrealloc(dst_boundaries[player], (dst_boundary_count[player]+src_boundary_count[player])*sizeof(int));
    for (int i = 0; i < src_boundary_count[player]; i++) {
        dst_boundaries[player][dst_boundary_count[player]+i] = src_boundaries[player][i] + dst_count[player];
    }
    dst_count[player] += src_count[player];
    dst_boundary_count[player] += src_boundary_count[player];
    //printf("concat_strategy_levels: player=%d, dst_count=%d, dst_boundary_count=%d.\n",
    //       player, dst_count[player], dst_boundary_count[player]);
}
コード例 #7
0
ファイル: spec2lts-grey.c プロジェクト: hinike/MyDocuments
int main(int argc, char *argv[]){
	char *files[2];
	RTinitPopt(&argc,&argv,options,1,2,files,NULL,"<model> [<lts>]",
		"Perform an enumerative reachability analysis of <model>\n"
		"Run the TorX remote procedure call protocol on <model> (--torx).\n\n"
		"Options");
	if (files[1]) {
		Warning(info,"Writing output to %s",files[1]);
		write_lts=1;
	} else {
		Warning(info,"No output, just counting the number of states");
		write_lts=0;
	}
	if (application==RunTorX && write_lts) Fatal(1,error,"A TorX server does not write to a file");
	Warning(info,"loading model from %s",files[0]);
	model_t model=GBcreateBase();
	GBsetChunkMethods(model,new_string_index,NULL,
		(int2chunk_t)SIgetC,(chunk2int_t)SIputC,(get_count_t)SIgetCount);

	GBloadFile(model,files[0],&model);

	if (RTverbosity >=2) {
	  fprintf(stderr,"Dependency Matrix:\n");
	  GBprintDependencyMatrix(stderr,model);
	}
	if (matrix) {
	  GBprintDependencyMatrix(stdout,model);
	  exit(0);
	}
	lts_type_t ltstype=GBgetLTStype(model);
	N=lts_type_get_state_length(ltstype);
	edge_info_t e_info=GBgetEdgeInfo(model);
	K=e_info->groups;
	Warning(info,"length is %d, there are %d groups",N,K);
	state_labels=lts_type_get_state_label_count(ltstype);
	edge_labels=lts_type_get_edge_label_count(ltstype);
	Warning(info,"There are %d state labels and %d edge labels",state_labels,edge_labels);
	if (state_labels&&write_lts&&!write_state) {
		Fatal(1,error,"Writing state labels, but not state vectors unsupported. "
			"Writing of state vector is enabled with the option --write-state");
	}
	int src[N];
	GBgetInitialState(model,src);
	Warning(info,"got initial state");
	int level=0;
	switch(application){
	case ReachVset:
		domain=vdom_create_default(N);
		visited_set=vset_create(domain,0,NULL);
		next_set=vset_create(domain,0,NULL);
		if (write_lts){
			output=lts_output_open(files[1],model,1,0,1,"viv",NULL);
			lts_output_set_root_vec(output,(uint32_t*)src);
			lts_output_set_root_idx(output,0,0);
			output_handle=lts_output_begin(output,0,0,0);	
		}
		vset_add(visited_set,src);
		vset_add(next_set,src);
		vset_t current_set=vset_create(domain,0,NULL);
		while (!vset_is_empty(next_set)){
		  if (RTverbosity >= 1)
		    Warning(info,"level %d has %d states, explored %d states %d trans",
			    level,(visited-explored),explored,trans);
		  level++;
		  vset_copy(current_set,next_set);
		  vset_clear(next_set);
		  vset_enum(current_set,explore_state_vector,model);
		}
		long long size;
		long nodes;
		vset_count(visited_set,&nodes,&size);
	    	Warning(info,"%lld reachable states represented symbolically with %ld nodes",size,nodes);
		break;
	case ReachTreeDBS:
		dbs=TreeDBScreate(N);
		if(TreeFold(dbs,src)!=0){
			Fatal(1,error,"expected 0");
		}
		if (write_lts){
			output=lts_output_open(files[1],model,1,0,1,write_state?"vsi":"-ii",NULL);
			if (write_state) lts_output_set_root_vec(output,(uint32_t*)src);
			lts_output_set_root_idx(output,0,0);
			output_handle=lts_output_begin(output,0,0,0);	
		}
		int limit=visited;
		while(explored<visited){
		  if (limit==explored){
		    if (RTverbosity >= 1)
		      Warning(info,"level %d has %d states, explored %d states %d trans",
			      level,(visited-explored),explored,trans);
		    limit=visited;
		    level++;
		  }
		  TreeUnfold(dbs,explored,src);
		  explore_state_index(model,explored,src);
		}
		break;
	case RunTorX:
		{
		torx_struct_t context = { model, ltstype };
		torx_ui(&context);
		return 0;
		}
	}
	if (write_lts){
		lts_output_end(output,output_handle);
		Warning(info,"finishing the writing");
		lts_output_close(&output);
		Warning(info,"state space has %d levels %d states %d transitions",level,visited,trans);
	} else {
		printf("state space has %d levels %d states %d transitions\n",level,visited,trans);
	}
	return 0;
}
コード例 #8
0
ファイル: spg-strategy.c プロジェクト: Meijuh/ltsmin
int choose_strategy_move(const parity_game* g, const recursive_result* strategy, const int player, const int* src,
                          int* current_player, bool* strategy_play, bool* result, bool* deadlock, int* dst)
{
    int group = -1;
    vset_t level = vset_create(g->domain, -1, NULL);
    vset_t tmp = vset_create(g->domain, -1, NULL);
    vset_t singleton = vset_create(g->domain, -1, NULL);
    vset_add(singleton, src);
    // Do a random run through the game, conforming to
    // the strategy in result.
    *current_player = (vset_member(g->v_player[player], src) ? player : 1-player);
    Print(hre_debug, "Using strategy of player %d. The position is owned by player %d.", player, *current_player);
    if (*current_player==player && vset_member(strategy->win[player], src))
    {
        //printf("Player %d chooses according to his/her winning strategy.\n", player);
        // Choose a transition according to the strategy of player
        *strategy_play = true;
        vset_t strategy_level = vset_create(g->domain, -1, NULL);
        compute_strategy_level(strategy_level, src, player, strategy);

        vset_clear(level);
        for (int i=0; i < g->num_groups; i++) {
            vset_next(tmp, singleton, g->e[i]);
            vset_intersect(tmp, strategy_level);
            if (!vset_is_empty(tmp))
            {
                vset_copy(level, tmp);
                // Choose a random element:
                //printf("Choosing a transition from transition group %d.\n", i);
                group = i;
                vset_random(level, dst);
                break;
            }
        }
        // Check for deadlocks
        if (vset_is_empty(level)) {
            *deadlock = true;
            *result = (*current_player != player);
            Print(infoLong, "Deadlock for player %d, player %s has won, result is %s.",
                   *current_player,
                   (*current_player==1) ? "0 (even / or)" : "1 (odd / and)",
                           *result ? "true" : "false");
        }
    }
    else
    {
        //Print(info, "Not player %d's turn or player %d has no winning strategy. Choosing an arbitrary move for player %d.",
        //       player, player, *current_player);
        // this states belongs to (1-player) or player does not have a winning strategy
        *strategy_play = false;
        vset_t strategy_level = vset_create(g->domain, -1, NULL);
        /*
        if (vset_member(result.win[current_player], src))
        {
            // winning move after all
            compute_strategy_level(strategy_level, src, current_player, result);
            if (vset_is_empty(strategy_level)) {
                Print(info, "Unexpected: src is in win[%d], but strategy_level is empty.", current_player);
            } else {
                strategy_play = true;
            }
        }
        */
        // choose a random move
        vset_clear(level);
        for (int i=0; i < g->num_groups; i++) {
            vset_next(tmp, singleton, g->e[i]);
            if (*strategy_play && !vset_is_empty(tmp)) {
                vset_intersect(tmp, strategy_level);
                if (!vset_is_empty(tmp))
                {
                    vset_copy(level, tmp);
                    // Choose a random element:
                    //printf("Choosing a transition from transition group %d.\n", i);
                    group = i;
                    vset_random(level, dst);
                    break;
                }
            } else {
                vset_union(level, tmp);
            }
        }
        // Check for deadlocks
        if (vset_is_empty(level)) {
            *deadlock = true;
            *result = (*current_player != player);
            Print(infoLong, "Deadlock for player %d, player %s has won, result is %s.",
                   *current_player,
                   (*current_player==1) ? "0 (even / or)" : "1 (odd / and)",
                           *result ? "true" : "false");
        } else if (!*strategy_play) {
            //Print(info, "choose randomly");
            vset_random(level, dst);
        }
    }
    return group;
}
コード例 #9
0
ファイル: pins2lts-sym.c プロジェクト: alaarman/ltsmin
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);
}