Example #1
0
def case1_synthesis(formula, ts_file):
    _, dfa_0, dfa_inf, bdd = twtl.translate(formula, kind='both', norm=True)

    logging.debug('alphabet: {}'.format(dfa_inf.props))

    for u, v, d in dfa_inf.g.edges_iter(data=True):
        logging.debug('({}, {}): {}'.format(u, v, d))

    dfa_inf.visualize(draw='matplotlib')
    plt.show()

    logging.debug('\nEnd of translate\n\n')

    logging.info('The bound of formula "%s" is (%d, %d)!', formula, *bdd)
    logging.info('Translated formula "%s" to normal DFA of size (%d, %d)!',
                 formula, *dfa_0.size())
    logging.info('Translated formula "%s" to infinity DFA of size (%d, %d)!',
                 formula, *dfa_inf.size())

    logging.debug('\n\nStart policy computation\n')

    ts = Ts.load(ts_file)
    ets = expand_duration_ts(ts)

    for name, dfa in [('normal', dfa_0), ('infinity', dfa_inf)]:
        logging.info('Constructing product automaton with %s DFA!', name)
        pa = ts_times_fsa(ets, dfa)
        logging.info('Product automaton size is: (%d, %d)', *pa.size())

        if name == 'infinity':
            for u in pa.g.nodes_iter():
                logging.debug('{} -> {}'.format(u, pa.g.neighbors(u)))

            pa.visualize(draw='matplotlib')
            plt.show()

        # compute optimal path in PA and then project onto the TS
        policy, output, tau = compute_control_policy(pa, dfa, dfa.kind)
        logging.info('Max deadline: %s', tau)
        if policy is not None:
            logging.info('Generated output word is: %s',
                         [tuple(o) for o in output])

            policy = [x for x in policy if x not in ets.state_map]
            out = StringIO.StringIO()
            for u, v in zip(policy[:-1], policy[1:]):
                print >> out, u, '->', ts.g[u][v][0]['duration'], '->',
            print >> out, policy[-1],
            logging.info('Generated control policy is: %s', out.getvalue())
            out.close()

            logging.info('Relaxation is: %s',
                         twtl.temporal_relaxation(output, formula=formula))
        else:
            logging.info('No control policy found!')
Example #2
0
def case2_verification(formula, ts_file):
    _, dfa_inf, bdd = twtl.translate(formula, kind=DFAType.Infinity, norm=True)

    logging.info('The bound of formula "%s" is (%d, %d)!', formula, *bdd)
    logging.info('Translated formula "%s" to infinity DFA of size (%d, %d)!',
                 formula, *dfa_inf.size())

    ts = Ts.load(ts_file)
    ts.g.add_edges_from(ts.g.edges(), weight=1)

    for u, v in ts.g.edges_iter():
        print u, '->', v

    result = verify(ts, dfa_inf)
    logging.info('The result of the verification procedure is %s!', result)
