simplenlg.framework.CoordinatedPhraseElement 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 newest version!
/*
* 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.framework;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import simplenlg.features.Feature;
import simplenlg.features.InternalFeature;
import simplenlg.features.NumberAgreement;
/**
*
* This class defines coordination between two or more phrases. Coordination
* involves the linking of phrases together through the use of key words such as
* and or but.
*
*
*
* The class does not perform any ordering on the coordinates and when realised
* they appear in the same order they were added to the coordination.
*
*
*
* As this class appears similar to the PhraseElement
class from an
* API point of view, it could have extended from the PhraseElement
* class. However, they are fundamentally different in their nature and thus
* form two distinct classes with similar APIs.
*
*
* @author D. Westwater, University of Aberdeen.
* @version 4.0
*/
public class CoordinatedPhraseElement extends NLGElement {
/**
* Coordinators which make the coordinate plural (eg, "and" but not "or")
*/
@SuppressWarnings("nls")
private static final List PLURAL_COORDINATORS = Arrays.asList("and");
/**
* Creates a blank coordinated phrase ready for new coordinates to be added.
* The default conjunction used is and.
*/
public CoordinatedPhraseElement() {
super();
this.setFeature(Feature.CONJUNCTION, "and"); //$NON-NLS-1$
}
/**
* Creates a coordinated phrase linking the two phrase together. The default
* conjunction used is and.
*
* @param coordinate1 the first coordinate.
* @param coordinate2 the second coordinate.
*/
public CoordinatedPhraseElement(Object coordinate1, Object coordinate2) {
this.addCoordinate(coordinate1);
this.addCoordinate(coordinate2);
this.setFeature(Feature.CONJUNCTION, "and"); //$NON-NLS-1$
}
/**
* Adds a new coordinate to this coordination. If the new coordinate is a
* NLGElement
then it is added directly to the coordination. If
* the new coordinate is a String
a StringElement
* is created and added to the coordination. StringElement
s
* will have their complementisers suppressed by default. In the case of
* clauses, complementisers will be suppressed if the clause is not the
* first element in the coordination.
*
* @param newCoordinate the new coordinate to be added.
*/
public void addCoordinate(Object newCoordinate) {
List coordinates = getFeatureAsElementList(InternalFeature.COORDINATES);
if(coordinates == null) {
coordinates = new ArrayList();
setFeature(InternalFeature.COORDINATES, coordinates);
} else if(coordinates.size() == 0) {
setFeature(InternalFeature.COORDINATES, coordinates);
}
if(newCoordinate instanceof NLGElement) {
if(((NLGElement) newCoordinate).isA(PhraseCategory.CLAUSE) && coordinates.size() > 0) {
((NLGElement) newCoordinate).setFeature(Feature.SUPRESSED_COMPLEMENTISER, true);
}
coordinates.add((NLGElement) newCoordinate);
} else if(newCoordinate instanceof String) {
NLGElement coordElement = new StringElement((String) newCoordinate);
coordElement.setFeature(Feature.SUPRESSED_COMPLEMENTISER, true);
coordinates.add(coordElement);
}
setFeature(InternalFeature.COORDINATES, coordinates);
}
@Override
public List getChildren() {
return this.getFeatureAsElementList(InternalFeature.COORDINATES);
}
/**
* Clears the existing coordinates in this coordination. It performs exactly
* the same as removeFeature(Feature.COORDINATES)
.
*/
public void clearCoordinates() {
removeFeature(InternalFeature.COORDINATES);
}
/**
* Adds a new pre-modifier to the phrase element. Pre-modifiers will be
* realised in the syntax before the coordinates.
*
* @param newPreModifier the new pre-modifier as an NLGElement
.
*/
public void addPreModifier(NLGElement newPreModifier) {
List preModifiers = getFeatureAsElementList(InternalFeature.PREMODIFIERS);
if(preModifiers == null) {
preModifiers = new ArrayList();
}
preModifiers.add(newPreModifier);
setFeature(InternalFeature.PREMODIFIERS, preModifiers);
}
/**
* Adds a new pre-modifier to the phrase element. Pre-modifiers will be
* realised in the syntax before the coordinates.
*
* @param newPreModifier the new pre-modifier as a String
. It is used to
* create a StringElement
.
*/
public void addPreModifier(String newPreModifier) {
List preModifiers = getFeatureAsElementList(InternalFeature.PREMODIFIERS);
if(preModifiers == null) {
preModifiers = new ArrayList();
}
preModifiers.add(new StringElement(newPreModifier));
setFeature(InternalFeature.PREMODIFIERS, preModifiers);
}
/**
* Retrieves the list of pre-modifiers currently associated with this
* coordination.
*
* @return a List
of NLGElement
s.
*/
public List getPreModifiers() {
return getFeatureAsElementList(InternalFeature.PREMODIFIERS);
}
/**
* Retrieves the list of complements currently associated with this
* coordination.
*
* @return a List
of NLGElement
s.
*/
public List getComplements() {
return getFeatureAsElementList(InternalFeature.COMPLEMENTS);
}
/**
* Adds a new post-modifier to the phrase element. Post-modifiers will be
* realised in the syntax after the coordinates.
*
* @param newPostModifier the new post-modifier as an NLGElement
.
*/
public void addPostModifier(NLGElement newPostModifier) {
List postModifiers = getFeatureAsElementList(InternalFeature.POSTMODIFIERS);
if(postModifiers == null) {
postModifiers = new ArrayList();
}
postModifiers.add(newPostModifier);
setFeature(InternalFeature.POSTMODIFIERS, postModifiers);
}
/**
* Adds a new post-modifier to the phrase element. Post-modifiers will be
* realised in the syntax after the coordinates.
*
* @param newPostModifier the new post-modifier as a String
. It is used to
* create a StringElement
.
*/
public void addPostModifier(String newPostModifier) {
List postModifiers = getFeatureAsElementList(InternalFeature.POSTMODIFIERS);
if(postModifiers == null) {
postModifiers = new ArrayList();
}
postModifiers.add(new StringElement(newPostModifier));
setFeature(InternalFeature.POSTMODIFIERS, postModifiers);
}
/**
* Retrieves the list of post-modifiers currently associated with this
* coordination.
*
* @return a List
of NLGElement
s.
*/
public List getPostModifiers() {
return getFeatureAsElementList(InternalFeature.POSTMODIFIERS);
}
@Override
public String printTree(String indent) {
String thisIndent = indent == null ? " |-" : indent + " |-"; //$NON-NLS-1$ //$NON-NLS-2$
String childIndent = indent == null ? " | " : indent + " | "; //$NON-NLS-1$ //$NON-NLS-2$
String lastIndent = indent == null ? " \\-" : indent + " \\-"; //$NON-NLS-1$ //$NON-NLS-2$
String lastChildIndent = indent == null ? " " : indent + " "; //$NON-NLS-1$ //$NON-NLS-2$
StringBuffer print = new StringBuffer();
print.append("CoordinatedPhraseElement:\n"); //$NON-NLS-1$
List children = getChildren();
int length = children.size() - 1;
int index = 0;
for(index = 0; index < length; index++) {
print.append(thisIndent).append(children.get(index).printTree(childIndent));
}
if(length >= 0) {
print.append(lastIndent).append(children.get(length).printTree(lastChildIndent));
}
return print.toString();
}
/**
* Adds a new complement to the phrase element. Complements will be realised
* in the syntax after the coordinates. Complements differ from
* post-modifiers in that complements are crucial to the understanding of a
* phrase whereas post-modifiers are optional.
*
* @param newComplement the new complement as an NLGElement
.
*/
public void addComplement(NLGElement newComplement) {
List complements = getFeatureAsElementList(InternalFeature.COMPLEMENTS);
if(complements == null) {
complements = new ArrayList();
}
complements.add(newComplement);
setFeature(InternalFeature.COMPLEMENTS, complements);
}
/**
* Adds a new complement to the phrase element. Complements will be realised
* in the syntax after the coordinates. Complements differ from
* post-modifiers in that complements are crucial to the understanding of a
* phrase whereas post-modifiers are optional.
*
* @param newComplement the new complement as a String
. It is used to
* create a StringElement
.
*/
public void addComplement(String newComplement) {
List complements = getFeatureAsElementList(InternalFeature.COMPLEMENTS);
if(complements == null) {
complements = new ArrayList();
}
complements.add(new StringElement(newComplement));
setFeature(InternalFeature.COMPLEMENTS, complements);
}
/**
* A convenience method for retrieving the last coordinate in this
* coordination.
*
* @return the last coordinate as represented by a NLGElement
*/
public NLGElement getLastCoordinate() {
List children = getChildren();
return children != null && children.size() > 0 ? children.get(children.size() - 1) : null;
}
/**
* set the conjunction to be used in a coordinatedphraseelement
*/
public void setConjunction(String conjunction) {
setFeature(Feature.CONJUNCTION, conjunction);
}
/**
* @return conjunction used in coordinatedPhraseElement
*/
public String getConjunction() {
return getFeatureAsString(Feature.CONJUNCTION);
}
/**
* @return true if this coordinate is plural in a syntactic sense
*/
public boolean checkIfPlural() {
// doing this right is quite complex, take simple approach for now
int size = getChildren().size();
if(size == 1)
return (NumberAgreement.PLURAL.equals(getLastCoordinate().getFeature(Feature.NUMBER)));
else
return PLURAL_COORDINATORS.contains(getConjunction());
}
}