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            }
171            
172            public DependencyStructure getDependencyGraph() {
173                    return dependencyGraph;
174            }
175            
176    //      public void initAllowRoot(boolean allowRoot) throws MaltChainedException {
177    //              if (allowRoot == true) {
178    //                      leftstop = 0;
179    //              } else {
180    //                      leftstop = 1;
181    //              }
182    //      }
183            
184            
185            public void initialize(ParserConfiguration parserConfiguration) throws MaltChainedException {   
186                    if (parserConfiguration != null) {
187                            CovingtonConfig covingtonConfig = (CovingtonConfig)parserConfiguration;
188                            ArrayList<DependencyNode> sourceInput = covingtonConfig.getInput();
189                            setDependencyGraph(covingtonConfig.getDependencyGraph());
190                            for (int i = 0, n = sourceInput.size(); i < n; i++) {
191                                    input.add(dependencyGraph.getDependencyNode(sourceInput.get(i).getIndex()));
192                            }
193                            left = covingtonConfig.getLeft();
194                            right = covingtonConfig.getRight();
195                            rightstop = covingtonConfig.getRightstop();
196                            leftstop = covingtonConfig.getLeftstop();
197                    } else {
198                            for (int i = 0, n = dependencyGraph.getHighestTokenIndex(); i <= n; i++) {
199                                    DependencyNode node = dependencyGraph.getDependencyNode(i);
200                                    if (node != null) { 
201                                            input.add(node);
202                                    }
203                            }
204                            if (allowRoot == true) {
205                                    leftstop = 0;
206                            } else {
207                                    leftstop = 1;
208                            }
209                            rightstop = dependencyGraph.getHighestTokenIndex();
210                            left = leftstop;
211                            right = left + 1;
212                    }
213            }
214            
215            public void clear() throws MaltChainedException {
216                    dependencyGraph.clear();
217                    input.clear();
218                    historyNode = null;
219            }
220            
221            public boolean equals(Object obj) {
222                    if (this == obj)
223                            return true;
224                    if (obj == null)
225                            return false;
226                    if (getClass() != obj.getClass())
227                            return false;
228                    CovingtonConfig that = (CovingtonConfig)obj;
229                    
230                    if (input.size() != that.getInput().size())
231                            return false;
232                    if (dependencyGraph.nEdges() != that.getDependencyGraph().nEdges())
233                            return false;
234                    for (int i = 0; i < input.size(); i++) {
235                            if (input.get(i).getIndex() != that.getInput().get(i).getIndex()) {
236                                    return false;
237                            }
238                    }               
239                    return dependencyGraph.getEdges().equals(that.getDependencyGraph().getEdges());
240            }
241            public String toString() {
242                    final StringBuilder sb = new StringBuilder();
243                    sb.append(input.size());
244                    sb.append(", ");
245                    sb.append(dependencyGraph.nEdges());
246                    return sb.toString();
247            }
248    
249    }