001    package org.maltparser.parser.algorithm.covington;
002    
003    import java.util.ArrayList;
004    
005    import org.maltparser.core.exception.MaltChainedException;
006    import org.maltparser.core.symbol.SymbolTable;
007    import org.maltparser.core.symbol.SymbolTableHandler;
008    import org.maltparser.core.syntaxgraph.DependencyGraph;
009    import org.maltparser.core.syntaxgraph.DependencyStructure;
010    import org.maltparser.core.syntaxgraph.edge.Edge;
011    import org.maltparser.core.syntaxgraph.node.DependencyNode;
012    import org.maltparser.parser.ParserConfiguration;
013    import org.maltparser.parser.ParsingException;
014    /**
015     * @author Johan Hall
016     *
017     */
018    public class CovingtonConfig extends ParserConfiguration {
019            private ArrayList<DependencyNode> input;
020            private int right;
021            private int left;
022            private int leftstop;
023            private int rightstop;
024            private DependencyStructure dependencyGraph;
025            private boolean allowRoot;
026            private boolean allowShift;
027    
028            
029            public CovingtonConfig(SymbolTableHandler symbolTableHandler, boolean cr, boolean cs) throws MaltChainedException {
030                    super();
031                    input = new ArrayList<DependencyNode>();
032                    dependencyGraph = new DependencyGraph(symbolTableHandler);
033                    setAllowRoot(cr);
034                    setAllowShift(cs);
035            }
036    
037            public DependencyStructure getDependencyStructure() {
038                    return dependencyGraph;
039            }
040            
041            public ArrayList<DependencyNode> getInput() {
042                    return input;
043            }
044    
045            public boolean isTerminalState() {
046                    return right > rightstop;
047            }
048            
049            public int getRight() {
050                    return right;
051            }
052            
053            public void setRight(int right) {
054                    this.right = right;
055            }
056    
057            public int getLeft() {
058                    return left;
059            }
060    
061            public void setLeft(int left) {
062                    this.left = left;
063            }
064    
065            public int getLeftstop() {
066                    return leftstop;
067            }
068    
069            public int getRightstop() {
070                    return rightstop;
071            }
072    
073            public boolean isAllowRoot() {
074                    return allowRoot;
075            }
076    
077            public void setAllowRoot(boolean allowRoot) {
078                    this.allowRoot = allowRoot;
079            }
080    
081            public boolean isAllowShift() {
082                    return allowShift;
083            }
084    
085            public void setAllowShift(boolean allowShift) {
086                    this.allowShift = allowShift;
087            }
088    
089            public DependencyNode getLeftNode(int index) throws MaltChainedException {
090                    if (index < 0) {
091                            throw new ParsingException("Left index must be non-negative in feature specification. ");
092                    }
093                    if (left-index >= 0) {
094                            return input.get(left-index);
095                    }
096                    return null;
097            }
098            
099            public DependencyNode getRightNode(int index) throws MaltChainedException {
100                    if (index < 0) {
101                            throw new ParsingException("Right index must be non-negative in feature specification. ");
102                    }
103                    if (right+index < input.size()) {
104                            return input.get(right+index);
105                    }
106                    return null;
107            }
108            
109            public DependencyNode getLeftContextNode(int index) throws MaltChainedException {
110                    if (index < 0) {
111                            throw new ParsingException("LeftContext index must be non-negative in feature specification. ");
112                    }
113                    
114                    int tmpindex = 0;
115                    for (int i = left+1; i < right; i++) {
116                            if (!input.get(i).hasAncestorInside(left, right)) {
117                                    if (tmpindex == index) {
118                                            return input.get(i);
119                                    } else {
120                                            tmpindex++;
121                                    }
122                            }
123                    }
124                    return null;
125            }
126            
127            public DependencyNode getRightContextNode(int index) throws MaltChainedException {
128                    if (index < 0) {
129                            throw new ParsingException("RightContext index must be non-negative in feature specification. ");
130                    }
131                    int tmpindex = 0;
132                    for (int i = right-1; i > left; i--) {
133                            if (!input.get(i).hasAncestorInside(left, right)) {
134                                    if (tmpindex == index) {
135                                            return input.get(i);
136                                    } else {
137                                            tmpindex++;
138                                    }
139                            }
140                    }
141                    return null;
142            }
143            
144            public DependencyNode getLeftTarget() {
145                    return input.get(left);
146            }
147            
148            public DependencyNode getRightTarget() {
149                    return input.get(right);
150            }
151            
152            public void setDependencyGraph(DependencyStructure source) throws MaltChainedException {
153                    dependencyGraph.clear();
154                    for (int index : source.getTokenIndices()) {
155                            DependencyNode gnode = source.getTokenNode(index);
156                            DependencyNode pnode = dependencyGraph.addTokenNode(gnode.getIndex());
157                            for (SymbolTable table : gnode.getLabelTypes()) {
158                                    pnode.addLabel(table, gnode.getLabelSymbol(table));
159                            }
160                            
161                            if (gnode.hasHead()) {
162                                    Edge s = gnode.getHeadEdge();
163                                    Edge t = dependencyGraph.addDependencyEdge(s.getSource().getIndex(), s.getTarget().getIndex());
164                                    
165                                    for (SymbolTable table : s.getLabelTypes()) {
166                                            t.addLabel(table, s.getLabelSymbol(table));
167                                    }
168                            }
169                    }
170                    for (SymbolTable table : source.getDefaultRootEdgeLabels().keySet()) {
171                            dependencyGraph.setDefaultRootEdgeLabel(table, source.getDefaultRootEdgeLabelSymbol(table));
172                    }
173            }
174            
175            public DependencyStructure getDependencyGraph() {
176                    return dependencyGraph;
177            }
178            
179    //      public void initAllowRoot(boolean allowRoot) throws MaltChainedException {
180    //              if (allowRoot == true) {
181    //                      leftstop = 0;
182    //              } else {
183    //                      leftstop = 1;
184    //              }
185    //      }
186            
187            
188            public void initialize(ParserConfiguration parserConfiguration) throws MaltChainedException {   
189                    if (parserConfiguration != null) {
190                            CovingtonConfig covingtonConfig = (CovingtonConfig)parserConfiguration;
191                            ArrayList<DependencyNode> sourceInput = covingtonConfig.getInput();
192                            setDependencyGraph(covingtonConfig.getDependencyGraph());
193                            for (int i = 0, n = sourceInput.size(); i < n; i++) {
194                                    input.add(dependencyGraph.getDependencyNode(sourceInput.get(i).getIndex()));
195                            }
196                            left = covingtonConfig.getLeft();
197                            right = covingtonConfig.getRight();
198                            rightstop = covingtonConfig.getRightstop();
199                            leftstop = covingtonConfig.getLeftstop();
200                    } else {
201                            for (int i = 0, n = dependencyGraph.getHighestTokenIndex(); i <= n; i++) {
202                                    DependencyNode node = dependencyGraph.getDependencyNode(i);
203                                    if (node != null) { 
204                                            input.add(node);
205                                    }
206                            }
207                            if (allowRoot == true) {
208                                    leftstop = 0;
209                            } else {
210                                    leftstop = 1;
211                            }
212                            rightstop = dependencyGraph.getHighestTokenIndex();
213                            left = leftstop;
214                            right = left + 1;
215                    }
216            }
217            
218            public void clear() throws MaltChainedException {
219                    dependencyGraph.clear();
220                    input.clear();
221                    historyNode = null;
222            }
223            
224            public boolean equals(Object obj) {
225                    if (this == obj)
226                            return true;
227                    if (obj == null)
228                            return false;
229                    if (getClass() != obj.getClass())
230                            return false;
231                    CovingtonConfig that = (CovingtonConfig)obj;
232                    
233                    if (input.size() != that.getInput().size())
234                            return false;
235                    if (dependencyGraph.nEdges() != that.getDependencyGraph().nEdges())
236                            return false;
237                    for (int i = 0; i < input.size(); i++) {
238                            if (input.get(i).getIndex() != that.getInput().get(i).getIndex()) {
239                                    return false;
240                            }
241                    }               
242                    return dependencyGraph.getEdges().equals(that.getDependencyGraph().getEdges());
243            }
244            public String toString() {
245                    final StringBuilder sb = new StringBuilder();
246                    sb.append(input.size());
247                    sb.append(", ");
248                    sb.append(dependencyGraph.nEdges());
249                    return sb.toString();
250            }
251    
252    }