Source code for pyreason.scripts.utils.graphml_parser

import networkx as nx
import numba

import pyreason.scripts.numba_wrapper.numba_types.fact_node_type as fact_node
import pyreason.scripts.numba_wrapper.numba_types.fact_edge_type as fact_edge
import pyreason.scripts.numba_wrapper.numba_types.label_type as label
import pyreason.scripts.numba_wrapper.numba_types.interval_type as interval


[docs] class GraphmlParser: def __init__(self): self.graph = None self.non_fluent_facts = None
[docs] def parse_graph(self, graph_path, reverse): self.graph = nx.read_graphml(graph_path) self.graph = nx.DiGraph(self.graph) if reverse: self.graph = self.graph.reverse() return self.graph
[docs] def load_graph(self, graph): self.graph = nx.DiGraph(graph) return self.graph
[docs] def parse_graph_attributes(self, static_facts): facts_node = numba.typed.List.empty_list(fact_node.fact_type) facts_edge = numba.typed.List.empty_list(fact_edge.fact_type) specific_node_labels = numba.typed.Dict.empty(key_type=label.label_type, value_type=numba.types.ListType(numba.types.string)) specific_edge_labels = numba.typed.Dict.empty(key_type=label.label_type, value_type=numba.types.ListType(numba.types.Tuple((numba.types.string, numba.types.string)))) for n in self.graph.nodes: for key, value in self.graph.nodes[n].items(): # IF attribute is a float or int and it is less than 1, then make it a bound, else make it a label if (isinstance(value, (float, int)) and 1 >= value >= 0) or ( isinstance(value, str) and value.replace('.', '').isdigit() and 1 >= float(value) >= 0): l = str(key) l_bnd = float(value) u_bnd = 1 else: l = f'{key}-{value}' l_bnd = 1 u_bnd = 1 if isinstance(value, str): bnd_str = value.split(',') if len(bnd_str) == 2: try: low = int(bnd_str[0]) up = int(bnd_str[1]) if 1 >= low >= 0 and 1 >= up >= 0: l_bnd = low u_bnd = up l = str(key) except: pass if label.Label(l) not in specific_node_labels.keys(): specific_node_labels[label.Label(l)] = numba.typed.List.empty_list(numba.types.string) specific_node_labels[label.Label(l)].append(n) f = fact_node.Fact('graph-attribute-fact', n, label.Label(l), interval.closed(l_bnd, u_bnd), 0, 0, static=static_facts) facts_node.append(f) for e in self.graph.edges: for key, value in self.graph.edges[e].items(): # IF attribute is a float or int and it is less than 1, then make it a bound, else make it a label if (isinstance(value, (float, int)) and 1 >= value >= 0) or ( isinstance(value, str) and value.replace('.', '').isdigit() and 1 >= float(value) >= 0): l = str(key) l_bnd = float(value) u_bnd = 1 else: l = f'{key}-{value}' l_bnd = 1 u_bnd = 1 if isinstance(value, str): bnd_str = value.split(',') if len(bnd_str) == 2: try: low = int(bnd_str[0]) up = int(bnd_str[1]) if 1 >= low >= 0 and 1 >= up >= 0: l_bnd = low u_bnd = up l = str(key) except: pass if label.Label(l) not in specific_edge_labels.keys(): specific_edge_labels[label.Label(l)] = numba.typed.List.empty_list(numba.types.Tuple((numba.types.string, numba.types.string))) specific_edge_labels[label.Label(l)].append((e[0], e[1])) f = fact_edge.Fact('graph-attribute-fact', (e[0], e[1]), label.Label(l), interval.closed(l_bnd, u_bnd), 0, 0, static=static_facts) facts_edge.append(f) return facts_node, facts_edge, specific_node_labels, specific_edge_labels