Example #3
0
def postprocessing(logfilename,
                   ts_filename,
                   outdir,
                   lts_index,
                   rrg_iterations,
                   lts_iterations,
                   local_traj_iterations,
                   generate=()):
    '''Parses log file and generate statistics and figures.'''

    if not os.path.isdir(outdir):
        os.makedirs(outdir)

    with open(logfilename, 'r') as logfile:
        # first process general data
        data = dict()
        line = ''
        for line in logfile:
            prefix, line_data = line.split('--')
            if prefix.lower().rfind('info') >= 0:
                data.update(eval(line_data))
                if line_data.lower().find('start global planning') >= 0:
                    break
        print 'general data:', len(data)

        # second process data on global planner
        rrg_data = []
        iteration_data = None
        for line in logfile:
            prefix, line_data = line.split('--')
            if prefix.lower().rfind('info') >= 0:
                if line_data.lower().rfind('found solution') >= 0:
                    rrg_data.append(iteration_data)
                    break
                if line_data.lower().find('iteration') >= 0:
                    if iteration_data is not None:
                        rrg_data.append(iteration_data)
                    iteration_data = dict()
                iteration_data.update(eval(line_data))
        print 'rrg data:', len(rrg_data)

        rrg_stat_data = eval(line_data)
        for line in logfile:
            prefix, line_data = line.split('--')
            if prefix.lower().rfind('info') >= 0:
                if line_data.lower().find('end global planning') >= 0:
                    break
                rrg_stat_data.update(eval(line_data))
        print 'rrg_stat_data', len(rrg_stat_data)

        assert rrg_stat_data['Iterations'] == len(rrg_data)

        # third process data on local planner
        rrt_stat_data = dict()
        for line in logfile:
            prefix, line_data = line.split('--')
            if prefix.lower().rfind('info') >= 0:
                if line_data.lower().find('initialize local planner') >= 0:
                    break
                rrt_stat_data.update(eval(line_data))
        print 'rrt_stat_data:', len(rrt_stat_data)

        rrt_data = []
        execution_data = dict()
        for line in logfile:
            prefix, line_data = line.split('--')
            if prefix.lower().rfind('info') >= 0:
                if line_data.lower().find(
                        'local online planning finished') >= 0:
                    rrt_data.append(execution_data)
                    break
                # NOTE: second condition is for compatibility with Cozmo logs
                if (line_data.lower().find('start local planning step') >= 0
                        or line_data.lower().find('plan start time') >= 0):
                    rrt_data.append(execution_data)
                    execution_data = dict()
                execution_data.update(eval(line_data))
        print 'rrt data:', len(rrt_data)

    # save useful information
    with open(os.path.join(outdir, 'general_data.txt'), 'w') as f:
        for key in [
                'Robot initial configuration', 'Robot step size',
                'Global specification', 'Buchi size', 'Local specification'
        ]:
            print >> f, key, ':', data[key]

        for key in [
                'Iterations', 'global planning runtime', 'Size of TS',
                'Size of PA'
        ]:
            print >> f, key, ':', rrg_stat_data[key]
        pre, suff = rrg_stat_data['global policy']
        print >> f, 'Global policy size :', (len(pre), len(suff))

        # key = 'Computing potential function runtime'
        # print>>f, key, ':', rrt_stat_data[key]

    # get workspace
    wspace, style = data['Workspace']
    wspace.boundary.style = style
    ewspace, style = data['Expanded workspace']
    ewspace.boundary.style = style

    # get robot
    robot_name = data['Robot name']
    initConf = data['Robot initial configuration']
    stepsize = data['Robot step size']
    robot = eval(data['Robot constructor'])
    robot.diameter = data['Robot diameter']
    robot.localObst = data['Local obstacle label']

    # create simulation object
    sim = Simulate2D(wspace, robot, ewspace)
    sim.config['output-dir'] = outdir

    # add regions to workspace
    for key, value in data.iteritems():
        if isinstance(key, tuple) and key[0] == "Global region":
            r, style = value
            # add styles to region
            addStyle(r, style=style)
            # add region to workspace
            sim.workspace.addRegion(r)
            # create expanded region
            er = expandRegion(r, robot.diameter / 2)
            # add style to the expanded region
            addStyle(er, style=style)
            # add expanded region to the expanded workspace
            sim.expandedWorkspace.addRegion(er)

    # get local requests and obstacles
    localSpec = data['Local specification']
    requests = []
    obstacles = []
    for key, value in data.iteritems():
        if isinstance(key, tuple) and key[0] == "Local region":
            r, style, path, is_request = value
            # add styles to region
            addStyle(r, style=style)
            # add path
            if path:
                r.path = it.cycle(path)
                r.original_path = path[:]
            # add to requests or obstacles lists
            if is_request:
                name = next(iter(r.symbols))
                requests.append(Request(r, name, localSpec[name]))
            else:
                obstacles.append(r)

    # get robot sensor
    robot.sensor = eval(data['Robot sensor constructor'])

    # create RRG planner and load transition system, and global policy
    sim.offline = RRGPlanner(robot, None, 1)
    prefix, suffix = rrg_stat_data['global policy']
    sim.solution = (prefix, suffix[1:])
    print 'Global policy size:', len(prefix), len(suffix)

    if any(option in generate for option in ('workspace', 'expanded workspace',
                                             'global solution')):
        # set larger font for saving figures
        for r in sim.workspace.regions | sim.expandedWorkspace.regions:
            r.fontsize_orig = r.textStyle.get('fontsize', 12)
            r.textStyle['fontsize'] = 24

        # display workspace
        if 'workspace' in generate:
            sim.display(save='workspace.png')
        # display expanded workspace
        if 'expanded workspace' in generate:
            sim.display(expanded=True, save='eworkspace.png')
        # display solution for off-line problem
        if 'global solution' in generate:
            ts = sim.offline.ts
            sim.offline.ts = Ts.load(ts_filename)
            sim.display(expanded=True,
                        solution=prefix + suffix[1:],
                        save='global_solution.png')
            sim.offline.ts = ts

        # restore original fontsize
        for r in sim.workspace.regions:
            r.textStyle['fontsize'] = r.fontsize_orig
            del r.fontsize_orig

    # display both workspaces
    if 'both workspaces' in generate:
        sim.display(expanded='both')

    # show construction of rrg
    sim.offline.ts.init[initConf] = 1
    if 'RRG construction' in generate:
        sim.config['global-ts-color'] = {
            'node_color': 'blue',
            'edge_color': 'black'
        }
        sim.config['video-interval'] = 500
        sim.config['video-file'] = 'rrg_construction.mp4'
        sim.save_rrg_process(rrg_data)
        # reset to default colors
        sim.defaultConfiguration(reset=['global-ts-color'])

    if 'RRG iterations' in generate:
        sim.config['global-ts-color'] = {
            'node_color': 'blue',
            'edge_color': 'black'
        }
        rrg_iterations = [
            i + (i == -1) * (len(rrg_data) + 1) for i in rrg_iterations
        ]
        sim.save_rrg_iterations(rrg_data, rrg_iterations)
        # reset to default colors
        sim.defaultConfiguration(reset=['global-ts-color'])

    # set to global and to save animation
    sim.offline.ts = Ts.load(ts_filename)
    print 'TS size', sim.offline.ts.size()
    if 'offline plan' in generate:
        sim.config['video-interval'] = 30
        sim.config['sim-step'] = 0.02
        sim.config['video-file'] = 'global_plan.mp4'
        sim.simulate(loops=1, offline=True)
        sim.play(output='video', show=False)
        sim.save()

    # get online trajectory
    sim.offline.ts = Ts.load(ts_filename)
    trajectory = [d['new configuration'] for d in rrt_data]
    local_plans = [d['local plan'] for d in rrt_data] + [[]]
    potential = [d['potential'] for d in rrt_data] + [0]
    requests = [d['requests'] for d in rrt_data] + [[]]
    print len(trajectory), len(local_plans)

    if 'trajectory' in generate:
        # set larger font for saving figures
        for r in sim.workspace.regions | sim.expandedWorkspace.regions:
            r.fontsize_orig = r.textStyle.get('fontsize', 12)
            r.textStyle['fontsize'] = 24

        sim.config['trajectory-min-transparency'] = 0.2  # fading
        sim.config['trajectory-history-length'] = len(
            trajectory)  # full history
        sim.config['global-policy-color'] = 'orange'

        sim.online = LocalPlanner(None, sim.offline.ts, robot, localSpec)
        sim.online.trajectory = trajectory
        sim.online.robot.sensor.requests = []
        sim.display(expanded=True,
                    solution=prefix + suffix[1:],
                    show_robot=False,
                    localinfo=('trajectory', ),
                    save='trajectory.png')
        sim.defaultConfiguration(reset=[
            'trajectory-min-transparency', 'trajectory-history-length',
            'global-policy-color'
        ])

        # restore original fontsize
        for r in sim.workspace.regions:
            r.textStyle['fontsize'] = r.fontsize_orig
            del r.fontsize_orig

    # local plan visualization
    sim.online = LocalPlanner(None, sim.offline.ts, robot, localSpec)
    sim.online.trajectory = trajectory
    if 'online plan' in generate:
        sim.config['video-interval'] = 30
        sim.config['sim-step'] = 0.01
        sim.config['video-file'] = 'local_plan.mp4'
        sim.simulate(offline=False)
        sim.play(output='video',
                 show=False,
                 localinfo={
                     'trajectory': trajectory,
                     'plans': local_plans,
                     'potential': potential,
                     'requests': requests
                 })
        sim.save()

    if 'online trajectory iterations' in generate:
        sim.config['sim-step'] = 0.05
        sim.config['trajectory-min-transparency'] = 1.0  # no fading
        sim.config['trajectory-history-length'] = 100000  # entire history
        sim.config['image-file-template'] = 'local_trajectory_{frame:04d}.png'
        sim.config['global-policy-color'] = 'orange'
        # simulate and save
        sim.simulate(offline=False)
        sim.play(output='plots',
                 show=False,
                 localinfo={
                     'trajectory': trajectory,
                     'plans': local_plans,
                     'potential': potential,
                     'requests': requests
                 })
        sim.save(output='plots', frames=local_traj_iterations)
        # set initial values
        sim.defaultConfiguration(reset=[
            'trajectory-min-transparency', 'trajectory-history-length',
            'image-file-template', 'global-policy-color'
        ])

    msize = np.mean([d['tree size'] for d in rrt_data if d['tree size'] > 0])
    print 'Mean size:', msize
    for k, d in enumerate(rrt_data):
        if d['tree size'] > 0:
            print(k, d['tree size'])

    if any(option in generate
           for option in ('LTS iterations', 'LTS construction')):
        idx = lts_index
        print rrt_data[idx]['tree size']
        print 'current state:', rrt_data[idx - 1]['new configuration']

        lts_data = sorted([
            v for k, v in rrt_data[idx].items()
            if str(k).startswith('lts iteration')
        ],
                          key=lambda x: x[0])
        #     print lts_data

        sim.online.lts = Ts(directed=True, multi=False)
        sim.online.lts.init[rrt_data[idx - 1]['new configuration']] = 1
        # reset and fast-forward requests' locations
        for r in sim.robot.sensor.all_requests:
            aux = it.cycle(r.region.original_path)
            for _ in range(idx - 1):
                r.region.translate(next(aux))
        sim.robot.sensor.requests = [
            r for r in sim.robot.sensor.all_requests
            if r in rrt_data[idx]['requests']
        ]
        if 'LTS construction' in generate:
            sim.config['video-interval'] = 500
            sim.config['video-file'] = 'lts_construction.mp4'
            sim.save_lts_process(lts_data, endframe_hold=20)

        if 'LTS iterations' in generate:
            lts_iterations = [
                i + (i == -1) * len(lts_data) for i in lts_iterations
            ]
            sim.save_lts_iterations(lts_data, lts_iterations)

    if 'LTS statistics' in generate:
        metrics = [('tree size', True), ('local planning runtime', False),
                   ('local planning execution', False)]
        rrt_data = rrt_data[1:]
        # NOTE: This is for compatibility with the Cozmo logs
        if 'local planning execution' not in rrt_data[0]:
            for d in rrt_data:
                duration = (d['plan stop time'] - d['plan start time']) * 1000
                d['local planning execution'] = duration

        data = [len(d['requests']) for d in rrt_data]
        serviced = sum(n1 - n2 for n1, n2 in it.izip(data, data[1:])
                       if n1 > n2)

        with open(os.path.join(outdir, 'local_performance_stats.txt'),
                  'w') as f:
            print >> f, 'no trials:', len(rrt_data)
            print >> f, 'no requests serviced', serviced
            ops = [np.mean, np.min, np.max, np.std]
            for key, positive in metrics:
                if positive:
                    print >> f, key, [
                        op([
                            trial[key] for trial in rrt_data if trial[key] > 0
                        ]) for op in ops
                    ]
                else:
                    print >> f, key, [
                        op([trial[key] for trial in rrt_data]) for op in ops
                    ]
