Exemplo n.º 1
0
 def remove_node_attrs_p(self, n, attrs):
     """Remove attrs of a node in the p."""
     if n not in self.p.nodes():
         raise RuleError(
             "Node '%s' does not exist in the preserved "
             "part of the rule" % n)
     primitives.remove_node_attrs(self.p, n, attrs)
Exemplo n.º 2
0
    def remove_node_attrs_rhs(self, n, attrs):
        """Remove attrs of a node in the rhs."""
        if n not in self.rhs.nodes():
            raise RuleError(
                "Node '%s' does not exist in the right hand "
                "side of the rule" % n)

        p_keys = keys_by_value(self.p_rhs, n)
        for p_node in p_keys:
            primitives.remove_node_attrs(self.p, p_node, attrs)
        primitives.remove_node_attrs(self.rhs, n, attrs)
Exemplo n.º 3
0
    def remove_node_attrs(self, n, attrs):
        """Remove nodes attributes from a node in the graph."""
        if n not in self.lhs.nodes():
            raise RuleError(
                "Node '%s' does not exist in the left "
                "hand side of the rule" % n)

        p_keys = keys_by_value(self.p_lhs, n)
        if len(p_keys) == 0:
            raise RuleError(
                "Node '%s' is being removed by the rule, "
                "cannot remove attributes" % n)

        for k in p_keys:
            primitives.remove_node_attrs(self.p, k, attrs)
            primitives.remove_node_attrs(self.rhs, self.p_rhs[k], attrs)
        return
Exemplo n.º 4
0
    def inject_remove_node_attrs(self, n, attrs):
        """Inject a removal of node attrs by the rule.

        First, tries to find a node with the id `n` in the
        left-hand side, injects its attrs removal if found,
        otherwise, tries to find the corresponding node in
        the preserved part (it helps us to implement injection
        of the node attrs removal to only one of the clone nodes).


        Parameters
        ----------
        n : hashable
            Id of a node whose attrs to remove (node from the
            left-hand side or the preserved part).
        attrs : dict
            Dictionary with attributes to remove.

        Raises
        ------
        RuleError
            If `n` does not exist in neither the left-hand side
            nor the preserved part of the rule, or when the node
            whose attrs should be removed is itself is being removed
            by the rule.

        """
        if n not in self.lhs.nodes() and n not in self.p.nodes():
            raise RuleError(
                "Node '%s' exists in neither the left "
                "hand side of the rule nor the preserved part" % n)
        if n in self.lhs.nodes():
            p_keys = keys_by_value(self.p_lhs, n)
            if len(p_keys) == 0:
                raise RuleError(
                    "Node '%s' is being removed by the rule, "
                    "cannot remove attributes" % n)
        else:
            p_keys = [n]

        for k in p_keys:
            primitives.remove_node_attrs(self.p, k, attrs)
            primitives.remove_node_attrs(self.rhs, self.p_rhs[k], attrs)
        return
Exemplo n.º 5
0
def _propagate_rule_up(graph,
                       origin_typing,
                       rule,
                       instance,
                       p_origin,
                       p_typing,
                       inplace=False):

    if inplace is True:
        graph_prime = graph
    else:
        graph_prime = copy.deepcopy(graph)

    if p_typing is None:
        p_typing = {}

    lhs_removed_nodes = rule.removed_nodes()
    lhs_removed_node_attrs = rule.removed_node_attrs()
    p_removed_edges = rule.removed_edges()
    p_removed_edge_attrs = rule.removed_edge_attrs()
    lhs_cloned_nodes = rule.cloned_nodes()

    graph_prime_graph = id_of(graph.nodes())
    graph_prime_origin = copy.deepcopy(origin_typing)

    for lhs_node in rule.lhs.nodes():
        origin_node = instance[lhs_node]
        g_nodes = keys_by_value(origin_typing, origin_node)
        for node in g_nodes:
            if lhs_node in lhs_removed_nodes:
                primitives.remove_node(graph_prime, node)
                del graph_prime_graph[node]
                del graph_prime_origin[node]
            else:
                graph_prime_origin[node] = origin_node

    for lhs_node, p_nodes in lhs_cloned_nodes.items():
        nodes_to_clone = keys_by_value(origin_typing, instance[lhs_node])
        for node in nodes_to_clone:
            if node in p_typing.keys():
                p_nodes = p_typing[node]
            for i, p_node in enumerate(p_nodes):
                if i == 0:
                    graph_prime_origin[node] = p_origin[p_node]
                    graph_prime_graph[node] = node
                else:
                    new_name = primitives.clone_node(graph_prime, node)
                    graph_prime_origin[new_name] = p_origin[p_node]
                    graph_prime_graph[new_name] = node
            if len(p_nodes) == 0:
                primitives.remove_node(graph_prime, node)

    for lhs_node, attrs in lhs_removed_node_attrs.items():
        nodes_to_remove_attrs = keys_by_value(origin_typing,
                                              instance[lhs_node])
        for node in nodes_to_remove_attrs:
            primitives.remove_node_attrs(graph_prime, node, attrs)

    for p_u, p_v in p_removed_edges:
        us = keys_by_value(graph_prime_origin, p_origin[p_u])
        vs = keys_by_value(graph_prime_origin, p_origin[p_v])
        for u in us:
            for v in vs:
                if (u, v) in graph_prime.edges():
                    primitives.remove_edge(graph_prime, u, v)

    for (p_u, p_v), attrs in p_removed_edge_attrs.items():
        us = keys_by_value(origin_typing, p_origin[p_u])
        vs = keys_by_value(origin_typing, p_origin[p_v])
        for u in us:
            for v in vs:
                primitives.removed_edge_attrs(graph_prime, u, v, attrs)

    return (graph_prime, graph_prime_graph, graph_prime_origin)
