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 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() 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    //                      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)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