simplenlg.phrasespec.VPPhraseSpec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of SimpleNLG Show documentation
Show all versions of SimpleNLG Show documentation
Java API for Natural Language Generation
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is "Simplenlg".
*
* The Initial Developer of the Original Code is Ehud Reiter, Albert Gatt and Dave Westwater.
* Portions created by Ehud Reiter, Albert Gatt and Dave Westwater are Copyright (C) 2010-11 The University of Aberdeen. All Rights Reserved.
*
* Contributor(s): Ehud Reiter, Albert Gatt, Dave Wewstwater, Roman Kutlak, Margaret Mitchell.
*/
package simplenlg.phrasespec;
import java.util.List;
import simplenlg.features.DiscourseFunction;
import simplenlg.features.Feature;
import simplenlg.features.Form;
import simplenlg.features.InternalFeature;
import simplenlg.features.Person;
import simplenlg.features.Tense;
import simplenlg.framework.CoordinatedPhraseElement;
import simplenlg.framework.InflectedWordElement;
import simplenlg.framework.LexicalCategory;
import simplenlg.framework.NLGElement;
import simplenlg.framework.PhraseCategory;
import simplenlg.framework.PhraseElement;
import simplenlg.framework.NLGFactory;
import simplenlg.framework.WordElement;
/**
*
* This class defines a verb phrase. It is essentially
* a wrapper around the PhraseElement
class, with methods
* for setting common constituents such as Objects.
* For example, the setVerb
method in this class sets
* the head of the element to be the specified verb
*
* From an API perspective, this class is a simplified version of the SPhraseSpec
* class in simplenlg V3. It provides an alternative way for creating syntactic
* structures, compared to directly manipulating a V4 PhraseElement
.
*
* Methods are provided for setting and getting the following constituents:
*
* - PreModifier (eg, "reluctantly")
*
- Verb (eg, "gave")
*
- IndirectObject (eg, "Mary")
*
- Object (eg, "an apple")
*
- PostModifier (eg, "before school")
*
*
* NOTE: If there is a complex verb group, a preModifer set at the VP level appears before
* the verb, while a preModifier set at the clause level appears before the verb group. Eg
* "Mary unfortunately will eat the apple" ("unfortunately" is clause preModifier)
* "Mary will happily eat the apple" ("happily" is VP preModifier)
*
* NOTE: The setModifier method will attempt to automatically determine whether
* a modifier should be expressed as a PreModifier or PostModifier
*
* Features (such as negated) must be accessed via the setFeature
and
* getFeature
methods (inherited from NLGElement
).
* Features which are often set on VPPhraseSpec include
*
* - Modal (eg, "John eats an apple" vs "John can eat an apple")
*
- Negated (eg, "John eats an apple" vs "John does not eat an apple")
*
- Passive (eg, "John eats an apple" vs "An apple is eaten by John")
*
- Perfect (eg, "John ate an apple" vs "John has eaten an apple")
*
- Progressive (eg, "John eats an apple" vs "John is eating an apple")
*
- Tense (eg, "John ate" vs "John eats" vs "John will eat")
*
* Note that most VP features can be set on an SPhraseSpec, they will automatically
* be propogated to the VP
*
* VPPhraseSpec
are produced by the createVerbPhrase
* method of a PhraseFactory
*
*
* @author E. Reiter, University of Aberdeen.
* @version 4.1
*
*/
public class VPPhraseSpec extends PhraseElement {
/** create an empty clause
*/
public VPPhraseSpec(NLGFactory phraseFactory) {
super(PhraseCategory.VERB_PHRASE);
this.setFactory(phraseFactory);
// set default feature values
setFeature(Feature.PERFECT, false);
setFeature(Feature.PROGRESSIVE, false);
setFeature(Feature.PASSIVE, false);
setFeature(Feature.NEGATED, false);
setFeature(Feature.TENSE, Tense.PRESENT);
setFeature(Feature.PERSON, Person.THIRD);
setPlural(false);
setFeature(Feature.FORM, Form.NORMAL);
setFeature(InternalFeature.REALISE_AUXILIARY, true);
}
/** sets the verb (head) of a verb phrase.
* Extract particle from verb if necessary
* @param verb
*/
public void setVerb(Object verb) {
NLGElement verbElement;
if (verb instanceof String) { // if String given, check for particle
int space = ((String) verb).indexOf(' ');
if (space == -1) { // no space, so no particle
verbElement = getFactory().createWord(verb, LexicalCategory.VERB);
} else { // space, so break up into verb and particle
verbElement = getFactory().createWord(((String) verb)
.substring(0, space), LexicalCategory.VERB);
setFeature(Feature.PARTICLE, ((String) verb)
.substring(space + 1, ((String) verb).length()));
}
} else { // Object is not a String
verbElement = getFactory().createNLGElement(verb,LexicalCategory.VERB);
}
setHead(verbElement);
}
/**
* @return verb (head) of verb phrase
*/
public NLGElement getVerb() {
return getHead();
}
/** Sets the direct object of a clause (assumes this is the only direct object)
*
* @param object
*/
public void setObject(Object object) {
NLGElement objectPhrase;
if (object instanceof PhraseElement || object instanceof CoordinatedPhraseElement)
objectPhrase = (NLGElement) object;
else
objectPhrase = getFactory().createNounPhrase(object);
objectPhrase.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.OBJECT);
setComplement(objectPhrase);
}
/** Returns the direct object of a clause (assumes there is only one)
*
* @return subject of clause (assume only one)
*/
public NLGElement getObject() {
List complements = getFeatureAsElementList(InternalFeature.COMPLEMENTS);
for (NLGElement complement: complements)
if (complement.getFeature(InternalFeature.DISCOURSE_FUNCTION) == DiscourseFunction.OBJECT)
return complement;
return null;
}
/** Set the indirect object of a clause (assumes this is the only direct indirect object)
*
* @param indirectObject
*/
public void setIndirectObject(Object indirectObject) {
NLGElement indirectObjectPhrase;
if (indirectObject instanceof PhraseElement || indirectObject instanceof CoordinatedPhraseElement)
indirectObjectPhrase = (NLGElement) indirectObject;
else
indirectObjectPhrase = getFactory().createNounPhrase(indirectObject);
indirectObjectPhrase.setFeature(InternalFeature.DISCOURSE_FUNCTION, DiscourseFunction.INDIRECT_OBJECT);
setComplement(indirectObjectPhrase);
}
/** Returns the indirect object of a clause (assumes there is only one)
*
* @return subject of clause (assume only one)
*/
public NLGElement getIndirectObject() {
List complements = getFeatureAsElementList(InternalFeature.COMPLEMENTS);
for (NLGElement complement: complements)
if (complement.getFeature(InternalFeature.DISCOURSE_FUNCTION) == DiscourseFunction.INDIRECT_OBJECT)
return complement;
return null;
}
// note that addFrontModifier, addPostModifier, addPreModifier are inherited from PhraseElement
// likewise getFrontModifiers, getPostModifiers, getPreModifiers
/** Add a modifier to a verb phrase
* Use heuristics to decide where it goes
* @param modifier
*/
@Override
public void addModifier(Object modifier) {
// adverb is preModifier
// string which is one lexicographic word is looked up in lexicon,
// if it is an adverb than it becomes a preModifier
// Everything else is postModifier
if (modifier == null)
return;
// get modifier as NLGElement if possible
NLGElement modifierElement = null;
if (modifier instanceof NLGElement)
modifierElement = (NLGElement) modifier;
else if (modifier instanceof String) {
String modifierString = (String)modifier;
if (modifierString.length() > 0 && !modifierString.contains(" "))
modifierElement = getFactory().createWord(modifier, LexicalCategory.ANY);
}
// if no modifier element, must be a complex string
if (modifierElement == null) {
addPostModifier((String)modifier);
return;
}
// extract WordElement if modifier is a single word
WordElement modifierWord = null;
if (modifierElement != null && modifierElement instanceof WordElement)
modifierWord = (WordElement) modifierElement;
else if (modifierElement != null && modifierElement instanceof InflectedWordElement)
modifierWord = ((InflectedWordElement) modifierElement).getBaseWord();
if (modifierWord != null && modifierWord.getCategory() == LexicalCategory.ADVERB) {
addPreModifier(modifierWord);
return;
}
// default case
addPostModifier(modifierElement);
}
}