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/AnswerTuple.java2
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/QueryRecord.java116
2 files changed, 47 insertions, 71 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
index 9a9d0de..1e5fbd4 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
@@ -49,7 +49,7 @@ public class AnswerTuple {
49 /** 49 /**
50 * It returns the first argument if its arity equals length, a new AnswerTuple otherwise. 50 * It returns the first argument if its arity equals length, a new AnswerTuple otherwise.
51 */ 51 */
52 public static AnswerTuple getInstance(AnswerTuple extendedTuple, int length) { 52 public static AnswerTuple create(AnswerTuple extendedTuple, int length) {
53 if(length == extendedTuple.getArity()) return extendedTuple; 53 if(length == extendedTuple.getArity()) return extendedTuple;
54 else return new AnswerTuple(extendedTuple, length); 54 else return new AnswerTuple(extendedTuple, length);
55 } 55 }
diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
index 3edb2c3..dee2966 100644
--- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
+++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
@@ -9,7 +9,6 @@ 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;
13import uk.ac.ox.cs.pagoda.util.Utility; 12import uk.ac.ox.cs.pagoda.util.Utility;
14import uk.ac.ox.cs.pagoda.util.disposable.Disposable; 13import uk.ac.ox.cs.pagoda.util.disposable.Disposable;
15import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; 14import uk.ac.ox.cs.pagoda.util.disposable.DisposedException;
@@ -135,18 +134,6 @@ public class QueryRecord extends Disposable {
135 return updateUpperBoundAnswers(answerTuples, false); 134 return updateUpperBoundAnswers(answerTuples, false);
136 } 135 }
137 136
138 public boolean checkUpperBoundAnswers(AnswerTuples answerTuples) {
139 if(isDisposed()) throw new DisposedException();
140
141 return updateUpperBoundAnswers(answerTuples, true, false);
142 }
143
144 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
145 if(isDisposed()) throw new DisposedException();
146
147 return updateUpperBoundAnswers(answerTuples, toCheckAux, true);
148 }
149
150 public int getNumberOfAnswers() { 137 public int getNumberOfAnswers() {
151 if(isDisposed()) throw new DisposedException(); 138 if(isDisposed()) throw new DisposedException();
152 139
@@ -377,7 +364,7 @@ public class QueryRecord extends Disposable {
377 Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); 364 Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound.");
378 gapAnswerTuples.remove(answer); 365 gapAnswerTuples.remove(answer);
379 366
380 answer = AnswerTuple.getInstance(answer, answerVariables[0].length); 367 answer = AnswerTuple.create(answer, answerVariables[0].length);
381// if (soundAnswerTuples.contains(answer)) 368// if (soundAnswerTuples.contains(answer))
382// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound."); 369// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound.");
383 soundAnswerTuples.add(answer); 370 soundAnswerTuples.add(answer);
@@ -556,7 +543,6 @@ public class QueryRecord extends Disposable {
556 return false; 543 return false;
557 } 544 }
558 545
559 // TODO remove fully extended query
560 public Tuple<String> getExtendedQueryText() { 546 public Tuple<String> getExtendedQueryText() {
561 if(isDisposed()) throw new DisposedException(); 547 if(isDisposed()) throw new DisposedException();
562 548
@@ -655,75 +641,65 @@ public class QueryRecord extends Disposable {
655 return Objects.hash(queryText, soundAnswerTuples); 641 return Objects.hash(queryText, soundAnswerTuples);
656 } 642 }
657 643
658 private boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux, boolean _check_containment) { 644 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
659 if(!(answerTuples instanceof RDFoxAnswerTuples)) { 645 RDFoxAnswerTuples rdfAnswerTuples;
660 String msg = "The upper bound must be computed by RDFox!"; 646 if(answerTuples instanceof RDFoxAnswerTuples)
661 Utility.logError(msg); 647 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples;
662 throw new IllegalArgumentException(msg); 648 else {
649 Utility.logError("The upper bound must be computed by RDFox!");
650 return false;
663 } 651 }
664 652
665 RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples; 653 if(soundAnswerTuples.size() > 0) {
654 int number = 0;
655 for(; answerTuples.isValid(); answerTuples.moveNext()) {
656 ++number;
657 }
658 Utility.logDebug("The number of answers returned by an upper bound: " + number);
659 if(number <= soundAnswerTuples.size()) {
660 if(gapAnswerTuples != null) gapAnswerTuples.clear();
661 else gapAnswerTuples = new HashSet<AnswerTuple>();
666 662
667 Set<AnswerTuple> candidateGapAnswerTuples = new HashSet<AnswerTuple>(); 663 Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
668 AnswerTuple tuple; 664 return false;
669 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { 665 }
670 tuple = rdfoxAnswerTuples.getTuple(); 666 answerTuples.reset();
671 if(isBottom() || !tuple.hasAnonymousIndividual())
672 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple))
673 candidateGapAnswerTuples.add(tuple);
674 } 667 }
675 668
676 /*** START: debugging ***/ 669 boolean justCheck = (answerTuples.getArity() != answerVariables[1].length);
677 if(PagodaProperties.isDebuggingMode() && _check_containment) { 670
678 if(rdfoxAnswerTuples.getArity() != getAnswerVariables().length) 671 Set<AnswerTuple> tupleSet = new HashSet<AnswerTuple>();
679 throw new IllegalArgumentException( 672 AnswerTuple tuple, extendedTuple;
680 "The arity of answers (" + rdfoxAnswerTuples.getArity() + ") " + 673 for(; answerTuples.isValid(); answerTuples.moveNext()) {
681 "is different from the number of answer variables (" + 674 extendedTuple = rdfAnswerTuples.getTuple();
682 getAnswerVariables().length + ")"); 675 if(isBottom() || !extendedTuple.hasAnonymousIndividual()) {
683 676 tuple = AnswerTuple.create(extendedTuple, answerVariables[0].length);
684 Set<AnswerTuple> namedAnswerTuples = new HashSet<>(); 677 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) {
685 rdfoxAnswerTuples.reset(); 678 if(!toCheckAux && justCheck) return false;
686 int numberOfAnswers = 0; 679 tupleSet.add(extendedTuple);
687 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { 680 }
688 tuple = rdfoxAnswerTuples.getTuple();
689// if(isBottom() || !tuple.hasAnonymousIndividual()) {
690 namedAnswerTuples.add(tuple);
691// }
692 numberOfAnswers++;
693 } 681 }
694 Utility.logDebug("The number of answers returned by an upper bound: " + numberOfAnswers);
695 HashSet<AnswerTuple> difference = new HashSet<>(soundAnswerTuples);
696 difference.removeAll(namedAnswerTuples);
697 if(!difference.isEmpty())
698 throw new IllegalArgumentException("The upper bound does not contain the lower bound! Missing answers: " + difference
699 .size());
700 } 682 }
701 /*** END: debugging ***/
702 683
703 boolean update;
704 if(gapAnswerTuples == null) { 684 if(gapAnswerTuples == null) {
705 gapAnswerTuples = candidateGapAnswerTuples; 685 gapAnswerTuples = tupleSet;
706 update = true; 686
687 Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
688 return true;
707 } 689 }
708 else { 690
709 update = gapAnswerTuples.retainAll(candidateGapAnswerTuples); 691 boolean update = false;
692 for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) {
693 tuple = iter.next();
694 if(!tupleSet.contains(tuple)) {
695 iter.remove();
696 update = true;
697 }
710 } 698 }
711 699
712 if(update) 700 Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
713 Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers());
714 else
715 Utility.logInfo("Upper bound answers unchanged");
716 701
717 return update; 702 return update;
718
719// boolean update = false;
720// for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) {
721// tuple = iter.next();
722// if(!candidateGapAnswerTuples.contains(tuple)) {
723// iter.remove();
724// update = true;
725// }
726// }
727 } 703 }
728 704
729 public enum Step { 705 public enum Step {