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 
+
+