class PremodifierTest(unittest.TestCase):
    # @Before
    def setUp(self):
        self.lexicon = Lexicon.getDefaultLexicon()
        self.phraseFactory = NLGFactory(self.lexicon)
        self.realiser = Realiser(self.lexicon)

    # Test change from "a" to "an" in the presence of a premodifier with a vowel
    def testIndefiniteWithPremodifier(self):
        s = self.phraseFactory.createClause("there", "be")
        s.setFeature(Feature.TENSE, Tense.PRESENT)
        np = self.phraseFactory.createNounPhrase("a", "stenosis")
        s.setObject(np)
        # check without modifiers -- article should be "a"
        self.assertEqual("there is a stenosis",
                         self.realiser.realise(s).getRealisation())
        # add a single modifier -- should turn article to "an"
        np.addPreModifier(
            self.phraseFactory.createAdjectivePhrase("eccentric"))
        self.assertEqual("there is an eccentric stenosis",
                         self.realiser.realise(s).getRealisation())

    # Test for comma separation between premodifers
    def testMultipleAdjPremodifiers(self):
        np = self.phraseFactory.createNounPhrase("a", "stenosis")
        np.addPreModifier(
            self.phraseFactory.createAdjectivePhrase("eccentric"))
        np.addPreModifier(self.phraseFactory.createAdjectivePhrase("discrete"))
        self.assertEqual("an eccentric, discrete stenosis",
                         self.realiser.realise(np).getRealisation())

    # Test for comma separation between verb premodifiers
    def testMultipleAdvPremodifiers(self):
        adv1 = self.phraseFactory.createAdverbPhrase("slowly")
        adv2 = self.phraseFactory.createAdverbPhrase("discretely")
        # case 1: concatenated premods: should have comma
        vp = self.phraseFactory.createVerbPhrase("run")
        vp.addPreModifier(adv1)
        vp.addPreModifier(adv2)
        self.assertEqual("slowly, discretely runs",
                         self.realiser.realise(vp).getRealisation())
        # case 2: coordinated premods: no comma
        vp2 = self.phraseFactory.createVerbPhrase("eat")
        vp2.addPreModifier(
            self.phraseFactory.createCoordinatedPhrase(adv1, adv2))
        self.assertEqual("slowly and discretely eats",
                         self.realiser.realise(vp2).getRealisation())
Пример #2
0
class StandAloneExample(unittest.TestCase):
    def setUp(self):
        self.lexicon = XMLLexicon()
        self.nlgFactory = NLGFactory(self.lexicon)
        self.realiser = Realiser(self.lexicon)

    def testSentenceCreation(self):
        # create sentences
        thePark = self.nlgFactory.createNounPhrase("the", "park")
        bigp = self.nlgFactory.createAdjectivePhrase("big")
        bigp.setFeature(Feature.IS_COMPARATIVE, True)
        thePark.addModifier(bigp)
        # above relies on default placement rules.  You can force placement as a premodifier
        # (before head) by using addPreModifier
        toThePark = self.nlgFactory.createPrepositionPhrase("to")
        toThePark.setObject(thePark)
        # could also just say self.nlgFactory.createPrepositionPhrase("to", the Park)
        johnGoToThePark = self.nlgFactory.createClause("John", "go", toThePark)
        johnGoToThePark.setFeature(Feature.TENSE, Tense.PAST)
        johnGoToThePark.setFeature(Feature.NEGATED, True)
        # note that constituents (such as subject and object) are set with setXXX methods
        # while features are set with setFeature
        sentence = self.nlgFactory.createSentence(johnGoToThePark)
        # below creates a sentence DocumentElement by concatenating strings
        hePlayed = StringElement("he played")
        there = StringElement("there")
        football = WordElement("football")
        sentence2 = self.nlgFactory.createSentence()
        sentence2.addComponent(hePlayed)
        sentence2.addComponent(football)
        sentence2.addComponent(there)
        # now create a paragraph which contains these sentences
        paragraph = self.nlgFactory.createParagraph()
        paragraph.addComponent(sentence)
        paragraph.addComponent(sentence2)
        realised = self.realiser.realise(paragraph).getRealisation()
        # Test
        self.assertEqual(
            "John did not go to the bigger park. He played football there.\n\n",
            realised)

    def testMorphology(self):
        # second example - using simplenlg just for morphology
        word = self.nlgFactory.createWord("child", LexicalCategory.NOUN)
        # create InflectedWordElement from word element
        inflectedWord = InflectedWordElement(word)
        # set the inflected word to plural
        inflectedWord.setPlural(True)
        # realise the inflected word
        realised = self.realiser.realise(inflectedWord).getRealisation()
        # Test
        self.assertEqual('children', realised)
