Пример #1
0
    def added_edge_attrs(self):
        """Get edge attributes added by the rule.

        Returns
        -------
        attrs : dict
            Dictionary where keys are edges from `rhs`
            and values are attribute dictionaries to add.
        """
        attrs = dict()
        for s, t in self.rhs.edges():
            s_p_nodes = keys_by_value(self.p_rhs, s)
            t_p_nodes = keys_by_value(self.p_rhs, t)
            new_attrs = {}
            for s_p_node in s_p_nodes:
                for t_p_node in t_p_nodes:
                    if (s_p_node, t_p_node) in self.p.edges():
                        new_attrs = attrs_union(
                            new_attrs,
                            dict_sub(
                                self.rhs.edge[s][t],
                                self.p.edge[s_p_node][t_p_node]
                            )
                        )
        return attrs
Пример #2
0
    def removed_edge_attrs(self):
        """Get edge attributes removed by the rule.

        Returns
        -------
        attrs : dict
            Dictionary where keys are edges from `lhs`
            and values are attribute dictionaries to remove.
        """
        attrs = dict()
        for s, t in self.lhs.edges():
            s_p_nodes = keys_by_value(self.p_lhs, s)
            t_p_nodes = keys_by_value(self.p_lhs, t)
            new_attrs = {}
            for s_p_node in s_p_nodes:
                for t_p_node in t_p_nodes:
                    if (s_p_node, t_p_node) in self.p.edges():
                        new_attrs = attrs_union(
                            new_attrs,
                            dict_sub(
                                self.lhs.edge[s][t],
                                self.p.edge[s_p_node][t_p_node]
                            )
                        )
            if len(new_attrs) > 0:
                attrs[(s, t)] = new_attrs
        return attrs
Пример #3
0
 def removed_node_attrs(self):
     """."""
     attrs = dict()
     for node in self.lhs.nodes():
         p_nodes = keys_by_value(self.p_lhs, node)
         new_attrs = {}
         for p_node in p_nodes:
             new_attrs = attrs_union(new_attrs, dict_sub(
                 self.lhs.node[node], self.p.node[p_node]))
         if len(new_attrs) > 0:
             attrs[node] = new_attrs
     return attrs
Пример #4
0
 def added_node_attrs(self):
     """."""
     attrs = dict()
     for node in self.rhs.nodes():
         p_nodes = keys_by_value(self.p_rhs, node)
         # if len(p_nodes) == 0:
         #     attrs[node] = self.rhs.node[node]
         new_attrs = {}
         for p_node in p_nodes:
             new_attrs = attrs_union(new_attrs, dict_sub(
                 self.rhs.node[node], self.p.node[p_node]))
         if len(new_attrs) > 0:
             attrs[node] = new_attrs
     return attrs
Пример #5
0
 def added_edge_attrs(self):
     """."""
     attrs = dict()
     for s, t in self.rhs.edges():
         s_p_nodes = keys_by_value(self.p_rhs, s)
         t_p_nodes = keys_by_value(self.p_rhs, t)
         new_attrs = {}
         for s_p_node in s_p_nodes:
             for t_p_node in t_p_nodes:
                 if (s_p_node, t_p_node) in self.p.edges():
                     new_attrs = attrs_union(
                         new_attrs,
                         dict_sub(
                             self.rhs.edge[s][t],
                             self.p.edge[s_p_node][t_p_node]
                         )
                     )
     return attrs
Пример #6
0
    def removed_node_attrs(self):
        """Get node attributes removed by the rule.

        Returns
        -------
        attrs : dict
            Dictionary where keys are nodes from `lhs`
            and values are attribute dictionaries to remove.
        """
        attrs = dict()
        for node in self.lhs.nodes():
            p_nodes = keys_by_value(self.p_lhs, node)
            new_attrs = {}
            for p_node in p_nodes:
                new_attrs = attrs_union(new_attrs, dict_sub(
                    self.lhs.node[node], self.p.node[p_node]))
            if len(new_attrs) > 0:
                attrs[node] = new_attrs
        return attrs
Пример #7
0
 def removed_edge_attrs(self):
     """."""
     attrs = dict()
     for s, t in self.lhs.edges():
         s_p_nodes = keys_by_value(self.p_lhs, s)
         t_p_nodes = keys_by_value(self.p_lhs, t)
         new_attrs = {}
         for s_p_node in s_p_nodes:
             for t_p_node in t_p_nodes:
                 if (s_p_node, t_p_node) in self.p.edges():
                     new_attrs = attrs_union(
                         new_attrs,
                         dict_sub(
                             self.lhs.edge[s][t],
                             self.p.edge[s_p_node][t_p_node]
                         )
                     )
         if len(new_attrs) > 0:
             attrs[(s, t)] = new_attrs
     return attrs
Пример #8
0
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