diff options
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/query')
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java | 2 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/query/QueryRecord.java | 116 |
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; | |||
| 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; | ||
| 13 | import uk.ac.ox.cs.pagoda.util.Utility; | 12 | import uk.ac.ox.cs.pagoda.util.Utility; |
| 14 | import uk.ac.ox.cs.pagoda.util.disposable.Disposable; | 13 | import uk.ac.ox.cs.pagoda.util.disposable.Disposable; |
| 15 | import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; | 14 | import 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 { |
