def _remove_edge_rhs(self, node1, node2): """Remove edge from the rhs of the graph.""" primitives.remove_edge(self.rhs, node1, node2) for pn1 in keys_by_value(self.p_rhs, node1): for pn2 in keys_by_value(self.p_rhs, node2): if (pn1, pn2) in self.p.edges(): primitives.remove_edge(self.p, pn1, pn2)
def remove_edge_rhs(self, node1, node2): """Remove edge from the rhs of the graph.""" primitives.remove_edge(self.rhs, node1, node2) for pn1 in keys_by_value(self.p_rhs, node1): for pn2 in keys_by_value(self.p_rhs, node2): print(pn1, pn2) try: primitives.remove_edge(self.p, pn1, pn2) except GraphError: continue
def inject_remove_edge(self, n1, n2): """Inject removal of an edge by the rule. Parameters ---------- n1 : hashable Id of an edge's source node in `lhs`. n2 : hashable Id of an edge's target node in `lhs`. Raises ------ RuleError If some of the nodes are not found in neither `lhs` nor `p`, or if a corresponding edge in `p` does not exist. """ # Find nodes in p mapping to n1 & n2 p_keys_1 = keys_by_value(self.p_lhs, n1) p_keys_2 = keys_by_value(self.p_lhs, n2) # n1 is actually a node from `p` if len(p_keys_1) == 0: if n1 in self.p.nodes(): p_keys_1 = [n1] else: raise RuleError( "Node '%s' is not found in neither left-hand " "side nor preserved part" % n2) if len(p_keys_2) == 0: if n2 in self.p.nodes(): p_keys_2 = [n2] else: raise RuleError( "Node '%s' is not found in neither left-hand " "side nor preserved part" % str(n2)) for k1 in p_keys_1: for k2 in p_keys_2: if (k1, k2) in self.p.edges(): primitives.remove_edge(self.p, k1, k2) primitives.remove_edge(self.rhs, self.p_rhs[k1], self.p_rhs[k2]) else: raise RuleError( "Edge '%s->%s' does not exist in the preserved part" % (k1, k2)) return
def remove_edge(self, n1, n2): """Remove edge from the graph.""" # Find nodes in p mapping to n1 & n2 p_keys_1 = keys_by_value(self.p_lhs, n1) p_keys_2 = keys_by_value(self.p_lhs, n2) # Remove edge from the preserved part & rhs of the rule for k1 in p_keys_1: if k1 not in self.p.nodes(): raise RuleError( "Node with the id '%s' does not exist in " "the preserved part" % k1 ) for k2 in p_keys_2: if k2 not in self.p.nodes(): raise RuleError( "Node with the id '%s' does not exist in " "the preserved part" % k2 ) rhs_key_1 = self.p_rhs[k1] rhs_key_2 = self.p_rhs[k2] if self.p.is_directed(): if (k1, k2) not in self.p.edges(): raise RuleError( "Edge '%s->%s' does not exist in the preserved " "part of the rule " % (k1, k2) ) if (rhs_key_1, rhs_key_2) not in self.rhs.edges(): raise RuleError( "Edge '%s->%s' does not exist in the right hand " "side of the rule " % (rhs_key_1, rhs_key_2) ) primitives.remove_edge(self.p, k1, k2) primitives.remove_edge(self.rhs, rhs_key_1, rhs_key_2) else: if (k1, k2) not in self.p.edges() and\ (k2, k1) not in self.p.edges(): raise RuleError( "Edge '%s->%s' does not exist in the " "preserved part of the rule " % (k1, k2) ) if (rhs_key_1, rhs_key_2) not in self.rhs.edges() and\ (rhs_key_2, rhs_key_1) not in self.rhs.edges(): raise RuleError( "Edge '%s->%s' does not exist in the right " "hand side of the rule " % (rhs_key_1, rhs_key_2) ) primitives.remove_edge(self.p, k1, k2) return
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)
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)
def remove_edge_p(self, node1, node2): """Remove edge from the p of the graph.""" primitives.remove_edge(self.p, node1, node2)
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)
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)