def make_nonconflicting_check(aut_fnames, use_heuristic): """ Verify whether the automata do not conflict with each other. @param aut_fnames: Comma-seperated list of automata filenames. @type aut_fnames: C{str} @param use_heuristic: Compute a smart order for the automata (rather than use the supplied order). @type use_heuristic: C{str} @return: Indication that no conflict has been found (all is ok). @rtype: C{bool} """ common.print_line("Started nonconflicting check (version %s)" % automata.version) coll = collection.Collection() auts = load_automata(coll, aut_fnames, False, False) if parse_boolean(use_heuristic): auts = abstraction.order_automata(auts) # else, user has supplied the automata in the right order. result = abstraction.nonconflicting_check(auts) if result: print "nonconflicting_check: HOLDS" else: print "nonconflicting_check: CONFLICT FOUND" return result
def n_ary_unweighted_product(auts, delete_aut = False, report_progress = False, preserve_names = True): """ N-ary unweighted automata product. @param auts: Input automata. @type auts: C{list} of L{Automaton} @param delete_aut: Routine is allowed to delete the provided automata. @type delete_aut: C{bool} @param report_progress: Output progress of the computation. @type report_progress: C{bool} @param preserve_names: Try to preserve state names in the product. @type preserve_names: C{bool} @return: Resulting unweighted automaton. @rtype: L{Automaton} """ if report_progress: common.print_line("Computing product of %d unweighted automata" % len(auts)) if len(auts) == 1: return auts[0] prod, mapping = n_ary_unweighted_product_map(auts, preserve_names) del mapping if delete_aut: for aut in auts: aut.clear() return prod
def save_weighted_automaton(aut, title, fname): """ Save weighted automaton L{aut} in file L{fname}. @param aut: Automaton to save. @type aut: L{WeightedAutomaton} @param title: If existing, an additional text to output. If it contains C{%s}, string formatting is used to insert the filename at that point in the text. @type title: Either a C{str} or C{None} @param fname: Filename to write the automaton to. @type fname: C{str} """ assert isinstance(aut, weighted_structure.WeightedAutomaton) frontend.make_backup_file(fname) weighted_structure.save_automaton(aut, fname, make_backup=False) if title is not None: if title.find("%s") >= 0: common.print_line(title % (fname, )) else: common.print_line(title)
def make_weighted_projection(aut_name, evt_names, result_fname): """ Perform projection over a weighted automaton. @param aut_name: Filename of the automaton to project. @type aut_name: L{WeightedAutomaton} @param evt_names: Comma seperated list of event names to preserve. @type evt_names: C{str} @param result_fname: Filename for writing the resulting weighted automaton. @type result_fname: C{str} """ common.print_line("Started weighted projection computation (version %s)" % automata.version) coll = collection.Collection() waut = load_weighted_automaton(coll, aut_name, False, False) events = frontend.get_events(coll, evt_names) waut2 = weighted_projection.weighted_projection(waut, events) frontend.dump_stats("Computed weighted projection", waut2) save_weighted_automaton(waut2, "Projected automaton is saved in %s", result_fname)
def make_sequential_abstraction(aut_fnames, evt_names, result_fname): """ Perform sequential abstraction on a number of automata. @param aut_fnames: Comma-seperated list of automata filenames. @type aut_fnames: C{str} @param evt_names: Comma seperated list of event names. @type evt_names: C{str} @param result_fname: Filename for writing the resulting automaton. @type result_fname: C{str} """ common.print_line("Started sequential abstraction computations " "(version %s)" % automata.version) coll = collection.Collection() auts = load_automata(coll, aut_fnames, True, False) auts = abstraction.order_automata(auts) events = get_events(coll, evt_names) events = ensure_tau(coll, events) result = abstraction.sequential_abstraction(auts, events) save_automaton(result, "Abstraction is saved in %s", result_fname)
def make_natural_projection(aut_name, evt_names, result_fname): """ Perform projection over a language. @param aut_name: Filename of the automaton to project. @type aut_name: L{Automaton} @param evt_names: Comma seperated list of event names to preserve. @type evt_names: C{str} @param result_fname: Filename for writing the resulting automaton. @type result_fname: C{str} """ common.print_line("Started natural projection computation (version %s)" % automata.version) coll = collection.Collection() aut = load_automaton(coll, aut_name, False, False) events = get_events(coll, evt_names) aut2 = supervisor.unweighted_determinization(aut) result = supervisor.natural_projection_map(aut2, events)[0] dump_stats("Computed projection", result) save_automaton(result, "Projected automaton is saved in %s", result_fname)
def ensure_tau(collect, events): """ Ensure that the C{tau} event exists and is part of L{events}. @param collect: Collection to get the events from. @type collect: L{collection.Collection} @param events: Events. @type events: A C{set} of L{Event} @return: Possibly updated events. @rtype: A C{set} of L{Event} """ if 'tau' not in collect.events: raise exceptions.ModelError("Event 'tau' does not exist.") tau = collect.events['tau'] if tau not in events: common.print_line("Information: Adding event 'tau' to events.\n") evts = events.copy() evts.add(tau) return evts return events
def make_weighted_supervisor(comp_name, req_name, sup_name): """ Compute a weighted supervisor. @param comp_name: Available component (weighted automaton). @type comp_name: C{str} @param req_name: Available requirement (unweighted automaton). @type req_name: C{str} @param sup_name: Name of resulting supervisor (unweighted automaton). @type sup_name: C{str} """ common.print_line("Started weighted supervisor computation " "(version %s)" % automata.version) coll = collection.Collection() comp = load_weighted_automaton(coll, comp_name, False, True) req = frontend.load_automaton(coll, req_name, False, True) sup = weighted_supervisor.compute_weighted_supervisor(comp, req) if sup is None: common.print_line("Weighted supervisor cannot be computed.") return else: frontend.dump_stats("Computed weighted supervisor", sup) frontend.save_automaton(sup, "Supervisor is saved in %s\n", sup_name)
def compute_optimal_weighted_supervisor(comp, req): """ Compute optimal weighted supervisor. @param comp: Available component (weighted automaton). @type comp: C{WeightedAutomaton} @param req: Available requirement (unweighted automaton). @type req: C{UnweightedAutomaton} @return: Resulting supervisor (unweighted automaton). @type: C{UnweightedAutomaton} """ # Compute supremal supervisor without considering weight. wsup = compute_weight.compute_weighted_supremal(comp, req) if wsup is None: return None obs_alphabet = set(evt for evt in comp.alphabet if evt.observable) waut2 = weighted_projection.weighted_projection(wsup, obs_alphabet) waut2 = weighted_determinization(waut2) weight_map = compute_weight.compute_state_weights(waut2, marker_valfn = lambda s: 0) # Throw out all states with infinite weight. waut3 = remove_automaton_states(waut2, lambda s: weight_map[s] is not maxplus.INFINITE) waut3.reduce(True, False) reduced_comp = weighted_product.n_ary_weighted_product([comp, waut3], algorithm.FIRST_EDGE) unfolded, weight_map = compute_weight.unfold_automaton_map(reduced_comp, weight_map[waut2.initial]) comp = conversion.remove_weights(comp) sup = unfolded prev_unfolded = None while True: sup = supervisor.make_supervisor([comp], [sup]) if sup is None: break prev_unfolded = sup # 'sup' is a good solution. sup = sup.copy() state_map = make_state_mapping(sup, unfolded) max_weight = max(weight_map[state_map[state]] for state in sup.get_states() if sum(1 for edge in state.get_outgoing()) == 0) common.print_line("Pruning weight %d" % max_weight) for state in list(sup.get_states()): if weight_map[state_map[state]] == max_weight and \ sum(1 for edge in state.get_outgoing()) == 0: sup.remove_state(state) assert prev_unfolded is not None return prev_unfolded
def dump_stats(title, aut): """ Output some basic statistics about an automaton. @param title: Title to put above the statistics. @type title: C{str} @param aut: Automaton. @type aut: L{Automaton} """ common.print_line(title + "\n" + str(aut))
def generate_task_resource_use(comp_names, req_names, text_path, plots, usefname): """ Generate a task/resource usage picture for path L{text_path} with components L{comp_names} and requirements L{req_names}. Output data in L{usefname}. @param comp_names: Available components (weighted automata). @type comp_names: C{list} of L{str} @param req_names: Available requirements (unweighted automata). @type req_names: C{list} of L{str} @param text_path: Sequence of events on the path (a sequence of event names, comma or white-space seperated). @type text_path: C{string} @param plots: Names of automata to plot, if specified. @type plots: C{str} @param usefname: Filename for writing task/resource use to. @type usefname: C{str} @note: The L{comp_names} and L{req_names} are only used to compute the shape of the pieces at the heap. Therefore, for type 1 requirements (where the requirements automata are not used in that calculation), L{req_names} should be left empty. """ common.print_line('Started generation of task/resource use (version %s)' % automata.version) coll = collection.Collection() comp_list = load_weighted_automata(coll, comp_names, False, True) req_list = frontend.load_automata(coll, req_names, False, True) plots = set(plots.replace(',', ' ').split()) if plots: # Non-empty set. plot_auts = set(aut for aut in comp_list + req_list if aut.name in plots) else: plot_auts = None # All automata should be plotted. uses = compute_weight.generate_task_resource_use(comp_list, req_list, plot_auts, text_path) if usefname: handle = open(usefname, 'w') for use in uses: handle.write('%s\t%s\t%s\t%s\n' % use) handle.close() else: for use in uses: print '%s\t%s\t%s\t%s' % use
def make_get_weighted_size(aut_fname): """ Display size of the weighted automaton. @param aut_fname: Filename of the weighted automaton. @type aut_fname: C{str} """ common.print_line("Started calculating size (version %s)" % automata.version) coll = collection.Collection() aut = load_weighted_automaton(coll, aut_fname, False, False) print str(aut)
def make_trim(aut_fname, out_fname): """ Trim the automaton L{aut} (reduce to reachable and co-reachable states). @param aut_fname: Filename of the automaton. @type aut_fname: C{str} @param out_fname: Filename of the resulting automaton. @type out_fname: C{str} """ common.print_line("Started trimming (version %s)" % automata.version) coll = collection.Collection() aut = load_automaton(coll, aut_fname, False, False) aut.reduce(True, True) dump_stats("Computed result", aut) save_automaton(aut, "Result is saved in %s\n", out_fname)
def make_remove_tau_event(aut_fname, out_fname): """ Remove 'tau' event from the automaton. May fail. @param aut_fname: Filename of the automaton. @type aut_fname: C{str} @param out_fname: Filename of the resulting automaton. @type out_fname: C{str} """ common.print_line("Started removing 'tau' event (version %s)" % automata.version) coll = collection.Collection() aut = load_automaton(coll, aut_fname, False, False) abstraction.remove_tau(aut) # Does in-place modification. dump_stats("Computed result", aut) save_automaton(aut, "Result is saved in %s\n", out_fname)
def make_add_tau_event(aut_fname, out_fname): """ Add 'tau' event to the automaton. @param aut_fname: Filename of the automaton. @type aut_fname: C{str} @param out_fname: Filename of the resulting automaton. @type out_fname: C{str} """ common.print_line("Started adding 'tau' event (version %s)" % automata.version) coll = collection.Collection() aut = load_automaton(coll, aut_fname, False, False) aut = abstraction.add_tau_event(aut) dump_stats("Computed result", aut) save_automaton(aut, "Result is saved in %s\n", out_fname)
def make_remove_weighted(waut_fname, result_fname): """ Remove the weights of weighted automaton L{waut_fname}, and write the result to L{result_fname}. @param waut_fname: Filename of weighted automaton to load. @type waut_fname: C{str} @param result_fname: Filename of the resulting unweighted automaton. @type result_fname: C{str} """ common.print_line("Started removing weights (version %s)" % automata.version) coll = collection.Collection() waut = load_weighted_automaton(coll, waut_fname, False, False) aut = conversion.remove_weights(waut) frontend.save_automaton(aut, "Result is saved in %s\n", result_fname)
def make_reset_weighted(aut_fname, result_fname): """ Reset the weights in weighted automaton L{aut_fname} to 0, and write the result to L{result_fname}. @param aut_fname: Filename of weighted automaton to load. @type aut_fname: C{str} @param result_fname: Filename for writing the resulting weighted automaton. @type result_fname: C{str} """ common.print_line("Started resetting weights (version %s)" % automata.version) coll = collection.Collection() aut = load_weighted_automaton(coll, aut_fname, False, False) aut.reset_weight(0) save_weighted_automaton(aut, "Result is saved in %s\n", result_fname)
def n_ary_weighted_product(auts, add_fn, delete_aut=False, report_progress=False): """ N-ary weighted automata product. @param auts: Input automata. @type auts: C{list} of L{WeightedAutomaton} @param add_fn: Name of the function to use for calculating the weight at new edge. @type add_fn: L{algorithm.SUM_EDGE_WEIGHTS}, L{algorithm.EQUAL_WEIGHT_EDGES}, L{algorithm.FIRST_EDGE}, or L{algorithm.FIRST_EDGE} @param delete_aut: Routine is allowed to delete the provided automata. @type delete_aut: C{bool} @param report_progress: Output progress of the computation. @type report_progress: C{bool} @return: Resulting weighted automaton. @rtype: L{WeightedAutomaton} """ if report_progress: common.print_line("Must do %d weighted product computations." \ % (len(auts) - 1)) props = algorithm.ManagerProperties(auts[0].collection) props.aut_type = algorithm.WEIGHTED_AUT props.marker_func = algorithm.MARKED_ALL props.explore_mgr = algorithm.ORIGINAL_STATE props.edge_calc = add_fn prod, prod_map = product.do_n_ary_product_map(props, auts, True) prod_map.clear() if delete_aut: for aut in auts: aut.clear() return prod
def make_unweight_time_optimal_supervisor(comp_names, req_names, evt_pairs, sup_name): """ Compute a non weighted time optimal supervisor. @param comp_names: Available components (weighted automata). @type comp_names: C{list} of L{str} @param req_names: Available requirements (unweighted automata). @type req_names: C{list} of L{str} @param evt_pairs: Additional event pairs (eg "{(a, b), (c, e)}", "type1", or "type2") @type evt_pairs: C{str} @param sup_name: Name of the resulting supervisor. @type sup_name: C{str} """ common.print_line("Started time unweight optimal supervisor computations " "(version %s)" % automata.version) coll = collection.Collection() comp_list = load_unweight_automata(coll, comp_names, False, True) req_list = frontend.load_automata(coll, req_names, False, True) evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs) result = compute_weight.compute_unweight_time_optimal_supervisor( comp_list, req_list, evt_pairs) if result is None: common.print_line('Could not compute the weighted supervisor') return wsup = result #one = maxplus.make_rowmat(0, heap_len) #one = maxplus.otimes_mat_mat(one, wmap[wsup.initial]) #biggest = one.get_scalar() #common.print_line("Sub-optimal makespan is %s" % biggest) #wsup = weighted_supervisor.reduce_automaton(wsup, wmap, eventdata, # heap_len) frontend.dump_stats("Computed unweighted supervisor", wsup) save_weighted_automaton(wsup, "Supervisor is saved in %s\n", sup_name)
def make_greedy_time_optimal_supervisor_row_vectors(comp_names, req_names, evt_pairs, sup_name, row_vectors, operator): """ Compute a greedy time optimal supervisor. @param comp_names: Available components (weighted automata). @type comp_names: C{list} of L{str} @param req_names: Available requirements (unweighted automata). @type req_names: C{list} of L{str} @param evt_pairs: Additional event pairs (eg "{(a, b), (c, e)}", "type1", or "type2") @type evt_pairs: C{str} @param sup_name: Name of the resulting supervisor. @type sup_name: C{str} """ common.print_line("Started greedy time optimal supervisor " "computation (version %s)" % automata.version) coll = collection.Collection() comp_list = load_weighted_automata(coll, comp_names, False, True) req_list = frontend.load_automata(coll, req_names, False, True) evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs) result = taskresource.compute_custom_eventdata(comp_list, evt_pairs) if result is None: common.print_line('Could not compute the event data from the ' 'components and event pairs\n' 'Perhaps they are inconsistent?') return eventdata, heap_len = result result = compute_weight.compute_greedy_time_optimal_supervisor( comp_list, req_list, eventdata, heap_len, row_vectors, operator) if result is None: common.print_line('Could not compute the weighted supervisor') return wsup, wmap = result one = maxplus.make_rowmat(0, heap_len) one = maxplus.otimes_mat_mat(one, wmap[wsup.initial]) biggest = one.get_scalar() common.print_line("Sub-optimal makespan is %s" % biggest) wsup = weighted_supervisor.reduce_automaton_row_vecors( wsup, wmap, eventdata, heap_len, row_vectors) frontend.dump_stats("Computed weighted supervisor", wsup) save_weighted_automaton(wsup, "Supervisor is saved in %s\n", sup_name)
def make_minimized(aut_name, result_fname): """ Perform minimization of the automaton stored in L{aut_name}, and write the result to L{result_fname}. @param aut_name: Filename of the automaton to. @type aut_name: L{Automaton} @param result_fname: Filename for writing the resulting automaton. @type result_fname: C{str} """ common.print_line("Started minimization computation (version %s)" % automata.version) coll = collection.Collection() aut = load_automaton(coll, aut_name, False, False) result = abstraction.abstraction(aut, aut.alphabet) dump_stats("Computed minimized result", result) save_automaton(result, "Minimized automaton is saved in %s", result_fname)
def make_controllability_check(plant_fname, sup_fname): """ Verify whether the plant is controllable with the supervisor. @param plant_fname: Filename of the plant automaton. @type plant_fname: C{str} @param sup_fname: Filename of the supervisor. @type sup_fname: C{str} """ common.print_line("Started controllability check (version %s)" % automata.version) coll = collection.Collection() sup_aut = load_automaton(coll, sup_fname, False, False) plant_aut = load_automaton(coll, plant_fname, False, False) contr_disableds, uncontr_disableds = \ find_disabled_events(sup_aut, plant_aut) if len(contr_disableds) > 0: print "States with disabled controllable events:" for sup_s, plant_s, dis_e in contr_disableds: print " (%d, %d): {%s}" % (plant_s.number, sup_s.number, ", ".join([e.name for e in dis_e])) print if len(uncontr_disableds) > 0: print "States with disabled uncontrollable events:" for sup_s, plant_s, dis_e, sup_p, plant_p in uncontr_disableds: print " (%d, %d): {%s}" % (plant_s.number, sup_s.number, ", ".join([e.name for e in dis_e])) print " Supervisor path: " + make_path_string(sup_p) print " Plant path: " + make_path_string(plant_p) print print "Supervisor is INCORRECT (has disabled uncontrollable events)" sys.exit(1) else: print "Supervisor is correct (no disabled uncontrollable events)"
def make_weighted_product(aut_fnames, result_fname): """ Multiply the weighthed automata in the L{aut_fnames} list, and write the result to L{result_fname}. @param aut_fnames: Comma-seperated list of weighted automata filenames. @type aut_fnames: C{str} @param result_fname: Filename for writing the resulting weighted automaton. @type result_fname: C{str} """ common.print_line("Started weighted product computations (version %s)" % automata.version) coll = collection.Collection() aut_list = load_weighted_automata(coll, aut_fnames, False, False) result = weighted_product.n_ary_weighted_product( aut_list, algorithm.SUM_EDGE_WEIGHTS, True, True) frontend.dump_stats("Computed product", result) save_weighted_automaton(result, "Product is saved in %s\n", result_fname)
def row_vector_compute(plant, req_names, evt_pairs, row_vector_names, operator_class): coll = collection.Collection() comp_list = weighted_frontend.load_weighted_automata( coll, plant, False, True) req_list = frontend.load_automata(coll, req_names, False, True) evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs) result = taskresource.compute_custom_eventdata(comp_list, evt_pairs) if result is None: common.print_line('Could not compute the event data from the ' 'components and event pairs\n' 'Perhaps they are inconsistent?') return eventdata, heap_len = result plant = weighted_product.n_ary_weighted_product( comp_list, algorithm.EQUAL_WEIGHT_EDGES) requirement = product.n_ary_unweighted_product(req_list) for comp in comp_list: comp.clear() del comp_list wsup = compute_weight.compute_weighted_supremal(plant, requirement) if wsup is None: return None requirement.clear() del requirement row_zero_mat = maxplus.make_rowmat(0, heap_len) row_epsilon_mat = maxplus.make_rowmat(maxplus.INFINITE, heap_len) marker_valfn = lambda state: row_zero_mat nonmarker_valfn = lambda state: row_epsilon_mat row_vecs = compute_state_row_vector(wsup, marker_valfn, nonmarker_valfn, eventdata, operator_class) return row_vecs
def check_marking_aware(waut, events): """ Verify that all incoming edges to marker states use events from the L{events} set. @param waut: Weighted automaton. @type waut: L{WeightedAutomaton} @param events: Events that must be used at incoming edges of marker states. @type events: A C{set} of L{Event} """ common.print_line("Started marking aware computations (version %s)" % automata.version) warnings = [] for state in waut.get_states(): if state.marked: labels = set(edge.label for edge in state.get_incoming()) for evt in labels: if evt not in events: warnings.append( "\tevent %s to state %d is not observable" % (evt.name, state.number)) if len(warnings) > 0: common.print_line(["Warning: Plant is not marking aware"]) common.print_line(warnings)
def make_time_optimal_supervisor(comp_names, req_names, evt_pairs, sup_name): """ Compute a time optimal supervisor. @param comp_names: Available components (weighted automata). @type comp_names: C{list} of C{str} @param req_names: Available requirements (unweighted automata). @type req_names: C{List} of C{str} @param evt_pairs: Additional event pairs (eg "{(a, b), (c, e)}", "type1", or "type2") @type evt_pairs: C{str} @param sup_name: Name of resulting supervisor (unweighted automaton). @type sup_name: C{str} """ common.print_line("Started time optimal supervisor computations " "(version %s)" % automata.version) coll = collection.Collection() comp_list = load_weighted_automata(coll, comp_names, False, True) req_list = frontend.load_automata(coll, req_names, False, True) evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs) result = compute_weight.compute_time_optimal_supervisor( comp_list, req_list, evt_pairs) if result is None: common.print_line("Time optimal supervisor cannot be computed.") return else: sup, min_weight = result common.print_line("Minimum makespan is %d" % min_weight) frontend.dump_stats("Computed time optimal supervisor", sup) frontend.save_automaton(sup, "Supervisor is saved in %s\n", sup_name)
def make_observer_check(aut_name, evt_names): """ Perform observer_check of the automaton stored in L{aut_name}. @param aut_name: Filename of the automaton to abstract. @type aut_name: L{Automaton} @param evt_names: Comma seperated list of event names to preserve. @type evt_names: C{str} """ common.print_line("Started observer-check computation (version %s)" % automata.version) coll = collection.Collection() aut = load_automaton(coll, aut_name, True, False) events = get_events(coll, evt_names) bad_events = abstraction.observer_check(aut, events) if len(bad_events) == 0: common.print_line("Observer-check property HOLDS") else: if len(bad_events) == 1: evt_text = "event" else: evt_text = "events" evts = ", ".join(event.name for event in bad_events) common.print_line("Observer-check property does not hold " "due to %s %s" % (evt_text, evts))
def make_supervisor(plant_fnames, spec_fnames, sup_fname): """ Construct a supervisor for controlling a plant within its specification. Function aborts if supervisor construction fails. @param plant_fnames: Filenames of the plant automata. @type plant_fnames: C{str} @param spec_fnames: Filenames of the specification automata. @type spec_fnames: C{str} @param sup_fname: Filename for the resulting supervisor. @type sup_fname: C{str} @todo: Supervisor computation should set the automaton kind by itself. """ common.print_line("Started supervisor computations (version %s)" % automata.version) coll = collection.Collection() plants = load_automata(coll, plant_fnames, False, True) specs = load_automata(coll, spec_fnames, False, True) sup = supervisor.make_supervisor(plants, specs) if sup is None: print "Supervisor is empty" sys.exit(1) else: # FIXME: This is the wrong place for setting the result kind npl = sum(1 for plant in plants if plant.aut_kind == 'plant') nsp = sum(1 for spec in specs if spec.aut_kind == 'requirement') if npl == len(plants) and nsp == len(specs): if sup.aut_kind == 'unknown': sup.set_kind('supervisor') dump_stats("Computed supervisor", sup) save_automaton(sup, "Supervisor saved in %s", sup_fname)
def compute_shortest_path(comp_names, req_names, evt_pairs): """ Compute shortest path with A* algorithm and type 1 requirements. @param comp_names: Available components (weighted automata). @type comp_names: C{list} of L{str} @param req_names: Name of the requirement automata (unweighted automata). @type req_names: C{list} of L{str} @param evt_pairs: Additional event pairs (eg "{(a, b), (c, e)}", "type1", or "type2") @type evt_pairs: C{str} """ common.print_line('Started shortest path type 1 computation (version %s)' % automata.version) coll = collection.Collection() comp_list = load_weighted_automata(coll, comp_names, False, True) req_list = frontend.load_automata(coll, req_names, False, True) evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs) compute_weight.compute_shortest_path(comp_list, req_list, evt_pairs)
def make_language_equivalence_test(aut1_fname, aut2_fname): """ Check whether the language of L{aut1_fname} is included in the language of L{aut2_fname}. @param aut1_fname: Filename of the first automaton. @type aut1_fname: C{str} @param aut2_fname: Filename of the second automaton. @type aut2_fname: C{str} """ common.print_line("Started language equivalence test (version %s)" % automata.version) coll = collection.Collection() aut1 = load_automaton(coll, aut1_fname, False, False) aut2 = load_automaton(coll, aut2_fname, False, False) res = verification.language_equivalence(aut1, aut2) if res: print "Language equivalence HOLDS" else: print "Language equivalence is INCORRECT"