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            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)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    }