示例#1
0
    def add_semantics(self, frame, tree_name, anchor):
        """
        Given a lemma and tree names, returns sem trees given by all matching
        verb classes and their frames. This is where all of the transformation
        logic currently lives for how to compute the semantics for combinations 
        of wh/PRO/gerunds/relclauses. These essentially act as 'metagrammar rules'
        that can be applied successively.
        """

        tree = self.grammar.get(tree_name)
        declarative_tree = self.grammar.get_declarative_tree(tree.tree_family)
        assert declarative_tree is not None
        sub_nouns = [n for n in declarative_tree.subst_nodes() if n.prefix() == "NP"]

        # Going to lexicalize for each frame
        tree = tree.copy()

        xtag_family = self.xtag_mapper.get_xtag_family(frame.primary, frame.secondary) 
        if xtag_family is None or xtag_family != tree.tree_family:
            return None

        # Currently ignore trees with more than one anchor (like Tnx0VPnx1)
        if len(tree.anchor_positions()) > 1:
            return None

        # Can't align semantics if wrong number of nouns/subnodes
        if len(frame.np_var_order) != len(sub_nouns):
            return None

        # Lexicalize tree
        tree.lexicalize(anchor)

        # Align np vars and substitution nodes
        node_entity_dict = {}
        for np_var, subst_node in zip(frame.np_var_order, sub_nouns):
            node_entity_dict[subst_node.label()] = np_var

        tree = SemTree.convert(tree)

        # Map event semantics to root
        sem_dict = frame.sem_dict
        tree.semantics = sem_dict["Event"]
        tree.sem_var = tree.semantics.event()
        # Map argument semantics to subst nodes
        for node_label, np_var in node_entity_dict.items():
            subst_node = tree.find(node_label)
            if subst_node is not None:
                #subst_node.semantics = sem_dict[np_var.name]
                tree.semantics = tree.semantics.concat(sem_dict[np_var.name])
                subst_node.sem_var = np_var

        # Check for PRO trees
        # Unclear to me how to handle the semantics here
        # The "PRO" noun should be replaced by a noun in the tree that this
        # would be substituted into. Probably need to handle during subst.
        if "PRO" in tree.tree_name:
            nps = [n for n in tree.subtrees() if n.prefix() == "NP"]
            pro_np = [n for n in nps if n.has_pro()][0]
            control_np = [n for n in nps if n.has_control()][0]

        # Relative Clauses 
        # In a relative clause, the root and and foot both represent the 
        # variable that was extracted e.g. in "cat -> cat that chased the dog"
        # both "cat" and "cat that chased the dog" refer to the cat entity
        if tree.tree_name.startswith("betaN"):
            nps = [n for n in tree.subtrees() if n.prefix() == "NP" and n.label() not in ["NP_r", "NP_f", "NP_w"]]
            extracted = [n for n in nps if n.has_trace()][0] 
            tree.find("NP_r").sem_var = node_entity_dict[extracted.label()]
            tree.find("NP_f").sem_var = node_entity_dict[extracted.label()]
            wh_var = VariableFactory.get_var()
            tree.find("NP_w").sem_var = wh_var

        return tree