def main():

    Rho = namedtuple('Rho', ['lower', 'upper'])
    rhos = [Rho(lower=0.98, upper=1.04), Rho(lower=0.98, upper=1.04)]

#     # Case Study 1
#     with Timer('IJRR 2013 Case-Study 1'):
#         r1 = Ts.load('./robot_1.yaml')
#         r2 = Ts.load('./robot_2.yaml')
#         ts_tuple = (r1, r2)
#         formula = ('[]<>gather && [](r1gather -> X(!r1gather U r1upload)) '
#                   '&& [](r2gather -> X(!r2gather U r2upload))')
#         opt_prop = set(['gather'])
#         logger.info('Formula: %s', formula)
#         logger.info('opt_prop: %s', opt_prop)
#         prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
#                     lomap.multi_agent_optimal_run(ts_tuple, formula, opt_prop)
#         logger.info('Cost: %d', suffix_cycle_cost)
#         logger.info('Prefix length: %d', prefix_length)
#         # Find the controls that will produce this run
#         control_prefixes = []
#         control_suffix_cycles = []
#         for i in range(0, len(ts_tuple)):
#             ts = ts_tuple[i]
#             control_prefixes.append(ts.controls_from_run(prefixes[i]))
#             control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
#             logger.info('%s run prefix: %s', ts.name, prefixes[i])
#             logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
#             logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
#             logger.info('%s control suffix cycle: %s', ts.name,
#                                                     control_suffix_cycles[i])
#
#     logger.info('<><><> <><><> <><><>')

    # Case Study 2
    with Timer('IJRR 2013 Case-Study 2'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather && r2gather)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload))')
        opt_prop = set(['r1gather','r2gather'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
         lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])

    logger.info('<><><> <><><> <><><>')

    # Case Study 3
    with Timer('IJRR 2013 Case-Study 3'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather && r2gather)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload)) '
                   '&& [](!(r1gather1 && r2gather1) && !(r1gather2 && r2gather2)'
                   '&& !(r1gather3 && r2gather3) && !(r1gather4 && r2gather4))')
        opt_prop = set(['r1gather','r2gather'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
         lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])

    logger.info('<><><> <><><> <><><>')

    # Case Study 4
    with Timer('IJRR 2013 Case-Study 4'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather4 && r2gather2)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload))')
        opt_prop = set(['r1gather4','r2gather2'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
                      lomap.multi_agent_optimal_run(ts_tuple, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])

    logger.info('<><><> <><><> <><><>')

    # Case Study 4 w/ sync
    with Timer('IJRR 2013 Case-Study 4 (w/ sync)'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather4 && r2gather2)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload))')
        opt_prop = set(['r1gather4','r2gather2'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
         lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])
