def reify_edges(g: Graph, model: Model) -> Graph: """ Reify all edges in *g* that have reifications in *model*. Args: g: a :class:`~penman.graph.Graph` object model: a model defining reifications Returns: A new :class:`~penman.graph.Graph` object with reified edges. Example: >>> from penman.codec import PENMANCodec >>> from penman.models.amr import model >>> from penman.transform import reify_edges >>> codec = PENMANCodec(model=model) >>> g = codec.decode('(c / chapter :mod 7)') >>> g = reify_edges(g, model) >>> print(codec.encode(g)) (c / chapter :ARG1-of (_ / have-mod-91 :ARG2 7)) """ vars = g.variables() if model is None: model = Model() new_epidata = dict(g.epidata) new_triples: List[BasicTriple] = [] for triple in g.triples: if model.is_role_reifiable(triple[1]): in_triple, node_triple, out_triple = model.reify(triple, vars) if appears_inverted(g, triple): in_triple, out_triple = out_triple, in_triple new_triples.extend((in_triple, node_triple, out_triple)) var = node_triple[0] vars.add(var) # manage epigraphical markers new_epidata[in_triple] = [Push(var)] old_epis = new_epidata.pop(triple) if triple in new_epidata else [] node_epis, out_epis = _edge_markers(old_epis) new_epidata[node_triple] = node_epis new_epidata[out_triple] = out_epis # we don't know where to put the final POP without configuring # the tree; maybe this should be a tree operation? else: new_triples.append(triple) g = Graph(new_triples, epidata=new_epidata, metadata=g.metadata) logger.info('Reified edges: %s', g) return g
def test_reify(self, mini_amr): m = Model() with pytest.raises(ModelError): m.reify(('a', ':ARG0', 'b')) with pytest.raises(ModelError): m.reify(('a', ':accompanier', 'b')) with pytest.raises(ModelError): m.reify(('a', ':domain', 'b')) with pytest.raises(ModelError): m.reify(('a', ':mod', 'b')) m = Model.from_dict(mini_amr) with pytest.raises(ModelError): m.reify(('a', ':ARG0', 'b')) assert m.reify( ('a', ':accompanier', 'b')) == (('_', ':ARG0', 'a'), ('_', ':instance', 'accompany-01'), ('_', ':ARG1', 'b')) with pytest.raises(ModelError): assert m.reify(('a', ':domain', 'b')) assert m.reify( ('a', ':mod', 'b')) == (('_', ':ARG1', 'a'), ('_', ':instance', 'have-mod-91'), ('_', ':ARG2', 'b')) # ensure unique ids if variables is specified assert m.reify(('a', ':mod', 'b'), variables={'a', 'b', '_'}) == (('_2', ':ARG1', 'a'), ('_2', ':instance', 'have-mod-91'), ('_2', ':ARG2', 'b'))