Exemplo n.º 6
0
def _propagate_rule_to(graph, origin_typing, rule, instance, p_origin,
                       inplace=False):

    if inplace is True:
        graph_prime = graph
    else:
        graph_prime = copy.deepcopy(graph)

    lhs_removed_nodes = rule.removed_nodes()
    lhs_removed_node_attrs = rule.removed_node_attrs()
    p_removed_edges = rule.removed_edges()
    p_removed_edge_attrs = rule.removed_edge_attrs()
    lhs_cloned_nodes = rule.cloned_nodes()

    graph_prime_graph = id_of(graph.nodes())
    graph_prime_origin = dict()

    for lhs_node in rule.lhs.nodes():
        origin_node = instance[lhs_node]
        g_nodes = keys_by_value(
            origin_typing, origin_node)
        for node in g_nodes:
            if lhs_node in lhs_removed_nodes:
                primitives.remove_node(
                    graph_prime, node)
                del graph_prime_graph[node]
            else:
                graph_prime_origin[node] = origin_node

    for lhs_node, p_nodes in lhs_cloned_nodes.items():
        nodes_to_clone = keys_by_value(origin_typing, instance[lhs_node])
        for node in nodes_to_clone:
            for i, p_node in enumerate(p_nodes):
                if i == 0:
                    graph_prime_origin[node] = p_origin[p_node]
                    graph_prime_graph[node] = node
                else:
                    new_name = primitives.clone_node(
                        graph_prime,
                        node)
                    graph_prime_origin[new_name] = p_origin[p_node]
                    graph_prime_graph[new_name] = node

    for lhs_node, attrs in lhs_removed_node_attrs.items():
        nodes_to_remove_attrs = keys_by_value(
            origin_typing, instance[lhs_node])
        for node in nodes_to_remove_attrs:
            primitives.remove_node_attrs(
                graph_prime,
                node, attrs)

    for p_u, p_v in p_removed_edges:
        us = keys_by_value(graph_prime_origin, p_origin[p_u])
        vs = keys_by_value(graph_prime_origin, p_origin[p_v])
        for u in us:
            for v in vs:
                if (u, v) in graph_prime.edges():
                    primitives.remove_edge(
                        graph_prime, u, v)

    for (p_u, p_v), attrs in p_removed_edge_attrs.items():
        us = keys_by_value(origin_typing, p_origin[p_u])
        vs = keys_by_value(origin_typing, p_origin[p_v])
        for u in us:
            for v in vs:
                primitives.removed_edge_attrs(
                    graph_prime, u, v, attrs)

    return (graph_prime, graph_prime_graph, graph_prime_origin)