Example #5
0
def main():

    Rho = namedtuple('Rho', ['lower', 'upper'])
    rhos = [Rho(lower=0.98, upper=1.04), Rho(lower=0.98, upper=1.04)]

#     # Case Study 1
#     with Timer('IJRR 2013 Case-Study 1'):
#         r1 = Ts.load('./robot_1.yaml')
#         r2 = Ts.load('./robot_2.yaml')
#         ts_tuple = (r1, r2)
#         formula = ('[]<>gather && [](r1gather -> X(!r1gather U r1upload)) '
#                   '&& [](r2gather -> X(!r2gather U r2upload))')
#         opt_prop = set(['gather'])
#         logger.info('Formula: %s', formula)
#         logger.info('opt_prop: %s', opt_prop)
#         prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
#                     lomap.multi_agent_optimal_run(ts_tuple, formula, opt_prop)
#         logger.info('Cost: %d', suffix_cycle_cost)
#         logger.info('Prefix length: %d', prefix_length)
#         # Find the controls that will produce this run
#         control_prefixes = []
#         control_suffix_cycles = []
#         for i in range(0, len(ts_tuple)):
#             ts = ts_tuple[i]
#             control_prefixes.append(ts.controls_from_run(prefixes[i]))
#             control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
#             logger.info('%s run prefix: %s', ts.name, prefixes[i])
#             logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
#             logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
#             logger.info('%s control suffix cycle: %s', ts.name,
#                                                     control_suffix_cycles[i])
#
#     logger.info('<><><> <><><> <><><>')

    # Case Study 2
    with Timer('IJRR 2013 Case-Study 2'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather && r2gather)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload))')
        opt_prop = set(['r1gather','r2gather'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
         lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])

    logger.info('<><><> <><><> <><><>')

    # Case Study 3
    with Timer('IJRR 2013 Case-Study 3'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather && r2gather)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload)) '
                   '&& [](!(r1gather1 && r2gather1) && !(r1gather2 && r2gather2)'
                   '&& !(r1gather3 && r2gather3) && !(r1gather4 && r2gather4))')
        opt_prop = set(['r1gather','r2gather'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
         lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])

    logger.info('<><><> <><><> <><><>')

    # Case Study 4
    with Timer('IJRR 2013 Case-Study 4'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather4 && r2gather2)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload))')
        opt_prop = set(['r1gather4','r2gather2'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
                      lomap.multi_agent_optimal_run(ts_tuple, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])

    logger.info('<><><> <><><> <><><>')

    # Case Study 4 w/ sync
    with Timer('IJRR 2013 Case-Study 4 (w/ sync)'):
        r1 = Ts.load('./robot_1.yaml')
        r2 = Ts.load('./robot_2.yaml')
        ts_tuple = (r1, r2)
        formula = ('[]<>gather && [](gather->(r1gather4 && r2gather2)) '
                   '&& [](r1gather -> X(!r1gather U r1upload)) '
                   '&& [](r2gather -> X(!r2gather U r2upload))')
        opt_prop = set(['r1gather4','r2gather2'])
        logger.info('Formula: %s', formula)
        logger.info('opt_prop: %s', opt_prop)
        prefix_length, prefixes, suffix_cycle_cost, suffix_cycles = \
         lomap.robust_multi_agent_optimal_run(ts_tuple, rhos, formula, opt_prop)
        logger.info('Cost: %d', suffix_cycle_cost)
        logger.info('Prefix length: %d', prefix_length)
        # Find the controls that will produce this run
        control_prefixes = []
        control_suffix_cycles = []
        for i in range(0, len(ts_tuple)):
            ts = ts_tuple[i]
            control_prefixes.append(ts.controls_from_run(prefixes[i]))
            control_suffix_cycles.append(ts.controls_from_run(suffix_cycles[i]))
            logger.info('%s run prefix: %s', ts.name, prefixes[i])
            logger.info('%s control perfix: %s', ts.name, control_prefixes[i])
            logger.info('%s suffix cycle: %s', ts.name, suffix_cycles[i])
            logger.info('%s control suffix cycle: %s', ts.name,
                                                    control_suffix_cycles[i])