Пример #3
0
class Realizer(object):
    def __init__(self):
        verb2noun, noun2verb, verb2actor, actor2verb = utils.noun_verb(
            prop.morph_verb)
        self.verb2noun = verb2noun
        self.verb2actor = verb2actor

        sub2word = utils.subgraph_word(prop.verbalization)
        self.sub2word = sub2word

        lexicon = Lexicon.getDefaultLexicon()
        self.nlgFactory = NLGFactory(lexicon)
        self.realiser = Realiser(lexicon)

    def create_clause(self, subject, vp, _object, frontmodifiers, complements):
        phrase = self.nlgFactory.createClause()
        phrase.setSubject(subject)
        phrase.setVerbPhrase(vp)

        if _object != None:
            phrase.setObject(_object)

        for frontmodifier in frontmodifiers:
            phrase = self.add_frontmodifier(phrase, frontmodifier)

        for complement in complements:
            phrase = self.add_complement(phrase, complement)
        return phrase

    def create_np(self, determiner, head, number, premodifiers, postmodifiers):
        np = self.nlgFactory.createNounPhrase()
        np.setNoun(head)

        if determiner != '':
            np.setDeterminer(determiner)

        if number == 'singular':
            np.setFeature(Feature.NUMBER, NumberAgreement.SINGULAR)
        elif number == 'plural':
            np.setFeature(Feature.NUMBER, NumberAgreement.PLURAL)

        for premodifier in premodifiers:
            np = self.add_premodifier(np, premodifier)

        for postmodifier in postmodifiers:
            np = self.add_postmodifier(np, postmodifier)

        return np

    def create_vp(self, sentence):
        verb = sentence['verb']
        voice = sentence['voice']
        tense = sentence['tense']
        perfect = sentence['perfect']
        form = sentence['form']
        modal = sentence['modal']

        vp = self.nlgFactory.createVerbPhrase()
        vp.setVerb(verb)

        if tense == "past":
            vp.setFeature(Feature.TENSE, Tense.PAST)
        elif tense == "present":
            vp.setFeature(Feature.TENSE, Tense.PRESENT)
        elif tense == "future":
            vp.setFeature(Feature.TENSE, Tense.FUTURE)

        if voice == "active":
            vp.setFeature(Feature.PASSIVE, Boolean(False))
        else:
            vp.setFeature(Feature.PASSIVE, Boolean(True))

        if perfect:
            vp.setFeature(Feature.PERFECT, Boolean(True))
        else:
            vp.setFeature(Feature.PERFECT, Boolean(False))

        if form == 'negative':
            vp.setFeature(Feature.NEGATED, Boolean(True))
        elif form == 'infinitive':
            vp.setFeature(Feature.FORM, Form.INFINITIVE)

        if modal == 'possible':
            vp.setFeature(Feature.MODAL, "can")
        elif modal == 'obligate':
            vp.setFeature(Feature.MODAL, "must")
        elif modal == 'permit':
            vp.setFeature(Feature.MODAL, "may")
        elif modal == 'recommend':
            vp.setFeature(Feature.MODAL, "should")
        return vp

    def create_pp(self, preposition, np):
        pp = self.nlgFactory.createPrepositionPhrase()
        pp.addComplement(np)
        pp.setPreposition(preposition)
        return pp

    def create_adjp(self, adjective):
        adjp = self.nlgFactory.createAdjectivePhrase(adjective)
        return adjp

    def create_advp(self, adverb):
        advp = self.nlgFactory.createAdverbPhrase(adverb)
        return advp

    def create_possessive(self):
        np = self.nlgFactory.createNounPhrase()
        np.setFeature(Feature.PRONOMINAL, Boolean(True))
        np.setFeature(Feature.POSSESSIVE, Boolean(True))
        return np

    def add_complement(self, phrase, complement):
        phrase.addComplement(complement)
        return phrase

    def add_premodifier(self, phrase, premodifier):
        phrase.addPreModifier(premodifier)
        return phrase

    def add_postmodifier(self, phrase, postmodifier):
        phrase.addPostModifier(postmodifier)
        return phrase

    def add_frontmodifier(self, phrase, frontmodifier):
        phrase.addFrontModifier(frontmodifier)
        return phrase

    def add_complementiser(self, phrase, complement):
        phrase.setFeature(Feature.COMPLEMENTISER, complement)
        return phrase

    def process_np(self, root):
        determiner, premodifiers, head, postmodifiers = '', [], '', []
        for node in self.tree.edges[root]:
            if self.tree.nodes[node].type == 'terminal':
                if self.tree.nodes[node].name == 'DT':
                    determiner = self.tree.nodes[node].lexicon
                elif self.tree.nodes[node].label > -1 and self.tree.nodes[
                        node].rule_id == self.tree.nodes[root].rule_id:
                    head = self.tree.nodes[node].lexicon
                elif self.tree.nodes[node].name == 'PRP$':
                    mod = self.create_possessive()
                    premodifiers.append(mod)
                else:
                    mod = self.tree.nodes[node].lexicon
                    if head == '':
                        premodifiers.append(mod)
                    else:
                        postmodifiers.append(mod)
            else:
                mod = self.process(node)
                if mod != None:
                    if head == '':
                        premodifiers.append(mod)
                    else:
                        postmodifiers.append(mod)

        if head == '':
            head = copy.copy(determiner)
            determiner = ''
        p = self.create_np(determiner=determiner,
                           head=head,
                           number='singular',
                           premodifiers=premodifiers,
                           postmodifiers=postmodifiers)
        return p

    def process_vp(self, root, sentence):
        for node in self.tree.edges[root]:
            if self.tree.nodes[node].type == 'terminal':
                # treat modals
                if self.tree.nodes[node].name == 'MD':
                    sentence['modal'] = self.tree.nodes[node].lexicon
                # treat infinitive
                elif self.tree.nodes[node].name == 'TO':
                    sentence['form'] = 'infinitive'
                # treat negative
                elif self.tree.nodes[node].lexicon == 'not':
                    sentence['form'] = 'negative'
                elif self.tree.nodes[node].name == 'VB':
                    sentence['verb'] = self.tree.nodes[node].lexicon


