001package org.maltparser.parser.algorithm.covington;
002
003import org.maltparser.core.exception.MaltChainedException;
004import org.maltparser.core.propagation.PropagationManager;
005import org.maltparser.core.syntaxgraph.DependencyStructure;
006import org.maltparser.core.syntaxgraph.edge.Edge;
007import org.maltparser.core.syntaxgraph.node.DependencyNode;
008import org.maltparser.parser.ParserConfiguration;
009import org.maltparser.parser.TransitionSystem;
010import org.maltparser.parser.history.GuideUserHistory;
011import org.maltparser.parser.history.action.ComplexDecisionAction;
012import org.maltparser.parser.history.action.GuideUserAction;
013import org.maltparser.parser.transition.TransitionTable;
014/**
015 * @author Johan Hall
016 *
017 */
018public class NonProjective extends TransitionSystem {
019        protected static final int SHIFT = 1;
020        protected static final int NOARC = 2;
021        protected static final int RIGHTARC = 3;
022        protected static final int LEFTARC = 4;
023        
024        
025        public NonProjective(PropagationManager propagationManager) throws MaltChainedException {
026                super(propagationManager);
027        }
028        
029        public void apply(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException {
030                CovingtonConfig covingtonConfig = (CovingtonConfig)config;
031                currentAction.getAction(actionContainers);
032                
033                Edge e = null;
034                switch (transActionContainer.getActionCode()) {
035                case LEFTARC:
036                        e = covingtonConfig.getDependencyGraph().addDependencyEdge(covingtonConfig.getRightTarget().getIndex(), covingtonConfig.getLeftTarget().getIndex());
037                        addEdgeLabels(e);
038                        break;
039                case RIGHTARC:
040                        e = covingtonConfig.getDependencyGraph().addDependencyEdge(covingtonConfig.getLeftTarget().getIndex(), covingtonConfig.getRightTarget().getIndex());
041                        addEdgeLabels(e);
042                        break;
043                default:
044                        break;
045                }
046                update(covingtonConfig, transActionContainer.getActionCode());  
047        }
048        
049        private void update(CovingtonConfig covingtonConfig, int trans) {
050                if (trans == SHIFT) {
051                        covingtonConfig.setRight(covingtonConfig.getRight() + 1);
052                        covingtonConfig.setLeft(covingtonConfig.getRight() - 1);
053                } else { 
054                        DependencyNode rightNode = covingtonConfig.getRightTarget();
055                        int leftstop = covingtonConfig.getLeftstop();
056                        int left = covingtonConfig.getLeft();
057                        left--;
058                        DependencyNode leftNode = null;
059                        while (left >= leftstop) {
060                                leftNode = covingtonConfig.getInput().get(left);
061                                if (rightNode.findComponent().getIndex() != leftNode.findComponent().getIndex() &&
062                                                !(leftNode.hasHead() && rightNode.hasHead())) {
063                                        break;
064                                }
065                                left--;
066                        }
067                        if (left < leftstop) {
068                                covingtonConfig.setRight(covingtonConfig.getRight() + 1);
069                                covingtonConfig.setLeft(covingtonConfig.getRight() - 1);
070                        } else {
071                                covingtonConfig.setLeft(left);
072                        }
073                }
074        }
075        
076        public GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException {
077        final CovingtonConfig covingtonConfig = (CovingtonConfig)config;
078        if (!covingtonConfig.isAllowRoot() && covingtonConfig.getLeftTarget().isRoot()) {
079                return updateActionContainers(history, NonProjective.NOARC, null);
080        }
081        return null; 
082        }
083        
084        protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
085                ttable.addTransition(SHIFT, "SH", false, null);
086                ttable.addTransition(NOARC, "NA", 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                transActionContainer.setAction(NOARC);
096                for (int i = 0; i < arcLabelActionContainers.length; i++) {
097                        arcLabelActionContainers[i].setAction(-1);
098                }
099                currentAction.addAction(actionContainers);
100        }
101        
102        public String getName() {
103                return "covnonproj";
104        }
105        
106        public boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException {
107                CovingtonConfig covingtonConfig = (CovingtonConfig)config;
108                DependencyNode leftTarget = covingtonConfig.getLeftTarget();
109                DependencyNode rightTarget = covingtonConfig.getRightTarget();
110                DependencyStructure dg = covingtonConfig.getDependencyGraph();
111                currentAction.getAction(actionContainers);
112                int trans = transActionContainer.getActionCode();
113                
114                if (trans == SHIFT && covingtonConfig.isAllowShift() == false) {
115                        return false;
116                }
117                if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
118                        return false;
119                }
120                if (trans == LEFTARC && leftTarget.isRoot()) { 
121                        return false;
122                }
123                if (trans == LEFTARC && dg.hasLabeledDependency(leftTarget.getIndex())) { 
124                        return false;
125                }
126                if (trans == RIGHTARC && dg.hasLabeledDependency(rightTarget.getIndex())) { 
127                        return false;
128                }
129                return true;
130        }
131        
132        public GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException {
133                return updateActionContainers(history, NonProjective.NOARC, null);
134        }
135}