@@ -82,6 +82,54 @@ def existsSemiDirectedPath(node_from: Node, node_to: Node, G: Graph) -> bool: ##
82
82
83
83
return False
84
84
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
+
85
133
def GetUncoveredCirclePath (node_from : Node , node_to : Node , G : Graph , exclude_node : List [Node ]) -> Generator [Node ] | None :
86
134
Q = Queue ()
87
135
V = set ()
@@ -802,7 +850,8 @@ def rule9(graph: Graph, nodes: List[Node], changeFlag):
802
850
for node_B in possible_children :
803
851
if graph .is_adjacent_to (node_B , node_C ):
804
852
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 ):
806
855
edge1 = graph .get_edge (node_A , node_C )
807
856
graph .remove_edge (edge1 )
808
857
graph .add_edge (Edge (node_A , node_C , Endpoint .TAIL , Endpoint .ARROW ))
0 commit comments