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