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 }