package edu.berkeley.nlp.syntax;
import edu.berkeley.nlp.util.IdentityHashSet;
import edu.berkeley.nlp.util.functional.FunctionalUtils;
import edu.berkeley.nlp.util.functional.Predicate;
import java.io.StringReader;
import java.util.List;
import java.util.Set;
/**
* User: aria42
* Date: Mar 24, 2009
*/
public enum GrammaticalRole {
SUBJECT, OBJECT, OTHER, NONE, NULL;
private static boolean isObject(TreePath<String> treePath) {
for (TreePath.Transition<String> transition : treePath.getTransitions()) {
if (transition.getDirection() != TreePath.Direction.UP) {
return false;
}
}
return true;
}
private static boolean isSubject(TreePath<String> treePath) {
boolean hitS = false;
for (TreePath.Transition<String> trans : treePath.getTransitions()) {
Tree<String> toNode = trans.getToNode();
TreePath.Direction dir = trans.getDirection();
Tree<String> dest = trans.getToNode();
if (dest.getLabel().startsWith("S")) {
hitS = true;
continue;
}
if (!hitS) {
if (dir != TreePath.Direction.UP) {
return false;
}
}
if (hitS) {
if (!(dir == TreePath.Direction.DOWN_RIGHT)) {
return false;
}
}
}
return hitS;
}
public static GrammaticalRole findRole(final Tree<String> node, final Tree<String> root)
{
Set<Tree<String>> nodes = new IdentityHashSet<Tree<String>>(root.getPostOrderTraversal());
if (!nodes.contains(node)) {
return GrammaticalRole.NONE;
}
GrammaticalRole curRole = GrammaticalRole.OTHER;
List<Tree<String>> vpNodes = FunctionalUtils.filter(nodes,new Predicate<Tree<String>>() {
public Boolean apply(Tree<String> input) {
return input.isPhrasal() && input.getLabel().startsWith("VP");
}
});
TreePathFinder<String> tpf = new TreePathFinder<String>(root);
for (Tree<String> vpNode : vpNodes) {
if (vpNode == node) continue;
TreePath<String> tp = tpf.findPath(node,vpNode);
if (isSubject(tp)) {
return GrammaticalRole.SUBJECT;
}
if (isObject(tp)) {
curRole = GrammaticalRole.OBJECT;
}
}
return curRole;
}
public static void main(String[] args) {
String treeStr = "(ROOT (S (NP (DT The) (NN dog)) (VP (VBD ran) (NN home))))";
StringReader reader = new StringReader(treeStr);
Tree<String> tree = new Trees.PennTreeReader(reader).next();
Tree<String> subjNode = tree.getChildren().get(0).getChildren().get(0);
Tree<String> objNode = tree.getChild(0).getChild(1).getChild(1);
System.out.println("subjNode is " + GrammaticalRole.findRole(subjNode,tree));
System.out.println("objNode is " + GrammaticalRole.findRole(objNode,tree));
}
}