def test_inject_clone_node(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) new_p_node, new_rhs_node = rule.inject_clone_node(2) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert (new_p_node in rule.p.nodes()) assert (new_rhs_node in rule.rhs.nodes()) assert (rule.p_rhs[new_p_node] == new_rhs_node) assert ((1, new_p_node) in rule.p.edges()) assert ((3, new_p_node) in rule.p.edges()) assert ((1, new_rhs_node) in rule.rhs.edges()) assert ((3, new_rhs_node) in rule.rhs.edges()) new_p_node, new_rhs_node = rule.inject_clone_node(2) assert (len(keys_by_value(rule.p_lhs, 2)) == 3) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) rule.inject_remove_node(3) try: rule.inject_clone_node(3) raise ValueError("Cloning of removed node was not caught") except: pass
def test_inject_clone_node(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) new_p_node, new_rhs_node = rule.inject_clone_node(2) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert(new_p_node in rule.p.nodes()) assert(new_rhs_node in rule.rhs.nodes()) assert(rule.p_rhs[new_p_node] == new_rhs_node) assert((1, new_p_node) in rule.p.edges()) assert((3, new_p_node) in rule.p.edges()) assert((1, new_rhs_node) in rule.rhs.edges()) assert((3, new_rhs_node) in rule.rhs.edges()) new_p_node, new_rhs_node = rule.inject_clone_node(2) assert(len(keys_by_value(rule.p_lhs, 2)) == 3) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) rule.inject_remove_node(3) try: rule.inject_clone_node(3) raise ValueError("Cloning of removed node was not caught") except: pass
def test_rewrite(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, (2, {"a": {1, 2}}), 3]) prim.add_edges_from(pattern, [(1, 2), (2, 3)]) lhs_typing = { "g0": { 1: "circle", 2: "square", 3: "triangle" }, "g00": { 1: "white", 2: "white", 3: "black" } } p = nx.DiGraph() p.add_nodes_from([1, 2, 3]) p.add_edges_from([(2, 3)]) rhs = nx.DiGraph() prim.add_nodes_from( rhs, [1, (2, { "a": {3, 5} }), (3, { "new_attrs": {1} }), 4]) prim.add_edges_from(rhs, [(2, 1, { "new_attrs": {2} }), (2, 4, { "new_attrs": {3} }), (2, 3, { "new_attrs": {4} })]) p_lhs = {1: 1, 2: 2, 3: 3} p_rhs = {1: 1, 2: 2, 3: 3} rule = Rule(p, pattern, rhs, p_lhs, p_rhs) rhs_typing = { "g0": { 1: "circle", 2: "square", 3: "triangle", 4: "triangle" }, "g00": { 1: "white", 2: "white", 3: "black", 4: "black" } } instances = self.hierarchy.find_matching("g1", pattern, lhs_typing) # print(instances[0]) self.hierarchy.rewrite("g1", rule, instances[0], lhs_typing, rhs_typing)
def test_inject_remove_node(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) rule.inject_remove_node(2) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert (2 in rule.lhs.nodes()) assert (2 not in rule.p.nodes()) assert (2 not in rule.rhs.nodes())
def test_inject_remove_node(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) rule.inject_remove_node(2) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert(2 in rule.lhs.nodes()) assert(2 not in rule.p.nodes()) assert(2 not in rule.rhs.nodes())
def test_find_matching(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [(1, { 'state': 'p' }), (2, { 'name': 'BND' }), (3), (4)]) prim.add_edges_from(pattern, [(1, 2, { 's': 'p' }), (3, 2, { 's': 'u' }), (3, 4)]) find_matching(self.graph, pattern)
def test_find_matching(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [(1, {'state': 'p'}), (2, {'name': 'BND'}), (3), (4)] ) prim.add_edges_from(pattern, [(1, 2, {'s': 'p'}), (3, 2, {'s': 'u'}), (3, 4)] ) find_matching(self.graph, pattern)
def test_inject_add_node(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) try: rule.inject_add_node(3) raise ValueError("Node duplication was not caught") except RuleError: pass rule.inject_add_node(4) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert (4 in rule.rhs.nodes() and 4 not in rule.lhs.nodes() and 4 not in rule.p.nodes())
def test_inject_add_node(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) try: rule.inject_add_node(3) raise ValueError("Node duplication was not caught") except RuleError: pass rule.inject_add_node(4) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert(4 in rule.rhs.nodes() and 4 not in rule.lhs.nodes() and 4 not in rule.p.nodes())
def test_inject_merge_nodes(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) new_name = rule.inject_merge_nodes([1, 2]) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert((new_name, new_name) in rule.rhs.edges()) assert((3, new_name) in rule.rhs.edges()) new_p_name, new_rhs_name = rule.inject_clone_node(2) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) new_name = rule.inject_merge_nodes([2, 3]) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert(new_p_name in rule.rhs.nodes())
def test_find_matching(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, (2, {"a": 1}), 3]) prim.add_edges_from(pattern, [(1, 2), (2, 3)]) pattern_typing = {1: "circle", 2: "square", 3: "triangle"} instances = self.hierarchy.find_matching(graph_id="g1", pattern=pattern, pattern_typing={ "g0": pattern_typing, "g00": { 1: "white", 2: "white", 3: "black" } }) assert (len(instances) == 1)
def test_inject_merge_nodes(self): pattern = NXGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) new_name = rule.inject_merge_nodes([1, 2]) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert ((new_name, new_name) in rule.rhs.edges()) assert ((3, new_name) in rule.rhs.edges()) new_p_name, new_rhs_name = rule.inject_clone_node(2) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) new_name = rule.inject_merge_nodes([2, 3]) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert (new_rhs_name in rule.rhs.nodes())
def test_controlled_up_propagation(self): pattern = nx.DiGraph() pattern.add_nodes_from(["A"]) rule = Rule.from_transform(pattern) p_clone, _ = rule.inject_clone_node("A") rule.inject_add_node("D") p_typing = { "nn1": { "A_bye": {}, "A_hello": {p_clone} }, "n1": { "A": p_clone } } instance = {"A": "A"} nugget_1 = nx.DiGraph() primitives.add_nodes_from( nugget_1, ["A_bye", "A_hello", "A_res_1", "p", "B", "mod"]) primitives.add_edges_from(nugget_1, [("A_res_1", "A_hello"), ("A_res_1", "A_bye"), ("p", "A_res_1"), ("mod", "p"), ("B", "mod")]) self.hierarchy.add_graph("nn1", nugget_1) self.hierarchy.add_typing( "nn1", "n1", { "A_bye": "A", "A_hello": "A", "A_res_1": "A_res_1", "p": "p", "B": "B", "mod": "mod" }) new_hierarchy, _ = self.hierarchy.rewrite("ag", rule, instance, p_typing=p_typing, inplace=False) primitives.print_graph(new_hierarchy.get_graph("nn1")) print(new_hierarchy.typing["nn1"]["n1"])
def test_inject_remove_edge_attrs(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2, { "a12": {True} }), (3, 2, { "a32": {True} })]) rule = Rule.from_transform(pattern) rule.inject_remove_edge_attrs(1, 2, {"a12": {True}}) assert ("a12" not in rule.p.edge[1][2]) new_p_node, new_rhs_node = rule.inject_clone_node(2) assert ("a12" not in rule.p.edge[1][new_p_node]) rule.inject_remove_edge_attrs(3, new_p_node, {"a32": {True}}) assert ("a32" in rule.p.edge[3][2]) assert ("a32" not in rule.p.edge[3][new_p_node]) assert ("a32" in rule.rhs.edge[3][rule.p_rhs[2]]) assert ("a32" not in rule.rhs.edge[3][new_rhs_node])
def test_inject_remove_edge_attrs(self): pattern = nx.DiGraph() prim.add_nodes_from( pattern, [1, 2, 3]) prim.add_edges_from( pattern, [(1, 2, {"a12": {True}}), (3, 2, {"a32": {True}})]) rule = Rule.from_transform(pattern) rule.inject_remove_edge_attrs(1, 2, {"a12": {True}}) assert("a12" not in rule.p.adj[1][2]) new_p_node, new_rhs_node = rule.inject_clone_node(2) assert("a12" not in rule.p.adj[1][new_p_node]) rule.inject_remove_edge_attrs(3, new_p_node, {"a32": {True}}) assert("a32" in rule.p.adj[3][2]) assert("a32" not in rule.p.adj[3][new_p_node]) assert("a32" in rule.rhs.adj[3][rule.p_rhs[2]]) assert("a32" not in rule.rhs.adj[3][new_rhs_node])
def test_component_getters(self): pattern = nx.DiGraph() prim.add_nodes_from( pattern, [(1, {"a1": {1}}), (2, {"a2": {2}}), (3, {"a3": {3}})] ) prim.add_edges_from( pattern, [ (1, 2, {"a12": {12}}), (2, 3), (3, 2, {"a32": {32}}) ] ) rule = Rule.from_transform(pattern) rule.remove_node(1) rule.remove_edge(2, 3) new_name, _ = rule.clone_node(2) print(new_name) rule.remove_node_attrs(3, {"a3": {3}}) rule.remove_edge_attrs(3, 2, {"a32": {32}}) rule.add_node_attrs(3, {"a3": {100}}) rule.add_node(4) rule.add_edge_rhs(4, "21") assert(rule.removed_nodes() == {1}) print(rule.removed_edges()) assert(rule.removed_edges() == {(2, 3), (new_name[0], 3)}) assert(len(rule.cloned_nodes()) == 1 and 2 in rule.cloned_nodes().keys()) assert(len(rule.removed_node_attrs()) == 1 and 3 in rule.removed_node_attrs()[3]["a3"]) assert(len(rule.removed_edge_attrs()) == 1 and 32 in rule.removed_edge_attrs()[(3, 2)]["a32"]) assert(rule.added_nodes() == {4}) assert(rule.added_edges() == {(4, "21")}) # rule.merged_nodes() # rule.added_edge_attrs() assert(len(rule.added_node_attrs()) == 1 and 100 in rule.added_node_attrs()[3]["a3"]) assert(rule.is_restrictive() and rule.is_relaxing())
def test_inject_add_node_attrs(self): pattern = NXGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) clone_name_p, clone_name_rhs = rule.inject_clone_node(2) rule.inject_add_node(4) merge = rule.inject_merge_nodes([1, 3]) rule.inject_add_node_attrs(2, {"a": {True}}) assert ("a" in rule.rhs.get_node(2)) rule.inject_add_node_attrs(clone_name_p, {"b": {True}}) assert ("b" in rule.rhs.get_node(clone_name_rhs)) assert ("b" not in rule.rhs.get_node(2)) rule.inject_add_node_attrs(4, {"c": {True}}) assert ("c" in rule.rhs.get_node(4)) rule.inject_add_node_attrs(merge, {"d": {True}}) assert ("d" in rule.rhs.get_node(merge)) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs)
def test_inject_add_edge(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) rule.inject_add_node(4) rule.inject_add_edge(1, 4) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert ((1, 4) in rule.rhs.edges()) merge_node = rule.inject_merge_nodes([1, 2]) rule.inject_add_edge(merge_node, 3) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert ((merge_node, 3) in rule.rhs.edges()) new_p_node, new_rhs_node = rule.inject_clone_node(2) rule.inject_add_edge(new_p_node, merge_node) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert ((new_rhs_node, merge_node) in rule.rhs.edges())
def test_inject_add_edge(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) rule.inject_add_node(4) rule.inject_add_edge(1, 4) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert((1, 4) in rule.rhs.edges()) merge_node = rule.inject_merge_nodes([1, 2]) rule.inject_add_edge(merge_node, 3) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert((merge_node, 3) in rule.rhs.edges()) new_p_node, new_rhs_node = rule.inject_clone_node(2) rule.inject_add_edge(new_p_node, merge_node) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert((new_rhs_node, merge_node) in rule.rhs.edges())
def test_inject_remove_node_attrs(self): pattern = nx.DiGraph() prim.add_nodes_from( pattern, [1, (2, {"a2": {True}}), (3, {"a3": {False}})]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) rule.inject_remove_node_attrs(3, {"a3": {False}}) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert("a3" not in rule.p.node[3]) assert("a3" in rule.lhs.node[3]) new_p_node, new_rhs_node = rule.inject_clone_node(2) rule.inject_remove_node_attrs(new_p_node, {"a2": {True}}) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs) assert("a2" not in rule.p.node[new_p_node]) assert("a2" in rule.p.node[2]) assert("a2" not in rule.rhs.node[new_rhs_node]) assert("a2" in rule.rhs.node[2])
def test_inject_add_node_attrs(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2, 3]) prim.add_edges_from(pattern, [(1, 2), (3, 2)]) rule = Rule.from_transform(pattern) clone_name_p, clone_name_rhs = rule.inject_clone_node(2) rule.inject_add_node(4) merge = rule.inject_merge_nodes([1, 3]) rule.inject_add_node_attrs(2, {"a": {True}}) assert("a" in rule.rhs.node[2]) assert("a" in rule.rhs.node[clone_name_rhs]) rule.inject_add_node_attrs(clone_name_p, {"b": {True}}) assert("b" in rule.rhs.node[clone_name_rhs]) assert("b" not in rule.rhs.node[2]) rule.inject_add_node_attrs(4, {"c": {True}}) assert("c" in rule.rhs.node[4]) rule.inject_add_node_attrs(merge, {"d": {True}}) assert("d" in rule.rhs.node[merge]) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs)
def test_inject_add_edge_attrs(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [0, 1, 2, 3]) prim.add_edges_from(pattern, [(0, 1), (0, 2), (1, 2), (3, 2)]) rule = Rule.from_transform(pattern) clone_name_p, clone_name_rhs = rule.inject_clone_node(2) rule.inject_add_node(4) rule.inject_add_edge(4, 3) merge = rule.inject_merge_nodes([1, 3]) rule.inject_add_edge_attrs(0, 1, {"a": {True}}) assert ("a" in rule.rhs.edge[0][merge]) rule.inject_add_edge_attrs(0, clone_name_p, {"b": {True}}) assert ("b" in rule.rhs.edge[0][clone_name_rhs]) rule.inject_add_edge_attrs(merge, clone_name_p, {"c": {True}}) assert ("c" in rule.rhs.edge[merge][clone_name_rhs]) assert ("c" not in rule.rhs.edge[merge][2]) rule.inject_add_edge_attrs(4, merge, {"d": {True}}) assert ("d" in rule.rhs.edge[4][merge]) check_homomorphism(rule.p, rule.lhs, rule.p_lhs) check_homomorphism(rule.p, rule.rhs, rule.p_rhs)
def test_find_matching(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [ 1, (2, {"a": 1}), 3 ]) prim.add_edges_from(pattern, [ (1, 2), (2, 3) ]) pattern_typing = {1: "circle", 2: "square", 3: "triangle"} instances = self.hierarchy.find_matching( graph_id="g1", pattern=pattern, pattern_typing={ "g0": pattern_typing, "g00": {1: "white", 2: "white", 3: "black"} } ) assert(len(instances) == 1)
def test_from_commands(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [(1, { 'state': 'p' }), (2, { 'name': 'BND' }), 3, 4]) prim.add_edges_from(pattern, [(1, 2, { 's': 'p' }), (3, 2, { 's': 'u' }), (3, 4)]) p = nx.DiGraph() prim.add_nodes_from(p, [(1, { 'state': 'p' }), ("1_clone", { 'state': 'p' }), (2, { 'name': 'BND' }), 3, 4]) prim.add_edges_from(p, [(1, 2), ('1_clone', 2), (3, 4)]) rhs = nx.DiGraph() prim.add_nodes_from(rhs, [(1, { 'state': 'p' }), ("1_clone", { 'state': 'p' }), (2, { 'name': 'BND' }), 3, 4, 5]) prim.add_edges_from(rhs, [(1, 2, { 's': 'u' }), ('1_clone', 2), (2, 4), (3, 4), (5, 3)]) p_lhs = {1: 1, '1_clone': 1, 2: 2, 3: 3, 4: 4} p_rhs = {1: 1, '1_clone': '1_clone', 2: 2, 3: 3, 4: 4} rule1 = Rule(p, pattern, rhs, p_lhs, p_rhs) commands = "clone 1.\n" +\ "delete_edge 3 2.\n" +\ "add_node 5.\n" +\ "add_edge 2 4.\n" +\ "add_edge 5 3." rule2 = Rule.from_transform(pattern, commands) assert ((5, 3) in rule2.rhs.edges()) assert (5 in rule2.rhs.nodes() and 5 not in rule2.p.nodes()) assert ((2, 4) in rule2.rhs.edges())
def test_from_commands(self): pattern = nx.DiGraph() prim.add_nodes_from( pattern, [(1, {'state': 'p'}), (2, {'name': 'BND'}), 3, 4] ) prim.add_edges_from( pattern, [(1, 2, {'s': 'p'}), (3, 2, {'s': 'u'}), (3, 4)] ) p = nx.DiGraph() prim.add_nodes_from( p, [(1, {'state': 'p'}), ("1_clone", {'state': 'p'}), (2, {'name': 'BND'}), 3, 4]) prim.add_edges_from( p, [(1, 2), ('1_clone', 2), (3, 4)]) rhs = nx.DiGraph() prim.add_nodes_from( rhs, [(1, {'state': 'p'}), ("1_clone", {'state': 'p'}), (2, {'name': 'BND'}), 3, 4, 5]) prim.add_edges_from( rhs, [(1, 2, {'s': 'u'}), ('1_clone', 2), (2, 4), (3, 4), (5, 3)]) p_lhs = {1: 1, '1_clone': 1, 2: 2, 3: 3, 4: 4} p_rhs = {1: 1, '1_clone': '1_clone', 2: 2, 3: 3, 4: 4} rule1 = Rule(p, pattern, rhs, p_lhs, p_rhs) commands = "clone 1.\n" +\ "delete_edge 3 2.\n" +\ "add_node 5.\n" +\ "add_edge 2 4.\n" +\ "add_edge 5 3." rule2 = Rule.from_transform(pattern, commands) assert((5, 3) in rule2.rhs.edges()) assert(5 in rule2.rhs.nodes() and 5 not in rule2.p.nodes()) assert((2, 4) in rule2.rhs.edges())
def test_add_rule_multiple_typing(self): lhs = nx.DiGraph() prim.add_nodes_from(lhs, [1, 2, 3, 4]) prim.add_edges_from(lhs, [(1, 3), (2, 3), (4, 3)]) p = nx.DiGraph() prim.add_nodes_from(p, [1, 3, 31, 4]) prim.add_edges_from(p, [(1, 3), (1, 31), (4, 3), (4, 31)]) rhs = copy.deepcopy(p) p_lhs = {1: 1, 3: 3, 31: 3, 4: 4} p_rhs = {1: 1, 3: 3, 31: 31, 4: 4} lhs_typing_g2 = {1: 1, 2: 1, 3: 2, 4: 4} rhs_typing_g2 = {1: 1, 3: 2, 31: 2, 4: 4} lhs_typing_g3 = {1: 1, 2: 1, 3: 1, 4: 2} rhs_typing_g3 = {1: 1, 3: 1, 31: 1, 4: 2} rule = Rule(p, lhs, rhs, p_lhs, p_rhs) self.hierarchy.add_rule("r2", rule, {"name": "Second rule: with multiple typing"}) self.hierarchy.add_rule_typing("r2", "g2", lhs_typing_g2, rhs_typing_g2) self.hierarchy.add_rule_typing("r2", "g3", lhs_typing_g3, rhs_typing_g3) pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, 2]) prim.add_edges_from(pattern, [(2, 1)]) lhs_typing = { "g0": { 1: "circle", 2: "circle" }, "g00": { 1: "black", 2: "white" } } p = nx.DiGraph() prim.add_nodes_from(p, [1, 2, 21]) prim.add_edges_from(p, [(21, 1)]) rhs = copy.deepcopy(p) p_lhs = {1: 1, 2: 2, 21: 2} p_rhs = {1: 1, 2: 2, 21: 21} rule = Rule(p, pattern, rhs, p_lhs, p_rhs) rhs_typing = { "g0": ({ 1: "circle", 2: "circle", 21: "circle", }), "g00": ({ 1: "black", 2: "white", 21: "white" }) } instances = self.hierarchy.find_matching("g1", pattern, lhs_typing) self.hierarchy.rewrite("g1", rule, instances[0], lhs_typing, rhs_typing)
def __init__(self): self.hierarchy = NetworkXHierarchy() a = nx.DiGraph() primitives.add_nodes_from(a, [ ("red", {"sex": {"male", "female"}}), ("blue", {"location": {"far", "close"}}) ]) primitives.add_edges_from(a, [ ("red", "red", {"type": {"friend", "supervisor"}}), ("red", "blue", {"type": "works"}), ("blue", "blue") ]) self.hierarchy.add_graph("a", a) b = nx.DiGraph() primitives.add_nodes_from(b, [ ("prof", {"sex": {"male", "female"}}), ("student", {"sex": {"male", "female"}}), ("school", {"location": {"far", "close"}}), ("institute", {"location": {"far", "close"}}) ]) primitives.add_edges_from( b, [ ("prof", "prof", {"type": "friend"}), ("student", "student", {"type": "friend"}), ("prof", "student", {"type": {"friend", "supervisor"}}), ("student", "prof", {"type": "friend"}), ("prof", "school"), ("prof", "institute"), ("student", "school"), ("institute", "school") ]) self.hierarchy.add_graph("b", b) b_a = { "prof": "red", "student": "red", "school": "blue", "institute": "blue" } self.hierarchy.add_graph("bb", b) self.hierarchy.add_typing("b", "bb", {n: n for n in b.nodes()}) self.hierarchy.add_typing("b", "a", b_a) self.hierarchy.add_typing("bb", "a", b_a) c = nx.DiGraph() primitives.add_nodes_from(c, [ ("Alice", {"sex": "female"}), ("Bob", {"sex": "male"}), ("John", {"sex": "male"}), ("Nancy", {"sex": "female"}), ("ENS", {"location": "close"}), ("INRIA") ]) primitives.add_edges_from(c, [ ("Alice", "Bob", {"type": "friend"}), ("Alice", "ENS"), ("John", "Alice", {"type": "supervisor"}), ("John", "ENS"), ("Nancy", "John", {"type": "friend"}), ("Nancy", "INRIA") ]) c_b = { "Alice": "student", "Bob": "student", "John": "prof", "Nancy": "prof", "ENS": "school", "INRIA": "institute" } self.hierarchy.add_graph("c", c) self.hierarchy.add_typing("c", "b", c_b)
def __init__(self): self.hierarchy = Hierarchy(directed=True) g0 = nx.DiGraph() prim.add_node(g0, "circle", {"a": {1, 2, 3}}) prim.add_node(g0, "square", {"a": {1, 2, 3, 5}}) prim.add_node(g0, "triangle", {"new_attrs": {1}}) prim.add_edges_from( g0, [ ("circle", "circle"), # , {"b": {1, 2, 3, 4}}), ("circle", "square"), ("square", "circle", { "new_attrs": {2} }), ("square", "triangle", { "new_attrs": {3, 4} }) ]) self.hierarchy.add_graph("g0", g0, {"name": "Shapes"}) g00 = nx.DiGraph() prim.add_node(g00, 'black', {"a": {1, 2, 3}, "new_attrs": {1}}) prim.add_node(g00, 'white', {"a": {1, 2, 3, 5}}) prim.add_edges_from(g00, [('white', 'white', { "new_attrs": 2 }), ('white', 'black', { "new_attrs": {4, 3} }), ('black', 'black'), ('black', 'white')]) self.hierarchy.add_graph("g00", g00, {"name": "Colors"}) g1 = nx.DiGraph() prim.add_nodes_from(g1, [("black_circle", { "a": {1, 2, 3} }), "white_circle", "black_square", ("white_square", { "a": {1, 2} }), "black_triangle", "white_triangle"]) prim.add_edges_from( g1, [ ("black_circle", "black_circle"), # {"b": {1, 2, 3, 4}}), ("black_circle", "white_circle"), ("black_circle", "black_square"), ("white_circle", "black_circle"), ("white_circle", "white_square"), ("black_square", "black_circle"), ("black_square", "black_triangle"), ("black_square", "white_triangle"), ("white_square", "white_circle"), ("white_square", "black_triangle"), ("white_square", "white_triangle") ]) self.hierarchy.add_graph("g1", g1) self.hierarchy.add_typing( "g1", "g0", { "black_circle": "circle", "white_circle": "circle", "black_square": "square", "white_square": "square", "black_triangle": "triangle", "white_triangle": "triangle" }) self.hierarchy.add_typing( "g1", "g00", { "black_square": "black", "black_circle": "black", "black_triangle": "black", "white_square": "white", "white_circle": "white", "white_triangle": "white" }) g2 = nx.DiGraph() prim.add_nodes_from(g2, [ (1, { "a": {1, 2} }), 2, 3, 4, (5, { "a": {1} }), 6, 7, ]) prim.add_edges_from( g2, [ (1, 2), # {"b": {1, 2, 3}}), (2, 3), (3, 6), (3, 7), (4, 2), (4, 5), (5, 7) ]) self.hierarchy.add_graph("g2", g2) self.hierarchy.add_typing( "g2", "g1", { 1: "black_circle", 2: "black_circle", 3: "black_square", 4: "white_circle", 5: "white_square", 6: "white_triangle", 7: "black_triangle" }) g3 = nx.DiGraph() prim.add_nodes_from( g3, [ (1), # {"a": {1, 2}}), 2, 3, 5, (4), # {"a": {1}}), 6, 7, ]) prim.add_edges_from( g3, [ (1, 1), # , {"b": {1, 2, 3}}), (1, 2), (1, 3), (1, 5), (2, 1), (3, 4), (4, 7), (4, 6), (5, 6), (5, 7) ]) self.hierarchy.add_graph("g3", g3) self.hierarchy.add_typing( "g3", "g1", { 1: "black_circle", 2: "white_circle", 3: "white_circle", 5: "black_square", 4: "white_square", 6: "white_triangle", 7: "black_triangle" }) g4 = nx.DiGraph() prim.add_nodes_from(g4, [1, 2, 3]) prim.add_edges_from(g4, [(1, 2), (2, 3)]) self.hierarchy.add_graph("g4", g4) self.hierarchy.add_typing("g4", "g2", {1: 2, 2: 3, 3: 6}) self.hierarchy.add_typing("g4", "g3", {1: 1, 2: 5, 3: 6}) g5 = nx.DiGraph() prim.add_nodes_from( g5, [ ("black_circle"), # {"a": {255}}), ("black_square"), # {"a": {256}}), ("white_triangle"), # {"a": {257}}), ("star") # , {"a": {258}}) ]) prim.add_edges_from( g5, [ ("black_circle", "black_square"), ("black_square", "white_triangle"), # , {"b": {11}}), ("star", "black_square"), ("star", "white_triangle") ]) self.hierarchy.add_graph("g5", g5)
def __init__(self): hierarchy = NetworkXHierarchy() base = nx.DiGraph() prim.add_nodes_from(base, [ ("circle", {"a": {1, 2, 3}}), ("square", {"b": {1, 2, 3}}) ]) prim.add_edges_from(base, [ ("circle", "circle"), ("square", "square"), ("circle", "square", {"c": {5, 6, 7}}), ("square", "circle") ]) hierarchy.add_graph("base", base) a1 = nx.DiGraph() prim.add_nodes_from(a1, [ ("black_circle", {"a": {1}}), ("white_circle", {"a": {2}}), ("black_square", {"b": {1}}), ("white_square", {"b": {1}}) ]) prim.add_edges_from(a1, [ ("white_circle", "white_circle"), ("white_circle", "white_square", {"c": {5}}), ("black_circle", "black_square"), ("black_square", "white_square"), ("black_circle", "white_square", {"c": {6}}) ]) hierarchy.add_graph("a1", a1) hierarchy.add_typing( "a1", "base", { "black_circle": "circle", "white_circle": "circle", "white_square": "square", "black_square": "square" } ) a2 = nx.DiGraph() prim.add_nodes_from(a2, [ ("right_circle", {"a": {1, 2}}), ("middle_square", {"b": {1}}), ("left_circle", {"a": 1}) ]) prim.add_edges_from(a2, [ ("right_circle", "middle_square", {"c": {5, 6, 7}}), ("left_circle", "middle_square", {"c": {6, 7}}) ]) hierarchy.add_graph("a2", a2) hierarchy.add_typing( "a2", "base", { "right_circle": "circle", "middle_square": "square", "left_circle": "circle" } ) self.hierarchy = hierarchy
def get_rule_projections(tx, hierarchy, graph_id, rule, instance, rhs_typing=None): """Execute the query finding rule liftings.""" if rhs_typing is None: rhs_typing = {} projections = {} if rule.is_relaxing(): if len(rule.lhs.nodes()) > 0: lhs_instance = { n: instance[n] for n in rule.lhs.nodes() } lhs_vars = { n: n for n in rule.lhs.nodes()} match_instance_vars = { v: lhs_instance[k] for k, v in lhs_vars.items() } # Match nodes query = "// Match nodes the instance of the rewritten graph \n" query += "MATCH {}".format( ", ".join([ "({}:{} {{id: '{}'}})".format(k, graph_id, v) for k, v in match_instance_vars.items() ]) ) query += "\n\n" carry_vars = list(lhs_vars.values()) for k, v in lhs_vars.items(): query += ( "OPTIONAL MATCH (n)<-[:typing*1..]-({})\n".format(v) + "WITH {} \n".format( ", ".join( carry_vars + ["collect(DISTINCT {{type:'node', origin: {}.id, id: n.id, graph:labels(n)[0], attrs: properties(n)}}) as {}_dict\n".format( v, v)]) ) ) carry_vars.append("{}_dict".format(v)) # Match edges for (u, v) in rule.p.edges(): edge_var = "{}_{}".format(lhs_vars[u], lhs_vars[v]) query += "OPTIONAL MATCH ({}_instance)-[{}:edge]->({}_instance)\n".format( lhs_vars[u], edge_var, lhs_vars[v]) query += "WHERE ({})<-[:typing*1..]-({}) AND ({})<-[:typing*1..]-({})\n".format( "{}_instance".format(lhs_vars[u]), lhs_vars[u], "{}_instance".format(lhs_vars[v]), lhs_vars[v]) query += ( "WITH {} \n".format( ", ".join(carry_vars + [ "collect({{type: 'edge', source: {}.id, target: {}.id, graph:labels({})[0], attrs: properties({})}}) as {}\n".format( "{}_instance".format(lhs_vars[u]), "{}_instance".format(lhs_vars[v]), "{}_instance".format(lhs_vars[u]), edge_var, edge_var) ]) ) ) carry_vars.append(edge_var) query += "RETURN {}".format( ", ".join( ["{}_dict as {}".format(v, v) for v in lhs_vars.values()] + ["{}_{}".format(lhs_vars[u], lhs_vars[v]) for u, v in rule.p.edges()])) result = tx.run(query) record = result.single() l_l_ts = {} l_nodes = {} l_edges = {} for k, v in record.items(): if len(v) > 0: if v[0]["type"] == "node": for el in v: l_node = keys_by_value(instance, el["origin"])[0] if el["graph"] not in l_nodes: l_nodes[el["graph"]] = {} l_l_ts[el["graph"]] = {} if el["id"] not in l_nodes[el["graph"]]: l_nodes[el["graph"]][el["id"]] = {} l_nodes[el["graph"]][el["id"]] = attrs_union( l_nodes[el["graph"]][el["id"]], attrs_intersection( generic.convert_props_to_attrs(el["attrs"]), get_node(rule.lhs, l_node))) l_l_ts[el["graph"]][l_node] = el["id"] else: for el in v: l_sources = keys_by_value(l_l_ts[el["graph"]], el["source"]) l_targets = keys_by_value(l_l_ts[el["graph"]], el["target"]) for l_source in l_sources: for l_target in l_targets: if exists_edge(rule.l, l_source, l_target): if el["graph"] not in l_edges: l_edges[el["graph"]] = {} if (el["source"], el["target"]) not in l_edges[el["graph"]]: l_edges[el["graph"]][(el["source"], el["target"])] = {} l_edges[el["graph"]][(el["source"], el["target"])] =\ attrs_union( l_edges[el["graph"]][(el["source"], el["target"])], attrs_intersection( generic.convert_props_to_attrs(el["attrs"]), get_edge(rule.lhs, l_source, l_target))) for graph, typing in hierarchy.get_descendants(graph_id).items(): if graph in l_nodes: nodes = l_nodes[graph] else: nodes = {} if graph in l_edges: edges = l_edges[graph] else: edges = {} l = nx.DiGraph() add_nodes_from(l, [(k, v) for k, v in nodes.items()]) if graph in l_edges: add_edges_from( l, [(s, t, v) for (s, t), v in edges.items()]) rhs, p_rhs, r_r_t = pushout( rule.p, l, rule.rhs, compose(rule.p_lhs, l_l_ts[graph]), rule.p_rhs) l_t_t = {n: n for n in nodes} # Modify P_T and R_T according to the controlling # relation rhs_typing if graph in rhs_typing.keys(): r_t_factorization = { r_r_t[k]: v for k, v in rhs_typing[graph].items() } added_t_nodes = set() for n in rhs.nodes(): if n in r_t_factorization.keys(): # If corresponding R_T node is specified in # the controlling relation add nodes of T # that type it to P t_nodes = r_t_factorization[n] for t_node in t_nodes: if t_node not in l_t_t.values() and\ t_node not in added_t_nodes: new_p_node = generate_new_id( l.nodes(), t_node) l.add_node(new_p_node) added_t_nodes.add(t_node) p_rhs[new_p_node] = n l_t_t[new_p_node] = t_node else: p_rhs[keys_by_value(l_t_t, t_node)[0]] = n projections[graph] = { "rule": Rule(p=l, rhs=rhs, p_rhs=p_rhs), "instance": l_t_t, "l_l_t": l_l_ts[graph], "p_p_t": {k: l_l_ts[graph][v] for k, v in rule.p_lhs.items()}, "r_r_t": r_r_t } return projections
"""ReGraph hierarchy tutorial ex 1.""" import networkx as nx from regraph import Hierarchy, plot_graph, primitives # create an empty hierarchy hierarchy = Hierarchy() # initialize graphs `t` & `g` t = nx.DiGraph() primitives.add_nodes_from(t, ["agent", "action", "state"]) primitives.add_edges_from(t, [("agent", "agent"), ("state", "agent"), ("agent", "action"), ("action", "state")]) g = nx.DiGraph() primitives.add_nodes_from(g, ["protein", "region", "activity", "mod"]) primitives.add_edges_from(g, [("region", "protein"), ("activity", "protein"), ("activity", "region"), ("protein", "mod"), ("region", "mod"), ("mod", "activity")]) # add graphs to the hierarchy hierarchy.add_graph("T", t) hierarchy.add_graph("G", g) # add typing of `g` by `t` mapping = { "protein": "agent", "region": "agent", "activity": "state", "mod": "action" }
def test_neo4j_hierarchy_versioning(self): """Test hierarchy versioning functionality.""" try: hierarchy = Neo4jHierarchy(uri="bolt://localhost:7687", user="******", password="******") hierarchy._clear() hierarchy.add_graph("shapes", node_list=[("c", { "a": 1 }), ("s", { "b": 2 })]) hierarchy.add_graph("colors", node_list=[("w", { "a": 1, "b": 2 }), ("b", { "a": 1, "b": 2 })]) hierarchy.add_graph("ag", node_list=[("wc", { "a": 1 }), "bc", "ws", ("bs", { "b": 2 })]) hierarchy.add_graph("nugget", node_list=[("wc1", { "a": 1 }), "wc2", "bc1", "ws1", ("bs2", { "b": 2 })]) hierarchy.add_typing("ag", "shapes", { "wc": "c", "bc": "c", "ws": "s", "bs": "s" }) hierarchy.add_typing("ag", "colors", { "wc": "w", "bc": "b", "ws": "w", "bs": "b" }) hierarchy.add_typing("nugget", "ag", { "wc1": "wc", "wc2": "wc", "bc1": "bc", "ws1": "ws", "bs2": "bs" }) hierarchy.add_typing("nugget", "colors", { "wc1": "w", "wc2": "w", "bc1": "b", "ws1": "w", "bs2": "b" }) hierarchy.add_graph("base", node_list=[("node", {"a": 1, "b": 2})]) hierarchy.add_typing("colors", "base", {"w": "node", "b": "node"}) pattern = nx.DiGraph() pattern.add_nodes_from(["s", "c"]) rule = Rule.from_transform(pattern) rule.inject_add_edge("s", "c", {"c": 3}) hierarchy.rewrite("nugget", rule, {"s": "bs2", "c": "wc1"}) h = VersionedHierarchy(hierarchy) rollback_commit = h._heads["master"] pattern = nx.DiGraph() primitives.add_nodes_from(pattern, [("s", { "b": 2 }), ("c", { "a": 1 })]) primitives.add_edges_from(pattern, [("s", "c", {"c": 3})]) rule2 = Rule.from_transform(pattern) clone, _ = rule2.inject_clone_node("s") rule2.inject_add_node("new_node") rule2.inject_add_edge("new_node", "s", {"d": 4}) merged_rule_node = rule2.inject_merge_nodes([clone, "c"]) rule2.inject_remove_edge("s", "c") rhs_instances, first_commit = h.rewrite( "ag", rule2, { "s": "bs", "c": "wc" }, message="Rewriting neo4j graph") merged_ag_node = rhs_instances["ag"][merged_rule_node] h.branch('test') pattern = nx.DiGraph() pattern.add_nodes_from(["ws"]) rule3 = Rule.from_transform(pattern) rule3.inject_remove_node("ws") h.rewrite("ag", rule3, {"ws": "ws"}, message="Removed ws from ag") h.switch_branch("master") pattern = nx.DiGraph() pattern.add_nodes_from([merged_ag_node]) rule4 = Rule.from_transform(pattern) rule4.inject_clone_node(merged_ag_node) h.rewrite("ag", rule4, {merged_ag_node: merged_ag_node}, message="Cloned merged from ag") h.merge_with("test") data = h.to_json() h1 = VersionedHierarchy.from_json(hierarchy, data) h1.print_history() h1.rollback(rollback_commit) # except ServiceUnavailable as e: # print(e) except: print()
def get_rule_liftings(tx, graph_id, rule, instance, p_typing=None): """Execute the query finding rule liftings.""" if p_typing is None: p_typing = {} liftings = {} if len(rule.lhs.nodes()) > 0: lhs_vars = { n: n for n in rule.lhs.nodes()} match_instance_vars = {lhs_vars[k]: v for k, v in instance.items()} # Match nodes query = "// Match nodes the instance of the rewritten graph \n" query += "MATCH {}".format( ", ".join([ "({}:{} {{id: '{}'}})".format(k, graph_id, v) for k, v in match_instance_vars.items() ]) ) query += "\n\n" carry_vars = list(lhs_vars.values()) for k, v in lhs_vars.items(): query += ( "OPTIONAL MATCH (n)-[:typing*1..]->({})\n".format(v) + "WITH {} \n".format( ", ".join(carry_vars + [ "collect({{type:'node', origin: {}.id, id: n.id, graph:labels(n)[0], attrs: properties(n)}}) as {}_dict\n".format( v, v)]) ) ) carry_vars.append("{}_dict".format(v)) # Match edges for (u, v) in rule.lhs.edges(): edge_var = "{}_{}".format(lhs_vars[u], lhs_vars[v]) query += "OPTIONAL MATCH ({}_instance)-[{}:edge]->({}_instance)\n".format( lhs_vars[u], edge_var, lhs_vars[v]) query += "WHERE ({})-[:typing*1..]->({}) AND ({})-[:typing*1..]->({})\n".format( "{}_instance".format(lhs_vars[u]), lhs_vars[u], "{}_instance".format(lhs_vars[v]), lhs_vars[v]) query += ( "WITH {} \n".format( ", ".join(carry_vars + [ "collect({{type: 'edge', source: {}.id, target: {}.id, attrs: properties({}), graph:labels({})[0]}}) as {}\n".format( "{}_instance".format(lhs_vars[u]), "{}_instance".format(lhs_vars[v]), edge_var, "{}_instance".format(lhs_vars[u]), edge_var) ]) ) ) carry_vars.append(edge_var) query += "RETURN {}".format( ", ".join( ["{}_dict as {}".format(v, v) for v in lhs_vars.values()] + ["{}_{}".format(lhs_vars[u], lhs_vars[v]) for u, v in rule.lhs.edges()])) result = tx.run(query) record = result.single() l_g_ls = {} lhs_nodes = {} lhs_edges = {} for k, v in record.items(): if len(v) > 0: if v[0]["type"] == "node": for el in v: if el["graph"] not in lhs_nodes: lhs_nodes[el["graph"]] = [] l_g_ls[el["graph"]] = {} l_g_ls[el["graph"]][el["id"]] = keys_by_value( instance, el["origin"])[0] # compute attr intersection attrs = attrs_intersection( generic.convert_props_to_attrs(el["attrs"]), get_node(rule.lhs, l_g_ls[el["graph"]][el["id"]])) lhs_nodes[el["graph"]].append((el["id"], attrs)) else: for el in v: if el["graph"] not in lhs_edges: lhs_edges[el["graph"]] = [] # compute attr intersection attrs = attrs_intersection( generic.convert_props_to_attrs(el["attrs"]), get_edge( rule.lhs, l_g_ls[el["graph"]][el["source"]], l_g_ls[el["graph"]][el["target"]])) lhs_edges[el["graph"]].append( (el["source"], el["target"], attrs) ) for graph, nodes in lhs_nodes.items(): lhs = nx.DiGraph() add_nodes_from(lhs, nodes) if graph in lhs_edges: add_edges_from( lhs, lhs_edges[graph]) p, p_lhs, p_g_p = pullback( lhs, rule.p, rule.lhs, l_g_ls[graph], rule.p_lhs) l_g_g = {n[0]: n[0] for n in nodes} # Remove controlled things from P_G if graph in p_typing.keys(): l_g_factorization = { keys_by_value(l_g_g, k)[0]: v for k, v in p_typing[graph].items() } p_g_nodes_to_remove = set() for n in p.nodes(): l_g_node = p_lhs[n] # If corresponding L_G node is specified in # the controlling relation, remove all # the instances of P nodes not mentioned # in this relations if l_g_node in l_g_factorization.keys(): p_nodes = l_g_factorization[l_g_node] if p_g_p[n] not in p_nodes: del p_g_p[n] del p_lhs[n] p_g_nodes_to_remove.add(n) for n in p_g_nodes_to_remove: p.remove_node(n) liftings[graph] = { "rule": Rule(p=p, lhs=lhs, p_lhs=p_lhs), "instance": l_g_g, "l_g_l": l_g_ls[graph], "p_g_p": p_g_p } else: query = generic.ancestors_query(graph_id, "graph", "homomorphism") result = tx.run(query) ancestors = [record["ancestor"] for record in result] for a in ancestors: liftings[a] = { "rule": Rule.identity_rule(), "instance": {}, "l_g_l": {}, "p_g_p": {} } return liftings
def test_rewrite(self): pattern = nx.DiGraph() prim.add_nodes_from(pattern, [ 1, (2, {"a": {1, 2}}), 3 ]) prim.add_edges_from(pattern, [ (1, 2), (2, 3) ]) lhs_typing = { "g0": {1: "circle", 2: "square", 3: "triangle"}, "g00": {1: "white", 2: "white", 3: "black"} } p = nx.DiGraph() p.add_nodes_from([ 1, 2, 3 ]) p.add_edges_from([ (2, 3) ]) rhs = nx.DiGraph() prim.add_nodes_from(rhs, [ 1, (2, {"a": {3, 5}}), (3, {"new_attrs": {1}}), 4 ]) prim.add_edges_from(rhs, [ (2, 1, {"new_attrs": {2}}), (2, 4, {"new_attrs": {3}}), (2, 3, {"new_attrs": {4}}) ]) p_lhs = {1: 1, 2: 2, 3: 3} p_rhs = {1: 1, 2: 2, 3: 3} rule = Rule(p, pattern, rhs, p_lhs, p_rhs) rhs_typing = { "g0": { 1: "circle", 2: "square", 3: "triangle", 4: "triangle" }, "g00": { 1: "white", 2: "white", 3: "black", 4: "black" } } instances = self.hierarchy.find_matching( "g1", pattern, lhs_typing ) # print(instances[0]) self.hierarchy.rewrite( "g1", rule, instances[0], lhs_typing, rhs_typing )
def __init__(self): hierarchy = Hierarchy() hierarchy = Hierarchy() colors = nx.DiGraph() primitives.add_nodes_from( colors, [("red", {"r": 255, "g": 0, "b": 0}), ("blue", {"r": 0, "g": 0, "b": 255})] ) primitives.add_edges_from( colors, [("red", "red"), ("blue", "red"), ("red", "blue")] ) hierarchy.add_graph("colors", colors) mmm = nx.DiGraph() primitives.add_nodes_from( mmm, ["component", "state", "action"] ) primitives.add_edges_from( mmm, [("component", "action"), ("component", "component"), ("state", "component"), ("action", "state")] ) hierarchy.add_graph("mmm", mmm) mm = nx.DiGraph() primitives.add_nodes_from( mm, ["gene", "residue", "state", "mod"] ) primitives.add_edges_from( mm, [("residue", "gene"), ("state", "gene"), ("state", "residue"), ("mod", "state"), ("gene", "mod")] ) hierarchy.add_graph("mm", mm) action_graph = nx.DiGraph() primitives.add_nodes_from( action_graph, ["A", "A_res_1", "p_a", "B", "mod1", "mod2", "C", "p_c", "activity"] ) primitives.add_edges_from( action_graph, [("A_res_1", "A"), ("p_a", "A_res_1"), ("mod1", "p_a"), ("B", "mod1"), ("p_c", "C"), ("B", "mod2"), ("activity", "B"), ("mod2", "p_c")] ) hierarchy.add_graph("ag", action_graph) nugget_1 = nx.DiGraph() primitives.add_nodes_from( nugget_1, ["A", "A_res_1", "p", "B", "mod"] ) primitives.add_edges_from( nugget_1, [("A_res_1", "A"), ("p", "A_res_1"), ("mod", "p"), ("B", "mod")] ) hierarchy.add_graph("n1", nugget_1) nugget_2 = nx.DiGraph() primitives.add_nodes_from( nugget_2, ["B", "activity", "mod", "p", "C"]) primitives.add_edges_from(nugget_2, [ ("activity", "B"), ("B", "mod"), ("mod", "p"), ("p", "C")]) hierarchy.add_graph("n2", nugget_2) # add typings hierarchy.add_typing( "mm", "mmm", { "gene": "component", "residue": "component", "state": "state", "mod": "action" }, total=True ) hierarchy.add_typing( "mm", "colors", { "gene": "red", "residue": "red", "state": "red", "mod": "blue" } ) hierarchy.add_typing( "ag", "mm", { "A": "gene", "B": "gene", "A_res_1": "residue", "mod1": "mod", "p_a": "state", "C": "gene", "activity": "state", "p_c": "state", "mod2": "mod" }, total=True ) hierarchy.add_typing( "n1", "ag", { "A": "A", "B": "B", "A_res_1": "A_res_1", "mod": "mod1", "p": "p_a", }, total=True ) hierarchy.add_typing( "n2", "ag", { "B": "B", "C": "C", "p": "p_c", "activity": "activity", "mod": "mod2", }, total=True ) self.hierarchy = hierarchy
def test_add_rule(self): lhs = nx.DiGraph() prim.add_nodes_from(lhs, [1, 2, 3]) prim.add_edges_from(lhs, [(1, 2), (2, 1), (2, 3)]) p = nx.DiGraph() prim.add_nodes_from(p, [1, 2, 3, 31]) prim.add_edges_from(p, [(1, 2), (2, 3), (2, 31)]) rhs = nx.DiGraph() prim.add_nodes_from(rhs, [1, 2, 3, 31, 4]) prim.add_edges_from(rhs, [(1, 2), (4, 2), (2, 3), (2, 31)]) p_lhs = {1: 1, 2: 2, 3: 3, 31: 3} p_rhs = {1: 1, 2: 2, 3: 3, 31: 3} rule = Rule(p, lhs, rhs, p_lhs, p_rhs) lhs_typing = {1: "black_circle", 2: "white_circle", 3: "white_square"} rhs_typing = { 1: "black_circle", 2: "white_circle", 3: "white_square", 31: "white_square", 4: "black_circle" } self.hierarchy.add_rule("r1", rule, {"name": "First rule"}) self.hierarchy.add_rule_typing("r1", "g1", lhs_typing, rhs_typing) pattern = nx.DiGraph() prim.add_nodes_from(pattern, [1, (2, {"a": {1, 2}}), 3]) prim.add_edges_from(pattern, [(1, 2), (2, 3)]) lhs_typing = { "g0": { 1: "circle", 2: "square", 3: "triangle" }, "g00": { 1: 'white', 2: 'white', 3: 'black' } } p = nx.DiGraph() prim.add_nodes_from(p, [1, 11, 2, 3]) prim.add_edges_from(p, [(2, 3)]) rhs = nx.DiGraph() prim.add_nodes_from(rhs, [ 1, 11, (2, { "a": {3, 5} }), (3, { "new_attrs": {1} }), ]) prim.add_edges_from(rhs, [(2, 3, {"new_attrs": {4}})]) p_lhs = {1: 1, 11: 1, 2: 2, 3: 3} p_rhs = {1: 1, 11: 11, 2: 2, 3: 3} rule = Rule(p, pattern, rhs, p_lhs, p_rhs) rhs_typing = { "g0": { 1: "circle", 11: "circle", 2: "square", 3: "triangle" }, "g00": { 1: "white", 11: "white", 2: "white", 3: "black" } } instances = self.hierarchy.find_matching("g1", pattern, lhs_typing) self.hierarchy.rewrite("g1", rule, instances[0], lhs_typing, rhs_typing)
def test_add_rule_multiple_typing(self): lhs = nx.DiGraph() prim.add_nodes_from(lhs, [1, 2, 3, 4]) prim.add_edges_from(lhs, [ (1, 3), (2, 3), (4, 3) ]) p = nx.DiGraph() prim.add_nodes_from(p, [1, 3, 31, 4]) prim.add_edges_from(p, [ (1, 3), (1, 31), (4, 3), (4, 31) ]) rhs = copy.deepcopy(p) p_lhs = {1: 1, 3: 3, 31: 3, 4: 4} p_rhs = {1: 1, 3: 3, 31: 31, 4: 4} lhs_typing_g2 = { 1: 1, 2: 1, 3: 2, 4: 4 } rhs_typing_g2 = { 1: 1, 3: 2, 31: 2, 4: 4 } lhs_typing_g3 = { 1: 1, 2: 1, 3: 1, 4: 2 } rhs_typing_g3 = { 1: 1, 3: 1, 31: 1, 4: 2 } rule = Rule(p, lhs, rhs, p_lhs, p_rhs) self.hierarchy.add_rule( "r2", rule, {"name": "Second rule: with multiple typing"}) self.hierarchy.add_rule_typing( "r2", "g2", lhs_typing_g2, rhs_typing_g2) self.hierarchy.add_rule_typing( "r2", "g3", lhs_typing_g3, rhs_typing_g3) pattern = nx.DiGraph() prim.add_nodes_from(pattern, [ 1, 2 ]) prim.add_edges_from(pattern, [ (2, 1) ]) lhs_typing = { "g0": {1: "circle", 2: "circle"}, "g00": {1: "black", 2: "white"} } p = nx.DiGraph() prim.add_nodes_from(p, [ 1, 2, 21 ]) prim.add_edges_from(p, [ (21, 1) ]) rhs = copy.deepcopy(p) p_lhs = {1: 1, 2: 2, 21: 2} p_rhs = {1: 1, 2: 2, 21: 21} rule = Rule(p, pattern, rhs, p_lhs, p_rhs) rhs_typing = { "g0": ({ 1: "circle", 2: "circle", 21: "circle", }), "g00": ({ 1: "black", 2: "white", 21: "white" }) } instances = self.hierarchy.find_matching( "g1", pattern, lhs_typing ) self.hierarchy.rewrite( "g1", rule, instances[0], lhs_typing, rhs_typing )
def __init__(self): hierarchy = NetworkXHierarchy() base = nx.DiGraph() prim.add_nodes_from(base, [("circle", { "a": {1, 2, 3} }), ("square", { "b": {1, 2, 3} })]) prim.add_edges_from(base, [("circle", "circle"), ("square", "square"), ("circle", "square", { "c": {5, 6, 7} }), ("square", "circle")]) hierarchy.add_graph("base", base) a1 = nx.DiGraph() prim.add_nodes_from(a1, [("black_circle", { "a": {1} }), ("white_circle", { "a": {2} }), ("black_square", { "b": {1} }), ("white_square", { "b": {1} })]) prim.add_edges_from(a1, [("white_circle", "white_circle"), ("white_circle", "white_square", { "c": {5} }), ("black_circle", "black_square"), ("black_square", "white_square"), ("black_circle", "white_square", { "c": {6} })]) hierarchy.add_graph("a1", a1) hierarchy.add_typing( "a1", "base", { "black_circle": "circle", "white_circle": "circle", "white_square": "square", "black_square": "square" }) a2 = nx.DiGraph() prim.add_nodes_from(a2, [("right_circle", { "a": {1, 2} }), ("middle_square", { "b": {1} }), ("left_circle", { "a": 1 })]) prim.add_edges_from(a2, [("right_circle", "middle_square", { "c": {5, 6, 7} }), ("left_circle", "middle_square", { "c": {6, 7} })]) hierarchy.add_graph("a2", a2) hierarchy.add_typing( "a2", "base", { "right_circle": "circle", "middle_square": "square", "left_circle": "circle" }) self.hierarchy = hierarchy
def test_add_rule(self): lhs = nx.DiGraph() prim.add_nodes_from(lhs, [ 1, 2, 3 ]) prim.add_edges_from(lhs, [ (1, 2), (2, 1), (2, 3) ]) p = nx.DiGraph() prim.add_nodes_from(p, [ 1, 2, 3, 31 ]) prim.add_edges_from(p, [ (1, 2), (2, 3), (2, 31) ]) rhs = nx.DiGraph() prim.add_nodes_from(rhs, [ 1, 2, 3, 31, 4 ]) prim.add_edges_from(rhs, [ (1, 2), (4, 2), (2, 3), (2, 31) ]) p_lhs = {1: 1, 2: 2, 3: 3, 31: 3} p_rhs = {1: 1, 2: 2, 3: 3, 31: 3} rule = Rule(p, lhs, rhs, p_lhs, p_rhs) lhs_typing = { 1: "black_circle", 2: "white_circle", 3: "white_square" } rhs_typing = { 1: "black_circle", 2: "white_circle", 3: "white_square", 31: "white_square", 4: "black_circle" } self.hierarchy.add_rule("r1", rule, {"name": "First rule"}) self.hierarchy.add_rule_typing("r1", "g1", lhs_typing, rhs_typing) pattern = nx.DiGraph() prim.add_nodes_from(pattern, [ 1, (2, {"a": {1, 2}}), 3 ]) prim.add_edges_from(pattern, [ (1, 2), (2, 3) ]) lhs_typing = { "g0": {1: "circle", 2: "square", 3: "triangle"}, "g00": {1: 'white', 2: 'white', 3: 'black'} } p = nx.DiGraph() prim.add_nodes_from(p, [ 1, 11, 2, 3 ]) prim.add_edges_from(p, [ (2, 3) ]) rhs = nx.DiGraph() prim.add_nodes_from(rhs, [ 1, 11, (2, {"a": {3, 5}}), (3, {"new_attrs": {1}}), ]) prim.add_edges_from(rhs, [ (2, 3, {"new_attrs": {4}}) ]) p_lhs = {1: 1, 11: 1, 2: 2, 3: 3} p_rhs = {1: 1, 11: 11, 2: 2, 3: 3} rule = Rule(p, pattern, rhs, p_lhs, p_rhs) rhs_typing = { "g0": { 1: "circle", 11: "circle", 2: "square", 3: "triangle" }, "g00": { 1: "white", 11: "white", 2: "white", 3: "black" } } instances = self.hierarchy.find_matching( "g1", pattern, lhs_typing) self.hierarchy.rewrite( "g1", rule, instances[0], lhs_typing, rhs_typing)
def test_refinement(self): graph = NXGraph() prim.add_nodes_from(graph, [ ("a", { "name": "Bob" }), ("b", { "name": "Jane" }), ("c", { "name": "Alice" }), ("d", { "name": "Joe" }), ]) prim.add_edges_from(graph, [("a", "a", { "type": "friends" }), ("a", "b", { "type": "enemies" }), ("c", "a", { "type": "colleages" }), ("d", "a", { "type": "siblings" })]) pattern = NXGraph() pattern.add_nodes_from(["x", "y"]) pattern.add_edges_from([("y", "x")]) instance = {"x": "a", "y": "d"} # Remove node side-effects rule = Rule.from_transform(NXGraph.copy(pattern)) rule.inject_remove_node("x") new_instance = rule.refine(graph, instance) assert (new_instance == {"x": "a", "y": "d", "b": "b", "c": "c"}) assert (prim.get_node(rule.lhs, "x") == prim.get_node(graph, "a")) assert (prim.get_edge(rule.lhs, "x", "b") == prim.get_edge(graph, "a", "b")) assert (prim.get_edge(rule.lhs, "c", "x") == prim.get_edge(graph, "c", "a")) # Remove edge side-effects rule = Rule.from_transform(NXGraph.copy(pattern)) rule.inject_remove_edge("y", "x") new_instance = rule.refine(graph, instance) assert (prim.get_edge(rule.lhs, "y", "x") == prim.get_edge(graph, "d", "a")) # Merge side-effects rule = Rule.from_transform(NXGraph.copy(pattern)) rule.inject_merge_nodes(["x", "y"]) new_instance = rule.refine(graph, instance) assert (new_instance == {"x": "a", "y": "d", "b": "b", "c": "c"}) assert (rule.lhs.get_node("x") == graph.get_node("a")) assert (rule.lhs.get_node("y") == graph.get_node("d")) assert (rule.lhs.get_edge("y", "x") == graph.get_edge("d", "a")) # Combined side-effects # Ex1: Remove cloned edge + merge with some node graph.remove_edge("a", "a") pattern.add_node("z") pattern.add_edge("x", "z") instance["z"] = "b" rule = Rule.from_transform(NXGraph.copy(pattern)) p_node, _ = rule.inject_clone_node("x") rule.inject_remove_node("z") rule.inject_remove_edge("y", p_node) rule.inject_merge_nodes([p_node, "y"]) new_instance = rule.refine(graph, instance) assert (new_instance == {"x": "a", "y": "d", "z": "b", "c": "c"}) assert (prim.get_node(rule.lhs, "x") == prim.get_node(graph, "a")) assert (prim.get_node(rule.lhs, "y") == prim.get_node(graph, "d")) assert (prim.get_edge(rule.lhs, "y", "x") == prim.get_edge(graph, "d", "a")) # test with rule inversion backup = NXGraph.copy(graph) rhs_g = graph.rewrite(rule, new_instance) inverted = rule.get_inverted_rule() rhs_gg = graph.rewrite(inverted, rhs_g) # print(rhs_gg) old_node_labels = {v: new_instance[k] for k, v in rhs_gg.items()} graph.relabel_nodes(old_node_labels) assert (backup == graph)
def __init__(self): self.hierarchy = NetworkXHierarchy(directed=True) g0 = nx.DiGraph() prim.add_node(g0, "circle", {"a": {1, 2, 3}}) prim.add_node(g0, "square", {"a": {1, 2, 3, 5}}) prim.add_node(g0, "triangle", {"new_attrs": {1}}) prim.add_edges_from(g0, [ ("circle", "circle"), # , {"b": {1, 2, 3, 4}}), ("circle", "square"), ("square", "circle", {"new_attrs": {2}}), ("square", "triangle", {"new_attrs": {3, 4}}) ]) self.hierarchy.add_graph("g0", g0, {"name": "Shapes"}) g00 = nx.DiGraph() prim.add_node(g00, 'black', {"a": {1, 2, 3}, "new_attrs": {1}}) prim.add_node(g00, 'white', {"a": {1, 2, 3, 5}}) prim.add_edges_from(g00, [ ('white', 'white', {"new_attrs": 2}), ('white', 'black', {"new_attrs": {4, 3}}), ('black', 'black'), ('black', 'white') ]) self.hierarchy.add_graph("g00", g00, {"name": "Colors"}) g1 = nx.DiGraph() prim.add_nodes_from(g1, [ ("black_circle", {"a": {1, 2, 3}}), "white_circle", "black_square", ("white_square", {"a": {1, 2}}), "black_triangle", "white_triangle" ]) prim.add_edges_from(g1, [ ("black_circle", "black_circle"), # {"b": {1, 2, 3, 4}}), ("black_circle", "white_circle"), ("black_circle", "black_square"), ("white_circle", "black_circle"), ("white_circle", "white_square"), ("black_square", "black_circle"), ("black_square", "black_triangle"), ("black_square", "white_triangle"), ("white_square", "white_circle"), ("white_square", "black_triangle"), ("white_square", "white_triangle") ]) self.hierarchy.add_graph("g1", g1) self.hierarchy.add_typing( "g1", "g0", {"black_circle": "circle", "white_circle": "circle", "black_square": "square", "white_square": "square", "black_triangle": "triangle", "white_triangle": "triangle"} ) self.hierarchy.add_typing( "g1", "g00", { "black_square": "black", "black_circle": "black", "black_triangle": "black", "white_square": "white", "white_circle": "white", "white_triangle": "white" } ) g2 = nx.DiGraph() prim.add_nodes_from(g2, [ (1, {"a": {1, 2}}), 2, 3, 4, (5, {"a": {1}}), 6, 7, ]) prim.add_edges_from(g2, [ (1, 2), # {"b": {1, 2, 3}}), (2, 3), (3, 6), (3, 7), (4, 2), (4, 5), (5, 7) ]) self.hierarchy.add_graph("g2", g2) self.hierarchy.add_typing( "g2", "g1", {1: "black_circle", 2: "black_circle", 3: "black_square", 4: "white_circle", 5: "white_square", 6: "white_triangle", 7: "black_triangle"} ) g3 = nx.DiGraph() prim.add_nodes_from(g3, [ (1), # {"a": {1, 2}}), 2, 3, 5, (4), # {"a": {1}}), 6, 7, ]) prim.add_edges_from(g3, [ (1, 1), # , {"b": {1, 2, 3}}), (1, 2), (1, 3), (1, 5), (2, 1), (3, 4), (4, 7), (4, 6), (5, 6), (5, 7) ]) self.hierarchy.add_graph("g3", g3) self.hierarchy.add_typing( "g3", "g1", {1: "black_circle", 2: "white_circle", 3: "white_circle", 5: "black_square", 4: "white_square", 6: "white_triangle", 7: "black_triangle"} ) g4 = nx.DiGraph() prim.add_nodes_from(g4, [1, 2, 3]) prim.add_edges_from(g4, [ (1, 2), (2, 3) ]) self.hierarchy.add_graph("g4", g4) self.hierarchy.add_typing("g4", "g2", {1: 2, 2: 3, 3: 6}) self.hierarchy.add_typing("g4", "g3", {1: 1, 2: 5, 3: 6}) g5 = nx.DiGraph() prim.add_nodes_from(g5, [ ("black_circle"), # {"a": {255}}), ("black_square"), # {"a": {256}}), ("white_triangle"), # {"a": {257}}), ("star") # , {"a": {258}}) ]) prim.add_edges_from(g5, [ ("black_circle", "black_square"), ("black_square", "white_triangle"), # , {"b": {11}}), ("star", "black_square"), ("star", "white_triangle") ]) self.hierarchy.add_graph("g5", g5)