Ejemplo n.º 1
0
def optimal_run(t, formula, opt_prop):
    try:
        logger.info('T has %d states', len(t.g))
        # Convert formula to Buchi automaton
        b = Buchi()
        b.from_formula(formula)
        logger.info('B has %d states', len(b.g))
        # Compute the product automaton
        p = ts_times_buchi(t, b)
        logger.info('P has %d states', len(p.g))
        logger.info('Set F has %d states', len(p.final))
        # Find the set S of states w/ opt_prop
        s = p.nodes_w_prop(opt_prop)
        logger.info('Set S has %d states', len(s))
        # Compute the suffix_cycle* and suffix_cycle_cost*
        suffix_cycle_cost, suffix_cycle_on_p = min_bottleneck_cycle(
            p.g, s, p.final)
        # Compute the prefix: a shortest path from p.init to suffix_cycle
        prefix_length = float('inf')
        prefix_on_p = ['']
        i_star = 0
        for init_state in p.init.keys():
            for i in range(0, len(suffix_cycle_on_p)):
                length, prefix = source_to_target_dijkstra(
                    p.g, init_state, suffix_cycle_on_p[i], degen_paths=True)
                if (length < prefix_length):
                    prefix_length = length
                    prefix_on_p = prefix
                    i_star = i

        if (prefix_length == float('inf')):
            raise Exception(__name__, 'Could not compute the prefix.')

        # Wrap suffix_cycle_on_p as required
        if i_star != 0:
            # Cut and paste
            suffix_cycle_on_p = suffix_cycle_on_p[i_star:] + suffix_cycle_on_p[
                1:i_star + 1]

        # Compute projection of prefix and suffix-cycle to T and return
        suffix_cycle = [x[0] for x in suffix_cycle_on_p]
        prefix = [x[0] for x in prefix_on_p]
        return (prefix_length, prefix, suffix_cycle_cost, suffix_cycle)
    except Exception as ex:
        if (len(ex.args) == 2):
            print("{}: {}".format(*ex.args))
        else:
            print("{}: Unknown exception {}: {}".format(
                __name__, type(ex), ex))
            exc_type, exc_value, exc_traceback = sys.exc_info()
            traceback.print_tb(exc_traceback)
            exit(1)
Ejemplo n.º 2
0
def test_ts_times_buchi():
    ts = Ts.load('./simple_network.yaml')

    print('Loaded transition system of size', ts.size())
    ts.visualize(edgelabel='weight', draw='matplotlib')
    plt.show()

    for u, d in ts.g.nodes_iter(data=True):
        print u, d
    print
    for u, v, d in ts.g.edges_iter(data=True):
        print u, v, d

    spec = 'G (F a && F g && !e)'
    buchi = Buchi()
    buchi.from_formula(spec)
    print('Created Buchi automaton of size', buchi.size())
    buchi.visualize(draw='matplotlib')
    plt.show()

    print
    for u, d in buchi.g.nodes_iter(data=True):
        print u, d
    print
    for u, v, d in buchi.g.edges_iter(data=True):
        print u, v, d

    pa = ts_times_buchi(ts, buchi)
    print('Created product automaton of size', pa.size())
    pa.visualize(draw='matplotlib')
    plt.show()

    print
    for u, d in pa.g.nodes_iter(data=True):
        print u, d
    print
    for u, v, d in pa.g.edges_iter(data=True):
        print u, v, d

    cost, prefix, suffix = policy_buchi_pa(pa)

    print('cost:', cost)
    print('prefix:', prefix)
    print('suffix:', suffix)
def compute_sync_seqs(ts_tuple, rhos, tts, b, prefix, suffix):
    """
	Compute synchronization sequences for each, i.e. wait sets,
	for each agent so that correctness in the field is guaranteed.

	Parameters
	----------
	ts_tuple: Tuple of transition system objects
		ts_tuple[i] is the transition that models agent i.

	tts: A transition system object
		tts is the team transition system that models the asynchronous
		behavior of the team of agents who are individually modeled as
		the transition systems in ts_tuple.

	b: A buchi object
		This is the buchi automaton that corresponds to the negation of
		the mission specification.

	prefix: A list of tuples
		This is the prefix of the run on the team transition system tts.

	suffix: A list of tuples
		This is the suffix of the run on the team transition system tts.

	Results
	-------
	wait_sets: A 2-D list of sets
		wait_sets[i][j] gives the list of agents that agent i must wait at
		position j of the run before satisfying any propositions at that
		state and proceeding with the next position in its run.
	"""

    # Indeces of the agents
    agents = list(range(0, len(ts_tuple)))

    # Run is prefix + suffix after removing duplicate states
    run = prefix[0:-1] + suffix[0:-1]
    suffix_start = len(prefix) - 1
    logger.debug('suffix start:%d, run:%s', suffix_start, run)

    # Everyone goes in lock-step by default
    wait_sets = [[set(agents) - {ii} for jj in run] for ii in agents]

    for pos in range(0, len(run)):
        logger.info("Considering position %d" % pos)
        if pos == 0:
            logger.info("Skipping initial position")
            continue
        if pos == suffix_start:
            logger.info("Skipping suffix start")
            continue

        # Heuristic, check no sync before considering
        # agents individually
        for this_agent in agents:
            wait_sets[this_agent][pos] = set()
        field_ts = construct_field_event_ts(agents, rhos, ts_tuple, tts, run,
                                            wait_sets, suffix_start)
        p = ts_times_buchi(field_ts, b)
        if empty_language(p):
            logger.info('Heuristic succeeded!')
            continue

        # Revert wait sets for this position to their default values
        logger.info('Heuristic did not help...')
        for this_agent in agents:
            wait_sets[this_agent][pos] = set(agents) - {this_agent}

        for this_agent in agents:
            for that_agent in set(agents) - {this_agent}:
                logger.info("Removing %s from %s's wait set", that_agent,
                            this_agent)
                wait_sets[this_agent][pos].remove(that_agent)
                # Generate the field TS
                field_ts = construct_field_event_ts(agents, rhos, ts_tuple,
                                                    tts, run, wait_sets,
                                                    suffix_start)
                # Take the product
                p = ts_times_buchi(field_ts, b)
                # Check if the language of inverted formula is empty
                if empty_language(p):
                    logger.info('Empty Language')
                else:
                    logger.info('Non-empty language')
                    # Revert change made to wait set of this_agent
                    wait_sets[this_agent][pos].add(that_agent)

    return wait_sets