diff options
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/query')
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/query/QueryRecord.java | 157 |
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; | |||
| 9 | import uk.ac.ox.cs.pagoda.rules.GeneralProgram; | 9 | import uk.ac.ox.cs.pagoda.rules.GeneralProgram; |
| 10 | import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; | 10 | import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; |
| 11 | import uk.ac.ox.cs.pagoda.util.Namespace; | 11 | import uk.ac.ox.cs.pagoda.util.Namespace; |
| 12 | import uk.ac.ox.cs.pagoda.util.PagodaProperties; | ||
| 12 | import uk.ac.ox.cs.pagoda.util.Utility; | 13 | import uk.ac.ox.cs.pagoda.util.Utility; |
| 13 | import uk.ac.ox.cs.pagoda.util.tuples.Tuple; | 14 | import uk.ac.ox.cs.pagoda.util.tuples.Tuple; |
| 14 | import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; | 15 | import 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 | } |
