goodmami / penman

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

How to transfer the following example to a reversed sentense? #107

Closed 14H034160212 closed 2 years ago

14H034160212 commented 2 years ago

Hi,

I got an question for the following example which is related to that question. https://github.com/goodmami/penman/issues/106 But the difference is the following example has different AMR structure to represent the same sentence. I am curious how to modify AMR graph to get a reversed sentnece.

In this case, the original sentence is "If you can use a computer, then you have keyboarding skills". The reversed sentence can be "If you have keyboarding skills, then you can use a computer".

# ::snt If you can use a computer, then you have keyboarding skills.
(h / have-03
      :ARG0 (y / you)
      :ARG1 (s / skill
            :topic (k / keyboard))
      :condition (p / possible-01
            :ARG1 (u / use-01
                  :ARG0 y
                  :ARG1 (c / computer))))

In this case, the original sentence is "If Alice can use a computer, then Bob have keyboarding skills". The reversed sentence can be "If Bob have keyboarding skills, then Alice can use a computer".

# ::snt If Alice can use a computer, then Bob have keyboarding skills.
(h / have-03
      :ARG0 (p / person
            :name (n / name
                  :op1 "Bob"))
      :ARG1 (s / skill
            :topic (k / keyboard))
      :condition (p2 / possible-01
            :ARG1 (u / use-01
                  :ARG0 (p3 / person
                        :name (n2 / name
                              :op1 "Alice"))
                  :ARG1 (c / computer))))
goodmami commented 2 years ago

As far as the Penman library is concerned, I think I have answered this query in #106. You will identify the nodes to swap via some search, then you remove the old triples and add the new ones. The graphs in this issue are just slightly different, so you will need to decide how you will identify the pattern and how you will modify it to get the graph you want, but these steps are up to you.

Do let me know if the Penman library is raising an error or is otherwise unable to make the modifications you want.

14H034160212 commented 2 years ago

Hi Goodmami,

Thanks a lot for your help. I solve the question using string manipulation for the graph, it seems straightforward to do that, and it does what I want now.

def swappable_conditions_2(g):
    graph = penman.encode(g)
    if ":ARG0" in graph and ":ARG1" in graph and ":condition" in graph:
        start = graph.index("(")
        end = graph.index(":condition")
        split_new_condition = ":condition "+ graph[start:end] +":polarity -)"
        split_old_condition = graph[end+len(":condition "):len(graph)-2] + "\n" +":polarity -" + "\n"
        new_contructed_graph = split_old_condition + split_new_condition + ")"
        return new_contructed_graph
goodmami commented 2 years ago

I strongly suggest you follow the example in #106 instead of doing string manipulations, which will only work for a very limited number of graphs.

14H034160212 commented 2 years ago

Thanks, I will rethink it.

14H034160212 commented 2 years ago

Hi Goodmami,

Thanks for your suggestion. In this case, I tried to use penman and string manipulation to reverse the sentence and got the following results.

Original sentence: If you can use a computer, then you have keyboarding skills. Reverse the sentence using Penman: You have the skill of a keyboard and you can use a computer. Reverse the sentence using string manipulation: You can use a computer if you have the skill of a keyboard.

The output results seem string manipulation is better than Penman in this case.

The following one is the original sentence and AMR structure.

# ::snt If you can use a computer, then you have keyboarding skills.
(h / have-03
      :ARG0 (y / you)
      :ARG1 (s / skill
            :topic (k / keyboard))
      :condition (p / possible-01
            :ARG1 (u / use-01
                  :ARG0 y
                  :ARG1 (c / computer))))

The following one is the reversed sentence and AMR output from penman.

# ::snt You have the skill of a keyboard and you can use a computer.
'(h / have-03
   :condition-of (p / possible-01
                    :ARG1 (u / use-01
                             :ARG0 y
                             :ARG1 (c / computer)))
   :ARG0 (y / you)
   :ARG1 (s / skill
            :topic (k / keyboard)))'

Here is the code for penman in this case.

def swappable_conditions(g):
    for inst in g.instances():
        if (len(g.edges(source=inst.source, role=':ARG0')) == 1  ## this if is working for contraposition law
         and len(g.edges(source=inst.source, role=':ARG1')) == 1
         and len(g.edges(source=inst.source, role=':condition')) == 1):
            yield inst.source

graphs = ["(h / have-03      :ARG0 (y / you)      :ARG1 (s / skill            :topic (k / keyboard))      :condition (p / possible-01            :ARG1 (u / use-01                  :ARG0 y                  :ARG1 (c / computer))))"]
return_list = []
for graph in graphs:
    g = penman.decode(graph)
    if len(list(swappable_conditions(g))) != 0:
        swap_condition = list(swappable_conditions(g))
        z0 = swap_condition[0]
        z_arg0 = g.edges(source=z0, role=':ARG0')[0].target
        z_arg1 = g.edges(source=z0, role=':ARG1')[0].target
        z_condition = g.edges(source=z0, role=':condition')[0].target
        g.triples.remove((z0, ':ARG0', z_arg0))  # remove the triples
        g.triples.remove((z0, ':ARG1', z_arg1))
        g.triples.remove((z0, ':condition', z_condition))
        g.epidata.clear()
        g.triples.insert(0,(z_condition, ':condition', z0))
        g.triples.insert(1,(z0, ':ARG0', z_arg0))
        g.triples.insert(2,(z0, ':ARG1', z_arg1))
        new_graph = penman.encode(g)
        return_list.append(new_graph)

## To convert graphs to sentences
gtos = amrlib.load_gtos_model("./pretrained_models/model_generate_t5wtense-v0_1_0")
sents, _ = gtos.generate(return_list)
## sents = ['You have the skill of a keyboard and you can use a computer.']

The following one is the reversed sentence and AMR output from my string manipulation.

# ::snt You can use a computer if you have the skill of a keyboard.
(p / possible-01
                 :ARG1 (u / use-01
                          :ARG0 y
                          :ARG1 (c / computer))
:condition (h / have-03
   :ARG0 (y / you)
   :ARG1 (s / skill
            :topic (k / keyboard))))
goodmami commented 2 years ago

The output results seem string manipulation is better than Penman in this case.

I don't know how the gtos model of amrlib works, but if you swap out other graph-to-string realizers I'd expect that you'd see different strings. For these graph manipulations, it's better to look at the output graphs directly.

And I don't know if even the original graph is very good for the sentence. Since the top node carries the focus, it looks more like the graph for "You have keyboarding skills if you can use a computer." For the given sentence, I'd expect the top node to be the reification of the :condition; namely, have-condition-91. But that's beside the point.

My main point is that string manipulation of the graph doesn't scale. Sure, you could write a function that matches the entire input graph as a string and outputs the perfectly swapped graph as a string, and it would be easier and possibly better than graph manipulations, but it would only work for that one graph. String matching parts of the graph is only a little more scalable, but it risks that you could output an ill-formed graph (if your replacement does not fit the graph where it's inserted). Graph operations work for more inputs because they abstract over many kinds of string variation and are less likely to result in an ill-formed graph, but they are a bit harder to implement.

14H034160212 commented 2 years ago

Thanks a lot for the great feedback! Do you know if there are any other graph-to-string realizers or the graph-to-string realizers you often used instead of the gtos model?

goodmami commented 2 years ago

Do you know if there are any other graph-to-string realizers or the graph-to-string realizers you often used instead of the gtos model?

There are plenty, but I don't actually use them, at least not now. You might try a search on the ACL Anthology (e.g., for AMR generation) and see what turns up.

14H034160212 commented 2 years ago

Thanks a lot!