001    package org.maltparser.parser.algorithm.stack;
002    
003    import java.util.Stack;
004    
005    import org.maltparser.core.exception.MaltChainedException;
006    import org.maltparser.core.syntaxgraph.DependencyStructure;
007    import org.maltparser.core.syntaxgraph.node.DependencyNode;
008    import org.maltparser.parser.DependencyParserConfig;
009    import org.maltparser.parser.Oracle;
010    import org.maltparser.parser.ParserConfiguration;
011    import org.maltparser.parser.history.GuideUserHistory;
012    import org.maltparser.parser.history.action.GuideUserAction;
013    /**
014     * @author Johan Hall
015     *
016     */
017    public class ProjectiveOracle  extends Oracle {
018            public ProjectiveOracle(DependencyParserConfig manager, GuideUserHistory history) throws MaltChainedException {
019                    super(manager, history);
020                    setGuideName("projective");
021            }
022            
023            public GuideUserAction predict(DependencyStructure gold, ParserConfiguration configuration) throws MaltChainedException {
024                    StackConfig config = (StackConfig)configuration;
025                    Stack<DependencyNode> stack = config.getStack();
026    
027                    if (stack.size() < 2) {
028                            return updateActionContainers(Projective.SHIFT, null);
029                    } else {
030                            DependencyNode left = stack.get(stack.size()-2);
031                            int leftIndex = left.getIndex();
032                            int rightIndex = stack.get(stack.size()-1).getIndex();
033                            if (!left.isRoot() && gold.getTokenNode(leftIndex).getHead().getIndex() == rightIndex) {
034                                    return updateActionContainers(Projective.LEFTARC, gold.getTokenNode(leftIndex).getHeadEdge().getLabelSet());
035                            } else if (gold.getTokenNode(rightIndex).getHead().getIndex() == leftIndex && checkRightDependent(gold, config.getDependencyGraph(), rightIndex)) {
036                                    return updateActionContainers(Projective.RIGHTARC, gold.getTokenNode(rightIndex).getHeadEdge().getLabelSet());
037                            } else {
038                                    return updateActionContainers(Projective.SHIFT, null);
039                            } // Solve the problem with non-projective input.
040                    }
041            }
042            
043            private boolean checkRightDependent(DependencyStructure gold, DependencyStructure parseDependencyGraph, int index) throws MaltChainedException {
044                    if (gold.getTokenNode(index).getRightmostDependent() == null) {
045                            return true;
046                    } else if (parseDependencyGraph.getTokenNode(index).getRightmostDependent() != null) {
047                            if (gold.getTokenNode(index).getRightmostDependent().getIndex() == parseDependencyGraph.getTokenNode(index).getRightmostDependent().getIndex()) {
048                                    return true;
049                            }
050                    }
051                    return false;
052            }
053            
054            public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {
055                    
056            }
057            
058            public void terminate() throws MaltChainedException {
059                    
060            }
061    }