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 Projective 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 Projective(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//                      config.setArcParent(covingtonConfig.getRightTarget());
039//                      config.setArcChild(covingtonConfig.getLeftTarget());
040                        break;
041                case RIGHTARC:
042                        e = covingtonConfig.getDependencyGraph().addDependencyEdge(covingtonConfig.getLeftTarget().getIndex(), covingtonConfig.getRightTarget().getIndex());
043                        addEdgeLabels(e);
044//                      config.setArcParent(covingtonConfig.getLeftTarget());
045//                      config.setArcChild(covingtonConfig.getRightTarget());
046                        break;
047                default:
048//                      config.setArcParent(null);
049//                      config.setArcChild(null);
050                        break;
051                }
052                update(covingtonConfig, transActionContainer.getActionCode());  
053        }
054        
055        private void update(CovingtonConfig covingtonConfig, int trans) throws MaltChainedException {
056                if (trans == SHIFT || trans == RIGHTARC) {
057                        covingtonConfig.setRight(covingtonConfig.getRight() + 1);
058                        covingtonConfig.setLeft(covingtonConfig.getRight() - 1);
059                } else {
060                        int leftstop = covingtonConfig.getLeftstop();
061                        int left = covingtonConfig.getLeft();
062                        if (trans == NOARC) {
063                                DependencyStructure dg = covingtonConfig.getDependencyStructure();
064                                DependencyNode leftNode = covingtonConfig.getInput().get(covingtonConfig.getLeft());
065                                if (dg.getTokenNode(leftNode.getIndex()) != null && dg.getTokenNode(leftNode.getIndex()).hasHead()) {
066                                        left = dg.getTokenNode(leftNode.getIndex()).getHead().getIndex();
067                                } else {
068                                        left = leftstop - 1;
069                                }
070                        } else {
071                                DependencyNode rightNode = covingtonConfig.getRightTarget();
072                                left--;
073                                DependencyNode leftNode = null;
074                                while (left >= leftstop) {
075                                        leftNode = covingtonConfig.getInput().get(left);
076                                        if (rightNode.findComponent().getIndex() != leftNode.findComponent().getIndex()) {
077                                                break;
078                                        }
079                                        left--;
080                                }
081                        }
082                        
083                        if (left < leftstop) {
084                                covingtonConfig.setRight(covingtonConfig.getRight() + 1);
085                                covingtonConfig.setLeft(covingtonConfig.getRight() - 1);
086                        } else {
087                                covingtonConfig.setLeft(left);
088                        }
089                }
090        }
091        
092        public GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException {
093        final CovingtonConfig covingtonConfig = (CovingtonConfig)config;
094        if (!covingtonConfig.isAllowRoot() && covingtonConfig.getLeftTarget().isRoot()) {
095                return updateActionContainers(history, Projective.NOARC, null);
096        }
097                return null;
098        }
099        
100        protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
101                ttable.addTransition(SHIFT, "SH", false, null);
102                ttable.addTransition(NOARC, "NA", false, null);
103                ttable.addTransition(RIGHTARC, "RA", true, null);
104                ttable.addTransition(LEFTARC, "LA", true, null);
105        }
106        
107        protected void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException {
108                GuideUserAction currentAction = new ComplexDecisionAction(history);
109                
110                transActionContainer.setAction(SHIFT);
111                transActionContainer.setAction(NOARC);
112                for (int i = 0; i < arcLabelActionContainers.length; i++) {
113                        arcLabelActionContainers[i].setAction(-1);
114                }
115                currentAction.addAction(actionContainers);
116        }
117        
118        public String getName() {
119                return "covproj";
120        }
121        
122        public boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException {
123                CovingtonConfig covingtonConfig = (CovingtonConfig)config;
124                DependencyNode leftTarget = covingtonConfig.getLeftTarget();
125                DependencyNode rightTarget = covingtonConfig.getRightTarget();
126                DependencyStructure dg = covingtonConfig.getDependencyGraph();
127                currentAction.getAction(actionContainers);
128                int trans = transActionContainer.getActionCode();
129                
130                if (trans == SHIFT && covingtonConfig.isAllowShift() == false) {
131                        return false;
132                }
133                if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
134                        return false;
135                }
136                if (trans == LEFTARC && leftTarget.isRoot()) { 
137                        return false;
138                }
139                if (trans == LEFTARC && dg.hasLabeledDependency(leftTarget.getIndex())) { 
140                        return false;
141                }
142                if (trans == RIGHTARC && dg.hasLabeledDependency(rightTarget.getIndex())) { 
143                        return false;
144                }
145                return true;
146        }
147        
148        public GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException {
149                return updateActionContainers(history, Projective.NOARC, null);
150        }
151}
152