def test_rewrite_remove_order(data): """Rewritings that only remove hyperedges and add nodes may be applied in any order if we ignore already removed.""" for congruence in [True, False]: h1 = data.draw(PE.gen_hypergraph(congruence=congruence)) h2 = Hypergraph(congruence=congruence) h3 = Hypergraph(congruence=congruence) mapping12 = h2.add_from(h1) mapping23 = h3.add_from(h2) rwa = data.draw(PE.gen_rewrite(h1, num_add_hyperedges=0, num_merge=0)) rwb = data.draw(PE.gen_rewrite(h1, num_add_hyperedges=0, num_merge=0)) h1.rewrite(**rwa) h1.rewrite(**rwb, ignore_already_removed=True) rwa2 = PE.map_rewrite(rwa, mapping12) rwb2 = PE.map_rewrite(rwb, mapping12) h2.rewrite(**rwb2) h2.rewrite(**rwa2, ignore_already_removed=True) rwa3 = PE.map_rewrite(rwa2, mapping23) rwb3 = PE.map_rewrite(rwb2, mapping23) h3.rewrite(add=(rwa3['add'] + rwb3['add']), remove=(rwa3['remove'] + rwb3['remove'])) assert h1.isomorphic(h2) assert h1.isomorphic(h3)
def test_rewrite_noremove_order(data): """Rewritings that don't remove may be applied in any order""" for congruence in [True, False]: h1 = data.draw(PE.gen_hypergraph(congruence=congruence)) h2 = Hypergraph(congruence=congruence) h3 = Hypergraph(congruence=congruence) mapping12 = h2.add_from(h1) mapping23 = h3.add_from(h2) rwa = data.draw(PE.gen_rewrite(h1, num_remove=0)) rwb = data.draw(PE.gen_rewrite(h1, num_remove=0)) h1.rewrite(**rwa) h1.rewrite(**rwb) rwa2 = PE.map_rewrite(rwa, mapping12) rwb2 = PE.map_rewrite(rwb, mapping12) h2.rewrite(**rwb2) h2.rewrite(**rwa2) rwa3 = PE.map_rewrite(rwa2, mapping23) rwb3 = PE.map_rewrite(rwb2, mapping23) h3.rewrite(add=(rwa3['add'] + rwb3['add']), merge=(rwa3['merge'] + rwb3['merge'])) assert h1.isomorphic(h2) assert h1.isomorphic(h3)
def test_rewriting(data): """Rewriting leaves graph in a consistent state. Also adding really adds and merging really merges, removing is tested separately (because addition has higher priority than removing).""" for congruence in [True, False]: h = data.draw(PE.gen_hypergraph(congruence=congruence)) for i in range(2): rw = data.draw(PE.gen_rewrite(h)) added = h.rewrite(**rw) h.check_integrity() nodes = h.nodes() hyperedges = h.hyperedges() for n1, n2 in rw['merge']: n1 = n1.follow() n2 = n2.follow() assert n1 == n2 assert n1 in nodes for e in added: if isinstance(e, Node): assert e in nodes else: assert e in hyperedges
def test_remove(data): """Removing indeed removes""" for congruence in [True, False]: h = data.draw(PE.gen_hypergraph(congruence=congruence)) rw = data.draw(PE.gen_rewrite(h, num_add_hyperedges=0, num_merge=0)) h.rewrite(**rw) hyperedges = h.hyperedges() for h in rw['remove']: assert not h in hyperedges
def test_listener(data): """This tests events. Note that the integrity is non-strict.""" for congruence in [True, False]: h1 = data.draw(PE.gen_hypergraph(congruence=congruence)) class _L: def __init__(self, to_add): self.to_add = to_add def on_add(self, hypergraph, elements): hypergraph.check_integrity(False) for e in elements: assert e in hypergraph assert e not in self.to_add self.to_add |= set(elements) def on_merge(self, hypergraph, node, removed, added, reason): hypergraph.check_integrity(False) assert node not in hypergraph assert node.merged in hypergraph assert node in self.to_add assert node.merged in self.to_add for h in removed: assert h not in hypergraph assert h.merged in hypergraph assert h in self.to_add for h in added: assert h in hypergraph assert h not in self.to_add self.to_add -= set(removed) self.to_add -= set([node]) self.to_add |= set(added) def on_remove(self, hypergraph, elements): hypergraph.check_integrity(False) for e in elements: assert e not in hypergraph assert e in self.to_add self.to_add -= set(elements) lis = _L(set(h1.nodes()) | set(h1.hyperedges())) h1.listeners.add(lis) rw = data.draw(PE.gen_rewrite(h1)) h1.rewrite(**rw) h2 = Hypergraph(congruence=congruence) h2.rewrite(add=lis.to_add) assert h1.isomorphic(h2)
def test_add_from(data): """add_from results in isomorphic graph, and its mapping can be used to apply the same transformations to each copy. Moreover, the order of elements in the rewrite may be different.""" for congruence in [True, False]: h1 = data.draw(PE.gen_hypergraph(congruence=congruence)) h2 = Hypergraph(congruence=congruence) mapping = h2.add_from(h1) assert h1.isomorphic(h2) rw1 = data.draw(PE.gen_rewrite(h1)) rw2 = PE.map_rewrite(data.draw(PE.gen_permuted_rewrite(rw1)), mapping) h1.rewrite(**rw1) h2.rewrite(**rw2) assert h1.isomorphic(h2)
def test_add_removed(data): """Removing hyperedges and then adding the same hyperedges is noop.""" for congruence in [True, False]: h1 = data.draw(PE.gen_hypergraph(congruence=congruence)) h2 = Hypergraph(congruence=congruence) mapping = h2.add_from(h1) rw1 = data.draw(PE.gen_rewrite(h1)) rw2 = PE.map_rewrite(rw1, mapping) rw2['remove'] = [] h1.rewrite(**rw1) if congruence: h1.rewrite(add=rw1['remove']) else: # For the noncongruent case we have to have to be careful with duplicates h1.rewrite(add=set(rw1['remove'])) h2.rewrite(**rw2) assert h1.isomorphic(h2)