simplenlg.phrasespec.VPPhraseSpec Maven / Gradle / Ivy
/*
* The contents of this file are subject to the Mozilla Public License
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* https://www.mozilla.org/en-US/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 Westwater, Roman Kutlak, Margaret Mitchell, and Saad Mahamood.
*/
package simplenlg.phrasespec;
import java.util.List;
import simplenlg.features.*;
import simplenlg.framework.*;
/**
*
* 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
*/
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)
*/
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)
*/
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
*/
@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);
}
}