@@ -82,6 +82,54 @@ def existsSemiDirectedPath(node_from: Node, node_to: Node, G: Graph) -> bool: ##
8282
8383 return False
8484
85+
86+
87+ def traversePotentiallyDirected (node : Node , edge : Edge ) -> Node | None :
88+ if node == edge .get_node1 ():
89+ if (edge .get_endpoint1 () == Endpoint .TAIL or edge .get_endpoint1 () == Endpoint .CIRCLE ) and \
90+ (edge .get_endpoint2 () == Endpoint .ARROW or edge .get_endpoint2 () == Endpoint .CIRCLE ):
91+ return edge .get_node2 ()
92+ elif node == edge .get_node2 ():
93+ if (edge .get_endpoint2 () == Endpoint .TAIL or edge .get_endpoint2 () == Endpoint .CIRCLE ) and \
94+ (edge .get_endpoint1 () == Endpoint .ARROW or edge .get_endpoint1 () == Endpoint .CIRCLE ):
95+ return edge .get_node1 ()
96+ return None
97+
98+
99+ def existsUncoveredPdPath (node_from : Node , node_next : Node , node_to : Node , G : Graph ) -> bool :
100+ Q = Queue ()
101+ V = set ([node_from , node_next ])
102+
103+ for node_u in G .get_adjacent_nodes (node_next ):
104+ edge = G .get_edge (node_next , node_u )
105+ node_c = traversePotentiallyDirected (node_next , edge )
106+
107+ if node_c is None :
108+ continue
109+
110+ if not V .__contains__ (node_c ):
111+ V .add (node_c )
112+ Q .put ((node_c , [node_from , node_next , node_c ]))
113+
114+ while not Q .empty ():
115+ node_t , path = Q .get_nowait ()
116+ if node_t == node_to and is_uncovered_path (path , G ):
117+ # print(f"Found uncovered pd path: {[node.get_name() for node in path]}")
118+ return True
119+
120+ for node_u in G .get_adjacent_nodes (node_t ):
121+ edge = G .get_edge (node_t , node_u )
122+ node_c = traversePotentiallyDirected (node_t , edge )
123+
124+ if node_c is None :
125+ continue
126+
127+ if not V .__contains__ (node_c ):
128+ V .add (node_c )
129+ Q .put ((node_c , path + [node_c ]))
130+
131+ return False
132+
85133def GetUncoveredCirclePath (node_from : Node , node_to : Node , G : Graph , exclude_node : List [Node ]) -> Generator [Node ] | None :
86134 Q = Queue ()
87135 V = set ()
@@ -802,7 +850,8 @@ def rule9(graph: Graph, nodes: List[Node], changeFlag):
802850 for node_B in possible_children :
803851 if graph .is_adjacent_to (node_B , node_C ):
804852 continue
805- if existsSemiDirectedPath (node_from = node_B , node_to = node_C , G = graph ):
853+
854+ if existsUncoveredPdPath (node_from = node_A , node_next = node_B , node_to = node_C , G = graph ):
806855 edge1 = graph .get_edge (node_A , node_C )
807856 graph .remove_edge (edge1 )
808857 graph .add_edge (Edge (node_A , node_C , Endpoint .TAIL , Endpoint .ARROW ))
0 commit comments