001    package org.maltparser.parser;
002    
003    import java.util.HashMap;
004    
005    import org.maltparser.core.exception.MaltChainedException;
006    import org.maltparser.core.propagation.PropagationManager;
007    import org.maltparser.core.symbol.SymbolTable;
008    import org.maltparser.core.symbol.SymbolTableHandler;
009    import org.maltparser.core.symbol.TableHandler;
010    import org.maltparser.core.syntaxgraph.DependencyGraph;
011    import org.maltparser.core.syntaxgraph.LabelSet;
012    import org.maltparser.core.syntaxgraph.edge.Edge;
013    import org.maltparser.parser.history.GuideUserHistory;
014    import org.maltparser.parser.history.action.GuideUserAction;
015    import org.maltparser.parser.history.container.ActionContainer;
016    import org.maltparser.parser.transition.TransitionTable;
017    import org.maltparser.parser.transition.TransitionTableHandler;
018    /**
019     * @author Johan Hall
020     *
021     */
022    public abstract class TransitionSystem {
023            protected HashMap<String, TableHandler> tableHandlers;
024            protected TransitionTableHandler transitionTableHandler;
025            protected ActionContainer[] actionContainers;
026            protected ActionContainer transActionContainer;
027            protected ActionContainer[] arcLabelActionContainers;
028            protected PropagationManager propagationManager = null;
029            
030            public TransitionSystem() throws MaltChainedException { }
031            
032            public abstract void apply(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException;
033            public abstract boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException;
034            public abstract GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException;
035            protected abstract void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException;
036            protected abstract void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException;
037            public abstract String getName();
038            public abstract GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException;
039            
040            protected GuideUserAction updateActionContainers(GuideUserHistory history, int transition, LabelSet arcLabels) throws MaltChainedException {    
041                    transActionContainer.setAction(transition);
042    
043                    if (arcLabels == null) {
044                            for (int i = 0; i < arcLabelActionContainers.length; i++) {
045                                    arcLabelActionContainers[i].setAction(-1);      
046                            }
047                    } else {
048                            for (int i = 0; i < arcLabelActionContainers.length; i++) {
049                                    if (arcLabelActionContainers[i] == null) {
050                                            throw new MaltChainedException("arcLabelActionContainer " + i + " is null when doing transition " + transition);
051                                    }
052                                    
053                                    Integer code = arcLabels.get(arcLabelActionContainers[i].getTable());
054                                    if (code != null) {
055                                            arcLabelActionContainers[i].setAction(code.shortValue());
056                                    } else {
057                                            arcLabelActionContainers[i].setAction(-1);
058                                    }
059                            }               
060                    }
061                    GuideUserAction oracleAction = history.getEmptyGuideUserAction();
062                    oracleAction.addAction(actionContainers);
063                    return oracleAction;
064            }
065            
066            protected boolean isActionContainersLabeled() {
067                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
068                            if (arcLabelActionContainers[i].getActionCode() < 0) {
069                                    return false;
070                            }
071                    }
072                    return true;
073            }
074            
075            protected void addEdgeLabels(Edge e) throws MaltChainedException {
076                    if (e != null) { 
077                            for (int i = 0; i < arcLabelActionContainers.length; i++) {
078                                    if (arcLabelActionContainers[i].getActionCode() != -1) {
079                                            e.addLabel((SymbolTable)arcLabelActionContainers[i].getTable(), arcLabelActionContainers[i].getActionCode());
080                                    } else {
081                                            e.addLabel((SymbolTable)arcLabelActionContainers[i].getTable(), ((DependencyGraph)e.getBelongsToGraph()).getDefaultRootEdgeLabelCode((SymbolTable)arcLabelActionContainers[i].getTable()));
082                                    }
083                            }
084                            if (propagationManager != null) {
085                                    propagationManager.propagate(e);
086                            }
087                    }
088            }
089            
090            public void initTransitionSystem(GuideUserHistory history) throws MaltChainedException {
091                    this.actionContainers = history.getActionContainerArray();
092                    if (actionContainers.length < 1) {
093                            throw new ParsingException("Problem when initialize the history (sequence of actions). There are no action containers. ");
094                    }
095                    int nLabels = 0;
096                    for (int i = 0; i < actionContainers.length; i++) {
097                            if (actionContainers[i].getTableContainerName().startsWith("A.")) {
098                                    nLabels++;
099                            }
100                    }
101                    int j = 0;
102                    for (int i = 0; i < actionContainers.length; i++) {
103                            if (actionContainers[i].getTableContainerName().equals("T.TRANS")) {
104                                    transActionContainer = actionContainers[i];
105                            } else if (actionContainers[i].getTableContainerName().startsWith("A.")) {
106                                    if (arcLabelActionContainers == null) {
107                                            arcLabelActionContainers = new ActionContainer[nLabels];
108                                    }
109                                    arcLabelActionContainers[j++] = actionContainers[i];
110                            }
111                    }
112                    initWithDefaultTransitions(history);
113            }
114            
115            public void initTableHandlers(String decisionSettings, SymbolTableHandler symbolTableHandler) throws MaltChainedException {
116                    transitionTableHandler = new TransitionTableHandler();
117                    tableHandlers = new HashMap<String, TableHandler>();
118                    
119                    final String[] decisionElements =  decisionSettings.split(",|#|;|\\+");
120                    
121                    int nTrans = 0;
122                    for (int i = 0; i < decisionElements.length; i++) {
123                            int index = decisionElements[i].indexOf('.');
124                            if (index == -1) {
125                                    throw new ParsingException("Decision settings '"+decisionSettings+"' contain an item '"+decisionElements[i]+"' that does not follow the format {TableHandler}.{Table}. ");
126                            }
127                            if (decisionElements[i].substring(0,index).equals("T")) {
128                                    if (!getTableHandlers().containsKey("T")) {
129                                            getTableHandlers().put("T", getTransitionTableHandler());
130                                    }
131                                    if (decisionElements[i].substring(index+1).equals("TRANS")) {
132                                            if (nTrans == 0) {
133                                                    TransitionTable ttable = (TransitionTable)getTransitionTableHandler().addSymbolTable("TRANS");
134                                                    addAvailableTransitionToTable(ttable);
135                                            } else {
136                                                    throw new ParsingException("Illegal decision settings '"+decisionSettings+"'");
137                                            }
138                                            nTrans++;
139                                    }  
140                            } else if (decisionElements[i].substring(0,index).equals("A")) {
141                                    if (!getTableHandlers().containsKey("A")) {
142                                            getTableHandlers().put("A", symbolTableHandler);
143                                    }
144                            } else {
145                                    throw new ParsingException("The decision settings '"+decisionSettings+"' contains an unknown table handler '"+decisionElements[i].substring(0,index)+"'. " +
146                                                    "Only T (Transition table handler) and A (ArcLabel table handler) is allowed. ");
147                            }
148                    }
149            }
150            
151            public void copyAction(GuideUserAction source, GuideUserAction target) throws MaltChainedException {
152                    source.getAction(actionContainers);
153                    target.addAction(actionContainers);
154            }
155            
156            public HashMap<String, TableHandler> getTableHandlers() {
157                    return tableHandlers;
158            }
159    
160            public TransitionTableHandler getTransitionTableHandler() {
161                    return transitionTableHandler;
162            }
163            
164            public PropagationManager getPropagationManager() {
165                    return propagationManager;
166            }
167    
168    //      protected void doPropagation(Edge e) throws MaltChainedException{
169    //
170    //      }
171            
172            public void setPropagationManager(PropagationManager propagationManager) {
173                    this.propagationManager = propagationManager;
174            }
175    
176            public String getActionString(GuideUserAction action) throws MaltChainedException {
177                    StringBuilder sb = new StringBuilder();
178                    action.getAction(actionContainers);
179                    TransitionTable ttable = (TransitionTable)getTransitionTableHandler().getSymbolTable("TRANS");
180                    sb.append(ttable.getSymbolCodeToString(transActionContainer.getActionCode()));
181                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
182                            if (arcLabelActionContainers[i].getActionCode() != -1) {
183                                    sb.append("+");
184                                    sb.append(arcLabelActionContainers[i].getTable().getSymbolCodeToString(arcLabelActionContainers[i].getActionCode()));
185                            }
186                    }
187                    return sb.toString();
188            }
189    }