001package org.maltparser.parser.algorithm.stack;
002
003import java.util.Stack;
004
005import org.maltparser.core.exception.MaltChainedException;
006import org.maltparser.core.propagation.PropagationManager;
007import org.maltparser.core.syntaxgraph.LabelSet;
008import org.maltparser.core.syntaxgraph.edge.Edge;
009import org.maltparser.core.syntaxgraph.node.DependencyNode;
010import org.maltparser.parser.ParserConfiguration;
011import org.maltparser.parser.TransitionSystem;
012import org.maltparser.parser.history.GuideUserHistory;
013import org.maltparser.parser.history.action.ComplexDecisionAction;
014import org.maltparser.parser.history.action.GuideUserAction;
015import org.maltparser.parser.transition.TransitionTable;
016/**
017 * @author Johan Hall
018 *
019 */
020public class Projective extends TransitionSystem {
021        protected static final int SHIFT = 1;
022        protected static final int RIGHTARC = 2;
023        protected static final int LEFTARC = 3;
024        
025        public Projective(PropagationManager propagationManager) throws MaltChainedException {
026                super(propagationManager);
027        }
028        
029        public void apply(GuideUserAction currentAction, ParserConfiguration configuration) throws MaltChainedException {
030                final StackConfig config = (StackConfig)configuration;
031                final Stack<DependencyNode> stack = config.getStack();
032                currentAction.getAction(actionContainers);
033                Edge e = null;
034                DependencyNode head = null;
035                DependencyNode dep = null;
036                switch (transActionContainer.getActionCode()) {
037                case LEFTARC:
038                        head = stack.pop(); 
039                        dep = stack.pop();
040                        e = config.getDependencyStructure().addDependencyEdge(head.getIndex(), dep.getIndex());
041                        addEdgeLabels(e);
042                        stack.push(head);
043                        break;
044                case RIGHTARC:
045                        dep = stack.pop(); 
046                        e = config.getDependencyStructure().addDependencyEdge(stack.peek().getIndex(), dep.getIndex());
047                        addEdgeLabels(e);
048                        break;
049                default:
050                        final Stack<DependencyNode> input = config.getInput();
051                        if (input.isEmpty()) {
052                                stack.pop();
053                        } else {
054                                stack.push(input.pop()); // SHIFT
055                        }
056                        break;
057                }
058        }
059        
060        public boolean permissible(GuideUserAction currentAction, ParserConfiguration configuration) throws MaltChainedException {
061                final StackConfig config = (StackConfig)configuration;
062                currentAction.getAction(actionContainers);
063                final int trans = transActionContainer.getActionCode();
064                if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
065                        return false;
066                }
067                final Stack<DependencyNode> stack = config.getStack();
068                if ((trans == LEFTARC || trans == RIGHTARC) && stack.size() < 2) {
069                        return false;
070                }
071                if (trans == LEFTARC && stack.get(stack.size()-2).isRoot()) { 
072                        return false;
073                }
074                if (trans == SHIFT && config.getInput().isEmpty()) { 
075                        return false;
076                }
077                
078                return true;
079        }
080        
081        public GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException {
082                return null;
083        }
084        
085        protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
086                ttable.addTransition(SHIFT, "SH", false, null);
087                ttable.addTransition(RIGHTARC, "RA", true, null);
088                ttable.addTransition(LEFTARC, "LA", true, null);
089        }
090        
091        protected void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException {
092                GuideUserAction currentAction = new ComplexDecisionAction(history);
093                
094                transActionContainer.setAction(SHIFT);
095                for (int i = 0; i < arcLabelActionContainers.length; i++) {
096                        arcLabelActionContainers[i].setAction(-1);
097                }
098                currentAction.addAction(actionContainers);
099        }
100        
101        public String getName() {
102                return "projective";
103        }
104        
105        public GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException {
106                if (((StackConfig)configuration).getInput().isEmpty()) {
107                        LabelSet labelSet = ((StackConfig)configuration).getDependencyGraph().getDefaultRootEdgeLabels();
108                        return updateActionContainers(history, RIGHTARC, labelSet);
109                }       
110                return updateActionContainers(history, SHIFT, null);
111        }
112}