aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/query
diff options
context:
space:
mode:
authorRncLsn <rnc.lsn@gmail.com>2015-05-29 18:35:51 +0100
committerRncLsn <rnc.lsn@gmail.com>2015-05-29 18:35:51 +0100
commit4b7253559c290b6fdd1c4122830f153fda85dd62 (patch)
tree37c1487e4682be719dec532ca3d7e1af353fb9a1 /src/uk/ac/ox/cs/pagoda/query
parent6a559a415b3bdb3048021839e5bcf5bbf5aa4bbd (diff)
downloadACQuA-4b7253559c290b6fdd1c4122830f153fda85dd62.tar.gz
ACQuA-4b7253559c290b6fdd1c4122830f153fda85dd62.zip
Disposable.
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/query')
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java2
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java37
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java5
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/QueryRecord.java1327
4 files changed, 738 insertions, 633 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
index cb2b0a3..78aced1 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
@@ -172,7 +172,7 @@ public class AnswerTuple {
172 String lexicalForm = matcher.group("lexicalForm"); 172 String lexicalForm = matcher.group("lexicalForm");
173 String dataTypeIRI = matcher.group("dataType"); 173 String dataTypeIRI = matcher.group("dataType");
174 Datatype dataType; 174 Datatype dataType;
175 if (dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL; 175 if(dataTypeIRI == null || dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL;
176 else dataType = uk.ac.ox.cs.JRDFox.model.Datatype.value(dataTypeIRI); 176 else dataType = uk.ac.ox.cs.JRDFox.model.Datatype.value(dataTypeIRI);
177 terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, dataType); 177 terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, dataType);
178 } 178 }
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java
index e1e5302..81efed0 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java
@@ -1,23 +1,22 @@
1package uk.ac.ox.cs.pagoda.query; 1package uk.ac.ox.cs.pagoda.query;
2 2
3public interface AnswerTuples { 3import uk.ac.ox.cs.pagoda.util.disposable.Disposable;
4
5 public void reset();
6
7 public boolean isValid();
8
9 public int getArity();
10
11 public String[] getAnswerVariables();
12
13 public void moveNext();
14
15 public void dispose();
16
17 public AnswerTuple getTuple();
18
19 public boolean contains(AnswerTuple t);
20
21 public void remove();
22 4
5public abstract class AnswerTuples extends Disposable {
6
7 public abstract void reset();
8
9 public abstract boolean isValid();
10
11 public abstract int getArity();
12
13 public abstract String[] getAnswerVariables();
14
15 public abstract void moveNext();
16
17 public abstract AnswerTuple getTuple();
18
19 public abstract boolean contains(AnswerTuple t);
20
21 public abstract void remove();
23} 22}
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java
index 3e0f320..fd3fb1f 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java
@@ -3,7 +3,7 @@ package uk.ac.ox.cs.pagoda.query;
3import java.util.Iterator; 3import java.util.Iterator;
4import java.util.Set; 4import java.util.Set;
5 5
6public class AnswerTuplesImp implements AnswerTuples { 6public class AnswerTuplesImp extends AnswerTuples {
7 7
8 int m_index; 8 int m_index;
9 Iterator<AnswerTuple> m_iter; 9 Iterator<AnswerTuple> m_iter;
@@ -54,9 +54,6 @@ public class AnswerTuplesImp implements AnswerTuples {
54 } 54 }
55 55
56 @Override 56 @Override
57 public void dispose() {}
58
59 @Override
60 public void reset() { 57 public void reset() {
61 if (m_answers1 == null || m_answers1.isEmpty()) { 58 if (m_answers1 == null || m_answers1.isEmpty()) {
62 m_index = 2; 59 m_index = 2;
diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
index 1f81a78..742b7da 100644
--- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
+++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
@@ -11,6 +11,8 @@ import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper;
11import uk.ac.ox.cs.pagoda.util.Namespace; 11import uk.ac.ox.cs.pagoda.util.Namespace;
12import uk.ac.ox.cs.pagoda.util.PagodaProperties; 12import uk.ac.ox.cs.pagoda.util.PagodaProperties;
13import uk.ac.ox.cs.pagoda.util.Utility; 13import uk.ac.ox.cs.pagoda.util.Utility;
14import uk.ac.ox.cs.pagoda.util.disposable.Disposable;
15import uk.ac.ox.cs.pagoda.util.disposable.DisposedException;
14import uk.ac.ox.cs.pagoda.util.tuples.Tuple; 16import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
15import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; 17import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder;
16 18
@@ -18,162 +20,180 @@ import java.io.*;
18import java.lang.reflect.Type; 20import java.lang.reflect.Type;
19import java.util.*; 21import java.util.*;
20 22
21public class QueryRecord { 23public class QueryRecord extends Disposable {
22 24
23 public static final String botQueryText = "SELECT ?X WHERE { ?X <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Nothing> }"; 25 public static final String botQueryText =
24 public static final String SEPARATOR = "----------------------------------------"; 26 "SELECT ?X WHERE { ?X <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Nothing> }";
25 private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString(); 27 public static final String SEPARATOR = "----------------------------------------";
26 boolean processed = false; 28 private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString();
27 String stringQueryID = null; 29 boolean processed = false;
28 OWLOntology relevantOntology = null; 30 String stringQueryID = null;
29 Set<DLClause> relevantClauses = new HashSet<DLClause>(); 31 OWLOntology relevantOntology = null;
30 double[] timer; 32 Set<DLClause> relevantClauses = new HashSet<DLClause>();
31 int subID; 33 double[] timer;
32 DLClause queryClause = null; 34 int subID;
33 int queryID = -1; 35 DLClause queryClause = null;
34 Set<AnswerTuple> soundAnswerTuples = new HashSet<AnswerTuple>(); 36 int queryID = -1;
35 private Step difficulty; 37 Set<AnswerTuple> soundAnswerTuples = new HashSet<AnswerTuple>();
36 private String queryText; 38 private Step difficulty;
37 private String[][] answerVariables = null; 39 private String queryText;
38 private Set<AnswerTuple> gapAnswerTuples = null; 40 private String[][] answerVariables = null;
39 private QueryManager m_manager; 41 private Set<AnswerTuple> gapAnswerTuples = null;
40 42 private QueryManager m_manager;
41 private QueryRecord() { 43
42 } 44 private QueryRecord() {
45 }
43 46
44// private boolean containsAuxPredicate(String str) { 47// private boolean containsAuxPredicate(String str) {
45// return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") || 48// return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") ||
46// str.contains("internal:def"); 49// str.contains("internal:def");
47// } 50// }
48 51
49 public QueryRecord(QueryManager manager, String text, int id, int subID) { 52 public QueryRecord(QueryManager manager, String text, int id, int subID) {
50 m_manager = manager; 53 m_manager = manager;
51 resetInfo(text, id, subID); 54 resetInfo(text, id, subID);
52 resetTimer(); 55 resetTimer();
53 } 56 }
54 57
55 public static Collection<String> collectQueryTexts(Collection<QueryRecord> queryRecords) { 58 public static Collection<String> collectQueryTexts(Collection<QueryRecord> queryRecords) {
56 Collection<String> texts = new LinkedList<String>(); 59 Collection<String> texts = new LinkedList<String>();
57 for(QueryRecord record : queryRecords) 60 for(QueryRecord record : queryRecords)
58 texts.add(record.queryText); 61 texts.add(record.queryText);
59 return texts; 62 return texts;
60 } 63 }
61 64
62 public void resetInfo(String text, int id, int subid) { 65 public void resetInfo(String text, int id, int subid) {
63 queryID = id; 66 if(isDisposed()) throw new DisposedException();
64 subID = subid; 67
65 stringQueryID = id + (subID == 0 ? "" : "_" + subID); 68 queryID = id;
66 m_manager.remove(queryText); 69 subID = subid;
67 m_manager.put(text, this); 70 stringQueryID = id + (subID == 0 ? "" : "_" + subID);
68 queryClause = null; 71 m_manager.remove(queryText);
69 answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text); 72 m_manager.put(text, this);
70 queryText = text; // .replace("_:", "?"); 73 queryClause = null;
71 } 74 answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text);
72 75 queryText = text; // .replace("_:", "?");
73 public void resetTimer() { 76 }
74 int length = Step.values().length; 77
75 timer = new double[length]; 78 public void resetTimer() {
76 for(int i = 0; i < length; ++i) timer[i] = 0; 79 if(isDisposed()) throw new DisposedException();
77 } 80
78 81 int length = Step.values().length;
79 public AnswerTuples getAnswers() { 82 timer = new double[length];
80 if(isProcessed()) 83 for(int i = 0; i < length; ++i) timer[i] = 0;
81 return getLowerBoundAnswers(); 84 }
82 85
83 return getUpperBoundAnswers(); 86 public AnswerTuples getAnswers() {
84 } 87 if(isDisposed()) throw new DisposedException();
85 88
86 public AnswerTuples getLowerBoundAnswers() { 89 if(isProcessed())
87 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples); 90 return getLowerBoundAnswers();
88 } 91
89 92 return getUpperBoundAnswers();
90 public AnswerTuples getUpperBoundAnswers() { 93 }
91 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples); 94
92 } 95 public AnswerTuples getLowerBoundAnswers() {
93 96 if(isDisposed()) throw new DisposedException();
94 public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) { 97
95 if(answerTuples == null) return false; 98 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples);
96 boolean update = false; 99 }
97 for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) { 100
98 tuple = answerTuples.getTuple(); 101 public AnswerTuples getUpperBoundAnswers() {
99 if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) { 102 if(isDisposed()) throw new DisposedException();
100 soundAnswerTuples.add(tuple); 103
101 if(gapAnswerTuples != null) 104 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples);
102 gapAnswerTuples.remove(tuple); 105 }
103 update = true; 106
104 } 107 public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) {
105 } 108 if(isDisposed()) throw new DisposedException();
106 109
107 if(soundAnswerTuples.isEmpty()) 110 if(answerTuples == null) return false;
108 Utility.logInfo("Lower bound answers empty"); 111 boolean update = false;
109 else if(update) 112 for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) {
110 Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size()); 113 tuple = answerTuples.getTuple();
111 else 114 if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) {
112 Utility.logInfo("Lower bound answers unchanged"); 115 soundAnswerTuples.add(tuple);
113 116 if(gapAnswerTuples != null)
114 return update; 117 gapAnswerTuples.remove(tuple);
115 } 118 update = true;
116 119 }
117 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) { 120 }
118 return updateUpperBoundAnswers(answerTuples, false); 121
119 } 122 if(soundAnswerTuples.isEmpty())
120 123 Utility.logInfo("Lower bound answers empty");
121 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { 124 else if(update)
122 if(!(answerTuples instanceof RDFoxAnswerTuples)) { 125 Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size());
123 String msg = "The upper bound must be computed by RDFox!"; 126 else
124 Utility.logError(msg); 127 Utility.logInfo("Lower bound answers unchanged");
125 throw new IllegalArgumentException(msg); 128
126 } 129 return update;
127 130 }
128 RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples; 131
129 132 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) {
130 Set<AnswerTuple> candidateGapAnswerTuples = new HashSet<AnswerTuple>(); 133 if(isDisposed()) throw new DisposedException();
131 AnswerTuple tuple; 134
132 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { 135 return updateUpperBoundAnswers(answerTuples, false);
133 tuple = rdfoxAnswerTuples.getTuple(); 136 }
134 if(isBottom() || !tuple.hasAnonymousIndividual()) 137
135 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) 138 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
136 candidateGapAnswerTuples.add(tuple); 139 if(isDisposed()) throw new DisposedException();
137 } 140
138 141 if(!(answerTuples instanceof RDFoxAnswerTuples)) {
139 /*** START: debugging ***/ 142 String msg = "The upper bound must be computed by RDFox!";
140 if(PagodaProperties.isDebuggingMode()) { 143 Utility.logError(msg);
141 if(rdfoxAnswerTuples.getArity() != getAnswerVariables().length) 144 throw new IllegalArgumentException(msg);
142 throw new IllegalArgumentException( 145 }
143 "The arity of answers (" + rdfoxAnswerTuples.getArity() + ") " + 146
144 "is different from the number of answer variables (" + 147 RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples;
145 getAnswerVariables().length + ")"); 148
146 149 Set<AnswerTuple> candidateGapAnswerTuples = new HashSet<AnswerTuple>();
147 Set<AnswerTuple> namedAnswerTuples = new HashSet<>(); 150 AnswerTuple tuple;
148 rdfoxAnswerTuples.reset(); 151 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
149 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { 152 tuple = rdfoxAnswerTuples.getTuple();
150 tuple = rdfoxAnswerTuples.getTuple(); 153 if(isBottom() || !tuple.hasAnonymousIndividual())
154 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple))
155 candidateGapAnswerTuples.add(tuple);
156 }
157
158 /*** START: debugging ***/
159 if(PagodaProperties.isDebuggingMode()) {
160 if(rdfoxAnswerTuples.getArity() != getAnswerVariables().length)
161 throw new IllegalArgumentException(
162 "The arity of answers (" + rdfoxAnswerTuples.getArity() + ") " +
163 "is different from the number of answer variables (" +
164 getAnswerVariables().length + ")");
165
166 Set<AnswerTuple> namedAnswerTuples = new HashSet<>();
167 rdfoxAnswerTuples.reset();
168 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
169 tuple = rdfoxAnswerTuples.getTuple();
151// if(isBottom() || !tuple.hasAnonymousIndividual()) { 170// if(isBottom() || !tuple.hasAnonymousIndividual()) {
152 namedAnswerTuples.add(tuple); 171 namedAnswerTuples.add(tuple);
153// } 172// }
154 } 173 }
155 HashSet<AnswerTuple> difference = new HashSet<>(soundAnswerTuples); 174 HashSet<AnswerTuple> difference = new HashSet<>(soundAnswerTuples);
156 difference.removeAll(namedAnswerTuples); 175 difference.removeAll(namedAnswerTuples);
157 if(!difference.isEmpty()) 176 if(!difference.isEmpty())
158 throw new IllegalArgumentException("The upper bound does not contain the lower bound! Missing answers: " + difference 177 throw new IllegalArgumentException("The upper bound does not contain the lower bound! Missing answers: " + difference
159 .size()); 178 .size());
160 } 179 }
161 /*** END: debugging ***/ 180 /*** END: debugging ***/
162 181
163 boolean update; 182 boolean update;
164 if(gapAnswerTuples == null) { 183 if(gapAnswerTuples == null) {
165 gapAnswerTuples = candidateGapAnswerTuples; 184 gapAnswerTuples = candidateGapAnswerTuples;
166 update = true; 185 update = true;
167 } else { 186 }
168 update = gapAnswerTuples.retainAll(candidateGapAnswerTuples); 187 else {
169 } 188 update = gapAnswerTuples.retainAll(candidateGapAnswerTuples);
170 189 }
171 if(update) 190
172 Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers()); 191 if(update)
173 else 192 Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers());
174 Utility.logInfo("Upper bound answers unchanged"); 193 else
175 194 Utility.logInfo("Upper bound answers unchanged");
176 return update; 195
196 return update;
177 197
178// boolean update = false; 198// boolean update = false;
179// for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) { 199// for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) {
@@ -183,96 +203,116 @@ public class QueryRecord {
183// update = true; 203// update = true;
184// } 204// }
185// } 205// }
186 } 206 }
187 207
188 public int getNumberOfAnswers() { 208 public int getNumberOfAnswers() {
189 return soundAnswerTuples.size() + gapAnswerTuples.size(); 209 if(isDisposed()) throw new DisposedException();
190 } 210
191 211 return soundAnswerTuples.size() + gapAnswerTuples.size();
192 public void markAsProcessed() { 212 }
193 processed = true; 213
194 } 214 public void markAsProcessed() {
195 215 processed = true;
196 public boolean isProcessed() { 216 }
197 if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true; 217
198 return processed; 218 public boolean isProcessed() {
199 } 219 if(isDisposed()) throw new DisposedException();
200 220
201 public String[] getDistinguishedVariables() { 221 if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true;
202 return answerVariables[1]; 222 return processed;
203 } 223 }
204 224
205 public String[] getAnswerVariables() { 225 public String[] getDistinguishedVariables() {
206 return answerVariables[0]; 226 if(isDisposed()) throw new DisposedException();
207 } 227
208 228 return answerVariables[1];
209 public String[][] getVariables() { 229 }
210 return answerVariables; 230
211 } 231 public String[] getAnswerVariables() {
212 232 if(isDisposed()) throw new DisposedException();
213 public String getQueryText() { 233
214 return queryText; 234 return answerVariables[0];
215 } 235 }
216 236
217 public String getQueryID() { 237 public String[][] getVariables() {
218 return stringQueryID; 238 if(isDisposed()) throw new DisposedException();
219 } 239
220 240 return answerVariables;
221 public AnswerTuples getGapAnswers() { 241 }
222 return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples); 242
223 } 243 public String getQueryText() {
224 244 if(isDisposed()) throw new DisposedException();
225 public String toString() { 245
226 return queryText; 246 return queryText;
227 } 247 }
228 248
229 public void outputAnswers(BufferedWriter writer) throws IOException { 249 public String getQueryID() {
230 250 if(isDisposed()) throw new DisposedException();
231 int answerCounter = soundAnswerTuples.size(); 251
232 if(!isProcessed()) answerCounter += gapAnswerTuples.size(); 252 return stringQueryID;
233 253 }
234 Utility.logInfo("The number of answer tuples: " + answerCounter); 254
235 255 public AnswerTuples getGapAnswers() {
236 if (writer != null) { 256 if(isDisposed()) throw new DisposedException();
237 writer.write("-------------- Query " + queryID + " ---------------------"); 257
238 writer.newLine(); 258 return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples);
239 writer.write(queryText); 259 }
240 writer.newLine(); 260
241 StringBuilder space = new StringBuilder(); 261 public String toString() {
242 int arity = getArity(), varSpace = 0; 262 if(isDisposed()) throw new DisposedException();
243 for (int i = 0; i < arity; ++i) 263
244 varSpace += answerVariables[0][i].length(); 264 return queryText;
245 for (int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i) 265 }
246 space.append(" "); 266
247 for (int i = 0; i < getArity(); ++i) { 267 public void outputAnswers(BufferedWriter writer) throws IOException {
248 writer.write(space.toString()); 268 if(isDisposed()) throw new DisposedException();
249 writer.write(answerVariables[0][i]); 269
250 } 270 int answerCounter = soundAnswerTuples.size();
251 writer.newLine(); 271 if(!isProcessed()) answerCounter += gapAnswerTuples.size();
252 writer.write(SEPARATOR); 272
253 writer.newLine(); 273 Utility.logInfo("The number of answer tuples: " + answerCounter);
254 for (AnswerTuple tuple: soundAnswerTuples) { 274
255 writer.write(tuple.toString()); 275 if(writer != null) {
256 writer.newLine(); 276 writer.write("-------------- Query " + queryID + " ---------------------");
257 } 277 writer.newLine();
258 if(!isProcessed()) 278 writer.write(queryText);
259 for (AnswerTuple tuple: gapAnswerTuples) { 279 writer.newLine();
260 writer.write("*"); 280 StringBuilder space = new StringBuilder();
261 writer.write(tuple.toString()); 281 int arity = getArity(), varSpace = 0;
262 writer.newLine(); 282 for(int i = 0; i < arity; ++i)
263 } 283 varSpace += answerVariables[0][i].length();
284 for(int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i)
285 space.append(" ");
286 for(int i = 0; i < getArity(); ++i) {
287 writer.write(space.toString());
288 writer.write(answerVariables[0][i]);
289 }
290 writer.newLine();
291 writer.write(SEPARATOR);
292 writer.newLine();
293 for(AnswerTuple tuple : soundAnswerTuples) {
294 writer.write(tuple.toString());
295 writer.newLine();
296 }
297 if(!isProcessed())
298 for(AnswerTuple tuple : gapAnswerTuples) {
299 writer.write("*");
300 writer.write(tuple.toString());
301 writer.newLine();
302 }
264// writer.write(SEPARATOR); 303// writer.write(SEPARATOR);
265 writer.newLine(); 304 writer.newLine();
266 } 305 }
267 306
268 } 307 }
269 308
270 public void outputAnswerStatistics() { 309 public void outputAnswerStatistics() {
310 if(isDisposed()) throw new DisposedException();
271 311
272 int answerCounter = soundAnswerTuples.size(); 312 int answerCounter = soundAnswerTuples.size();
273 if(!isProcessed()) answerCounter += gapAnswerTuples.size(); 313 if(!isProcessed()) answerCounter += gapAnswerTuples.size();
274 314
275 Utility.logInfo("The number of answer tuples: " + answerCounter); 315 Utility.logInfo("The number of answer tuples: " + answerCounter);
276// if (jsonAnswers != null) { 316// if (jsonAnswers != null) {
277// JSONObject jsonAnswer = new JSONObject(); 317// JSONObject jsonAnswer = new JSONObject();
278// 318//
@@ -297,407 +337,476 @@ public class QueryRecord {
297// 337//
298// jsonAnswers.put(Integer.toString(queryID), jsonAnswer); 338// jsonAnswers.put(Integer.toString(queryID), jsonAnswer);
299// } 339// }
300 } 340 }
301 341
302 public void outputTimes() { 342 public void outputTimes() {
303 for (Step step: Step.values()) { 343 if(isDisposed()) throw new DisposedException();
304 Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]); 344
305 } 345 for(Step step : Step.values()) {
306 } 346 Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]);
307 347 }
308 public String outputSoundAnswerTuple() { 348 }
309 StringBuilder builder = new StringBuilder(); 349
310 for (AnswerTuple tuple: soundAnswerTuples) 350 public String outputSoundAnswerTuple() {
311 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); 351 if(isDisposed()) throw new DisposedException();
312 return builder.toString(); 352
313 } 353 StringBuilder builder = new StringBuilder();
314 354 for(AnswerTuple tuple : soundAnswerTuples)
315 public String outputGapAnswerTuple() { 355 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR);
316 StringBuilder builder = new StringBuilder(); 356 return builder.toString();
317 for(AnswerTuple tuple : gapAnswerTuples) 357 }
318 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); 358
319 return builder.toString(); 359 public String outputGapAnswerTuple() {
320 } 360 if(isDisposed()) throw new DisposedException();
321 361
322 public Step getDifficulty() { 362 StringBuilder builder = new StringBuilder();
323 return difficulty; 363 for(AnswerTuple tuple : gapAnswerTuples)
324 } 364 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR);
325 365 return builder.toString();
326 public void setDifficulty(Step step) { 366 }
327 this.difficulty = step; 367
328 } 368 public Step getDifficulty() {
329 369 if(isDisposed()) throw new DisposedException();
330 public OWLOntology getRelevantOntology() { 370
331 return relevantOntology; 371 return difficulty;
332 } 372 }
333 373
334 public void setRelevantOntology(OWLOntology knowledgebase) { 374 public void setDifficulty(Step step) {
335 relevantOntology = knowledgebase; 375 if(isDisposed()) throw new DisposedException();
336 } 376
337 377 this.difficulty = step;
338 public void saveRelevantOntology(String filename) { 378 }
339 if(relevantOntology == null) return; 379
340 OWLOntologyManager manager = relevantOntology.getOWLOntologyManager(); 380 public OWLOntology getRelevantOntology() {
341 try { 381 if(isDisposed()) throw new DisposedException();
342 FileOutputStream outputStream = new FileOutputStream(filename); 382
343 manager.saveOntology(relevantOntology, outputStream); 383 return relevantOntology;
344 outputStream.close(); 384 }
345 } catch (OWLOntologyStorageException e) { 385
346 e.printStackTrace(); 386 public void setRelevantOntology(OWLOntology knowledgebase) {
347 } catch (FileNotFoundException e) { 387 if(isDisposed()) throw new DisposedException();
348 e.printStackTrace(); 388
349 } catch (IOException e) { 389 relevantOntology = knowledgebase;
350 e.printStackTrace(); 390 }
351 } 391
352 } 392 public void saveRelevantOntology(String filename) {
353 393 if(isDisposed()) throw new DisposedException();
354 public void saveRelevantClause() { 394
355 if(relevantClauses == null) return; 395 if(relevantOntology == null) return;
356 GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology); 396 OWLOntologyManager manager = relevantOntology.getOWLOntologyManager();
357 p.save(); 397 try {
358 } 398 FileOutputStream outputStream = new FileOutputStream(filename);
359 399 manager.saveOntology(relevantOntology, outputStream);
360 public void removeUpperBoundAnswers(Collection<AnswerTuple> answers) { 400 outputStream.close();
361 for (AnswerTuple answer: answers) { 401 } catch(OWLOntologyStorageException e) {
402 e.printStackTrace();
403 } catch(FileNotFoundException e) {
404 e.printStackTrace();
405 } catch(IOException e) {
406 e.printStackTrace();
407 }
408 }
409
410 public void saveRelevantClause() {
411 if(isDisposed()) throw new DisposedException();
412
413 if(relevantClauses == null) return;
414 GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology);
415 p.save();
416 }
417
418 public void removeUpperBoundAnswers(Collection<AnswerTuple> answers) {
419 if(isDisposed()) throw new DisposedException();
420
421 for(AnswerTuple answer : answers) {
362// if (soundAnswerTuples.contains(answer)) 422// if (soundAnswerTuples.contains(answer))
363// Utility.logError("The answer (" + answer + ") cannot be removed, because it is in the lower bound."); 423// Utility.logError("The answer (" + answer + ") cannot be removed, because it is in the lower bound.");
364 if (!gapAnswerTuples.contains(answer)) 424 if(!gapAnswerTuples.contains(answer))
365 Utility.logError("The answer (" + answer + ") cannot be removed, because it is not in the upper bound."); 425 Utility.logError("The answer (" + answer + ") cannot be removed, because it is not in the upper bound.");
366 gapAnswerTuples.remove(answer); 426 gapAnswerTuples.remove(answer);
367 } 427 }
368 } 428 }
369 429
370 public void addLowerBoundAnswers(Collection<AnswerTuple> answers) { 430 public void addLowerBoundAnswers(Collection<AnswerTuple> answers) {
371 for (AnswerTuple answer: answers) { 431 if(isDisposed()) throw new DisposedException();
372 if (!gapAnswerTuples.contains(answer)) 432
373 Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); 433 for(AnswerTuple answer : answers) {
374 gapAnswerTuples.remove(answer); 434 if(!gapAnswerTuples.contains(answer))
375 435 Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound.");
376 answer = AnswerTuple.getInstance(answer, answerVariables[0].length); 436 gapAnswerTuples.remove(answer);
437
438 answer = AnswerTuple.getInstance(answer, answerVariables[0].length);
377// if (soundAnswerTuples.contains(answer)) 439// if (soundAnswerTuples.contains(answer))
378// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound."); 440// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound.");
379 soundAnswerTuples.add(answer); 441 soundAnswerTuples.add(answer);
380 } 442 }
381 } 443 }
382 444
383 public int getNoOfSoundAnswers() { 445 public int getNoOfSoundAnswers() {
384 return soundAnswerTuples.size(); 446 if(isDisposed()) throw new DisposedException();
385 } 447
386 448 return soundAnswerTuples.size();
387 public void addProcessingTime(Step step, double time) { 449 }
388 timer[step.ordinal()] += time; 450
389 } 451 public void addProcessingTime(Step step, double time) {
390 452 if(isDisposed()) throw new DisposedException();
391 public int getArity() { 453
392 return answerVariables[0].length; 454 timer[step.ordinal()] += time;
393 } 455 }
394 456
395 public void addRelevantClauses(DLClause clause) { 457 public int getArity() {
396 relevantClauses.add(clause); 458 if(isDisposed()) throw new DisposedException();
397 } 459
398 460 return answerVariables[0].length;
399 public Set<DLClause> getRelevantClauses() { 461 }
400 return relevantClauses; 462
401 } 463 public void addRelevantClauses(DLClause clause) {
402 464 if(isDisposed()) throw new DisposedException();
403 public void clearClauses() { 465
404 relevantClauses.clear(); 466 relevantClauses.add(clause);
405 } 467 }
406 468
407 public boolean isHorn() { 469 public Set<DLClause> getRelevantClauses() {
408 for (DLClause clause: relevantClauses) 470 if(isDisposed()) throw new DisposedException();
409 if (clause.getHeadLength() > 1) 471
410 return false; 472 return relevantClauses;
411 return true; 473 }
412 } 474
413 475 public void clearClauses() {
414 public void saveABoxInTurtle(String filename) { 476 if(isDisposed()) throw new DisposedException();
415 try { 477
416 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); 478 relevantClauses.clear();
417 OWLIndividual a, b; 479 }
418 StringBuilder builder = new StringBuilder(); 480
419 for (OWLAxiom axiom: relevantOntology.getABoxAxioms(true)) { 481 public boolean isHorn() {
420 if (axiom instanceof OWLClassAssertionAxiom) { 482 if(isDisposed()) throw new DisposedException();
421 OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom; 483
422 OWLClass c = (OWLClass) classAssertion.getClassExpression(); 484 for(DLClause clause : relevantClauses)
423 a = classAssertion.getIndividual(); 485 if(clause.getHeadLength() > 1)
424 builder.append(a.toString()) 486 return false;
425 .append(" <") 487 return true;
426 .append(Namespace.RDF_TYPE) 488 }
427 .append("> ") 489
428 .append(c.toString()); 490 public void saveABoxInTurtle(String filename) {
429 } 491 if(isDisposed()) throw new DisposedException();
430 else if (axiom instanceof OWLObjectPropertyAssertionAxiom) { 492
431 OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom; 493 try {
432 OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty(); 494 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
433 a = propertyAssertion.getSubject(); 495 OWLIndividual a, b;
434 b = propertyAssertion.getObject(); 496 StringBuilder builder = new StringBuilder();
435 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString()); 497 for(OWLAxiom axiom : relevantOntology.getABoxAxioms(true)) {
436 } 498 if(axiom instanceof OWLClassAssertionAxiom) {
437 else if (axiom instanceof OWLDataPropertyAssertionAxiom) { 499 OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom;
438 OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom; 500 OWLClass c = (OWLClass) classAssertion.getClassExpression();
439 OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty(); 501 a = classAssertion.getIndividual();
440 a = propertyAssertion.getSubject(); 502 builder.append(a.toString())
441 OWLLiteral l = propertyAssertion.getObject(); 503 .append(" <")
442 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString()); 504 .append(Namespace.RDF_TYPE)
443 } 505 .append("> ")
444 506 .append(c.toString());
445 writer.write(builder.toString()); 507 }
446 writer.write(" ."); 508 else if(axiom instanceof OWLObjectPropertyAssertionAxiom) {
447 writer.newLine(); 509 OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom;
448 builder.setLength(0); 510 OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty();
449 } 511 a = propertyAssertion.getSubject();
450 writer.close(); 512 b = propertyAssertion.getObject();
451 } catch (IOException e) { 513 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString());
452 e.printStackTrace(); 514 }
453 } finally { 515 else if(axiom instanceof OWLDataPropertyAssertionAxiom) {
454 516 OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom;
455 } 517 OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty();
456 } 518 a = propertyAssertion.getSubject();
457 519 OWLLiteral l = propertyAssertion.getObject();
458 public void updateSubID() { 520 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString());
459 ++subID; 521 }
460 stringQueryID = String.valueOf(queryID) + "_" + subID; 522
461 } 523 writer.write(builder.toString());
462 524 writer.write(" .");
463 public DLClause getClause() { 525 writer.newLine();
464 if (queryClause != null) 526 builder.setLength(0);
465 return queryClause; 527 }
466 return queryClause = DLClauseHelper.getQuery(queryText, null); 528 writer.close();
467 } 529 } catch(IOException e) {
468 530 e.printStackTrace();
469 public boolean isBottom() { 531 } finally {
470 return queryID == 0; 532
471 } 533 }
472 534 }
473 public int getNoOfCompleteAnswers() { 535
474 return soundAnswerTuples.size() + gapAnswerTuples.size(); 536 public void updateSubID() {
475 } 537 if(isDisposed()) throw new DisposedException();
476 538
477 public int getSubID() { 539 ++subID;
478 return subID; 540 stringQueryID = String.valueOf(queryID) + "_" + subID;
479 } 541 }
480 542
481 public boolean hasSameGapAnswers(QueryRecord that) { 543 public DLClause getClause() {
482 return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples); 544 if(isDisposed()) throw new DisposedException();
483 } 545
484 546 if(queryClause != null)
485 public void dispose() { 547 return queryClause;
486 m_manager.remove(queryText); 548 return queryClause = DLClauseHelper.getQuery(queryText, null);
487 if(gapAnswerTuples != null) gapAnswerTuples = null; 549 }
488 if(soundAnswerTuples != null) soundAnswerTuples = null; 550
489 if (relevantClauses != null) relevantClauses.clear(); 551 public boolean isBottom() {
490 if (relevantOntology != null) 552 if(isDisposed()) throw new DisposedException();
491 relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology); 553
492 answerVariables = null; 554 return queryID == 0;
493 } 555 }
494 556
495 public boolean canBeEncodedIntoAtom() { 557 public int getNoOfCompleteAnswers() {
496 // FIXME 558 if(isDisposed()) throw new DisposedException();
497 return true; 559
560 return soundAnswerTuples.size() + gapAnswerTuples.size();
561 }
562
563 public int getSubID() {
564 if(isDisposed()) throw new DisposedException();
565
566 return subID;
567 }
568
569 public boolean hasSameGapAnswers(QueryRecord that) {
570 if(isDisposed()) throw new DisposedException();
571
572 return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples);
573 }
574
575 @Override
576 public void dispose() {
577 super.dispose();
578 m_manager.remove(queryText);
579 if(gapAnswerTuples != null) gapAnswerTuples = null;
580 if(soundAnswerTuples != null) soundAnswerTuples = null;
581 if(relevantClauses != null) relevantClauses.clear();
582 if(relevantOntology != null)
583 relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology);
584 answerVariables = null;
585 }
586
587 public boolean canBeEncodedIntoAtom() {
588 if(isDisposed()) throw new DisposedException();
589
590 // FIXME
591 return true;
498// return false; 592// return false;
499 } 593 }
500 594
501 public boolean isPredicate(AnswerTuple a, int i) { 595 public boolean isPredicate(AnswerTuple a, int i) {
502 Atom[] atoms = getClause().getBodyAtoms(); 596 if(isDisposed()) throw new DisposedException();
503 Variable v = Variable.create(answerVariables[1][i]); 597
504 String iri; 598 Atom[] atoms = getClause().getBodyAtoms();
505 for(Atom atom : atoms) { 599 Variable v = Variable.create(answerVariables[1][i]);
506 DLPredicate p = atom.getDLPredicate(); 600 String iri;
507 if (p instanceof AtomicConcept) { 601 for(Atom atom : atoms) {
508 if(((AtomicConcept) p).getIRI().equals(v.toString())) return true; 602 DLPredicate p = atom.getDLPredicate();
509 } 603 if(p instanceof AtomicConcept) {
510 else if (p instanceof AtomicRole) { 604 if(((AtomicConcept) p).getIRI().equals(v.toString())) return true;
511 iri = ((AtomicRole) p).getIRI(); 605 }
512 if (iri.equals(v.toString())) return true; 606 else if(p instanceof AtomicRole) {
513 if(iri.startsWith("?")) 607 iri = ((AtomicRole) p).getIRI();
514 iri = a.getGroundTerm(i).toString(); 608 if(iri.equals(v.toString())) return true;
515 if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true; 609 if(iri.startsWith("?"))
516 } 610 iri = a.getGroundTerm(i).toString();
517 } 611 if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true;
518 return false; 612 }
519 } 613 }
520 614 return false;
521 // TODO remove fully extended query 615 }
522 public Tuple<String> getExtendedQueryText() { 616
617 // TODO remove fully extended query
618 public Tuple<String> getExtendedQueryText() {
619 if(isDisposed()) throw new DisposedException();
620
523// String[] ret = new String[2];s 621// String[] ret = new String[2];s
524 int index = queryText.toUpperCase().indexOf(" WHERE"); 622 int index = queryText.toUpperCase().indexOf(" WHERE");
525 String extendedSelect = queryText.substring(0, index); 623 String extendedSelect = queryText.substring(0, index);
526 String extendedWhere= queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1); 624 String extendedWhere = queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1);
527 625
528 String sub, obj; 626 String sub, obj;
529 Map<String, Set<String>> links = new HashMap<String, Set<String>>(); 627 Map<String, Set<String>> links = new HashMap<String, Set<String>>();
530 Set<String> list; 628 Set<String> list;
531 for (Atom atom: getClause().getBodyAtoms()) 629 for(Atom atom : getClause().getBodyAtoms())
532 if (atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { 630 if(atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) {
533 sub = atom.getArgumentVariable(0).getName(); 631 sub = atom.getArgumentVariable(0).getName();
534 obj = atom.getArgumentVariable(1).getName(); 632 obj = atom.getArgumentVariable(1).getName();
535 if((list = links.get(sub)) == null) 633 if((list = links.get(sub)) == null)
536 links.put(sub, list = new HashSet<String>()); 634 links.put(sub, list = new HashSet<String>());
537 list.add(obj); 635 list.add(obj);
538 if((list = links.get(obj)) == null) 636 if((list = links.get(obj)) == null)
539 links.put(obj, list = new HashSet<String>()); 637 links.put(obj, list = new HashSet<String>());
540 list.add(sub); 638 list.add(sub);
541 } 639 }
542 640
543 StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder(); 641 StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder();
544// if (answerVariables[0] != answerVariables[1]) { 642// if (answerVariables[0] != answerVariables[1]) {
545 for (int i = answerVariables[0].length; i < answerVariables[1].length; ++i) { 643 for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) {
546// for (int i = 0; i < answerVariables[1].length; ++i) { 644// for (int i = 0; i < answerVariables[1].length; ++i) {
547 fullyExtra.append(" . ?") 645 fullyExtra.append(" . ?")
548 .append(answerVariables[1][i]) 646 .append(answerVariables[1][i])
549 .append(" " + RDF_TYPE + " <") 647 .append(" " + RDF_TYPE + " <")
550 .append(Namespace.PAGODA_ORIGINAL) 648 .append(Namespace.PAGODA_ORIGINAL)
551 .append(">"); 649 .append(">");
552 if ((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ; 650 if((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ;
553 else { 651 else {
554 extra.append(" . ?") 652 extra.append(" . ?")
555 .append(answerVariables[1][i]) 653 .append(answerVariables[1][i])
556 .append(" " + RDF_TYPE + " <") 654 .append(" " + RDF_TYPE + " <")
557 .append(Namespace.PAGODA_ORIGINAL) 655 .append(Namespace.PAGODA_ORIGINAL)
558 .append(">"); 656 .append(">");
559 } 657 }
560 } 658 }
561 659
562 if(extra.length() > 0) { 660 if(extra.length() > 0) {
563 extra.append(" }"); 661 extra.append(" }");
564 extendedWhere = extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString()); 662 extendedWhere =
565 } 663 extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString());
566 664 }
567 if(fullyExtra.length() > 0) { 665
568 fullyExtra.append(" }"); 666 if(fullyExtra.length() > 0) {
569 fullyExtendedWhere = fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra.toString()); 667 fullyExtra.append(" }");
570 } 668 fullyExtendedWhere =
669 fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra
670 .toString());
671 }
571// } 672// }
572 673
573 TupleBuilder result = new TupleBuilder(); 674 TupleBuilder result = new TupleBuilder();
574 result.append(extendedSelect + " " + fullyExtendedWhere); 675 result.append(extendedSelect + " " + fullyExtendedWhere);
575 676
576 extra.setLength(0); 677 extra.setLength(0);
577 if (answerVariables[0] != answerVariables[1]) { 678 if(answerVariables[0] != answerVariables[1]) {
578 for (int i = answerVariables[0].length; i < answerVariables[1].length; ++i) 679 for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i)
579 extra.append(" ?").append(answerVariables[1][i]); 680 extra.append(" ?").append(answerVariables[1][i]);
580 extendedSelect = extendedSelect + extra.toString(); 681 extendedSelect = extendedSelect + extra.toString();
581 } 682 }
582 result.append(extendedSelect + " " + extendedWhere); 683 result.append(extendedSelect + " " + extendedWhere);
583 684
584 return result.build(); 685 return result.build();
585 } 686 }
586 687
587 public boolean hasNonAnsDistinguishedVariables() { 688 public boolean hasNonAnsDistinguishedVariables() {
588 return answerVariables[1].length > answerVariables[0].length; 689 if(isDisposed()) throw new DisposedException();
589 } 690
590 691 return answerVariables[1].length > answerVariables[0].length;
591 /** 692 }
592 * Two <tt>QueryRecords</tt> are equal iff 693
593 * they have the same <tt>queryText</tt>, 694 /**
594 * <tt>soundAnswerTuples</tt>. 695 * Two <tt>QueryRecords</tt> are equal iff
595 */ 696 * they have the same <tt>queryText</tt>,
596 @Override 697 * <tt>soundAnswerTuples</tt>.
597 public boolean equals(Object o) { 698 */
598 if(!o.getClass().equals(getClass())) return false; 699 @Override
599 QueryRecord that = (QueryRecord) o; 700 public boolean equals(Object o) {
600 return this.queryText.equals(that.queryText) 701 if(isDisposed()) throw new DisposedException();
601 && soundAnswerTuples.equals(that.soundAnswerTuples); 702
602 } 703 if(!o.getClass().equals(getClass())) return false;
603 704 QueryRecord that = (QueryRecord) o;
604 @Override 705 return this.queryText.equals(that.queryText)
605 public int hashCode() { 706 && soundAnswerTuples.equals(that.soundAnswerTuples);
606 return Objects.hash(queryText, soundAnswerTuples); 707 }
607 } 708
608 709 @Override
609 public enum Step { 710 public int hashCode() {
610 LOWER_BOUND, 711 if(isDisposed()) throw new DisposedException();
611 UPPER_BOUND, 712
612 SIMPLE_UPPER_BOUND, 713 return Objects.hash(queryText, soundAnswerTuples);
613 LAZY_UPPER_BOUND, 714 }
614 L_SKOLEM_UPPER_BOUND, 715
615 EL_LOWER_BOUND, 716 public enum Step {
616 FRAGMENT, 717 LOWER_BOUND,
617 FRAGMENT_REFINEMENT, 718 UPPER_BOUND,
618 SUMMARISATION, 719 SIMPLE_UPPER_BOUND,
619 DEPENDENCY, 720 LAZY_UPPER_BOUND,
620 FULL_REASONING 721 L_SKOLEM_UPPER_BOUND,
621 } 722 EL_LOWER_BOUND,
622 723 FRAGMENT,
623 /** 724 FRAGMENT_REFINEMENT,
624 * A Json serializer, which considers the main attributes. 725 SUMMARISATION,
625 */ 726 DEPENDENCY,
626 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> { 727 FULL_REASONING
627 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { 728 }
628 Gson gson = new GsonBuilder().setPrettyPrinting().create(); 729
629 JsonObject object = new JsonObject(); 730 /**
630 object.addProperty("queryID", src.queryID); 731 * A Json serializer, which considers the main attributes.
631 object.addProperty("queryText", src.queryText); 732 */
733 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> {
734 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) {
735 Gson gson = new GsonBuilder().setPrettyPrinting().create();
736 JsonObject object = new JsonObject();
737 object.addProperty("queryID", src.queryID);
738 object.addProperty("queryText", src.queryText);
632// object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : ""); 739// object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : "");
633 740
634 object.add("answerVariables", context.serialize(src.getAnswerVariables())); 741 object.add("answerVariables", context.serialize(src.getAnswerVariables()));
635 object.add("answers", context.serialize(src.soundAnswerTuples)); 742 object.add("answers", context.serialize(src.soundAnswerTuples));
636// object.add("gapAnswers", context.serialize(src.gapAnswerTuples)); 743// object.add("gapAnswers", context.serialize(src.gapAnswerTuples));
637 744
638 return object; 745 return object;
639 } 746 }
640 } 747 }
641 748
642 /** 749 /**
643 * A Json deserializer, compliant to the output of the serializer defined above. 750 * A Json deserializer, compliant to the output of the serializer defined above.
644 */ 751 */
645 public static class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> { 752 public static class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> {
646 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 753 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
647 throws JsonParseException { 754 throws JsonParseException {
648 755
649 QueryRecord record = new QueryRecord(); 756 QueryRecord record = new QueryRecord();
650 JsonObject object = json.getAsJsonObject(); 757 JsonObject object = json.getAsJsonObject();
651 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); 758 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt();
652 record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); 759 record.queryText = object.getAsJsonPrimitive("queryText").getAsString();
653// record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString()); 760// record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString());
654 761
655 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); 762 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables");
656 record.answerVariables = new String[2][]; 763 record.answerVariables = new String[2][];
657 record.answerVariables[0] = new String[answerVariablesJson.size()]; 764 record.answerVariables[0] = new String[answerVariablesJson.size()];
658 for(int i = 0; i < answerVariablesJson.size(); i++) 765 for(int i = 0; i < answerVariablesJson.size(); i++)
659 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); 766 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString();
660 767
661 record.soundAnswerTuples = new HashSet<>(); 768 record.soundAnswerTuples = new HashSet<>();
662// record.gapAnswerTuples = new HashSet<>(); 769// record.gapAnswerTuples = new HashSet<>();
663 Type type = new TypeToken<AnswerTuple>() { }.getType(); 770 Type type = new TypeToken<AnswerTuple>() {
664 for (JsonElement answer : object.getAsJsonArray("answers")) { 771 }.getType();
665 record.soundAnswerTuples.add(context.deserialize(answer, type)); 772 for(JsonElement answer : object.getAsJsonArray("answers")) {
666 } 773 record.soundAnswerTuples.add(context.deserialize(answer, type));
774 }
667// for (JsonElement answer : object.getAsJsonArray("gapAnswers")) { 775// for (JsonElement answer : object.getAsJsonArray("gapAnswers")) {
668// record.soundAnswerTuples.add(context.deserialize(answer, type)); 776// record.soundAnswerTuples.add(context.deserialize(answer, type));
669// } 777// }
670 778
671 return record; 779 return record;
672 } 780 }
673 } 781 }
674 782
675 /** 783 /**
676 * Provides an instance (singleton) of Gson, having a specific configuration. 784 * Provides an instance (singleton) of Gson, having a specific configuration.
677 * */ 785 */
678 public static class GsonCreator { 786 public static class GsonCreator {
679 787
680 private static Gson gson; 788 private static Gson gson;
681 789
682 private GsonCreator() {} 790 private GsonCreator() {
683 791 }
684 public static Gson getInstance() { 792
685 if(gson == null) { 793 public static Gson getInstance() {
686 gson = new GsonBuilder() 794 if(gson == null) {
687 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer()) 795 gson = new GsonBuilder()
688 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer()) 796 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer())
689 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer()) 797 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer())
690 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer()) 798 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer())
691 .disableHtmlEscaping() 799 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer())
692 .setPrettyPrinting() 800 .disableHtmlEscaping()
693 .create(); 801 .setPrettyPrinting()
694 } 802 .create();
695 return gson; 803 }
696 } 804 return gson;
805 }
697 806
698// public static void dispose() { 807// public static void dispose() {
699// gson = null; 808// gson = null;
700// } 809// }
701 810
702 } 811 }
703} 812}