Exemplo n.º 7
0
def pullback_complement(a, b, d, a_b, b_d, inplace=False):
    """Find the final pullback complement from a->b->d.

    Makes changes to d inplace.
    """

    check_homomorphism(a, b, a_b, total=True)
    check_homomorphism(b, d, b_d, total=True)

    if not is_monic(b_d):
        raise InvalidHomomorphism(
            "Second homomorphism is not monic, "
            "cannot find final pullback complement!"
        )

    if inplace is True:
        c = d
    else:
        c = copy.deepcopy(d)

    a_c = dict()
    c_d = id_of(c.nodes())

    # Remove/clone nodes
    for b_node in b.nodes():
        a_keys = keys_by_value(a_b, b_node)
        # Remove nodes
        if len(a_keys) == 0:
            remove_node(c, b_d[b_node])
            del c_d[b_d[b_node]]
        # Keep nodes
        elif len(a_keys) == 1:
            a_c[a_keys[0]] = b_d[b_node]
        # Clone nodes
        else:
            i = 1
            for k in a_keys:
                if i == 1:
                    a_c[k] = b_d[b_node]
                    c_d[b_d[b_node]] = b_d[b_node]
                else:
                    new_name = clone_node(c, b_d[b_node])
                    a_c[k] = new_name
                    c_d[new_name] = b_d[b_node]
                i += 1

    # Remove edges
    for (b_n1, b_n2) in b.edges():
        a_keys_1 = keys_by_value(a_b, b_n1)
        a_keys_2 = keys_by_value(a_b, b_n2)
        if len(a_keys_1) > 0 and len(a_keys_2) > 0:
            for k1 in a_keys_1:
                for k2 in a_keys_2:
                    if d.is_directed():
                        if (k1, k2) not in a.edges() and\
                           (a_c[k1], a_c[k2]) in c.edges():
                            remove_edge(c, a_c[k1], a_c[k2])
                    else:
                        if (k1, k2) not in a.edges() and\
                           (k2, k1) not in a.edges():
                            if (a_c[k1], a_c[k2]) in d.edges() or\
                               (a_c[k2], a_c[k1]) in d.edges():
                                remove_edge(c, a_c[k1], a_c[k2])
    # Remove node attrs
    for a_node in a.nodes():
        attrs_to_remove = dict_sub(
            b.node[a_b[a_node]],
            a.node[a_node]
        )
        remove_node_attrs(c, a_c[a_node], attrs_to_remove)
        # removed_node_attrs[a_c[a_node]] = attrs_to_remove

    # Remove edge attrs
    for (n1, n2) in a.edges():
        attrs_to_remove = dict_sub(
            get_edge(b, a_b[n1], a_b[n2]),
            get_edge(a, n1, n2)
        )
        remove_edge_attrs(c, a_c[n1], a_c[n2], attrs_to_remove)
        # removed_edge_attrs[(a_c[n1], a_c[n2])] = attrs_to_remove

    return (c, a_c, c_d)
Exemplo n.º 8
0
def pullback_complement(a, b, d, a_b, b_d, inplace=False):
    """Find the final pullback complement from a->b->d.

    Makes changes to d inplace.
    """

    check_homomorphism(a, b, a_b, total=True)
    check_homomorphism(b, d, b_d, total=True)

    if not is_monic(b_d):
        raise InvalidHomomorphism("Second homomorphism is not monic, "
                                  "cannot find final pullback complement!")

    if inplace is True:
        c = d
    else:
        c = copy.deepcopy(d)

    a_c = dict()
    c_d = id_of(c.nodes())

    # Remove/clone nodes
    for b_node in b.nodes():
        a_keys = keys_by_value(a_b, b_node)
        # Remove nodes
        if len(a_keys) == 0:
            remove_node(c, b_d[b_node])
            del c_d[b_d[b_node]]
        # Keep nodes
        elif len(a_keys) == 1:
            a_c[a_keys[0]] = b_d[b_node]
        # Clone nodes
        else:
            i = 1
            for k in a_keys:
                if i == 1:
                    a_c[k] = b_d[b_node]
                    c_d[b_d[b_node]] = b_d[b_node]
                else:
                    new_name = clone_node(c, b_d[b_node])
                    a_c[k] = new_name
                    c_d[new_name] = b_d[b_node]
                i += 1

    # Remove edges
    for (b_n1, b_n2) in b.edges():
        a_keys_1 = keys_by_value(a_b, b_n1)
        a_keys_2 = keys_by_value(a_b, b_n2)
        if len(a_keys_1) > 0 and len(a_keys_2) > 0:
            for k1 in a_keys_1:
                for k2 in a_keys_2:
                    if d.is_directed():
                        if (k1, k2) not in a.edges() and\
                           (a_c[k1], a_c[k2]) in c.edges():
                            remove_edge(c, a_c[k1], a_c[k2])
                    else:
                        if (k1, k2) not in a.edges() and\
                           (k2, k1) not in a.edges():
                            if (a_c[k1], a_c[k2]) in d.edges() or\
                               (a_c[k2], a_c[k1]) in d.edges():
                                remove_edge(c, a_c[k1], a_c[k2])
    # Remove node attrs
    for a_node in a.nodes():
        attrs_to_remove = dict_sub(b.node[a_b[a_node]], a.node[a_node])
        remove_node_attrs(c, a_c[a_node], attrs_to_remove)
        # removed_node_attrs[a_c[a_node]] = attrs_to_remove

    # Remove edge attrs
    for (n1, n2) in a.edges():
        attrs_to_remove = dict_sub(get_edge(b, a_b[n1], a_b[n2]),
                                   get_edge(a, n1, n2))
        remove_edge_attrs(c, a_c[n1], a_c[n2], attrs_to_remove)
        # removed_edge_attrs[(a_c[n1], a_c[n2])] = attrs_to_remove

    return (c, a_c, c_d)