001    package org.maltparser.parser.algorithm.covington;
002    
003    import org.maltparser.core.exception.MaltChainedException;
004    import org.maltparser.core.syntaxgraph.DependencyStructure;
005    import org.maltparser.core.syntaxgraph.edge.Edge;
006    import org.maltparser.core.syntaxgraph.node.DependencyNode;
007    import org.maltparser.parser.ParserConfiguration;
008    import org.maltparser.parser.TransitionSystem;
009    import org.maltparser.parser.history.GuideUserHistory;
010    import org.maltparser.parser.history.History;
011    import org.maltparser.parser.history.action.ComplexDecisionAction;
012    import org.maltparser.parser.history.action.GuideUserAction;
013    import org.maltparser.parser.transition.TransitionTable;
014    /**
015     * @author Johan Hall
016     *
017     */
018    public 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() throws MaltChainedException {
026                    super();
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                    return null;
078            }
079            
080            protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
081                    ttable.addTransition(SHIFT, "SH", false, null);
082                    ttable.addTransition(NOARC, "NA", false, null);
083                    ttable.addTransition(RIGHTARC, "RA", true, null);
084                    ttable.addTransition(LEFTARC, "LA", true, null);
085            }
086            
087            protected void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException {
088                    GuideUserAction currentAction = new ComplexDecisionAction((History)history);
089                    
090                    transActionContainer.setAction(SHIFT);
091                    transActionContainer.setAction(NOARC);
092                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
093                            arcLabelActionContainers[i].setAction(-1);
094                    }
095                    currentAction.addAction(actionContainers);
096            }
097            
098            public String getName() {
099                    return "covnonproj";
100            }
101            
102            public boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException {
103                    CovingtonConfig covingtonConfig = (CovingtonConfig)config;
104                    DependencyNode leftTarget = covingtonConfig.getLeftTarget();
105                    DependencyNode rightTarget = covingtonConfig.getRightTarget();
106                    DependencyStructure dg = covingtonConfig.getDependencyGraph();
107                    currentAction.getAction(actionContainers);
108                    int trans = transActionContainer.getActionCode();
109                    
110                    if (trans == SHIFT && covingtonConfig.isAllowShift() == false) {
111                            return false;
112                    }
113                    if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
114                            return false;
115                    }
116                    if (trans == LEFTARC && leftTarget.isRoot()) { 
117                            return false;
118                    }
119                    if (trans == LEFTARC && dg.hasLabeledDependency(leftTarget.getIndex())) { 
120                            return false;
121                    }
122                    if (trans == RIGHTARC && dg.hasLabeledDependency(rightTarget.getIndex())) { 
123                            return false;
124                    }
125                    return true;
126            }
127            
128            public GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException {
129                    return updateActionContainers(history, NonProjective.NOARC, null);
130            }
131    }