001package org.maltparser.parser.algorithm.nivre;
002
003import org.maltparser.core.exception.MaltChainedException;
004import org.maltparser.core.syntaxgraph.DependencyStructure;
005import org.maltparser.core.syntaxgraph.node.DependencyNode;
006import org.maltparser.parser.DependencyParserConfig;
007import org.maltparser.parser.Oracle;
008import org.maltparser.parser.ParserConfiguration;
009import org.maltparser.parser.history.GuideUserHistory;
010import org.maltparser.parser.history.action.GuideUserAction;
011/**
012 * @author Johan Hall
013 *
014 */
015public class ArcEagerOracle extends Oracle {
016
017        public ArcEagerOracle(DependencyParserConfig manager, GuideUserHistory history) throws MaltChainedException {
018                super(manager, history);
019                setGuideName("ArcEager");
020        }
021        
022        public GuideUserAction predict(DependencyStructure gold, ParserConfiguration config) throws MaltChainedException {
023                final NivreConfig nivreConfig = (NivreConfig)config;
024                final DependencyNode stackPeek = nivreConfig.getStack().peek();
025                final int stackPeekIndex = stackPeek.getIndex();
026                final int inputPeekIndex = nivreConfig.getInput().peek().getIndex();
027                
028                if (!stackPeek.isRoot() && gold.getTokenNode(stackPeekIndex).getHead().getIndex() == inputPeekIndex) {
029                        return updateActionContainers(ArcEager.LEFTARC, gold.getTokenNode(stackPeekIndex).getHeadEdge().getLabelSet());
030                } else if (gold.getTokenNode(inputPeekIndex).getHead().getIndex() == stackPeekIndex) {
031                        return updateActionContainers(ArcEager.RIGHTARC, gold.getTokenNode(inputPeekIndex).getHeadEdge().getLabelSet());
032                } else if (!nivreConfig.isAllowReduce() && !stackPeek.hasHead()) {
033                        return updateActionContainers(ArcEager.SHIFT, null);
034                } else if (gold.getTokenNode(inputPeekIndex).hasLeftDependent() &&
035                                gold.getTokenNode(inputPeekIndex).getLeftmostDependent().getIndex() < stackPeekIndex) {
036                        return updateActionContainers(ArcEager.REDUCE, null);
037                } else if (gold.getTokenNode(inputPeekIndex).getHead().getIndex() < stackPeekIndex && 
038                                (!gold.getTokenNode(inputPeekIndex).getHead().isRoot() || nivreConfig.isAllowRoot())) {
039                        return updateActionContainers(ArcEager.REDUCE, null);
040                } else {
041                        return updateActionContainers(ArcEager.SHIFT, null);
042                }
043        }
044        
045        public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {}
046        
047        public void terminate() throws MaltChainedException {}
048}