示例#1
0
文件: tree.py 项目: y1ngyang/ReGraph
def clone_node(hie, g_id, parent, node, new_name, propagate=False):
    """Create a clone of a node. If propagate is True, also clone all the nodes typed by it"""
    if isinstance(hie.node[g_id], GraphNode):
        if new_name in hie.node[g_id].graph.nodes():
            raise ValueError("node {} already in graph".format(new_name))
        if propagate:
            lhs = nx.DiGraph()
            lhs.add_node(node)
            ppp = nx.DiGraph()
            ppp.add_node(node)
            ppp.add_node(new_name)
            rhs = nx.DiGraph()
            rhs.add_node(node)
            rhs.add_node(new_name)
            rule = Rule(ppp, lhs, rhs, {node: node, new_name: node}, None)
            _rewrite(hie, g_id, rule, {node: node})
        else:
            prim.clone_node(hie.node[g_id].graph, node, new_name)
            for _, typing in hie.out_edges(g_id):
                mapping = hie.edge[g_id][typing].mapping
                if node in mapping.keys():
                    mapping[new_name] = mapping[node]

    elif isinstance(hie.node[g_id], RuleNode):
        hie.node[g_id].rule.clone_rhs_node(node, new_name)
        for _, typing in hie.out_edges(g_id):
            mapping = hie.edge[g_id][typing].rhs_mapping
            if node in mapping:
                mapping[new_name] = mapping[node]
    else:
        raise ValueError("node is neither a rule nor a graph")
示例#2
0
文件: tree.py 项目: y1ngyang/ReGraph
def rm_node(hie, g_id, parent, node_id, force=False):
    """remove a node from a graph """
    if isinstance(hie.node[g_id], GraphNode):
        if [
                c for c in all_children(hie, g_id)
                if node_id in hie.edge[c][g_id].mapping.values()
        ]:
            if not force:
                raise ValueError("some nodes are typed by {}"
                                 "set the force argument to"
                                 "delete the as well".format(node_id))

        lhs = nx.DiGraph()
        lhs.add_node(node_id)
        ppp = nx.DiGraph()
        rhs = nx.DiGraph()
        rule = Rule(ppp, lhs, rhs)
        _rewrite(hie, g_id, rule, {node_id: node_id})
    elif isinstance(hie.node[g_id], RuleNode):
        hie.node[g_id].rule.remove_node_rhs(node_id)
        for _, typing in hie.out_edges(g_id):
            if node_id in hie.edge[g_id][typing].rhs_mapping.keys():
                del hie.edge[g_id][typing].rhs_mapping[node_id]
    else:
        raise ValueError("node is neither a rule nor a graph")
