def step_12(woflan_object, return_asap_when_unsound=False): woflan_object.set_r_g_s_c( reachability_graph(woflan_object.get_s_c_net(), woflan_object.get_initial_marking(), woflan_object.get_net())) if woflan_object.print_diagnostics: print('There are non-live tasks.') if return_asap_when_unsound: return False return step_13(woflan_object, return_asap_when_unsound=return_asap_when_unsound)
def compute_non_live_sequences(woflan_object): """ We want to compute the sequences of transitions which lead to deadlocks. To do this, we first compute a reachbility graph (possible, since we know that the Petri Net is bounded) and then we convert it to a spanning tree. Afterwards, we compute the paths which lead to nodes from which the final marking cannot be reached. Note: We are searching for the shortest sequence. After the first red node, all successors are also red. Therefore, we do not have to consider them. :param woflan_object: Object that contains the necessary information :return: List of sequence of transitions, each sequence is a list """ woflan_object.set_r_g( reachability_graph(woflan_object.get_net(), woflan_object.get_initial_marking())) f_m = convert_marking(woflan_object.get_net(), woflan_object.get_final_marking()) sucessfull_terminate_state = None for node in woflan_object.get_r_g().nodes: if all(np.equal(woflan_object.get_r_g().nodes[node]['marking'], f_m)): sucessfull_terminate_state = node break # red nodes are those from which the final marking is not reachable red_nodes = [] for node in woflan_object.get_r_g().nodes: if not nx.has_path(woflan_object.get_r_g(), node, sucessfull_terminate_state): red_nodes.append(node) # Compute directed spanning tree spanning_tree = nx.algorithms.tree.Edmonds( woflan_object.get_r_g()).find_optimum() queue = set() paths = {} # root node queue.add(0) paths[0] = [] processed_nodes = set() red_paths = [] while len(queue) > 0: v = queue.pop() for node in spanning_tree.neighbors(v): if node not in paths and node not in processed_nodes: paths[node] = paths[v].copy() # we can use directly 0 here, since we are working on a spanning tree and there should be no more edges to a node paths[node].append(woflan_object.get_r_g().get_edge_data( v, node)[0]['transition']) if node not in red_nodes: queue.add(node) else: red_paths.append(paths[node]) processed_nodes.add(v) return red_paths
def step_11(woflan_object, return_asap_when_unsound=False): woflan_object.set_r_g_s_c( reachability_graph(woflan_object.get_s_c_net(), woflan_object.get_initial_marking(), woflan_object.get_net())) if nx.is_strongly_connected(woflan_object.get_r_g_s_c()): if woflan_object.print_diagnostics: print('All tasks are live.') return True else: if return_asap_when_unsound: return False return step_13(woflan_object, return_asap_when_unsound=return_asap_when_unsound)