示例#2
0
    def get_nonverb_semtree(self, tree_name, anchor):
        """
        Returns the semantically annotated tree specified by tree_name anchored
        by anchor. Note: the semantic info should eventually live somewhere
        that is more flexible (json, xml, etc)
        """

        tree = self.grammar.get(tree_name)
        tree.lexicalize(anchor)
        tree = SemTree.convert(tree)

        '''
        if tree.initial():
            v = VariableFactory.get_var(pre=anchor[0])
        else:
            v = VariableFactory.get_var()
        '''

        sem_map = {
            "alphaNXN": {
                "NP": (lambda a: "", "x1"),
                "N": (lambda a: "ISA(x1, %s)" % a.upper(), "x1"),
            },
            "betaAn": {
                "N_r": (lambda a: "ISA(x1, %s)" % a.upper(), "x1"),
                "N_f": (lambda a: "", "x1"),
            },
            "betaNn": {
                "N_r": (lambda a: "ISA(x1, %s)" % a.upper(), "x1"),
                "N_f": (lambda a: "", "x1"),
            },
            ("betaDnx", "a"): {
                "NP_r": (lambda a: "EXISTS(x1)|", "x1"),
                "NP_f": (lambda a: "", "x1"),
            },
            ("betaDnx", "an"): {
                "NP_r": (lambda a: "EXISTS(x1)|", "x1"),
                "NP_f": (lambda a: "", "x1"),
            },
            ("betaDnx", "the"): {
                "NP_r": (lambda a: "EXISTS(x1)|", "x1"),
                "NP_f": (lambda a: "", "x1"),
            },
            ("betaDnx", "one"): {
                "NP_r": (lambda a: "EXISTS(x1)|", "x1"),
                "NP_f": (lambda a: "", "x1"),
            },
            "betaVvx": {
                "VP_r": (lambda a: "", "x1"),
                "VP": (lambda a: "", "x1"),
            },
            "betanxPnx": {
                "NP_r": (lambda a: "%s(x1, y1)" % a, "x1"),
                "NP": (lambda a: "", "y1"),
                "NP_f": (lambda a: "", "x1"),
            },
            "betavxPnx": {
                "VP_r": (lambda a: "%s(x1, y1)" % a, "x1"),
                "NP": (lambda a: "", "y1"),
                "VP": (lambda a: "", "x1"),
            },
            "betasPUs": {
                "S_r": (lambda a: "", "AND(x1,y1)"),
                "S_f": (lambda a: "", "x1"),
                "S_1": (lambda a: "", "y1"),
            },
            "betaARBvx": {
                "VP": (lambda a: "", "x1"),
                "VP_r": (lambda a: "%s(x1)" % a, "x1"),
            },
            "betanxPUnx": {
                "NP_f": (lambda a: "", "x1"),
                "NP_r": (lambda a: "equal(x1,y1)", "x1"),
                "NP": (lambda a: "", "y1"),
            },
            "betaPUs": {
                "S_r": (lambda a: "", "x1"),
                "S": (lambda a: "", "x1"),
            },
            "betaVs": {
                "S_r": (lambda a: "", "x1"),
                "S": (lambda a: "", "x1"),
            },
            "betanx1CONJnx2": {
                "NP": (lambda a: "", "AND(x1,y1)"),
                "NP_1": (lambda a: "", "x1"),
                "NP_2": (lambda a: "", "y1"),
            },
            "betanxGnx": {
                "NP_r": (lambda a: "EXISTS(x1)|belongs_to(x1,y1)", "x1"),
                "NP_f": (lambda a: "", "x1"),
                "NP": (lambda a: "", "y1"),
            },
            "betavxPs": {
                "VP_r": (lambda a: "", "x1"),
                "VP_f": (lambda a: "", "x1"),
                "PP": (lambda a: "%s(x1, y1)" % a, "y1"),
                "S": (lambda a: "", "y1"),
            },
            "betas1CONJs2": {
                "S": (lambda a: "", "AND(x1,y1)"),
                "S_1": (lambda a: "", "x1"),
                "S_2": (lambda a: "", "y1"),
            },
            "betaARBs": {
                "S": (lambda a: "", "x1"),
                "S_r": (lambda a: "%s(x1)" % a, "x1"),
            },
            "betaCONJs": {
                "S_c": (lambda a: "", "x1"),
                "S_r": (lambda a: "", "x1"),
            },
        }


        if (tree_name, anchor) in sem_map:
            key = (tree_name, anchor)
        elif tree_name in sem_map:
            key = tree_name
        else:
            print(tree_name, anchor)
            raise NotImplementedError

        node_dict = sem_map[key]
        for node_label, (sem_str, var_str) in node_dict.items():
            sem_str = sem_str(anchor)
            node = tree.find(node_label)
            node.semantics = SemanticParser.parse(sem_str)
            var, rest = VariableParser.parse(var_str)
            node.sem_var = var

        return tree