diff --git a/src/graph.py b/src/graph.py index 6c4badc39094cf7142a4eaf69eb571f3eb5db0c7..e397f2af066d2e82d4fc405922d6d695950a22a2 100644 --- a/src/graph.py +++ b/src/graph.py @@ -296,7 +296,7 @@ class Graph(): relev_user_view_builder(dico, relevant_modules=relevant_processes) - generate_graph(self.get_output_dir()/'graphs'/"temp", dico, label_edge=True, label_node=True, render_graphs = render_graphs) + #generate_graph(self.get_output_dir()/'graphs'/"temp", dico, label_edge=True, label_node=True, render_graphs = render_graphs) diff --git a/src/outils_graph.py b/src/outils_graph.py index 8f9c20b9d2470da653d9c4671615eb56aaa437c7..7248b4bc68d631c53b2bb7a3482a9c8dc1b55e47 100644 --- a/src/outils_graph.py +++ b/src/outils_graph.py @@ -361,6 +361,10 @@ def get_name_from_id(dico, ID): for n in dico["nodes"]: if(n['id']==ID): names.append(n['name']) + if(ID=="output"): + names.append("output") + if(ID=="input"): + names.append("input") return names def get_output_nodes(dico): @@ -371,10 +375,23 @@ def get_output_nodes(dico): for e in dico["edges"]: none_outputs.append(e['A']) outputs = list(set(N) - set(none_outputs)) - outputs_names = [] - for o in outputs: - outputs_names+=get_name_from_id(dico=dico, ID=o) - return outputs_names + #outputs_names = [] + #for o in outputs: + # outputs_names+=get_name_from_id(dico=dico, ID=o) + return outputs + +def get_input_nodes(dico): + N = [] + for n in dico["nodes"]: + N.append(n['id']) + none_inputs = [] + for e in dico["edges"]: + none_inputs.append(e['B']) + inputs = list(set(N) - set(none_inputs)) + #inputs_names = [] + #for o in inputs: + # inputs_names+=get_name_from_id(dico=dico, ID=o) + return inputs def remove_edges_with_node(edges, nodes): edges_without_node = [] @@ -411,44 +428,202 @@ def exist_path(A, B, edges): return False -def nr_path(n, r, dico, R, outputs): - +def nr_path_succ(n, r, dico, R): rest_of_R = set(R)-set([r]) - rest_of_R_ids = [] - for r_p in rest_of_R: - rest_of_R_ids+=get_id_from_name(dico, r_p) - edges = remove_edges_with_node(dico["edges"], rest_of_R_ids) - - for n_ids in get_id_from_name(dico, n): - for r_ids in get_id_from_name(dico, r): - if(exist_path(n_ids, r_ids, edges)): - return True + edges = remove_edges_with_node(dico["edges"], rest_of_R) + if(exist_path(n, r, edges)): + return True return False +def nr_path_pred(r, n, dico, R): + rest_of_R = set(R)-set([r]) + edges = remove_edges_with_node(dico["edges"], rest_of_R) + if(exist_path(r, n, edges)): + return True + return False + def rSucc(n, dico, R, outputs): tab = [] for r in set(R).union(set(outputs)): - if(nr_path(n, r, dico, R, outputs)): + if(nr_path_succ(n, r, dico, R+list(outputs))): + tab.append(r) + return tab + +def rSuccM(M, dico, R, outputs): + tab = [] + for n in M: + tab += rSucc(n, dico, R, outputs) + return list(set(tab)) + +def rPred(n, dico, R, inputs): + tab = [] + for r in set(R).union(set(inputs)): + if(nr_path_pred(r, n, dico, R+list(inputs))): tab.append(r) return tab +def rPredM(M, dico, R, inputs): + tab = [] + for n in M: + tab += rPred(n, dico, R, inputs) + return list(set(tab)) + +def generate_subsets(original_set): + # Base case: If the set is empty, return a set with the empty subset + if not original_set: + return [[]] + + # Recursive step: Take one element from the set + first_element = original_set[0] + rest_set = original_set[1:] + + # Recursively find all subsets of the remaining elements + subsets_without_first = generate_subsets(rest_set) + + # For each subset, add the first element to create new subsets + subsets_with_first = [subset + first_element for subset in subsets_without_first] + + # Return all subsets (with and without the first element) + return subsets_without_first + subsets_with_first + +def set_has_incoming_edge_different_M(dico, M): + tab = [] + for n in M: + for edge in dico["edges"]: + if(edge['B']==n and (edge['A'] not in M)): + tab.append(n) + return list(set(tab)) + +def set_has_outcoming_edge_different_M(dico, M): + tab = [] + for n in M: + for edge in dico["edges"]: + if(edge['A']==n and (edge['B'] not in M)): + tab.append(n) + return list(set(tab)) + +def get_names_tab(dico, tab): + final = [] + for group in tab: + if(type(group)==str): + names = get_name_from_id(dico, group) + else: + names = [] + for node in group: + names+=get_name_from_id(dico, node) + final.append(names) + return final + def relev_user_view_builder(dico, relevant_modules): - R = relevant_modules + R = [] + for r in relevant_modules: + R+=get_id_from_name(dico, r) outputs = get_output_nodes(dico) + inputs = get_input_nodes(dico) + #dico['nodes'].append({'id':"input", 'name':"input"}) + #dico['nodes'].append({'id':"output", 'name':"output"}) + for out in outputs: + dico["edges"].append({'A':out, 'B':'output'}) + #TODO remove this -> it's to replicate the one in the algortihm demo + dico["edges"].append({'A':get_id_from_name(dico, "M5")[0], 'B':'output'}) + for input in inputs: + dico["edges"].append({'A':"input", 'B':input}) U = [] - markes_statues = {} + #Step 1 + marked_statues = {} N = [] for n in dico["nodes"]: - # markes_statues[n['name']] = "marked" - N.append(n['name']) + # marked_statues[n['name']] = "marked" + N.append(n['id']) N_minus_R = set(N) - set(R) for n in N_minus_R: - markes_statues[n] = "unmarked" - #print(N_minus_R) + marked_statues[n] = "unmarked" + #Line 3, 4 and 5 + in_r = {} + for r in R: + in_r[r] = [] + for n in set(N) - set(R): + if(rSucc(n, dico, R, ["output"])==[r]): + in_r[r].append(n) + marked_statues[n] = "marked" + #Line 6, 7 and 8 + out_r = {} for r in R: - in_r = [] + out_r[r] = [] for n in set(N) - set(R): - if(rSucc(n, dico, R, outputs)==[r]): - in_r.append(n) - print(r, in_r) \ No newline at end of file + if(rPred(n, dico, R, ["input"])==[r] and marked_statues[n] == "unmarked"): + out_r[r].append(n) + marked_statues[n] = "marked" + + + #Line 10 + for r in R: + M = set([r]).union(set(in_r[r])).union(set(out_r[r])) + U = set(U).union(M) + #Step 2 + NRC = [] + order = list(set(N) - set(R)) + order.sort() + for n in order: + if(marked_statues[n] == 'unmarked'): + print(get_name_from_id(dico, n)) + def condition_line_13(NRC, n, dico, R, inputs, outputs): + #Ms = generate_subsets(NRC) + for i in range(len(NRC)): + M = NRC[i] + print("M", get_names_tab(dico, M), "-> rPredM", get_names_tab(dico, rPredM(M, dico, R, ["input"]))) + print('n', get_name_from_id(dico, n), '-> rPred', get_names_tab(dico, rPred(n, dico, R, ['input']))) + print("M", get_names_tab(dico, M), "-> rSuccM", get_names_tab(dico, rSuccM(M, dico, R, ["output"]))) + print('n', get_name_from_id(dico, n), '-> rSucc', get_names_tab(dico, rSucc(n, dico, R, ['output']))) + print() + if(rPredM(M, dico, R, ["input"])==rPred(n, dico, R, ["input"]) and + rSuccM(M, dico, R, ['output'])==rSucc(n , dico, R, ['output'])): + return True, i + return False, -1 + + #print('n', get_name_from_id(dico, n), '-> rPred', get_names_tab(dico, rPred(n, dico, R, ['input']))) + #print('n', get_name_from_id(dico, n), '-> rSucc', get_names_tab(dico, rSucc(n, dico, R, ['output']))) + check, index = condition_line_13(NRC, n, dico, R, ["input"], ['output']) + if(check): + NRC[index].append(n) + print("here") + else: + M = [n] + NRC.append(M) + print(get_names_tab(dico, NRC)) + + 1/0 + #Step 3 + changes_in_NRC = True + while(changes_in_NRC): + changes_in_NRC = False + temp_NRC = copy.deepcopy(NRC) + for i in range(len(temp_NRC)): + M1 = temp_NRC[i] + for y in range(len(temp_NRC)): + M2 = temp_NRC[y] + if(i>y): + M = M1+M2 + #set(M1).union(set(M2)) + V_minus = set_has_incoming_edge_different_M(dico, M) + V_plus = set_has_outcoming_edge_different_M(dico, M) + #Line 23 + condition_left, condition_right = True, True + for n in V_plus: + if(rPred(n, dico, R, ['input'])!=rPredM(M, dico, R, ["input"])): + condition_left = False + for n in V_minus: + if(rSucc(n, dico, R, ['output'])!=rSuccM(M, dico, R, ["output"])): + condition_left = False + if(condition_left and condition_right): + NRC.remove(M1) + NRC.remove(M2) + NRC.append(M) + changes_in_NRC = True + tab = list(U)+NRC + print(tab) + print(get_names_tab(dico, tab)) + return + +