示例#3
0
 def test_remove_edge(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.remove_edge(1, 2)
     assert_graph_eq(rule.lhs, self.pattern)
     assert(('d', 'a') in rule.p.edges())
     assert(('s', 'x') in rule.rhs.edges())
     return
示例#4
0
 def test_add_edge(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.add_edge(4, 2)
     assert_graph_eq(rule.lhs, self.pattern)
     assert_graph_eq(rule.p, self.p)
     assert(('s', 'y') in rule.rhs.edges())
     return
示例#5
0
    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)
示例#6
0
 def test_update_edge_attrs(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.update_edge_attrs(2, 3, {'b': 1})
     assert(rule.p.edge['b']['c'] is None)
     test_dict = {'b': FiniteSet({1})}
     # normalize_attrs(test_dict)
     assert(rule.rhs.edge['y']['z'] == test_dict)
     return
示例#7
0
 def merge_node_list(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.merge_node_list([2, 3], 'wow_name')
     assert(rule.lhs == self.pattern)
     assert(rule.p == self.p)
     assert('wow_name' in rule.rhs.nodes())
     assert(('wow_name', 'wow_name') in rule.rhs.edges())
     assert(('wow_name', 'y') in rule.rhs.edges())
示例#8
0
 def test_add_edge_attrs(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.add_edge_attrs(4, 1, {'amazing': True})
     assert_graph_eq(rule.p, self.p)
     t = {'amazing': {True}}
     normalize_attrs(t)
     assert(rule.rhs.edge['s']['x'] == t)
     return
示例#9
0
 def test_update_node_attrs(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.update_node_attrs(4, {'b': 2})
     assert(rule.p.node['d'] is None)
     test_dict = {'b': {2}}
     normalize_attrs(test_dict)
     assert(rule.rhs.node['s'] == test_dict)
     return
示例#10
0
 def test_merge_nodes(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     new_name = rule.merge_nodes(1, 4)
     assert_graph_eq(rule.lhs, self.pattern)
     assert_graph_eq(rule.p, self.p)
     assert(new_name in rule.rhs.nodes())
     assert((new_name, new_name) in rule.rhs.edges())
     assert((new_name, 'y') in rule.rhs.edges())
     return
示例#11
0
 def test_add_node(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.add_node('g', {'a': 1})
     assert_graph_eq(rule.p, self.p)
     assert_graph_eq(rule.lhs, self.pattern)
     assert('g' in rule.rhs)
     t = {'a': set([1])}
     normalize_attrs(t)
     assert(rule.rhs.node['g'] == t)
     return
示例#12
0
 def test_remove_node_attrs(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.add_node_attrs(4, {'a': 2})
     rule.remove_node_attrs(4, {'a': 1})
     t1 = {'a': set()}
     t2 = {'a': set([2])}
     normalize_attrs(t1)
     normalize_attrs(t2)
     assert(rule.p.node['d'] == t1)
     assert(rule.rhs.node['s'] == t2)
     return
示例#13
0
 def test_clone_node(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.clone_node(2)
     assert_graph_eq(rule.lhs, self.pattern)
     assert('b1' in rule.p.nodes())
     assert('y1' in rule.rhs.nodes())
     assert(('a', 'b1') in rule.p.edges())
     assert(('b1', 'c') in rule.p.edges())
     assert(('x', 'y1') in rule.rhs.edges())
     assert(('t', 'y1') in rule.rhs.edges())
     return
示例#14
0
 def test_remove_node(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.remove_node(2)
     assert_graph_eq(rule.lhs, self.pattern)
     assert('b' not in rule.p.nodes())
     assert(('a', 'b') not in rule.p.edges())
     assert(('b', 'c') not in rule.p.edges())
     assert('y' not in rule.rhs.nodes())
     assert(('x', 'y') not in rule.rhs.edges())
     assert(('t', 'y') not in rule.rhs.edges())
     assert(('y', 'z') not in rule.rhs.edges())
     return
示例#15
0
    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())
示例#16
0
 def test_remove_edge_attrs(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.remove_edge_attrs(2, 3, {'a': set()})
     t1 = {'a': {1}}
     normalize_attrs(t1)
     assert(rule.p.edge['b']['c'] == t1)
     assert(rule.rhs.edge['y']['z'] == t1)
     rule.remove_edge_attrs(2, 3, {'a': {1}})
     t2 = {'a': set()}
     normalize_attrs(t2)
     print(t2)
     print(rule.p.edge['b']['c'])
     assert(rule.p.edge['b']['c'] == t2)
     assert(rule.rhs.edge['y']['z'] == t2)
     return
示例#17
0
    def test_porpagation_node_attrs_adds(self):

        p = nx.DiGraph()
        primitives.add_nodes_from(
            p, [1, 2]
        )

        lhs = nx.DiGraph()
        primitives.add_nodes_from(
            lhs, [1, 2]
        )

        rhs = nx.DiGraph()
        primitives.add_nodes_from(
            rhs,
            [
                (1, {"a1": True}),
                (2, {"a2": 1}),
                (3, {"a3": "x"})]
        )

        rule = Rule(p, lhs, rhs)
        instance = {1: "A", 2: "A_res_1"}

        rhs_typing = {"mm": {3: "state"}}

        try:
            self.hierarchy.rewrite(
                "n1", rule, instance, lhs_typing=None, rhs_typing=rhs_typing)
            raise ValueError("Error was not caught!")
        except RewritingError:
            pass

        new_hierarchy, _ = self.hierarchy.rewrite(
            "n1", rule, instance,
            lhs_typing=None, rhs_typing=rhs_typing,
            strict=False, inplace=False)

        # test propagation of the node attribute adds
        assert("a1" in new_hierarchy.graph["n1"].node["A"])
        assert("a2" in new_hierarchy.graph["n1"].node["A_res_1"])
        assert("a3" in new_hierarchy.graph["n1"].node[3])

        assert("a1" in new_hierarchy.graph["ag"].node["A"])
        assert("a2" in new_hierarchy.graph["ag"].node["A_res_1"])
        assert("a3" in new_hierarchy.graph["ag"].node[3])
示例#18
0
文件: tree.py 项目: y1ngyang/ReGraph
def remove_attributes(hie, g_id, parent, node, json_attrs):
    """remove the attributes from json_attrs from the node"""
    attrs = prim.json_dict_to_attrs(json_attrs)
    if isinstance(hie.node[g_id], GraphNode):
        lhs = nx.DiGraph()
        lhs.add_node(node)
        add_node_attrs(lhs, node, attrs)
        ppp = nx.DiGraph()
        ppp.add_node(node)
        rhs = nx.DiGraph()
        rhs.add_node(node)
        rule = Rule(ppp, lhs, rhs)
        _rewrite(hie, g_id, rule, {node: node})
    elif isinstance(hie.node[g_id], RuleNode):
        hie.node[g_id].rule.remove_node_attrs_rhs(node, attrs)
    else:
        raise ValueError("node is neither a rule nor a graph")
示例#19
0
 def test_add_node_attrs(self):
     rule = Rule(self.p, self.pattern, self.rhs,
                 self.p_lhs, self.p_rhs)
     rule.add_node_attrs(1, {'a': 1})
     t1 = {'a': {1}}
     t2 = {'a': {1, 2}}
     t3 = {'a': {1, 2}, 'b': {1}}
     normalize_attrs(t1)
     normalize_attrs(t2)
     normalize_attrs(t3)
     assert(rule.rhs.node['x'] == t1)
     rule.add_node_attrs(4, {'a': 1})
     assert(rule.rhs.node['s'] == t1)
     rule.add_node_attrs(4, {'a': 2})
     assert(rule.rhs.node['s'] == t2)
     rule.add_node_attrs(4, {'b': 1})
     assert(rule.rhs.node['s'] == t3)
     return
示例#20
0
文件: tree.py 项目: y1ngyang/ReGraph
def new_rule(hie, parent, name, pattern_name=None):
    """create a new rule """
    if valid_child_name(hie, parent, name):
        if pattern_name is None:
            pattern = nx.DiGraph()
        else:
            pattern_id = child_from_name(hie, parent, pattern_name)
            pattern = hie.node[pattern_id].graph
        rule_id = hie.unique_graph_id(name)
        rule = Rule(pattern, pattern, pattern)
        hie.add_rule(rule_id, rule, {"name": name})
        if parent is not None:
            if pattern_name is None:
                hie.add_rule_typing(rule_id, parent, {}, {})
            else:
                mapping = hie.edge[pattern_id][parent].mapping
                hie.add_rule_typing(rule_id, parent, mapping, mapping)
    else:
        raise ValueError("Invalid new name")
示例#21
0
文件: tree.py 项目: y1ngyang/ReGraph
def merge_nodes(hie, g_id, parent, node1, node2, new_name):
    """merge node1 and node2 in graph or rule"""
    if isinstance(hie.node[g_id], GraphNode):
        if new_name in hie.node[g_id].graph.nodes():
            raise ValueError("node {} already exists".format(new_name))
        lhs = nx.DiGraph()
        lhs.add_node(node1)
        lhs.add_node(node2)
        ppp = nx.DiGraph()
        ppp.add_node(node1)
        ppp.add_node(node2)
        rhs = nx.DiGraph()
        rhs.add_node(new_name)
        rule = Rule(ppp, lhs, rhs, None, {node1: new_name, node2: new_name})
        _rewrite(hie, g_id, rule, {node1: node1, node2: node2})
    elif isinstance(hie.node[g_id], RuleNode):
        tmp_rule = copy.deepcopy(hie.node[g_id].rule)
        tmp_rule.merge_nodes_rhs(node1, node2, new_name)
        typings = {
            typing: copy.deepcopy(hie.edge[g_id][typing])
            for _, typing in hie.out_edges(g_id)
        }
        for typing_rule in typings.values():
            mapping = typing_rule.rhs_mapping
            if node1 in mapping.keys():
                if node2 in mapping.keys():
                    if mapping[node1] == mapping[node2]:
                        mapping[new_name] = mapping[node1]
                        del mapping[node1]
                        del mapping[node2]
                    else:
                        raise ValueError("merge nodes of different types")
                else:
                    raise ValueError("merge nodes of different types")
            else:
                if node2 in mapping.keys():
                    raise ValueError("merge nodes of different types")
        for _, typing in hie.out_edges(g_id):
            hie.edge[g_id][typing] = typings[typing]
        hie.node[g_id].rule = tmp_rule
    else:
        raise ValueError("node is neither a rule nor a graph")
示例#22
0
文件: tree.py 项目: y1ngyang/ReGraph
def rm_edge(hie, g_id, parent, node1, node2):
    """remove an edge from a graph, and all the edges typed by it"""
    if isinstance(hie.node[g_id], GraphNode):
        lhs = nx.DiGraph()
        lhs.add_node(node1)
        lhs.add_node(node2)
        lhs.add_edge(node1, node2)
        ppp = nx.DiGraph()
        ppp.add_node(node1)
        ppp.add_node(node2)
        rhs = nx.DiGraph()
        rhs.add_node(node1)
        rhs.add_node(node2)
        rule = Rule(ppp, lhs, rhs)
        _rewrite(hie, g_id, rule, {node1: node1, node2: node2})

    elif isinstance(hie.node[g_id], RuleNode):
        hie.node[g_id].rule.remove_edge_rhs(node1, node2)
    else:
        raise ValueError("node is neither a rule nor a graph")
示例#23
0
    def test_rewrite(self):
        pattern = nx.DiGraph()
        add_nodes_from(pattern, [(1, {
            'state': 'p'
        }), (2, {
            'name': 'BND'
        }), 3, 4])
        add_edges_from(pattern, [(1, 2, {
            's': 'p'
        }), (3, 2, {
            's': 'u'
        }), (3, 4)])

        p = nx.DiGraph()
        add_nodes_from(p, [(1, {'state': 'p'}), (2, {'name': 'BND'}), 3, 4])
        p.add_edges_from([(1, 2), (3, 4)])

        rhs = nx.DiGraph()
        add_nodes_from(rhs, [(1, {
            'state': 'p'
        }), (2, {
            'name': 'BND'
        }), (3, {
            'merged': 'yes'
        }), (4, {
            'new': 'yes'
        })])

        add_edges_from(rhs, [(1, 2, {
            's': 'u'
        }), (2, 4), (3, 3), (3, 4, {
            'from': 'merged'
        })])

        p_lhs = {1: 1, 2: 2, 3: 3, 4: 4}
        p_rhs = {1: 1, 2: 2, 3: 3, 4: 3}

        rule = Rule(p, pattern, rhs, p_lhs, p_rhs)
        instances = find_matching_with_types(self.graph, rule.lhs, {}, {}, {})
        rule.apply_to(self.graph, instances[0], rule)
示例#24
0
def _refine_rule_hierarchy(hierarchy, rule_hierarchy, lhs_instances):
    new_lhs_instances = {}

    new_rules = {}
    new_rule_homomorphisms = {}

    for graph, rule in rule_hierarchy["rules"].items():
        # refine rule
        new_lhs_instance = rule.refine(hierarchy.get_graph(graph),
                                       lhs_instances[graph])
        new_lhs_instances[graph] = new_lhs_instance

    # Update rule homomorphisms
    for (source,
         target), (lhs_h, p_h,
                   rhs_h) in rule_hierarchy["rule_homomorphisms"].items():
        typing = hierarchy.get_typing(source, target)
        source_rule = rule_hierarchy["rules"][source]
        target_rule = rule_hierarchy["rules"][target]
        for node in source_rule.lhs.nodes():
            if node not in lhs_h.keys():
                source_node = new_lhs_instances[source][node]
                target_node = typing[source_node]
                target_lhs_node = keys_by_value(new_lhs_instances[target],
                                                target_node)[0]
                lhs_h[node] = target_lhs_node

                if node in source_rule.p_lhs.values():
                    source_p_node = keys_by_value(source_rule.p_lhs, node)[0]
                    target_p_node = keys_by_value(target_rule.p_lhs, node)[0]
                    p_h[source_p_node] = target_p_node

                    source_rhs_node = source_rule.p_rhs[source_p_node]
                    target_rhs_node = target_rule.p_rhs[target_p_node]
                    rhs_h[source_rhs_node] = target_rhs_node

    if len(rule_hierarchy["rules"]) == 0:
        for graph in hierarchy.graphs():
            rule_hierarchy["rules"][graph] = Rule.identity_rule()
            new_lhs_instances[graph] = dict()
        for (s, t) in hierarchy.typings():
            rule_hierarchy["rule_homomorphisms"][(s, t)] = (dict(), dict(),
                                                            dict())
    else:
        for graph, rule in rule_hierarchy["rules"].items():
            # add identity rules where needed
            # to preserve the info on p/rhs_typing
            # add ancestors that are not included in rule hierarchy
            for ancestor, typing in hierarchy.get_ancestors(graph).items():
                if ancestor not in rule_hierarchy["rules"] and\
                   ancestor not in new_rules:
                    # Find a typing of ancestor by the graph
                    l_pred, l_pred_pred, l_pred_l_graph = pullback(
                        hierarchy.get_graph(ancestor), rule.lhs,
                        hierarchy.get_graph(graph), typing,
                        new_lhs_instances[graph])
                    new_rules[ancestor] = Rule(p=l_pred, lhs=l_pred)
                    new_lhs_instances[ancestor] = l_pred_pred
                    r_pred_r_graph = {
                        v: rule.p_rhs[k]
                        for k, v in l_pred_l_graph.items()
                    }
                    for successor in hierarchy.successors(ancestor):
                        if successor in rule_hierarchy["rules"]:
                            if successor == graph:
                                new_rule_homomorphisms[(ancestor, graph)] = (
                                    l_pred_l_graph, l_pred_l_graph,
                                    r_pred_r_graph)
                            else:
                                path = hierarchy.shortest_path(
                                    graph, successor)
                                lhs_h, p_h, rhs_h = rule_hierarchy[
                                    "rule_homomorphisms"][(path[0], path[1])]
                                for i in range(2, len(path)):
                                    new_lhs_h, new_p_h, new_rhs_h = rule_hierarchy[
                                        "rule_homomorphisms"][(path[i - 1],
                                                               path[i])]
                                    lhs_h = compose(lhs_h, new_lhs_h)
                                    p_h = compose(p_h, new_p_h)
                                    rhs_h = compose(rhs_h, new_rhs_h)

                                new_rule_homomorphisms[(
                                    ancestor,
                                    successor)] = (compose(
                                        l_pred_l_graph,
                                        lhs_h), compose(l_pred_l_graph, p_h),
                                                   compose(
                                                       r_pred_r_graph, rhs_h))
                        if successor in new_rules:
                            lhs_h = {
                                k: keys_by_value(
                                    new_lhs_instances[successor],
                                    hierarchy.get_typing(ancestor,
                                                         successor)[v])[0]
                                for k, v in
                                new_lhs_instances[ancestor].items()
                            }
                            new_rule_homomorphisms[(ancestor,
                                                    successor)] = (lhs_h,
                                                                   lhs_h,
                                                                   lhs_h)
                    for predecessor in hierarchy.predecessors(ancestor):
                        if predecessor in rule_hierarchy["rules"] or\
                           predecessor in new_rules:
                            lhs_h = {
                                k: keys_by_value(
                                    new_lhs_instances[ancestor],
                                    hierarchy.get_typing(
                                        predecessor, ancestor)[v])[0]
                                for k, v in
                                new_lhs_instances[predecessor].items()
                            }
                            new_rule_homomorphisms[(predecessor,
                                                    ancestor)] = (lhs_h, lhs_h,
                                                                  lhs_h)

            for descendant, typing in hierarchy.get_descendants(graph).items():
                if descendant not in rule_hierarchy["rules"] and\
                   descendant not in new_rules:
                    l_suc, l_graph_l_suc, l_suc_suc = image_factorization(
                        rule.lhs, hierarchy.get_graph(descendant),
                        compose(new_lhs_instances[graph], typing))
                    new_rules[descendant] = Rule(p=l_suc, lhs=l_suc)
                    new_lhs_instances[descendant] = l_suc_suc
                    p_graph_p_suc = {
                        k: l_graph_l_suc[v]
                        for k, v in rule.p_lhs.items()
                    }
                    for predecessor in hierarchy.predecessors(descendant):
                        if predecessor in rule_hierarchy["rules"]:
                            if predecessor == graph:
                                new_rule_homomorphisms[(
                                    predecessor, descendant)] = (l_graph_l_suc,
                                                                 p_graph_p_suc,
                                                                 p_graph_p_suc)
                            else:
                                path = hierarchy.shortest_path(
                                    predecessor, graph)
                                lhs_h, p_h, rhs_h = rule_hierarchy[
                                    "rule_homomorphisms"][(path[0], path[1])]
                                for i in range(2, len(path)):
                                    new_lhs_h, new_p_h, new_rhs_h = rule_hierarchy[
                                        "rule_homomorphisms"][(path[i - 1],
                                                               path[i])]
                                    lhs_h = compose(lhs_h, new_lhs_h)
                                    p_h = compose(p_h, new_p_h)
                                    rhs_h = compose(rhs_h, new_rhs_h)
                                new_rule_homomorphisms[(
                                    predecessor,
                                    descendant)] = (compose(
                                        lhs_h, l_graph_l_suc),
                                                    compose(
                                                        p_h, p_graph_p_suc),
                                                    compose(
                                                        rhs_h, p_graph_p_suc))
                        if predecessor in new_rules:
                            lhs_h = {
                                k: keys_by_value(
                                    new_lhs_instances[descendant],
                                    hierarchy.get_typing(
                                        predecessor, descendant)[v])[0]
                                for k, v in
                                new_lhs_instances[predecessor].items()
                            }
                            new_rule_homomorphisms[(predecessor,
                                                    descendant)] = (lhs_h,
                                                                    lhs_h,
                                                                    lhs_h)

                    for successor in hierarchy.successors(descendant):
                        if successor in rule_hierarchy["rules"] or\
                           successor in new_rules:
                            lhs_h = {
                                k: keys_by_value(
                                    new_lhs_instances[successor],
                                    hierarchy.get_typing(
                                        descendant, successor)[v])[0]
                                for k, v in
                                new_lhs_instances[descendant].items()
                            }
                            new_rule_homomorphisms[(descendant,
                                                    successor)] = (lhs_h,
                                                                   lhs_h,
                                                                   lhs_h)

    rule_hierarchy["rules"].update(new_rules)
    rule_hierarchy["rule_homomorphisms"].update(new_rule_homomorphisms)

    return new_lhs_instances
示例#25
0
def _get_rule_projections(hierarchy,
                          origin_id,
                          rule,
                          instance,
                          rhs_typing=None,
                          ignore=None):
    if ignore is None:
        ignore = []
    if rhs_typing is None:
        rhs_typing = {}
    projections = {}
    if rule.is_relaxing():
        for graph, origin_typing in hierarchy.get_descendants(
                origin_id).items():
            if graph not in ignore:
                if hierarchy.is_graph(graph):
                    # Compute canonical P_T
                    l_t, l_l_t, l_t_t = image_factorization(
                        rule.lhs, hierarchy.get_graph(graph),
                        compose(instance, origin_typing))

                    # Compute canonical R_T
                    r_t, l_t_r_t, r_r_t = pushout(rule.p, l_t, rule.rhs, l_l_t,
                                                  rule.p_rhs)

                    # 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 r_t.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 = primitives.generate_new_node_id(
                                            l_t, t_node)
                                        primitives.add_node(l_t, new_p_node)
                                        added_t_nodes.add(t_node)
                                        l_t_r_t[new_p_node] = n
                                        l_t_t[new_p_node] = t_node
                                    else:
                                        l_t_r_t[keys_by_value(l_t_t,
                                                              t_node)[0]] = n

                    projections[graph] = {
                        "rule": Rule(lhs=l_t, p=l_t, rhs=r_t, p_rhs=l_t_r_t),
                        "instance": l_t_t,
                        "l_l_t": l_l_t,
                        "p_p_t": {k: l_l_t[v]
                                  for k, v in rule.p_lhs.items()},
                        "r_r_t": r_r_t
                    }

    return projections
示例#26
0
def _get_rule_liftings(hierarchy,
                       origin_id,
                       rule,
                       instance,
                       p_typing=None,
                       ignore=None):
    if ignore is None:
        ignore = []
    if p_typing is None:
        p_typing = {}
    liftings = {}
    if rule.is_restrictive():
        for graph in hierarchy.bfs_tree(origin_id, reverse=True):
            if graph not in ignore:
                if graph != origin_id:
                    # find the lifting to a graph
                    if hierarchy.is_graph(graph):
                        origin_typing = hierarchy.get_typing(graph, origin_id)

                        # Compute L_G
                        l_g, l_g_g, l_g_l = pullback(
                            hierarchy.get_graph(graph), rule.lhs,
                            hierarchy.get_graph(origin_id), origin_typing,
                            instance)

                        # Compute canonical P_G
                        canonical_p_g, p_g_l_g, p_g_p = pullback(
                            l_g, rule.p, rule.lhs, l_g_l, rule.p_lhs)

                        # 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 canonical_p_g.nodes():
                                l_g_node = p_g_l_g[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_g_l_g[n]
                                        p_g_nodes_to_remove.add(n)

                            for n in p_g_nodes_to_remove:
                                primitives.remove_node(canonical_p_g, n)
                        liftings[graph] = {
                            "rule": Rule(p=canonical_p_g,
                                         lhs=l_g,
                                         p_lhs=p_g_l_g),
                            "instance": l_g_g,
                            "l_g_l": l_g_l,
                            "p_g_p": p_g_p
                        }

    return liftings
示例#27
0
def _propagate_up(hierarchy,
                  graph_id,
                  rule,
                  instance,
                  p_origin_m,
                  origin_m_origin_prime,
                  p_typing,
                  inplace=False):
    updated_graphs = dict()
    updated_homomorphisms = dict()
    updated_relations = set()
    updated_rules = dict()
    updated_rule_h = dict()

    if rule.is_restrictive():
        for graph in hierarchy.bfs_tree(graph_id, reverse=True):
            if graph != graph_id:
                if hierarchy.is_graph(graph):
                    origin_typing = hierarchy.get_typing(graph, graph_id)
                    graph_p_typing = None
                    if graph in p_typing.keys():
                        graph_p_typing = p_typing[graph]
                    (graph_prime, graph_prime_graph, graph_prime_origin) =\
                        _propagate_rule_up(
                            hierarchy.get_graph(graph),
                            origin_typing, rule, instance,
                            p_origin_m, graph_p_typing, inplace)
                    updated_graphs[graph] =\
                        (graph_prime, graph_prime_graph,
                         None, graph_prime_origin)

                    graph_successors = list(hierarchy.successors(graph))
                    if graph_id in graph_successors:
                        updated_homomorphisms[(graph, graph_id)] =\
                            compose(
                                graph_prime_origin,
                                origin_m_origin_prime)
                    if len(rule.removed_nodes()) > 0 or\
                       len(rule.cloned_nodes()) > 0:
                        for suc in graph_successors:
                            if suc != graph_id:
                                if suc in updated_graphs.keys():
                                    graph_prime_suc_prime =\
                                        get_unique_map_to_pullback(
                                            updated_graphs[suc][0].nodes(),
                                            updated_graphs[suc][1],
                                            updated_graphs[suc][3],
                                            compose(
                                                graph_prime_graph,
                                                hierarchy.adj[graph][suc][
                                                    "mapping"]),
                                            graph_prime_origin)
                                else:
                                    graph_prime_suc_prime = compose(
                                        graph_prime_graph,
                                        hierarchy.adj[graph][suc]["mapping"])
                                updated_homomorphisms[(graph, suc)] =\
                                    graph_prime_suc_prime

                        for pred in hierarchy.predecessors(graph):
                            if pred in updated_graphs.keys():
                                pred_m_graph_m = get_unique_map_to_pullback(
                                    graph_prime.nodes(), graph_prime_graph,
                                    graph_prime_origin,
                                    updated_graphs[pred][1],
                                    updated_graphs[pred][3])
                                updated_homomorphisms[(pred,
                                                       graph)] = pred_m_graph_m

                        # propagate changes to adjacent relations
                        for related_g in hierarchy.adjacent_relations(graph):
                            updated_relations.add((graph, related_g))
                else:
                    rule_to_rewrite = hierarchy.node[graph]["rule"]

                    (lhs_origin_typing,
                     p_origin_typing,
                     rhs_origin_typing) =\
                        hierarchy.get_rule_typing(graph, graph_id)

                    (lhs_prime, lhs_prime_lhs, lhs_prime_origin) =\
                        _propagate_rule_up(
                            rule_to_rewrite.lhs,
                            lhs_origin_typing, rule, instance,
                            p_origin_m, {}, inplace=False)

                    (pr_prime, pr_prime_pr, pr_prime_origin) =\
                        _propagate_rule_up(
                            rule_to_rewrite.p,
                            p_origin_typing, rule, instance,
                            p_origin_m, {}, inplace=False)

                    (rhs_prime, rhs_prime_rhs, rhs_prime_origin) =\
                        _propagate_rule_up(
                            rule_to_rewrite.rhs,
                            rhs_origin_typing, rule, instance,
                            p_origin_m, {}, inplace=False)

                    # find p_m -> lhs_m
                    new_p_lhs = get_unique_map_to_pullback(
                        lhs_prime.nodes(), lhs_prime_lhs, lhs_prime_origin,
                        compose(pr_prime_pr, rule_to_rewrite.p_lhs),
                        pr_prime_origin)

                    # find p_m -> rhs_m
                    new_p_rhs = get_unique_map_to_pullback(
                        rhs_prime.nodes(), rhs_prime_rhs, rhs_prime_origin,
                        compose(pr_prime_pr, rule_to_rewrite.p_rhs),
                        pr_prime_origin)

                    new_rule =\
                        Rule(pr_prime, lhs_prime, rhs_prime,
                             new_p_lhs, new_p_rhs)

                    updated_rules[graph] = new_rule

                    for suc in hierarchy.successors(graph):
                        if suc == graph_id:
                            lhs_prime_suc_prime =\
                                compose(lhs_prime_origin,
                                        origin_m_origin_prime)
                            rhs_prime_suc_prime =\
                                compose(rhs_prime_origin,
                                        origin_m_origin_prime)

                        if suc in updated_graphs.keys():
                            lhs_prime_suc_prime = get_unique_map_to_pullback(
                                updated_graphs[suc][0].nodes(),
                                updated_graphs[suc][1], updated_graphs[suc][3],
                                compose(
                                    lhs_prime_lhs,
                                    hierarchy.adj[graph][suc]["lhs_mapping"]),
                                lhs_prime_origin)
                            rhs_prime_suc_prime = get_unique_map_to_pullback(
                                updated_graphs[suc][0].nodes(),
                                updated_graphs[suc][1], updated_graphs[suc][3],
                                compose(
                                    rhs_prime_rhs,
                                    hierarchy.adj[graph][suc]["rhs_mapping"]),
                                rhs_prime_origin)

                        else:
                            lhs_prime_suc_prime =\
                                compose(
                                    lhs_prime_lhs,
                                    hierarchy.adj[graph][suc]["lhs_mapping"])
                            rhs_prime_suc_prime =\
                                compose(
                                    rhs_prime_rhs,
                                    hierarchy.adj[graph][suc]["rhs_mapping"])

                        updated_rule_h[(graph, suc)] =\
                            (lhs_prime_suc_prime, rhs_prime_suc_prime)

    else:
        for pred in hierarchy.predecessors(graph_id):
            if hierarchy.is_graph(pred):
                updated_homomorphisms[(pred, graph_id)] =\
                    compose(
                        hierarchy.adj[pred][graph_id]["mapping"],
                        origin_m_origin_prime)
            else:
                updated_rule_h[(pred, graph_id)] = (
                    compose(hierarchy.adj[pred][graph_id]["lhs_mapping"],
                            origin_m_origin_prime),
                    compose(hierarchy.adj[pred][graph_id]["rhs_mapping"],
                            origin_m_origin_prime))

    return {
        "graphs": updated_graphs,
        "homomorphisms": updated_homomorphisms,
        "rules": updated_rules,
        "rule_homomorphisms": updated_rule_h,
        "relations": updated_relations
    }
示例#28
0
    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)
示例#29
0
    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)
示例#30
0
    def test_propagation_node_adds(self):
        """Test propagation down of additions."""
        p = nx.DiGraph()
        primitives.add_nodes_from(
            p, ["B"]
        )

        l = nx.DiGraph()
        primitives.add_nodes_from(
            l, ["B"]
        )

        r = nx.DiGraph()
        primitives.add_nodes_from(
            r, ["B", "B_res_1", "X", "Y"]
        )
        primitives.add_edge(r, "B_res_1", "B")

        rule = Rule(p, l, r)

        instance = {"B": "B"}

        rhs_typing = {
            "mm": {"B_res_1": "residue"},
            "mmm": {"X": "component"}, "colors": {"Y": "red"}
        }
        try:
            self.hierarchy.rewrite(
                "n1", rule, instance, lhs_typing=None, rhs_typing=rhs_typing)
            raise ValueError("Error was not caught!")
        except RewritingError:
            pass

        new_hierarchy, _ = self.hierarchy.rewrite(
            "n1", rule, instance,
            lhs_typing=None, rhs_typing=rhs_typing,
            strict=False, inplace=False)

        # test propagation of node adds
        assert("B_res_1" in new_hierarchy.graph["n1"].nodes())
        assert("B_res_1" in new_hierarchy.graph["ag"].nodes())
        assert(new_hierarchy.typing["n1"]["ag"]["B_res_1"] == "B_res_1")
        assert(new_hierarchy.typing["ag"]["mm"]["B_res_1"] == "residue")
        assert(("B_res_1", "B") in new_hierarchy.graph["n1"].edges())
        assert(("B_res_1", "B") in new_hierarchy.graph["ag"].edges())

        assert("X" in new_hierarchy.graph["n1"].nodes())
        assert("X" in new_hierarchy.graph["ag"].nodes())
        assert("X" in new_hierarchy.graph["mm"].nodes())
        assert("X" in new_hierarchy.graph["colors"].nodes())
        assert(new_hierarchy.typing["n1"]["ag"]["X"] == "X")
        assert(new_hierarchy.typing["ag"]["mm"]["X"] == "X")
        assert(new_hierarchy.typing["mm"]["mmm"]["X"] == "component")
        assert(new_hierarchy.typing["mm"]["colors"]["X"] == "X")

        assert("Y" in new_hierarchy.graph["n1"].nodes())
        assert("Y" in new_hierarchy.graph["ag"].nodes())
        assert("Y" in new_hierarchy.graph["mm"].nodes())
        assert("Y" in new_hierarchy.graph["mm"].nodes())
        assert(new_hierarchy.typing["n1"]["ag"]["Y"] == "Y")
        assert(new_hierarchy.typing["ag"]["mm"]["Y"] == "Y")
        assert(new_hierarchy.typing["mm"]["mmm"]["Y"] == "Y")
        assert(new_hierarchy.typing["mm"]["colors"]["Y"] == "red")