aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/log4j.properties1
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java65
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java9
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/QueryRecord.java98
-rw-r--r--src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java36
-rw-r--r--src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java12
-rw-r--r--src/uk/ac/ox/cs/pagoda/util/Utility.java15
-rw-r--r--test/AllTests.xml6
-rw-r--r--test/uk/ac/ox/cs/pagoda/test_units/PagodaLUBM.java2
-rw-r--r--test/uk/ac/ox/cs/pagoda/test_units/PagodaUOBM.java2
-rw-r--r--test/uk/ac/ox/cs/pagoda/test_units/TestGlobalCorrectness.java27
-rw-r--r--test/uk/ac/ox/cs/pagoda/tester/PagodaTester.java6
-rw-r--r--test/uk/ac/ox/cs/pagoda/util/TestUtil.java3
13 files changed, 183 insertions, 99 deletions
diff --git a/config/log4j.properties b/config/log4j.properties
index 25da4d4..95d64a0 100644
--- a/config/log4j.properties
+++ b/config/log4j.properties
@@ -16,3 +16,4 @@ log4j.appender.FILE.MaxBackupIndex=3
16log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 16log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
17log4j.appender.FILE.layout.conversionPattern=%m%n 17log4j.appender.FILE.layout.conversionPattern=%m%n
18log4j.appender.FILE.append=false 18log4j.appender.FILE.append=false
19log4j.appender.FILE.Threshold=DEBUG
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
index 183cbe1..cd86282 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
@@ -15,6 +15,9 @@ import uk.ac.ox.cs.pagoda.util.Namespace;
15import java.lang.reflect.Type; 15import java.lang.reflect.Type;
16import java.util.HashMap; 16import java.util.HashMap;
17import java.util.Map; 17import java.util.Map;
18import java.util.StringTokenizer;
19import java.util.regex.Matcher;
20import java.util.regex.Pattern;
18 21
19public class AnswerTuple { 22public class AnswerTuple {
20 23
@@ -42,31 +45,31 @@ public class AnswerTuple {
42 for (int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i]; 45 for (int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i];
43 } 46 }
44 47
45 private AnswerTuple(String m_str) { 48// private AnswerTuple(String m_str) {
46 this.m_str = m_str; 49// this.m_str = m_str;
47 } 50// }
48 51
49 public int getArity() { 52 public int getArity() {
50 return m_tuple.length; 53 return m_tuple.length;
51 } 54 }
52 55
53 public int hashCode() { 56 public int hashCode() {
54 return toString().hashCode(); 57// return toString().hashCode();
55// int code = 0; 58 int code = 0;
56// for (int i = 0; i < m_tuple.length; ++i) 59 for (int i = 0; i < m_tuple.length; ++i)
57// code = code * 1997 + m_tuple[i].hashCode(); 60 code = code * 1997 + m_tuple[i].hashCode();
58// return code; 61 return code;
59 } 62 }
60 63
61 public boolean equals(Object obj) { 64 public boolean equals(Object obj) {
62 if (!(obj instanceof AnswerTuple)) return false; 65 if (!(obj instanceof AnswerTuple)) return false;
63 AnswerTuple that = (AnswerTuple) obj; 66 AnswerTuple that = (AnswerTuple) obj;
64 if (m_tuple.length != that.m_tuple.length) return false; 67 if (m_tuple.length != that.m_tuple.length) return false;
65 for (int i = 0; i < m_tuple.length; ++i) 68 for (int i = 0; i < m_tuple.length; ++i)
66 if (!m_tuple[i].equals(that.m_tuple[i])) 69 if (!m_tuple[i].equals(that.m_tuple[i]))
67 return false; 70 return false;
68 return true; 71 return true;
69// return toString().equals(obj.toString()); 72// return toString().equals(obj.toString());
70 } 73 }
71 74
72 public String toString() { 75 public String toString() {
@@ -77,7 +80,7 @@ public class AnswerTuple {
77 if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual) 80 if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)
78 sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">"); 81 sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">");
79 else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) { 82 else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) {
80 sb.append(((uk.ac.ox.cs.JRDFox.model.BlankNode) m_tuple[i]).toString()); 83 sb.append(m_tuple[i].toString());
81 } 84 }
82 else { 85 else {
83 Literal l = (Literal) m_tuple[i]; 86 Literal l = (Literal) m_tuple[i];
@@ -146,10 +149,40 @@ public class AnswerTuple {
146 149
147 } 150 }
148 151
149 public class AnswerTupleDeserializer implements JsonDeserializer<AnswerTuple> { 152 static final Pattern owlLiteralRegex = Pattern.compile("^\"(?<lexicalForm>[^@]+(@(?<langTag>.+))?)\"(^^<(?<dataType>.+)>)?$");
153
154 public static class AnswerTupleDeserializer implements JsonDeserializer<AnswerTuple> {
150 public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 155 public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
151 throws JsonParseException { 156 throws JsonParseException {
152 return new AnswerTuple(json.getAsJsonPrimitive().getAsString()); 157 String tuplesString = json.getAsJsonPrimitive().getAsString();
158 StringTokenizer tokenizer = new StringTokenizer(SEPARATOR);
159 GroundTerm[] terms = new GroundTerm[tokenizer.countTokens()];
160
161 // TODO test parsing
162 for (int i = 0; i < tokenizer.countTokens(); i++) {
163 String token = tokenizer.nextToken();
164 if (token.charAt(0) == '<') {
165 terms[i] = uk.ac.ox.cs.JRDFox.model.Individual.create(token.substring(1,token.length()-1));
166 }
167 else if (token.charAt(0) == '"') {
168 Matcher matcher = owlLiteralRegex.matcher(token);
169 if(matcher.matches()) {
170 String lexicalForm = matcher.group("lexicalForm");
171 String dataTypeIRI = matcher.group("dataType");
172 Datatype dataType;
173 if (dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL;
174 else dataType = uk.ac.ox.cs.JRDFox.model.Datatype.value(dataTypeIRI);
175 terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, dataType);
176 }
177 else {
178 throw new IllegalArgumentException("The given json does not represent a valid AnswerTuple");
179 }
180 }
181 else {
182 terms[i] = uk.ac.ox.cs.JRDFox.model.BlankNode.create(token);
183 }
184 }
185 return new AnswerTuple(terms);
153 } 186 }
154 } 187 }
155 188
diff --git a/src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java
new file mode 100644
index 0000000..3d25eaf
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java
@@ -0,0 +1,9 @@
1package uk.ac.ox.cs.pagoda.query;
2
3/*
4* A light version of QueryRecord,
5* which can be obtained easily from the Json serialization of QueryRecord.
6* */
7public class DeserializedQueryRecord {
8 // TODO implement
9}
diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
index 4b55046..6c87eb5 100644
--- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
+++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
@@ -19,7 +19,7 @@ public class QueryRecord {
19 19
20 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> }"; 20 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> }";
21 21
22 private Step diffculty; 22 private Step difficulty;
23 23
24 private String queryText; 24 private String queryText;
25 private int queryID = -1; 25 private int queryID = -1;
@@ -90,7 +90,7 @@ public class QueryRecord {
90 } 90 }
91 91
92 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { 92 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
93 RDFoxAnswerTuples rdfAnswerTuples; 93 RDFoxAnswerTuples rdfAnswerTuples;
94 if (answerTuples instanceof RDFoxAnswerTuples) 94 if (answerTuples instanceof RDFoxAnswerTuples)
95 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples; 95 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples;
96 else { 96 else {
@@ -125,7 +125,7 @@ public class QueryRecord {
125 if ((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) { 125 if ((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) {
126 if (!toCheckAux && justCheck) return false; 126 if (!toCheckAux && justCheck) return false;
127 tupleSet.add(extendedTuple); 127 tupleSet.add(extendedTuple);
128 } 128 }
129 } 129 }
130 } 130 }
131 131
@@ -146,7 +146,7 @@ public class QueryRecord {
146 } 146 }
147 147
148 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 148 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
149 149
150 return update; 150 return update;
151 } 151 }
152 152
@@ -292,11 +292,11 @@ public class QueryRecord {
292 } 292 }
293 293
294 public void setDifficulty(Step step) { 294 public void setDifficulty(Step step) {
295 this.diffculty = step; 295 this.difficulty = step;
296 } 296 }
297 297
298 public Step getDifficulty() { 298 public Step getDifficulty() {
299 return diffculty; 299 return difficulty;
300 } 300 }
301 301
302 OWLOntology relevantOntology = null; 302 OWLOntology relevantOntology = null;
@@ -567,14 +567,16 @@ public class QueryRecord {
567 return answerVariables[1].length > answerVariables[0].length; 567 return answerVariables[1].length > answerVariables[0].length;
568 } 568 }
569 569
570 /**
571 * A Json serializer, which considers the main attributes.
572 */
570 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> { 573 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> {
571
572 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { 574 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) {
573 Gson gson = new GsonBuilder().setPrettyPrinting().create(); 575 Gson gson = new GsonBuilder().setPrettyPrinting().create();
574 JsonObject object = new JsonObject(); 576 JsonObject object = new JsonObject();
575 object.addProperty("queryID", src.queryID); 577 object.addProperty("queryID", src.queryID);
576 object.addProperty("queryText", src.queryText); 578 object.addProperty("queryText", src.queryText);
577 object.addProperty("difficulty", src.diffculty.toString()); 579 object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : "");
578 580
579 object.add("answerVariables", context.serialize(src.getAnswerVariables())); 581 object.add("answerVariables", context.serialize(src.getAnswerVariables()));
580 object.add("answers", context.serialize(src.soundAnswerTuples)); 582 object.add("answers", context.serialize(src.soundAnswerTuples));
@@ -586,8 +588,10 @@ public class QueryRecord {
586 588
587 private QueryRecord() { } 589 private QueryRecord() { }
588 590
589 public class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> { 591 /**
590 592 * A Json deserializer, compliant to the output of the serializer defined above.
593 */
594 public static class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> {
591 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 595 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
592 throws JsonParseException { 596 throws JsonParseException {
593 597
@@ -595,6 +599,7 @@ public class QueryRecord {
595 JsonObject object = json.getAsJsonObject(); 599 JsonObject object = json.getAsJsonObject();
596 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); 600 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt();
597 record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); 601 record.queryText = object.getAsJsonPrimitive("queryText").getAsString();
602 record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString());
598 603
599 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); 604 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables");
600 record.answerVariables = new String[2][]; 605 record.answerVariables = new String[2][];
@@ -602,52 +607,63 @@ public class QueryRecord {
602 for(int i = 0; i < answerVariablesJson.size(); i++) 607 for(int i = 0; i < answerVariablesJson.size(); i++)
603 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); 608 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString();
604 609
605 record.soundAnswerTuples = context.deserialize(object.getAsJsonObject("answers"), 610 record.soundAnswerTuples = new HashSet<>();
606 new TypeToken<Set<AnswerTuple>>() {}.getType()); 611 record.gapAnswerTuples = new HashSet<>();
612 Type type = new TypeToken<AnswerTuple>() { }.getType();
613 for (JsonElement answer : object.getAsJsonArray("answers")) {
614 record.soundAnswerTuples.add(context.deserialize(answer, type));
615 }
616 for (JsonElement answer : object.getAsJsonArray("gapAnswers")) {
617 record.soundAnswerTuples.add(context.deserialize(answer, type));
618 }
607 619
608 record.gapAnswerTuples = context.deserialize(object.getAsJsonObject("gapAnswers"), 620 return record;
609 new TypeToken<Set<AnswerTuple>>() {}.getType());
610 return null;
611 } 621 }
612 } 622 }
613 623
614 /* 624 /**
615 * Two QueryRecords are equal iff 625 * Two <tt>QueryRecords</tt> are equal iff
616 * they have the same queryText and 626 * they have the same <tt>queryText</tt>,
617 * their AnswerTuples have the same string representation 627 * <tt>soundAnswerTuples</tt>
628 * and <tt>gapAnswerTuples</tt>.
618 * */ 629 * */
619 @Override 630 @Override
620 public boolean equals(Object o) { 631 public boolean equals(Object o) {
621 if(!o.getClass().equals(getClass())) return false; 632 if(!o.getClass().equals(getClass())) return false;
622 QueryRecord that = (QueryRecord) o; 633 QueryRecord that = (QueryRecord) o;
634 return this.queryText.equals(that.queryText)
635 && soundAnswerTuples.equals(that.soundAnswerTuples)
636 && gapAnswerTuples.equals(that.gapAnswerTuples);
637 }
623 638
624 if(!this.queryText.equals(that.queryText)) return false; 639 @Override
625 640 public int hashCode() {
626 if(soundAnswerTuples.size() != that.soundAnswerTuples.size()) return false; 641 return Objects.hash(queryText, soundAnswerTuples, gapAnswerTuples);
627 if(gapAnswerTuples.size() != that.gapAnswerTuples.size()) return false; 642 }
628
629 ArrayList<AnswerTuple> thisSoundAnswers = new ArrayList<>(soundAnswerTuples);
630 Collections.sort(thisSoundAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str));
631 643
632 ArrayList<AnswerTuple> thatSoundAnswers = new ArrayList<>(that.soundAnswerTuples); 644 public static class GsonCreator {
633 Collections.sort(thatSoundAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str));
634 645
635 Iterator<AnswerTuple> soundIt1 = this.soundAnswerTuples.iterator(); 646 private static Gson gson;
636 Iterator<AnswerTuple> soundIt2 = that.soundAnswerTuples.iterator();
637 while(soundIt1.hasNext() && soundIt2.hasNext())
638 if(!soundIt1.next().m_str.equals(soundIt2.next().m_str)) return false;
639 647
640 ArrayList<AnswerTuple> thisGapAnswers = new ArrayList<>(gapAnswerTuples); 648 private GsonCreator() {}
641 Collections.sort(thisGapAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str));
642 649
643 ArrayList<AnswerTuple> thatGapAnswers = new ArrayList<>(that.gapAnswerTuples); 650 public static Gson getInstance() {
644 Collections.sort(thatGapAnswers, (AnswerTuple t1, AnswerTuple t2) -> t1.m_str.compareTo(t2.m_str)); 651 if(gson == null) {
652 gson = new GsonBuilder()
653 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer())
654 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer())
655 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer())
656 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer())
657 .disableHtmlEscaping()
658 .setPrettyPrinting()
659 .create();
660 }
661 return gson;
662 }
645 663
646 Iterator<AnswerTuple> gapIt1 = this.gapAnswerTuples.iterator(); 664// public static void dispose() {
647 Iterator<AnswerTuple> gapIt2 = that.gapAnswerTuples.iterator(); 665// gson = null;
648 while(gapIt1.hasNext() && gapIt2.hasNext()) 666// }
649 if(!gapIt1.next().m_str.equals(gapIt2.next().m_str)) return false;
650 667
651 return true;
652 } 668 }
653} 669}
diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java
index 17838ae..4465764 100644
--- a/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java
+++ b/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java
@@ -1,24 +1,29 @@
1package uk.ac.ox.cs.pagoda.reasoner; 1package uk.ac.ox.cs.pagoda.reasoner;
2 2
3import java.util.Collection;
4
5import org.semanticweb.karma2.profile.ELHOProfile; 3import org.semanticweb.karma2.profile.ELHOProfile;
6import org.semanticweb.owlapi.model.OWLOntology; 4import org.semanticweb.owlapi.model.OWLOntology;
7 5import uk.ac.ox.cs.pagoda.multistage.MultiStageQueryEngine;
8import uk.ac.ox.cs.pagoda.multistage.*;
9import uk.ac.ox.cs.pagoda.owl.EqualitiesEliminator; 6import uk.ac.ox.cs.pagoda.owl.EqualitiesEliminator;
10import uk.ac.ox.cs.pagoda.owl.OWLHelper; 7import uk.ac.ox.cs.pagoda.owl.OWLHelper;
11import uk.ac.ox.cs.pagoda.query.*; 8import uk.ac.ox.cs.pagoda.query.AnswerTuples;
9import uk.ac.ox.cs.pagoda.query.GapByStore4ID;
10import uk.ac.ox.cs.pagoda.query.QueryRecord;
12import uk.ac.ox.cs.pagoda.query.QueryRecord.Step; 11import uk.ac.ox.cs.pagoda.query.QueryRecord.Step;
13import uk.ac.ox.cs.pagoda.reasoner.full.Checker; 12import uk.ac.ox.cs.pagoda.reasoner.full.Checker;
14import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; 13import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine;
15import uk.ac.ox.cs.pagoda.reasoner.light.KarmaQueryEngine; 14import uk.ac.ox.cs.pagoda.reasoner.light.KarmaQueryEngine;
16import uk.ac.ox.cs.pagoda.rules.DatalogProgram; 15import uk.ac.ox.cs.pagoda.rules.DatalogProgram;
17import uk.ac.ox.cs.pagoda.summary.HermitSummaryFilter; 16import uk.ac.ox.cs.pagoda.summary.HermitSummaryFilter;
18import uk.ac.ox.cs.pagoda.tracking.*; 17import uk.ac.ox.cs.pagoda.tracking.QueryTracker;
18import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoder;
19import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoderDisjVar1;
20import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoderWithGap;
19import uk.ac.ox.cs.pagoda.util.Timer; 21import uk.ac.ox.cs.pagoda.util.Timer;
20import uk.ac.ox.cs.pagoda.util.Utility; 22import uk.ac.ox.cs.pagoda.util.Utility;
21 23
24import java.util.Collection;
25import java.util.HashMap;
26
22public class MyQueryReasoner extends QueryReasoner { 27public class MyQueryReasoner extends QueryReasoner {
23 28
24 OWLOntology ontology; 29 OWLOntology ontology;
@@ -203,10 +208,17 @@ public class MyQueryReasoner extends QueryReasoner {
203 String[] extendedQuery = queryRecord.getExtendedQueryText(); 208 String[] extendedQuery = queryRecord.getExtendedQueryText();
204 209
205 queryUpperBound(upperStore, queryRecord, queryRecord.getQueryText(), queryRecord.getAnswerVariables()); 210 queryUpperBound(upperStore, queryRecord, queryRecord.getQueryText(), queryRecord.getAnswerVariables());
206 if (!queryRecord.processed() && !queryRecord.getQueryText().equals(extendedQuery[0])) 211
212 // TODO log correct partial answers
213 Utility.logDebug(toJson("upperBound1", queryRecord));
214 if (!queryRecord.processed() && !queryRecord.getQueryText().equals(extendedQuery[0])) {
207 queryUpperBound(upperStore, queryRecord, extendedQuery[0], queryRecord.getAnswerVariables()); 215 queryUpperBound(upperStore, queryRecord, extendedQuery[0], queryRecord.getAnswerVariables());
208 if (!queryRecord.processed() && queryRecord.hasNonAnsDistinguishedVariables()) 216 Utility.logDebug(toJson("upperBound2", queryRecord));
217 }
218 if (!queryRecord.processed() && queryRecord.hasNonAnsDistinguishedVariables()) {
209 queryUpperBound(upperStore, queryRecord, extendedQuery[1], queryRecord.getDistinguishedVariables()); 219 queryUpperBound(upperStore, queryRecord, extendedQuery[1], queryRecord.getDistinguishedVariables());
220 Utility.logDebug(toJson("upperBound3", queryRecord));
221 }
210 222
211 queryRecord.addProcessingTime(Step.UpperBound, t.duration()); 223 queryRecord.addProcessingTime(Step.UpperBound, t.duration());
212 if (queryRecord.processed()) { 224 if (queryRecord.processed()) {
@@ -268,13 +280,19 @@ public class MyQueryReasoner extends QueryReasoner {
268 280
269// int counter = 0; 281// int counter = 0;
270 282
283 private String toJson(String key, Object value) {
284 HashMap<String, Object> map = new HashMap<>();
285 map.put(key, value);
286 return QueryRecord.GsonCreator.getInstance().toJson(map);
287 }
288
271 private void queryUpperBound(BasicQueryEngine upperStore, QueryRecord queryRecord, String queryText, String[] answerVariables) { 289 private void queryUpperBound(BasicQueryEngine upperStore, QueryRecord queryRecord, String queryText, String[] answerVariables) {
272 AnswerTuples rlAnswer = null; 290 AnswerTuples rlAnswer = null;
273 try { 291 try {
274 Utility.logDebug(queryText); 292 Utility.logDebug(queryText);
275 rlAnswer = upperStore.evaluate(queryText, answerVariables); 293 rlAnswer = upperStore.evaluate(queryText, answerVariables);
276 Utility.logDebug(t.duration()); 294 Utility.logDebug(t.duration());
277 queryRecord.updateUpperBoundAnswers(rlAnswer); 295 queryRecord.updateUpperBoundAnswers(rlAnswer);
278 } finally { 296 } finally {
279 if (rlAnswer != null) rlAnswer.dispose(); 297 if (rlAnswer != null) rlAnswer.dispose();
280 rlAnswer = null; 298 rlAnswer = null;
diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java
index 1f08fdf..326bf7e 100644
--- a/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java
+++ b/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java
@@ -1,10 +1,8 @@
1package uk.ac.ox.cs.pagoda.reasoner; 1package uk.ac.ox.cs.pagoda.reasoner;
2 2
3import com.google.gson.Gson; 3import com.google.gson.Gson;
4import com.google.gson.GsonBuilder;
5import org.semanticweb.owlapi.model.OWLOntology; 4import org.semanticweb.owlapi.model.OWLOntology;
6import uk.ac.ox.cs.pagoda.owl.OWLHelper; 5import uk.ac.ox.cs.pagoda.owl.OWLHelper;
7import uk.ac.ox.cs.pagoda.query.AnswerTuple;
8import uk.ac.ox.cs.pagoda.query.AnswerTuples; 6import uk.ac.ox.cs.pagoda.query.AnswerTuples;
9import uk.ac.ox.cs.pagoda.query.QueryManager; 7import uk.ac.ox.cs.pagoda.query.QueryManager;
10import uk.ac.ox.cs.pagoda.query.QueryRecord; 8import uk.ac.ox.cs.pagoda.query.QueryRecord;
@@ -202,11 +200,7 @@ public abstract class QueryReasoner {
202 } 200 }
203 201
204 Timer t = new Timer(); 202 Timer t = new Timer();
205 Gson gson = new GsonBuilder() 203 Gson gson = QueryRecord.GsonCreator.getInstance();
206 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer())
207 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer())
208 .setPrettyPrinting()
209 .create();
210 for (QueryRecord record: queryRecords) { 204 for (QueryRecord record: queryRecords) {
211// if (Integer.parseInt(record.getQueryID()) != 218) continue; 205// if (Integer.parseInt(record.getQueryID()) != 218) continue;
212 Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", 206 Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------",
@@ -226,7 +220,7 @@ public abstract class QueryReasoner {
226 } 220 }
227 // TODO it can handle one call only 221 // TODO it can handle one call only
228 // if you call twice, you will end up with a json file with multiple roots 222 // if you call twice, you will end up with a json file with multiple roots
229 gson.toJson(queryRecords, answerWriter); 223 if(answerWriter != null) gson.toJson(queryRecords, answerWriter);
230 queryRecords.stream().forEach(record -> record.dispose()); 224 queryRecords.stream().forEach(record -> record.dispose());
231 } 225 }
232 226
@@ -251,5 +245,5 @@ public abstract class QueryReasoner {
251 public static QueryReasoner getHermiTReasoner(boolean toCheckSatisfiability) { 245 public static QueryReasoner getHermiTReasoner(boolean toCheckSatisfiability) {
252 return new HermiTReasoner(toCheckSatisfiability); 246 return new HermiTReasoner(toCheckSatisfiability);
253 } 247 }
254 248
255} 249}
diff --git a/src/uk/ac/ox/cs/pagoda/util/Utility.java b/src/uk/ac/ox/cs/pagoda/util/Utility.java
index 6d50ee0..b3a4df1 100644
--- a/src/uk/ac/ox/cs/pagoda/util/Utility.java
+++ b/src/uk/ac/ox/cs/pagoda/util/Utility.java
@@ -1,5 +1,6 @@
1package uk.ac.ox.cs.pagoda.util; 1package uk.ac.ox.cs.pagoda.util;
2 2
3import org.apache.log4j.Level;
3import org.apache.log4j.Logger; 4import org.apache.log4j.Logger;
4import org.semanticweb.HermiT.model.Atom; 5import org.semanticweb.HermiT.model.Atom;
5 6
@@ -11,7 +12,11 @@ import java.util.*;
11 12
12public class Utility { 13public class Utility {
13 14
14 private static final Logger LOGS = Logger.getLogger("PAGOdA"); 15 private static Logger LOGS;
16 static {
17 LOGS = Logger.getLogger("PAGOdA");
18 LOGS.setLevel(Level.INFO);
19 }
15 20
16 public static final String JAVA_FILE_SEPARATOR = "/"; 21 public static final String JAVA_FILE_SEPARATOR = "/";
17 public static final String FILE_SEPARATOR = System.getProperty("file.separator"); 22 public static final String FILE_SEPARATOR = System.getProperty("file.separator");
@@ -184,7 +189,7 @@ public class Utility {
184 } 189 }
185 190
186 private static StringBuilder logMessage = new StringBuilder(); 191 private static StringBuilder logMessage = new StringBuilder();
187 192
188 private static String getLogMessage(Object[] messages) { 193 private static String getLogMessage(Object[] messages) {
189 if (messages.length == 1) return messages[0].toString(); 194 if (messages.length == 1) return messages[0].toString();
190 else { 195 else {
@@ -198,7 +203,11 @@ public class Utility {
198 } 203 }
199 204
200 } 205 }
201 206
207 public static void setLogLevel(Level level) {
208 LOGS.setLevel(level);
209 }
210
202 public static void logInfo(Object... messages) { 211 public static void logInfo(Object... messages) {
203 if (LOGS != null) 212 if (LOGS != null)
204 LOGS.info(getLogMessage(messages)); 213 LOGS.info(getLogMessage(messages));
diff --git a/test/AllTests.xml b/test/AllTests.xml
index 8ce5fcf..cb8a0e3 100644
--- a/test/AllTests.xml
+++ b/test/AllTests.xml
@@ -9,4 +9,10 @@
9 </classes> 9 </classes>
10 </test> 10 </test>
11 11
12 <test name="PagodaLUBM">
13 <classes>
14 <class name="uk.ac.ox.cs.pagoda.test_units.PagodaLUBM" />
15 </classes>
16 </test>
17
12</suite> \ No newline at end of file 18</suite> \ No newline at end of file
diff --git a/test/uk/ac/ox/cs/pagoda/test_units/PagodaLUBM.java b/test/uk/ac/ox/cs/pagoda/test_units/PagodaLUBM.java
index 29abc87..1aded5b 100644
--- a/test/uk/ac/ox/cs/pagoda/test_units/PagodaLUBM.java
+++ b/test/uk/ac/ox/cs/pagoda/test_units/PagodaLUBM.java
@@ -13,7 +13,7 @@ public class PagodaLUBM {
13 TestGlobalCorrectness.test(Paths.get(ontoDir, "lubm/univ-bench.owl"), 13 TestGlobalCorrectness.test(Paths.get(ontoDir, "lubm/univ-bench.owl"),
14 Paths.get(ontoDir, "lubm/data/lubm" + number + ".ttl"), 14 Paths.get(ontoDir, "lubm/data/lubm" + number + ".ttl"),
15 Paths.get(ontoDir, "lubm/queries/test.sparql"), 15 Paths.get(ontoDir, "lubm/queries/test.sparql"),
16 Paths.get(ontoDir, "lubm/lubm" + number + ".ans")); 16 Paths.get(ontoDir, "lubm/lubm" + number + ".json"));
17 } 17 }
18 18
19 @Test 19 @Test
diff --git a/test/uk/ac/ox/cs/pagoda/test_units/PagodaUOBM.java b/test/uk/ac/ox/cs/pagoda/test_units/PagodaUOBM.java
index f53ed7e..ee9cf13 100644
--- a/test/uk/ac/ox/cs/pagoda/test_units/PagodaUOBM.java
+++ b/test/uk/ac/ox/cs/pagoda/test_units/PagodaUOBM.java
@@ -13,7 +13,7 @@ public class PagodaUOBM {
13 TestGlobalCorrectness.test(Paths.get(ontoDir, "uobm/univ-bench-dl.owl"), 13 TestGlobalCorrectness.test(Paths.get(ontoDir, "uobm/univ-bench-dl.owl"),
14 Paths.get(ontoDir, "uobm/data/uobm" + number + ".ttl"), 14 Paths.get(ontoDir, "uobm/data/uobm" + number + ".ttl"),
15 Paths.get(ontoDir, "uobm/queries/test.sparql"), 15 Paths.get(ontoDir, "uobm/queries/test.sparql"),
16 Paths.get(ontoDir, "uobm/uobm" + number + ".ans")); 16 Paths.get(ontoDir, "uobm/uobm" + number + ".json"));
17 } 17 }
18 18
19 @Test 19 @Test
diff --git a/test/uk/ac/ox/cs/pagoda/test_units/TestGlobalCorrectness.java b/test/uk/ac/ox/cs/pagoda/test_units/TestGlobalCorrectness.java
index 34ec8cd..ffaf8fc 100644
--- a/test/uk/ac/ox/cs/pagoda/test_units/TestGlobalCorrectness.java
+++ b/test/uk/ac/ox/cs/pagoda/test_units/TestGlobalCorrectness.java
@@ -1,13 +1,12 @@
1package uk.ac.ox.cs.pagoda.test_units; 1package uk.ac.ox.cs.pagoda.test_units;
2 2
3import com.google.gson.Gson; 3import com.google.gson.Gson;
4import com.google.gson.GsonBuilder;
5import com.google.gson.reflect.TypeToken; 4import com.google.gson.reflect.TypeToken;
6import org.apache.log4j.Logger; 5import org.apache.log4j.Level;
7import org.testng.Assert; 6import org.testng.Assert;
8import uk.ac.ox.cs.pagoda.query.AnswerTuple;
9import uk.ac.ox.cs.pagoda.query.QueryRecord; 7import uk.ac.ox.cs.pagoda.query.QueryRecord;
10import uk.ac.ox.cs.pagoda.tester.PagodaTester; 8import uk.ac.ox.cs.pagoda.tester.PagodaTester;
9import uk.ac.ox.cs.pagoda.util.Utility;
11 10
12import java.io.BufferedReader; 11import java.io.BufferedReader;
13import java.io.File; 12import java.io.File;
@@ -16,39 +15,37 @@ import java.lang.reflect.Type;
16import java.nio.file.Files; 15import java.nio.file.Files;
17import java.nio.file.Path; 16import java.nio.file.Path;
18import java.nio.file.Paths; 17import java.nio.file.Paths;
19import java.util.Collection;
20import java.util.Set; 18import java.util.Set;
21 19
22/* 20/**
23 * This is a unit test for TestNG. 21 * This is a unit test for TestNG.
24 * <p> 22 * <p>
25 * It tests the correctness on the final output. 23 * It tests the correctness on the final output.
26 * */ 24 * */
27public class TestGlobalCorrectness { 25public class TestGlobalCorrectness {
28 26
29 public static final Logger logger = Logger.getLogger(TestGlobalCorrectness.class);
30
31 public static void test(Path ontology, Path data, Path queries, Path givenAnswers) { 27 public static void test(Path ontology, Path data, Path queries, Path givenAnswers) {
32 try { 28 try {
33 Path computedAnswers = Paths.get(File.createTempFile("answers", ".tmp").getAbsolutePath()); 29 Utility.setLogLevel(Level.DEBUG);
30 Path computedAnswers = Paths.get(File.createTempFile("answers", ".json").getAbsolutePath());
34 PagodaTester.main(ontology.toString(), data.toString(), queries.toString(), computedAnswers.toString()); 31 PagodaTester.main(ontology.toString(), data.toString(), queries.toString(), computedAnswers.toString());
35 Assert.assertTrue(checkSameContent(computedAnswers, givenAnswers)); 32 assertSameContent(computedAnswers, givenAnswers);
36 } catch (IOException e) { 33 } catch (IOException e) {
37 e.printStackTrace(); 34 e.printStackTrace();
38 } 35 }
39 } 36 }
40 37
41 private static boolean checkSameContent(Path computedAnswersFile, Path givenAnswersFile) throws IOException { 38 private static void assertSameContent(Path computedAnswersFile, Path givenAnswersFile) throws IOException {
42 BufferedReader computedReader = Files.newBufferedReader(computedAnswersFile); 39 BufferedReader computedReader = Files.newBufferedReader(computedAnswersFile);
43 BufferedReader givenReader = Files.newBufferedReader(givenAnswersFile); 40 BufferedReader givenReader = Files.newBufferedReader(givenAnswersFile);
44 41
45 Gson gson = new GsonBuilder().create(); 42 Gson gson = QueryRecord.GsonCreator.getInstance();
46 43
47 Type cqType = new TypeToken<Set<AnswerTuple>>() {}.getType(); 44 Type cqType = new TypeToken<Set<QueryRecord>>() {}.getType();
48 Collection<QueryRecord> computedAnswers = gson.fromJson(computedReader, cqType); 45 Set<QueryRecord> computedAnswers = gson.fromJson(computedReader, cqType);
49 Collection<QueryRecord> givenAnswers = gson.fromJson(givenReader, cqType); 46 Set<QueryRecord> givenAnswers = gson.fromJson(givenReader, cqType);
50 47
51 return computedAnswers.equals(givenAnswers); 48 Assert.assertEquals(computedAnswers, givenAnswers);
52 } 49 }
53 50
54 51
diff --git a/test/uk/ac/ox/cs/pagoda/tester/PagodaTester.java b/test/uk/ac/ox/cs/pagoda/tester/PagodaTester.java
index 7dacdac..5e49f79 100644
--- a/test/uk/ac/ox/cs/pagoda/tester/PagodaTester.java
+++ b/test/uk/ac/ox/cs/pagoda/tester/PagodaTester.java
@@ -37,7 +37,7 @@ public class PagodaTester {
37 public static final int uobm_number = 1; 37 public static final int uobm_number = 1;
38 public static final String uobm_tbox = onto_dir + "uobm/univ-bench-dl.owl"; 38 public static final String uobm_tbox = onto_dir + "uobm/univ-bench-dl.owl";
39 public static final String uobm_abox = onto_dir + "uobm/data/uobm" + uobm_number + ".ttl"; 39 public static final String uobm_abox = onto_dir + "uobm/data/uobm" + uobm_number + ".ttl";
40 public static final String uobm_query = onto_dir + "uobm/queries/standard.sparql"; 40 public static final String uobm_query = onto_dir + "uobm/queries/test.sparql";
41 public static final String uobm_query_temp = onto_dir + "uobm/queries/temp.sparql"; 41 public static final String uobm_query_temp = onto_dir + "uobm/queries/temp.sparql";
42 public static final String uobm_query2 = onto_dir + "uobm/queries/standard_q2.sparql"; 42 public static final String uobm_query2 = onto_dir + "uobm/queries/standard_q2.sparql";
43 public static final String uobm_query9 = onto_dir + "uobm/queries/standard_q9.sparql"; 43 public static final String uobm_query9 = onto_dir + "uobm/queries/standard_q9.sparql";
@@ -93,8 +93,8 @@ public class PagodaTester {
93 public static void main(String... args) { 93 public static void main(String... args) {
94 if (args.length == 0) { 94 if (args.length == 0) {
95// args = new String[] {test_tbox, test_abox, test_query}; 95// args = new String[] {test_tbox, test_abox, test_query};
96 args = new String[] {lubm_tbox, lubm_abox, lubm_query, "/home/alessandro/Desktop/lubm1.ans"}; 96// args = new String[] {lubm_tbox, lubm_abox, lubm_query};
97// args = new String[] {uobm_tbox, uobm_abox, uobm_query.replace(".sparql", "_all_pagoda.sparql")}; 97 args = new String[] {uobm_tbox, uobm_abox, uobm_query, "/home/alessandro/Desktop/uobm1.ans"};
98// args = new String[] {fly, "null", fly_query.replace(".sparql", "_pellet.sparql") }; 98// args = new String[] {fly, "null", fly_query.replace(".sparql", "_pellet.sparql") };
99// args = new String[] {dbpedia_tbox, dbpedia_abox, dbpedia_query}; 99// args = new String[] {dbpedia_tbox, dbpedia_abox, dbpedia_query};
100// args = new String[] {travel_tbox, null, dbpedia_query274}; 100// args = new String[] {travel_tbox, null, dbpedia_query274};
diff --git a/test/uk/ac/ox/cs/pagoda/util/TestUtil.java b/test/uk/ac/ox/cs/pagoda/util/TestUtil.java
index 227398b..06d391a 100644
--- a/test/uk/ac/ox/cs/pagoda/util/TestUtil.java
+++ b/test/uk/ac/ox/cs/pagoda/util/TestUtil.java
@@ -48,7 +48,7 @@ public class TestUtil {
48 Files.copy(Paths.get(src), Paths.get(dst), REPLACE_EXISTING); 48 Files.copy(Paths.get(src), Paths.get(dst), REPLACE_EXISTING);
49 } 49 }
50 50
51 /* 51 /**
52 * Get the log file, which is assumed unique. 52 * Get the log file, which is assumed unique.
53 * */ 53 * */
54 public static String getLogFileName() { 54 public static String getLogFileName() {
@@ -61,4 +61,5 @@ public class TestUtil {
61 } 61 }
62 return null; 62 return null;
63 } 63 }
64
64} 65}