edu.stanford.nlp.parser.shiftreduce.CompoundUnaryTransition Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of stanford-parser Show documentation
Show all versions of stanford-parser Show documentation
Stanford Parser processes raw text in English, Chinese, German, Arabic, and French, and extracts constituency parse trees.
package edu.stanford.nlp.parser.shiftreduce;
import java.util.Arrays;
import java.util.List;
import edu.stanford.nlp.parser.common.ParserConstraint;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.util.TreeShapedStack;
/**
* Transition that makes a compound unary parse node in a partially
* finished tree. It potentially adds multiple unary layers to the
* current tree.
*
* @author John Bauer
*/
public class CompoundUnaryTransition implements Transition {
/**
* labels[0] is the top of the unary chain.
* A unary chain that results in a ROOT will have labels[0] == ROOT, for example.
*/
public final String[] labels;
/** root transitions are illegal in the middle of the tree, naturally */
public final boolean isRoot;
public CompoundUnaryTransition(List labels, boolean isRoot) {
this.labels = new String[labels.size()];
for (int i = 0; i < labels.size(); ++i) {
this.labels[i] = labels.get(i);
}
this.isRoot = isRoot;
}
/**
* Legal as long as there is at least one item on the state's stack
* and that item has not already been unary transformed.
*/
public boolean isLegal(State state, List constraints) {
if (state.finished) {
return false;
}
if (state.stack.size() == 0) {
return false;
}
final Tree top = state.stack.peek();
if (top.children().length == 1 && !top.isPreTerminal()) {
// Disallow unary transitions after we've already had a unary transition
return false;
}
if (top.label().value().equals(labels[0])) {
// Disallow unary transitions where the final label doesn't change
return false;
}
// TODO: need to think more about when a unary transition is
// allowed if the top of the stack is temporary
if (top.label().value().startsWith("@") && !labels[labels.length - 1].equals(top.label().value().substring(1))) {
// Disallow a transition if the top is a binarized node and the
// bottom of the unary transition chain isn't the same type
return false;
}
if (isRoot && (state.stack.size() > 1 || !state.endOfQueue())) {
return false;
}
// Now we check the constraints...
// Constraints only apply to CompoundUnaryTransitions if the tree
// is exactly the right size and the tree has not already been
// constructed to match the constraint. In that case, we check to
// see if the candidate transition contains the desired label.
if (constraints == null) {
return true;
}
for (ParserConstraint constraint : constraints) {
if (ShiftReduceUtils.leftIndex(top) != constraint.start || ShiftReduceUtils.rightIndex(top) != constraint.end - 1) {
continue;
}
if (constraint.state.matcher(top.value()).matches()) {
continue;
}
boolean found = false;
for (String label : labels) {
if (constraint.state.matcher(label).matches()) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
/**
* Add a unary node to the existing node on top of the stack
*/
public State apply(State state) {
return apply(state, 0.0);
}
/**
* Add a unary node to the existing node on top of the stack
*/
public State apply(State state, double scoreDelta) {
Tree top = state.stack.peek();
for (int i = labels.length - 1; i >= 0; --i) {
top = UnaryTransition.addUnaryNode(top, labels[i]);
}
TreeShapedStack stack = state.stack.pop();
stack = stack.push(top);
return new State(stack, state.transitions.push(this), state.separators, state.sentence, state.tokenPosition, state.score + scoreDelta, false);
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof CompoundUnaryTransition)) {
return false;
}
String[] otherLabels = ((CompoundUnaryTransition) o).labels;
return Arrays.equals(labels, otherLabels);
}
@Override
public int hashCode() {
return 29467607 ^ Arrays.hashCode(labels);
}
@Override
public String toString() {
return "CompoundUnary" + (isRoot ? "*" : "") + "(" + Arrays.asList(labels).toString() + ")";
}
private static final long serialVersionUID = 1;
}