--- code/amr.py.orig 2015-01-19 06:24:36.000000000 +0100 +++ code/amr.py 2015-09-18 10:57:44.000000000 +0200 @@ -163,6 +163,16 @@ """ print >> DEBUG_LOG, self.__str__() + @staticmethod + def inverted_label(label): + """Return the label of the inverted arc for an arc labeled `label`. If + the arc should not be inverted, return None.""" + if label == "mod": + return "domain" + elif label.endswith("-of-of") or label.endswith("-of") and label != "consist-of" and not label.startswith("prep-"): + return label[:-3] + else: + return None @staticmethod def parse_AMR_line(line): @@ -263,7 +273,11 @@ if node_value not in node_dict: node_relation_dict2[stack[-1]].append((relation_name, relation_value)) else: - node_relation_dict1[stack[-1]].append((relation_name, relation_value)) + inverted_relation_name = AMR.inverted_label(relation_name) + if inverted_relation_name is None: + node_relation_dict1[stack[-1]].append((relation_name, relation_value)) + else: + node_relation_dict1[relation_value].append((inverted_relation_name, stack[-1])) state = 2 elif c == "/": if in_quote: @@ -290,16 +304,13 @@ # node name is n # we have a relation arg1(upper level node, n) if cur_relation_name != "": - # if relation name ends with "-of", e.g."arg0-of", - # it is reverse of some relation. For example, if a is "arg0-of" b, - # we can also say b is "arg0" a. - # If the relation name ends with "-of", we store the reverse relation. - if not cur_relation_name.endswith("-of"): + # If the relation should be reversed, we store the reverse relation. + inverted_relation_name = AMR.inverted_label(cur_relation_name) + if inverted_relation_name is None: # stack[-2] is upper_level node we encountered, as we just add node_name to stack node_relation_dict1[stack[-2]].append((cur_relation_name, node_name)) else: - # cur_relation_name[:-3] is to delete "-of" - node_relation_dict1[node_name].append((cur_relation_name[:-3], stack[-2])) + node_relation_dict1[node_name].append((inverted_relation_name, stack[-2])) # clear current_relation_name cur_relation_name = "" else: @@ -327,10 +338,12 @@ return None relation_name = parts[0].strip() relation_value = parts[1].strip() - # store reverse of the relation - # we are sure relation_value is a node here, as "-of" relation is only between two nodes - if relation_name.endswith("-of"): - node_relation_dict1[relation_value].append((relation_name[:-3], stack[-1])) + inverted_relation_name = AMR.inverted_label(relation_name) + if inverted_relation_name is not None: + # Store the reverse of the relation. We are + # sure relation_value is a node here, as + # reversible relations are only between nodes. + node_relation_dict1[relation_value].append((inverted_relation_name, stack[-1])) # attribute value not seen before # Note that it might be a constant attribute value, or an unseen node # process this after we have seen all the node names @@ -359,6 +372,7 @@ node_value_list = [] relation_list = [] attribute_list = [] + delayed_inverted_edges = [] for v in node_name_list: if v not in node_dict: print >> ERROR_LOG, "Error: Node name not found", v @@ -370,6 +384,7 @@ attribute_dict = {} if v in node_relation_dict1: for v1 in node_relation_dict1[v]: + assert AMR.inverted_label(v1[0]) is None relation_dict[v1[1]] = v1[0] if v in node_relation_dict2: for v2 in node_relation_dict2[v]: @@ -379,7 +394,11 @@ attribute_dict[v2[0]] = v2[1][1:-1] # if value is a node name elif v2[1] in node_dict: - relation_dict[v2[1]] = v2[0] + inverted_label = AMR.inverted_label(v2[0]) + if inverted_label is None: + relation_dict[v2[1]] = v2[0] + else: + delayed_inverted_edges.append((v2[1], v, inverted_label)) else: attribute_dict[v2[0]] = v2[1] # each node has a relation map and attribute map @@ -387,6 +406,9 @@ attribute_list.append(attribute_dict) # add TOP as an attribute. The attribute value is the top node value attribute_list[0]["TOP"] = node_value_list[0] + for src, tgt, lab in delayed_inverted_edges: + idx = node_name_list.index(src) + relation_list[idx][tgt] = lab result_amr = AMR(node_name_list, node_value_list, relation_list, attribute_list) return result_amr @@ -404,4 +426,4 @@ print >> DEBUG_LOG, "AMR", amr_count current = AMR.parse_AMR_line(cur_line) current.output_amr() - amr_count += 1 \ No newline at end of file + amr_count += 1