goodmami / penman

PENMAN notation (e.g. AMR) in Python
https://penman.readthedocs.io/
MIT License
135 stars 26 forks source link

How to reverse the order for argument? #106

Closed 14H034160212 closed 2 years ago

14H034160212 commented 2 years ago

Hi,

I got one example and I want to modify the amr graph to get the reverse version of the reverse sentence for that. The original sentence:

# ::snt If you can use a computer, you have keyboarding skills.
(z0 / have-condition-91
      :ARG1 (z1 / have-03
            :ARG0 (z2 / you)
            :ARG1 (z3 / skill
                  :topic (z4 / keyboard-01)))
      :ARG2 (z5 / possible-01
            :ARG1 (z6 / use-01
                  :ARG0 z2
                  :ARG1 (z7 / computer))))

The reverse sentence would be

# ::snt If you have keyboardin skills, you can use a computer.

How can I do that? Many thanks!

goodmami commented 2 years ago

Firstly, to be clear, the ::snt metadata is not modeled beyond simply being stored along with the graph, so if you want to change that you simply reassign it. But if you are using that to illustrate that you want to swap the arguments in the graph, then you'll need to replace two triples: ('z0', ':ARG1', 'z1') and ('z0', ':ARG2', 'z5').

>>> import penman
>>> g = penman.decode('''
... # ::snt If you can use a computer, you have keyboarding skills.
... (z0 / have-condition-91
...       :ARG1 (z1 / have-03
...             :ARG0 (z2 / you)
...             :ARG1 (z3 / skill
...                   :topic (z4 / keyboard-01)))
...       :ARG2 (z5 / possible-01
...             :ARG1 (z6 / use-01
...                   :ARG0 z2
...                   :ARG1 (z7 / computer))))
... ''')
>>> g.triples.remove(('z0', ':ARG1', 'z1'))  # remove the triples
>>> g.triples.remove(('z0', ':ARG2', 'z5'))
>>> g.triples.append(('z0', ':ARG1', 'z5'))  # add the replacements
>>> g.triples.append(('z0', ':ARG2', 'z1'))
>>> g.metadata['snt'] = 'If you have keyboarding skills, you can use a computer.'
>>> print(penman.encode(g))
# ::snt If you have keyboarding skills, you can use a computer.
(z0 / have-condition-91
    :ARG1 (z5 / possible-01
              :ARG1 (z6 / use-01
                        :ARG0 z2
                        :ARG1 (z7 / computer)))
    :ARG2 (z1 / have-03
              :ARG0 (z2 / you)
              :ARG1 (z3 / skill
                        :topic (z4 / keyboard-01))))

Does that help?

14H034160212 commented 2 years ago

Thanks a lot. That makes sense!

14H034160212 commented 2 years ago

Hi, I got one more question. Do you have any idea to identify the z1 and z5 here? I want to construct a method to automatically do the reverse operation.

goodmami commented 2 years ago

You can use the other graph methods to find things, but it depends on what kinds of patterns you are looking for. For instance:

>>> def swappable_conditions(g):
...     for inst in g.instances():
...         if (inst.target == 'have-condition-91'
...                 and len(g.edges(source=inst.source, role=':ARG1')) == 1
...                 and len(g.edges(source=inst.source, role=':ARG2')) == 1):
...             yield inst.source
... 
>>> list(swappable_conditions(g))
['z0']
>>> g.edges(source='z0', role=':ARG1')
[Edge(source='z0', role=':ARG1', target='z1')]
>>> g.edges(source='z0', role=':ARG1')[0].target
'z1'
>>> g.edges(source='z0', role=':ARG2')[0].target
'z5'
goodmami commented 2 years ago

I'll take the :+1: to mean that your question was answered and close this thread.

14H034160212 commented 2 years ago

Thank you so much!