/** * This method performs the morphology for pronouns. * * @param element the <code>InflectedWordElement</code>. * @return a <code>StringElement</code> representing the word after inflection. */ public NLGElement doPronounMorphology(InflectedWordElement element) { String realised = null; if (!element.getFeatureAsBoolean(InternalFeature.NON_MORPH).booleanValue()) { Object genderValue = element.getFeature(LexicalFeature.GENDER); Object personValue = element.getFeature(Feature.PERSON); // way of getting discourseValue changed by vaudrypl NLGElement parent = element.getParent(); Object discourseValue = element.getFeature(InternalFeature.DISCOURSE_FUNCTION); if (discourseValue == DiscourseFunction.SUBJECT && parent != null && parent.isA(PhraseCategory.NOUN_PHRASE)) { discourseValue = parent.getFeature(InternalFeature.DISCOURSE_FUNCTION); } if (!(discourseValue instanceof DiscourseFunction)) discourseValue = DiscourseFunction.SUBJECT; int numberIndex = element.isPlural() ? 1 : 0; int genderIndex = (genderValue instanceof Gender) ? ((Gender) genderValue).ordinal() : 2; int personIndex = (personValue instanceof Person) ? ((Person) personValue).ordinal() : 2; if (personIndex == 2) { personIndex += genderIndex; } int positionIndex = 0; if (element.getFeatureAsBoolean(LexicalFeature.REFLEXIVE).booleanValue()) { positionIndex = 2; } else if (element.getFeatureAsBoolean(Feature.POSSESSIVE).booleanValue()) { positionIndex = 3; if (DiscourseFunction.SPECIFIER.equals(discourseValue)) { positionIndex++; } } else { positionIndex = (DiscourseFunction.SUBJECT.equals(discourseValue) && !element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue()) || (DiscourseFunction.OBJECT.equals(discourseValue) && element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue()) || DiscourseFunction.SPECIFIER.equals(discourseValue) || (DiscourseFunction.COMPLEMENT.equals(discourseValue) && element.getFeatureAsBoolean(Feature.PASSIVE).booleanValue()) ? 0 : 1; } realised = PRONOUNS[numberIndex][positionIndex][personIndex]; } else { realised = element.getBaseForm(); } // vaudrypl added element as 2nd argument StringElement realisedElement = new StringElement(realised, element); realisedElement.setFeature( InternalFeature.DISCOURSE_FUNCTION, element.getFeature(InternalFeature.DISCOURSE_FUNCTION)); return realisedElement; }
/** * Convenience class to realise any NLGElement as a sentence * * @param element * @return String realisation of the NLGElement */ public String realiseSentence(NLGElement element) { NLGElement realised = null; if (element instanceof DocumentElement) realised = realise(element); else { DocumentElement sentence = new DocumentElement(DocumentCategory.SENTENCE, null); sentence.addComponent(element); realised = realise(sentence); } if (realised == null) return null; else return realised.getRealisation(); }
/* * TODO: Let's go to sleep. reflexive verbs -- use of reflexive verb + * future proche */ public void _test_lets_go_to_sleep() { ArrayList<PicWordAction> phrases = new ArrayList<PicWordAction>(); phrases.add(new PicWordAction("on", Pic2NLG.ActionType.NOUN)); NLGElement se_coucher = Pic2NLG.factory.createNLGElement("coucher"); se_coucher.setFeature(LexicalFeature.REFLEXIVE, true); phrases.add(new PicWordAction(se_coucher, Pic2NLG.ActionType.VERB)); phrases.add(new PicWordAction("futur_proche", Pic2NLG.ActionType.TENSE_PRESENT)); assertEquals("On va se coucher", converter.convertPhrasesToNLG(phrases)); }
/** * This is the main method for performing the morphology. It effectively * examines the lexical category of the element and calls the relevant set * of rules from <code>MorphologyRules</em>. * * @param element * the <code>InflectedWordElement</code> * @return an <code>NLGElement</code> reflecting the correct inflection for * the word. * */ private NLGElement doMorphology(InflectedWordElement element) { NLGElement realisedElement = null; if (element.getFeatureAsBoolean(InternalFeature.NON_MORPH).booleanValue()) { realisedElement = new StringElement(element.getBaseForm()); realisedElement.setFeature( InternalFeature.DISCOURSE_FUNCTION, element.getFeature(InternalFeature.DISCOURSE_FUNCTION)); } else { NLGElement baseWord = element.getFeatureAsElement(InternalFeature.BASE_WORD); if (baseWord == null && this.lexicon != null) { baseWord = this.lexicon.lookupWord(element.getBaseForm()); } ElementCategory category = element.getCategory(); if (category instanceof LexicalCategory) { switch ((LexicalCategory) category) { case PRONOUN: realisedElement = MorphologyRules.doPronounMorphology(element); break; case NOUN: realisedElement = MorphologyRules.doNounMorphology(element, (WordElement) baseWord); break; case VERB: realisedElement = MorphologyRules.doVerbMorphology(element, (WordElement) baseWord); break; case ADJECTIVE: realisedElement = MorphologyRules.doAdjectiveMorphology(element, (WordElement) baseWord); break; case ADVERB: realisedElement = MorphologyRules.doAdverbMorphology(element, (WordElement) baseWord); break; default: realisedElement = new StringElement(element.getBaseForm()); realisedElement.setFeature( InternalFeature.DISCOURSE_FUNCTION, element.getFeature(InternalFeature.DISCOURSE_FUNCTION)); } } } return realisedElement; }
/** * Determines the maximim position at which this modifier can occur. * * @param modifier the modifier to be checked. * @return the maximum position for this modifier. */ private static int getMaxPos(NLGElement modifier) { int position = NOUN_POSITION; if (modifier.isA(LexicalCategory.ADJECTIVE) || modifier.isA(PhraseCategory.ADJECTIVE_PHRASE)) { WordElement adjective = getHeadWordElement(modifier); if (adjective.getFeatureAsBoolean(LexicalFeature.CLASSIFYING).booleanValue()) { position = CLASSIFYING_POSITION; } else if (adjective.getFeatureAsBoolean(LexicalFeature.COLOUR).booleanValue()) { position = COLOUR_POSITION; } else if (adjective.getFeatureAsBoolean(LexicalFeature.QUALITATIVE).booleanValue()) { position = QUALITATIVE_POSITION; } else { position = CLASSIFYING_POSITION; } } return position; }
/** Test the genders of multi-gender words, like chanteuse */ public void _test_je_veux_etre_chanteuse_gender() { ArrayList<PicWordAction> phrases = new ArrayList<PicWordAction>(); // je avoir [past] assez bonbon [plural] ==> j'ai eu assez des bonbons phrases.add(new PicWordAction("je", Pic2NLG.ActionType.NOUN)); phrases.add(new PicWordAction("vouloir", Pic2NLG.ActionType.VERB)); // phrases.add(new PicWordAction("past", Pic2NLG.wordTYPE.TENSE)); phrases.add(new PicWordAction("etre", Pic2NLG.ActionType.VERB)); NLGElement chanteuse = Pic2NLG.factory.createNounPhrase("un", "chanteur"); chanteuse.setFeature(LexicalFeature.GENDER, Gender.FEMININE); System.out.println(chanteuse); phrases.add(new PicWordAction(chanteuse, Pic2NLG.ActionType.NOUN)); // TODO: phrases.add(new PicWordAction("plural", // Pic2NLG.ActionType.NUMBER_AGREEMENT)); assertEquals("Je veux etre une chanteuse", converter.convertPhrasesToNLG(phrases)); }
@Override public SPhraseSpec generate() { Lexicon lexicon = Lexicon.getDefaultLexicon(); NLGFactory nlgFactory = new NLGFactory(lexicon); SPhraseSpec s = nlgFactory.createClause(); s.setFrontModifier("moreover"); NPPhraseSpec secondDive = nlgFactory.createNounPhrase("dive"); secondDive.setDeterminer("your"); secondDive.setPreModifier("second"); VPPhraseSpec be = nlgFactory.createVerbPhrase("be"); NLGElement predicative = nlgFactory.createInflectedWord("deep", LexicalCategory.ADVERB); predicative.setFeature(Feature.IS_COMPARATIVE, true); be.addComplement(predicative); PPPhraseSpec than = nlgFactory.createPrepositionPhrase("than"); NPPhraseSpec firstDive = nlgFactory.createNounPhrase("one"); firstDive.setDeterminer("the"); firstDive.setPreModifier("first"); than.addComplement(firstDive); s.setSubject(secondDive); s.setVerb(be); s.addComplement(than); s.setFeature(Feature.TENSE, Tense.PAST); SPhraseSpec which = nlgFactory.createClause(); VPPhraseSpec beNot = nlgFactory.createVerbPhrase("be"); beNot.setFeature(Feature.NEGATED, true); NLGElement recommended = nlgFactory.createAdjectivePhrase("recommended"); beNot.addComplement(recommended); beNot.addModifier("really"); which.setVerb(beNot); which.setFeature(Feature.COMPLEMENTISER, "which"); s.addComplement(which); return s; }
/** * Realises the specifier of the noun phrase. * * @param phrase the <code>PhraseElement</code> representing this noun phrase. * @param parent the parent <code>SyntaxProcessor</code> that will do the realisation of the * complementiser. * @param realisedElement the current realisation of the noun phrase. */ private static void realiseSpecifier( PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement) { NLGElement specifierElement = phrase.getFeatureAsElement(InternalFeature.SPECIFIER); if (specifierElement != null && !phrase.getFeatureAsBoolean(InternalFeature.RAISED).booleanValue() && !phrase.getFeatureAsBoolean(Feature.ELIDED).booleanValue()) { if (!specifierElement.isA(LexicalCategory.PRONOUN)) { specifierElement.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER)); } NLGElement currentElement = parent.realise(specifierElement); if (currentElement != null) { currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SPECIFIER); realisedElement.addComponent(currentElement); } } }
/** * Realises the head noun of the noun phrase. * * @param phrase the <code>PhraseElement</code> representing this noun phrase. * @param parent the parent <code>SyntaxProcessor</code> that will do the realisation of the * complementiser. * @param realisedElement the current realisation of the noun phrase. */ private static void realiseHeadNoun( PhraseElement phrase, SyntaxProcessor parent, ListElement realisedElement) { NLGElement headElement = phrase.getHead(); if (headElement != null) { headElement.setFeature(Feature.ELIDED, phrase.getFeature(Feature.ELIDED)); headElement.setFeature(LexicalFeature.GENDER, phrase.getFeature(LexicalFeature.GENDER)); headElement.setFeature(InternalFeature.ACRONYM, phrase.getFeature(InternalFeature.ACRONYM)); headElement.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER)); headElement.setFeature(Feature.PERSON, phrase.getFeature(Feature.PERSON)); headElement.setFeature(Feature.POSSESSIVE, phrase.getFeature(Feature.POSSESSIVE)); headElement.setFeature(Feature.PASSIVE, phrase.getFeature(Feature.PASSIVE)); NLGElement currentElement = parent.realise(headElement); currentElement.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SUBJECT); realisedElement.addComponent(currentElement); } }
/** * Retrieves the correct representation of the word from the element. This method will find the * <code>WordElement</code>, if it exists, for the given phrase or inflected word. * * @param element the <code>NLGElement</code> from which the head is required. * @return the <code>WordElement</code> */ private static WordElement getHeadWordElement(NLGElement element) { WordElement head = null; if (element instanceof WordElement) head = (WordElement) element; else if (element instanceof InflectedWordElement) { head = (WordElement) element.getFeature(InternalFeature.BASE_WORD); } else if (element instanceof PhraseElement) { head = getHeadWordElement(((PhraseElement) element).getHead()); } return head; }
@Override public NLGElement realise(NLGElement element) { NLGElement realisedElement = null; if (element instanceof InflectedWordElement) { realisedElement = doMorphology((InflectedWordElement) element); } else if (element instanceof StringElement) { realisedElement = element; } else if (element instanceof WordElement) { // AG: now retrieves the default spelling variant, not the baseform // String baseForm = ((WordElement) element).getBaseForm(); String defaultSpell = ((WordElement) element).getDefaultSpellingVariant(); if (defaultSpell != null) { realisedElement = new StringElement(defaultSpell); } } else if (element instanceof DocumentElement) { List<NLGElement> children = element.getChildren(); ((DocumentElement) element).setComponents(realise(children)); realisedElement = element; } else if (element instanceof ListElement) { realisedElement = new ListElement(); ((ListElement) realisedElement).addComponents(realise(element.getChildren())); } else if (element instanceof CoordinatedPhraseElement) { List<NLGElement> children = element.getChildren(); ((CoordinatedPhraseElement) element).clearCoordinates(); if (children != null && children.size() > 0) { ((CoordinatedPhraseElement) element).addCoordinate(realise(children.get(0))); for (int index = 1; index < children.size(); index++) { ((CoordinatedPhraseElement) element).addCoordinate(realise(children.get(index))); } realisedElement = element; } } else if (element != null) { realisedElement = element; } return realisedElement; }
@Override public List<NLGElement> realise(List<NLGElement> elements) { List<NLGElement> realisedElements = new ArrayList<NLGElement>(); NLGElement currentElement = null; NLGElement determiner = null; if (elements != null) { for (NLGElement eachElement : elements) { currentElement = realise(eachElement); if (currentElement != null) { realisedElements.add(realise(currentElement)); if (determiner == null && DiscourseFunction.SPECIFIER.equals( currentElement.getFeature(InternalFeature.DISCOURSE_FUNCTION))) { determiner = currentElement; determiner.setFeature(Feature.NUMBER, eachElement.getFeature(Feature.NUMBER)); // MorphologyRules.doDeterminerMorphology(determiner, // currentElement.getRealisation()); } else if (determiner != null) { if (currentElement instanceof ListElement) { NLGElement firstChild = ((ListElement) currentElement).getChildren().get(0); if (firstChild != null) { MorphologyRules.doDeterminerMorphology(determiner, firstChild.getRealisation()); } } else { MorphologyRules.doDeterminerMorphology(determiner, currentElement.getRealisation()); } determiner = null; } } } } return realisedElements; }
/** * Creates the appropriate pronoun if the subject of the noun phrase is pronominal. * * @param parent the parent <code>SyntaxProcessor</code> that will do the realisation of the * complementiser. * @param phrase the <code>PhraseElement</code> representing this noun phrase. * @return the <code>NLGElement</code> representing the pronominal. */ private static NLGElement createPronoun(SyntaxProcessor parent, PhraseElement phrase) { String pronoun = "it"; // $NON-NLS-1$ NLGFactory phraseFactory = phrase.getFactory(); Object personValue = phrase.getFeature(Feature.PERSON); if (Person.FIRST.equals(personValue)) { pronoun = "I"; // $NON-NLS-1$ } else if (Person.SECOND.equals(personValue)) { pronoun = "you"; // $NON-NLS-1$ } else { Object genderValue = phrase.getFeature(LexicalFeature.GENDER); if (Gender.FEMININE.equals(genderValue)) { pronoun = "she"; // $NON-NLS-1$ } else if (Gender.MASCULINE.equals(genderValue)) { pronoun = "he"; // $NON-NLS-1$ } } // AG: createWord now returns WordElement; so we embed it in an // inflected word element here NLGElement element; NLGElement proElement = phraseFactory.createWord(pronoun, LexicalCategory.PRONOUN); if (proElement instanceof WordElement) { element = new InflectedWordElement((WordElement) proElement); element.setFeature( LexicalFeature.GENDER, ((WordElement) proElement).getFeature(LexicalFeature.GENDER)); // Ehud - also copy over person element.setFeature(Feature.PERSON, ((WordElement) proElement).getFeature(Feature.PERSON)); } else { element = proElement; } element.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.SPECIFIER); element.setFeature(Feature.POSSESSIVE, phrase.getFeature(Feature.POSSESSIVE)); element.setFeature(Feature.NUMBER, phrase.getFeature(Feature.NUMBER)); if (phrase.hasFeature(InternalFeature.DISCOURSE_FUNCTION)) { element.setFeature( InternalFeature.DISCOURSE_FUNCTION, phrase.getFeature(InternalFeature.DISCOURSE_FUNCTION)); } return element; }
@Override public NLGElement realise(NLGElement element) { StringBuilder debug = new StringBuilder(); if (this.debug) { System.out.println("INITIAL TREE\n"); // $NON-NLS-1$ System.out.println(element.printTree(null)); debug.append("INITIAL TREE<br/>"); debug.append(element.printTree(" ").replaceAll("\n", "<br/>")); } NLGElement postSyntax = this.syntax.realise(element); if (this.debug) { System.out.println("<br/>POST-SYNTAX TREE<br/>"); // $NON-NLS-1$ System.out.println(postSyntax.printTree(null)); debug.append("<br/>POST-SYNTAX TREE<br/>"); debug.append(postSyntax.printTree(" ").replaceAll("\n", "<br/>")); } NLGElement postMorphology = this.morphology.realise(postSyntax); if (this.debug) { System.out.println("\nPOST-MORPHOLOGY TREE\n"); // $NON-NLS-1$ System.out.println(postMorphology.printTree(null)); debug.append("<br/>POST-MORPHOLOGY TREE<br/>"); debug.append(postMorphology.printTree(" ").replaceAll("\n", "<br/>")); } NLGElement postOrthography = this.orthography.realise(postMorphology); if (this.debug) { System.out.println("\nPOST-ORTHOGRAPHY TREE\n"); // $NON-NLS-1$ System.out.println(postOrthography.printTree(null)); debug.append("<br/>POST-ORTHOGRAPHY TREE<br/>"); debug.append(postOrthography.printTree(" ").replaceAll("\n", "<br/>")); } NLGElement postFormatter = null; if (this.formatter != null) { postFormatter = this.formatter.realise(postOrthography); if (this.debug) { System.out.println("\nPOST-FORMATTER TREE\n"); // $NON-NLS-1$ System.out.println(postFormatter.printTree(null)); debug.append("<br/>POST-FORMATTER TREE<br/>"); debug.append(postFormatter.printTree(" ").replaceAll("\n", "<br/>")); } } else { postFormatter = postOrthography; } if (this.debug) { postFormatter.setFeature("debug", debug.toString()); } return postFormatter; }
@Override public NLGElement realise(NLGElement element) { NLGElement realisedElement = null; if (element != null && !element.getFeatureAsBoolean(Feature.ELIDED).booleanValue()) { if (element instanceof DocumentElement) { List<NLGElement> children = element.getChildren(); ((DocumentElement) element).setComponents(realise(children)); realisedElement = element; } else if (element instanceof PhraseElement) { realisedElement = realisePhraseElement((PhraseElement) element); } else if (element instanceof ListElement) { realisedElement = new ListElement(); ((ListElement) realisedElement).addComponents(realise(element.getChildren())); } else if (element instanceof InflectedWordElement) { String baseForm = ((InflectedWordElement) element).getBaseForm(); ElementCategory category = element.getCategory(); if (this.lexicon != null && baseForm != null) { WordElement word = ((InflectedWordElement) element).getBaseWord(); if (word == null) { if (category instanceof LexicalCategory) { word = this.lexicon.lookupWord(baseForm, (LexicalCategory) category); } else { word = this.lexicon.lookupWord(baseForm); } } if (word != null) { ((InflectedWordElement) element).setBaseWord(word); } } realisedElement = element; } else if (element instanceof WordElement) { // AG: need to check if it's a word element, in which case it // needs to be marked for inflection InflectedWordElement infl = new InflectedWordElement((WordElement) element); // the inflected word inherits all features from the base word for (String feature : element.getAllFeatureNames()) { infl.setFeature(feature, element.getFeature(feature)); } realisedElement = realise(infl); } else if (element instanceof CoordinatedPhraseElement) { realisedElement = CoordinatedPhraseHelper.realise(this, (CoordinatedPhraseElement) element); } else { realisedElement = element; } } // Remove the spurious ListElements that have only one element. if (realisedElement instanceof ListElement) { if (((ListElement) realisedElement).size() == 1) { realisedElement = ((ListElement) realisedElement).getFirst(); } } return realisedElement; }