#                     if self.tree.nodes[node].label > -1 and self.tree.nodes[node].rule_id == self.tree.nodes[root].rule_id:
#                         sentence['verb'] = self.tree.nodes[node].lexicon
            else:
                if self.tree.nodes[node].name == 'VP':
                    sentence = self.process_vp(node, sentence)
                else:
                    p = self.process(node)
                    if p != None:
                        rule_id = self.tree.nodes[node].rule_id
                        rule = self.synchg.rules[rule_id]
                        edge = rule.name.split('/')[0]
                        pos = self.tree.nodes[node].name

                        if 'NP' in pos:
                            if edge == ':ARG1' and sentence[
                                    'voice'] == 'active':
                                sentence['object'] = p
                            else:
                                sentence['complements'].append(p)
                        elif pos == 'PP':
                            if edge == ':ARG0' and sentence[
                                    'voice'] == 'passive':
                                p = p.getChildren()[1]
                                sentence['subject'] = p
                            else:
                                sentence['complements'].append(p)
                        else:
                            sentence['complements'].append(p)
        return sentence

    def process_pp(self, root):
        preposition, np = '', None
        for node in self.tree.edges[root]:
            if self.tree.nodes[node].type == 'terminal':
                preposition = self.tree.nodes[node].lexicon
            else:
                np = self.process(node)
        p = self.create_pp(preposition, np)
        return p

    def process_adjvp(self, root):
        premodifiers, head, postmodifiers = [], '', []
        for node in self.tree.edges[root]:
            if self.tree.nodes[node].type == 'terminal':
                if self.tree.nodes[node].label > -1 and self.tree.nodes[
                        node].rule_id == self.tree.nodes[root].rule_id:
                    head = self.tree.nodes[node].lexicon
                else:
                    mod = self.tree.nodes[node].lexicon
                    if head == '':
                        premodifiers.append(mod)
                    else:
                        postmodifiers.append(mod)
            else:
                mod = self.process(node)
                if head == '':
                    premodifiers.append(mod)
                else:
                    postmodifiers.append(mod)
        if self.tree.nodes[root].name == 'ADJP':
            p = self.create_adjp(head)
        else:
            p = self.create_advp(head)

        for premodifier in premodifiers:
            self.add_premodifier(p, premodifier)

        for postmodifier in postmodifiers:
            self.add_postmodifier(p, postmodifier)
        return p

    def process_s(self, root):
        # get voice
        rule_id = self.tree.nodes[root].rule_id
        rule = self.synchg.rules[rule_id]
        voice = rule.features.voice

        sentence = {
            'subject': None,
            'object': None,
            'verb': '',
            'tense': 'present',
            'modal': '',
            'voice': voice,
            'perfect': False,
            'form': 'affirmative',
            'frontmodifiers': [],
            'complements': []
        }

        for node in self.tree.edges[root]:
            if self.tree.nodes[node].name not in ['.', ':']:
                rule_id = self.tree.nodes[node].rule_id
                rule = self.synchg.rules[rule_id]

                edge = rule.name.split('/')[0]
                pos = self.tree.nodes[node].name

                if pos == 'VP':
                    sentence = self.process_vp(node, sentence)
                else:
                    p = self.process(node)

                    if 'NP' in pos:
                        if edge == ':ARG0':
                            sentence['subject'] = p
                        elif edge == ':ARG1':
                            if voice == 'active':
                                sentence['subject'] = p
                            else:
                                sentence['object'] = p
                        else:
                            if sentence['verb'] == '':
                                sentence['frontmodifiers'].append(p)
                            else:
                                sentence['complements'].append(p)
                    elif pos == 'PP':
                        if edge == ':ARG0' and self.voice == 'passive':
                            p = p.getChildren()[1]
                            sentence['subject'] = p
                        else:
                            if sentence['verb'] == '':
                                sentence['frontmodifiers'].append(p)
                            else:
                                sentence['complements'].append(p)

        vp = self.create_vp(sentence)
        subject = sentence['subject']
        object = sentence['object']
        frontmodifiers = sentence['frontmodifiers']
        complements = sentence['complements']

        p = self.create_clause(subject=subject,
                               vp=vp,
                               _object=object,
                               frontmodifiers=frontmodifiers,
                               complements=complements)
        return p

    def process_sbar(self, root):
        p, complement = None, 'that'
        for node in self.tree.edges[root]:
            if self.tree.nodes[node].name == 'S':
                p = self.process_s(node)
            elif self.tree.nodes[node].name[0] == 'W':
                child = self.tree.edges[node][0]
                complement = self.tree.nodes[child].lexicon
        if p != None:
            p = self.add_complementiser(p, complement)
        return p

    def check_coordination(self, root):
        pass

    def process(self, root):
        if self.tree.nodes[root].name == 'S':
            p = self.process_s(root)
        # SUBORDINATE CLAUSE
        elif self.tree.nodes[root].name == 'SBAR':
            p = self.process_sbar(root)
        # NOUN PHRASE
        elif 'NP' in self.tree.nodes[root].name:
            p = self.process_np(root)
        # PREPOSITIONAL PHRASES
        elif self.tree.nodes[root].name == 'PP':
            p = self.process_pp(root)
        # ADJECTIVE AND ADVERBIAL PHRASES
        elif self.tree.nodes[root].name in ['ADJP', 'ADVP']:
            p = self.process_adjvp(root)
        elif self.tree.nodes[root].name == 'FRAG':
            p = self.process(self.tree.edges[root][0])
        else:
            p = None
        return p

    def run(self, tree, synchg):
        self.tree = tree
        self.synchg = synchg

        root = tree.root
        # TO DO: treat multi sentences
        if self.tree.nodes[root].name == 'MULTI-SENTENCE':
            p = None
        else:
            root = self.tree.edges[self.tree.root][0]
            self.subject, self.vp, self.object = None, None, None
            self.complements, self.frontmodifiers = [], []

            p = self.process(root)

        if p != None:
            return self.realiser.realise(p)
        else:
            return '-'
