aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/query
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/query')
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/QueryRecord.java157
1 files changed, 100 insertions, 57 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
index 4998a19..1ecd867 100644
--- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
+++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
@@ -9,6 +9,7 @@ import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxAnswerTuples;
9import uk.ac.ox.cs.pagoda.rules.GeneralProgram; 9import uk.ac.ox.cs.pagoda.rules.GeneralProgram;
10import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; 10import 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.Utility; 13import uk.ac.ox.cs.pagoda.util.Utility;
13import uk.ac.ox.cs.pagoda.util.tuples.Tuple; 14import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
14import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; 15import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder;
@@ -101,7 +102,13 @@ public class QueryRecord {
101 update = true; 102 update = true;
102 } 103 }
103 } 104 }
104 Utility.logInfo("The number of answers in the lower bound: " + soundAnswerTuples.size()); 105
106 if(soundAnswerTuples.isEmpty())
107 Utility.logInfo("Lower bound answers empty");
108 else if(update)
109 Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size());
110 else
111 Utility.logInfo("Lower bound answers unchanged");
105 112
106 return update; 113 return update;
107 } 114 }
@@ -111,69 +118,98 @@ public class QueryRecord {
111 } 118 }
112 119
113 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { 120 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
114 RDFoxAnswerTuples rdfAnswerTuples; 121 if(!(answerTuples instanceof RDFoxAnswerTuples)) {
115 if(answerTuples instanceof RDFoxAnswerTuples) 122 String msg = "The upper bound must be computed by RDFox!";
116 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples; 123 Utility.logError(msg);
117 else { 124 throw new IllegalArgumentException(msg);
118 Utility.logError("The upper bound must be computed by RDFox!");
119 return false;
120 } 125 }
121 126
122 if(soundAnswerTuples.size() > 0) { 127 RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples;
123 int number = 0;
124 for(; rdfAnswerTuples.isValid(); rdfAnswerTuples.moveNext()) {
125 ++number;
126 }
127 Utility.logInfo("The number of answers returned by an upper bound: " + number);
128 if(number == soundAnswerTuples.size()) {
129 if(gapAnswerTuples != null) gapAnswerTuples.clear();
130 else gapAnswerTuples = new HashSet<AnswerTuple>();
131 128
132 Utility.logInfo("The number of upper bound answers: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 129// if(soundAnswerTuples.size() > 0) {
133 return false; 130// int number = 0;
134 } else if(number < soundAnswerTuples.size()) 131// for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
135 throw new IllegalArgumentException("The upper bound answers must contain all the lower bound ones!"); 132// ++number;
136 rdfAnswerTuples.reset(); 133// }
137 } 134// Utility.logInfo("The number of answers returned by an upper bound: " + number);
135// if(number == soundAnswerTuples.size()) {
136// if(gapAnswerTuples != null) gapAnswerTuples.clear();
137// else gapAnswerTuples = new HashSet<AnswerTuple>();
138//
139// Utility.logInfo("The number of upper bound answers: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
140// return false;
141// } else if(number < soundAnswerTuples.size())
142// throw new IllegalArgumentException("The upper bound answers must contain all the lower bound ones!");
143// rdfoxAnswerTuples.reset();
144// }
138 145
139 boolean justCheck = (rdfAnswerTuples.getArity() != answerVariables[1].length); 146// boolean justCheck = (rdfoxAnswerTuples.getArity() < getDistinguishedVariables().length);
147// boolean justCheck = (rdfoxAnswerTuples.getArity() != getDistinguishedVariables().length);
148// if(justCheck) throw new Error("justCheck!");
149 boolean justCheck = false;
140 150
141 Set<AnswerTuple> tupleSet = new HashSet<AnswerTuple>(); 151 Set<AnswerTuple> candidateGapAnswerTuples = new HashSet<AnswerTuple>();
142 AnswerTuple tuple, extendedTuple; 152 AnswerTuple tuple, extendedTuple;
143 for(; rdfAnswerTuples.isValid(); rdfAnswerTuples.moveNext()) { 153 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
144 extendedTuple = rdfAnswerTuples.getTuple(); 154 extendedTuple = rdfoxAnswerTuples.getTuple();
145 if(isBottom() || !extendedTuple.hasAnonymousIndividual()) { 155 if(isBottom() || !extendedTuple.hasAnonymousIndividual()) {
146 tuple = AnswerTuple.create(extendedTuple, answerVariables[0].length); 156 tuple = AnswerTuple.create(extendedTuple, getAnswerVariables().length);
147 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) { 157 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) {
148 if(!toCheckAux && justCheck) return false; 158 if(!toCheckAux && justCheck) return false;
149 // TODO check 159 // TODO check
150// tupleSet.add(extendedTuple); 160 candidateGapAnswerTuples.add(extendedTuple);
151 tupleSet.add(tuple); 161// candidateGapAnswerTuples.add(tuple);
152 } 162 }
153 } 163 }
154 } 164 }
155 165
156 if(gapAnswerTuples == null) { 166 /*** START: debugging ***/
157 gapAnswerTuples = tupleSet; 167 if(PagodaProperties.isDebuggingMode()) {
158 168 Set<AnswerTuple> projectedAnswerTuples = new HashSet<>();
159 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 169 rdfoxAnswerTuples.reset();
160 return true; 170 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
171 extendedTuple = rdfoxAnswerTuples.getTuple();
172 if(isBottom() || !extendedTuple.hasAnonymousIndividual()) {
173 tuple = AnswerTuple.create(extendedTuple, getAnswerVariables().length);
174 projectedAnswerTuples.add(tuple);
175 }
176 }
177 HashSet<AnswerTuple> difference = new HashSet<>(soundAnswerTuples);
178 difference.removeAll(projectedAnswerTuples);
179 if(!difference.isEmpty())
180 throw new IllegalArgumentException("The upper bound does not contain the lower bound!");
161 } 181 }
182 /*** END: debugging ***/
162 183
163 boolean update = false; 184 boolean update;
164 for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) { 185 if(gapAnswerTuples == null) {
165 tuple = iter.next(); 186 gapAnswerTuples = candidateGapAnswerTuples;
166 if(!tupleSet.contains(tuple)) { 187 update = true;
167 iter.remove(); 188 } else {
168 update = true; 189 update = gapAnswerTuples.retainAll(candidateGapAnswerTuples);
169 }
170 } 190 }
171 191
172 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 192 if(update)
193 Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers());
194 else
195 Utility.logInfo("Upper bound answers unchanged");
173 196
174 return update; 197 return update;
198
199// boolean update = false;
200// for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) {
201// tuple = iter.next();
202// if(!candidateGapAnswerTuples.contains(tuple)) {
203// iter.remove();
204// update = true;
205// }
206// }
175 } 207 }
176 208
209 public int getNumberOfAnswers() {
210 return soundAnswerTuples.size() + gapAnswerTuples.size();
211 }
212
177 public void markAsProcessed() { 213 public void markAsProcessed() {
178 processed = true; 214 processed = true;
179 } 215 }
@@ -567,26 +603,33 @@ public class QueryRecord {
567 /** 603 /**
568 * Two <tt>QueryRecords</tt> are equal iff 604 * Two <tt>QueryRecords</tt> are equal iff
569 * they have the same <tt>queryText</tt>, 605 * they have the same <tt>queryText</tt>,
570 * <tt>soundAnswerTuples</tt> 606 * <tt>soundAnswerTuples</tt>.
571 * and <tt>gapAnswerTuples</tt>.
572 */ 607 */
573 @Override 608 @Override
574 public boolean equals(Object o) { 609 public boolean equals(Object o) {
575 if(!o.getClass().equals(getClass())) return false; 610 if(!o.getClass().equals(getClass())) return false;
576 QueryRecord that = (QueryRecord) o; 611 QueryRecord that = (QueryRecord) o;
577 return this.queryText.equals(that.queryText) 612 return this.queryText.equals(that.queryText)
578 && soundAnswerTuples.equals(that.soundAnswerTuples) 613 && soundAnswerTuples.equals(that.soundAnswerTuples);
579 && gapAnswerTuples.equals(that.gapAnswerTuples);
580 } 614 }
581 615
582 @Override 616 @Override
583 public int hashCode() { 617 public int hashCode() {
584 return Objects.hash(queryText, soundAnswerTuples, gapAnswerTuples); 618 return Objects.hash(queryText, soundAnswerTuples);
585 } 619 }
586 620
587 public enum Step { 621 public enum Step {
588 LowerBound, UpperBound, ELLowerBound, 622 LOWER_BOUND,
589 Fragment, FragmentRefinement, Summarisation, Dependency, FullReasoning 623 UPPER_BOUND,
624 SIMPLE_UPPER_BOUND,
625 LAZY_UPPER_BOUND,
626 L_SKOLEM_UPPER_BOUND,
627 EL_LOWER_BOUND,
628 FRAGMENT,
629 FRAGMENT_REFINEMENT,
630 SUMMARISATION,
631 DEPENDENCY,
632 FULL_REASONING
590 } 633 }
591 634
592 /** 635 /**
@@ -598,11 +641,11 @@ public class QueryRecord {
598 JsonObject object = new JsonObject(); 641 JsonObject object = new JsonObject();
599 object.addProperty("queryID", src.queryID); 642 object.addProperty("queryID", src.queryID);
600 object.addProperty("queryText", src.queryText); 643 object.addProperty("queryText", src.queryText);
601 object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : ""); 644// object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : "");
602 645
603 object.add("answerVariables", context.serialize(src.getAnswerVariables())); 646 object.add("answerVariables", context.serialize(src.getAnswerVariables()));
604 object.add("answers", context.serialize(src.soundAnswerTuples)); 647 object.add("answers", context.serialize(src.soundAnswerTuples));
605 object.add("gapAnswers", context.serialize(src.gapAnswerTuples)); 648// object.add("gapAnswers", context.serialize(src.gapAnswerTuples));
606 649
607 return object; 650 return object;
608 } 651 }
@@ -619,7 +662,7 @@ public class QueryRecord {
619 JsonObject object = json.getAsJsonObject(); 662 JsonObject object = json.getAsJsonObject();
620 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); 663 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt();
621 record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); 664 record.queryText = object.getAsJsonPrimitive("queryText").getAsString();
622 record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString()); 665// record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString());
623 666
624 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); 667 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables");
625 record.answerVariables = new String[2][]; 668 record.answerVariables = new String[2][];
@@ -628,14 +671,14 @@ public class QueryRecord {
628 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); 671 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString();
629 672
630 record.soundAnswerTuples = new HashSet<>(); 673 record.soundAnswerTuples = new HashSet<>();
631 record.gapAnswerTuples = new HashSet<>(); 674// record.gapAnswerTuples = new HashSet<>();
632 Type type = new TypeToken<AnswerTuple>() { }.getType(); 675 Type type = new TypeToken<AnswerTuple>() { }.getType();
633 for (JsonElement answer : object.getAsJsonArray("answers")) { 676 for (JsonElement answer : object.getAsJsonArray("answers")) {
634 record.soundAnswerTuples.add(context.deserialize(answer, type)); 677 record.soundAnswerTuples.add(context.deserialize(answer, type));
635 } 678 }
636 for (JsonElement answer : object.getAsJsonArray("gapAnswers")) { 679// for (JsonElement answer : object.getAsJsonArray("gapAnswers")) {
637 record.soundAnswerTuples.add(context.deserialize(answer, type)); 680// record.soundAnswerTuples.add(context.deserialize(answer, type));
638 } 681// }
639 682
640 return record; 683 return record;
641 } 684 }