Пример #4
0
class SimpleNLG4Test(unittest.TestCase):
    # Instantiates a new simplenlg test.
    def SimpleNLG4Test(self, name):
        super().__init__(name)

    # Set up the variables we'll need for this simplenlg.test to run
    # @Override @Before
    def setUp(self):
        self.lexicon = XMLLexicon()

        self.phraseFactory = NLGFactory(self.lexicon)
        self.realiser = Realiser(self.lexicon)

        self.man = self.phraseFactory.createNounPhrase("the", "man")
        self.woman = self.phraseFactory.createNounPhrase("the", "woman")
        self.dog = self.phraseFactory.createNounPhrase("the", "dog")
        self.boy = self.phraseFactory.createNounPhrase("the", "boy")

        self.beautiful = self.phraseFactory.createAdjectivePhrase("beautiful")
        self.stunning = self.phraseFactory.createAdjectivePhrase("stunning")
        self.salacious = self.phraseFactory.createAdjectivePhrase("salacious")

        self.onTheRock = self.phraseFactory.createPrepositionPhrase("on")
        self.np4 = self.phraseFactory.createNounPhrase("the", "rock")
        self.onTheRock.addComplement(self.np4)

        self.behindTheCurtain = self.phraseFactory.createPrepositionPhrase("behind")
        self.np5 = self.phraseFactory.createNounPhrase("the", "curtain")
        self.behindTheCurtain.addComplement(self.np5)

        self.inTheRoom = self.phraseFactory.createPrepositionPhrase("in")
        self.np6 = self.phraseFactory.createNounPhrase("the", "room")
        self.inTheRoom.addComplement(self.np6)

        self.underTheTable = self.phraseFactory.createPrepositionPhrase("under")
        self.underTheTable.addComplement(self.phraseFactory.createNounPhrase("the", "table"))

        self.proTest1 = self.phraseFactory.createNounPhrase("the", "singer")
        self.proTest2 = self.phraseFactory.createNounPhrase("some", "person")

        self.kick = self.phraseFactory.createVerbPhrase("kick")
        self.kiss = self.phraseFactory.createVerbPhrase("kiss")
        self.walk = self.phraseFactory.createVerbPhrase("walk")
        self.talk = self.phraseFactory.createVerbPhrase("talk")
        self.getUp = self.phraseFactory.createVerbPhrase("get up")
        self.fallDown = self.phraseFactory.createVerbPhrase("fall down")
        self.give = self.phraseFactory.createVerbPhrase("give")
        self.say = self.phraseFactory.createVerbPhrase("say")

    # @Override @After
    def tearDown(self):
        self.lexicon  = None
        self.realiser = None
        self.phraseFactory = None
        self.man = None
        self.woman = None
        self.dog = None
        self.boy = None
        self.np4 = None
        self.np5 = None
        self.np6 = None
        self.proTest1 = None
        self.proTest2 = None
        self.beautiful = None
        self.stunning = None
        self.salacious = None
        self.onTheRock = None
        self.behindTheCurtain= None
        self.inTheRoom = None
        self.underTheTable = None
        self.kick = None
        self.kiss = None
        self.walk = None
        self.talk = None
        self.getUp = None
        self.fallDown = None
        self.give = None
        self.say = None