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.java163
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java9
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/GapByTriple.java35
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java4
-rw-r--r--src/uk/ac/ox/cs/pagoda/query/QueryRecord.java713
5 files changed, 561 insertions, 363 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
index 8d7e0b1..54e4837 100644
--- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
+++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java
@@ -1,13 +1,10 @@
1package uk.ac.ox.cs.pagoda.query; 1package uk.ac.ox.cs.pagoda.query;
2 2
3import java.util.HashMap; 3import com.google.gson.*;
4import java.util.Map;
5
6import org.semanticweb.HermiT.model.Constant; 4import org.semanticweb.HermiT.model.Constant;
7import org.semanticweb.HermiT.model.Individual; 5import org.semanticweb.HermiT.model.Individual;
8import org.semanticweb.HermiT.model.Term; 6import org.semanticweb.HermiT.model.Term;
9import org.semanticweb.HermiT.model.Variable; 7import org.semanticweb.HermiT.model.Variable;
10
11import uk.ac.ox.cs.JRDFox.JRDFStoreException; 8import uk.ac.ox.cs.JRDFox.JRDFStoreException;
12import uk.ac.ox.cs.JRDFox.model.Datatype; 9import uk.ac.ox.cs.JRDFox.model.Datatype;
13import uk.ac.ox.cs.JRDFox.model.GroundTerm; 10import uk.ac.ox.cs.JRDFox.model.GroundTerm;
@@ -15,13 +12,21 @@ import uk.ac.ox.cs.JRDFox.model.Literal;
15import uk.ac.ox.cs.JRDFox.store.TupleIterator; 12import uk.ac.ox.cs.JRDFox.store.TupleIterator;
16import uk.ac.ox.cs.pagoda.util.Namespace; 13import uk.ac.ox.cs.pagoda.util.Namespace;
17 14
15import java.lang.reflect.Type;
16import java.util.HashMap;
17import java.util.Map;
18import java.util.StringTokenizer;
19import java.util.regex.Matcher;
20import java.util.regex.Pattern;
21
18public class AnswerTuple { 22public class AnswerTuple {
19 23
20 public static final String SEPARATOR = "\t"; 24 public static final String SEPARATOR = "\t";
25 static final Pattern owlLiteralRegex =
26 Pattern.compile("^\"(?<lexicalForm>[^@]+(@(?<langTag>.+))?)\"(^^<(?<dataType>.+)>)?$");
27 String m_str = null;
28 GroundTerm[] m_tuple;
21 29
22 String m_str = null;
23 GroundTerm[] m_tuple;
24
25 public AnswerTuple(TupleIterator iter, int arity) { 30 public AnswerTuple(TupleIterator iter, int arity) {
26 m_tuple = new GroundTerm[arity]; 31 m_tuple = new GroundTerm[arity];
27 try { 32 try {
@@ -29,107 +34,157 @@ public class AnswerTuple {
29 m_tuple[i] = iter.getGroundTerm(i); 34 m_tuple[i] = iter.getGroundTerm(i);
30 } catch (JRDFStoreException e) { 35 } catch (JRDFStoreException e) {
31 e.printStackTrace(); 36 e.printStackTrace();
32 } 37 }
33 } 38 }
34 39
35 public AnswerTuple(GroundTerm[] terms) { 40 public AnswerTuple(GroundTerm[] terms) {
36 m_tuple = terms; 41 m_tuple = terms;
37 } 42 }
38 43
44// private AnswerTuple(String m_str) {
45// this.m_str = m_str;
46// }
47
39 private AnswerTuple(AnswerTuple sup, int arity) { 48 private AnswerTuple(AnswerTuple sup, int arity) {
40 m_tuple = new GroundTerm[arity]; 49 m_tuple = new GroundTerm[arity];
41 for (int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i]; 50 for(int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i];
51 }
52
53 /**
54 * It returns the first argument if its arity equals length, a new AnswerTuple otherwise.
55 */
56 public static AnswerTuple getInstance(AnswerTuple extendedTuple, int length) {
57 if(length == extendedTuple.getArity()) return extendedTuple;
58 else return new AnswerTuple(extendedTuple, length);
42 } 59 }
43 60
44 public int getArity() { 61 public int getArity() {
45 return m_tuple.length; 62 return m_tuple.length;
46 } 63 }
47 64
48 public int hashCode() { 65 public int hashCode() {
49// return toString().hashCode(); 66// return toString().hashCode();
50 int code = 0; 67 int code = 0;
51 for (int i = 0; i < m_tuple.length; ++i) 68 for (int i = 0; i < m_tuple.length; ++i)
52 code = code * 1997 + m_tuple[i].hashCode(); 69 code = code * 1997 + m_tuple[i].hashCode();
53 return code; 70 return code;
54 } 71 }
55 72
56 public boolean equals(Object obj) { 73 public boolean equals(Object obj) {
57 if (!(obj instanceof AnswerTuple)) return false; 74 if (!(obj instanceof AnswerTuple)) return false;
58 AnswerTuple that = (AnswerTuple) obj; 75 AnswerTuple that = (AnswerTuple) obj;
59 if (m_tuple.length != that.m_tuple.length) return false; 76 if (m_tuple.length != that.m_tuple.length) return false;
60 for (int i = 0; i < m_tuple.length; ++i) 77 for (int i = 0; i < m_tuple.length; ++i)
61 if (!m_tuple[i].equals(that.m_tuple[i])) 78 if (!m_tuple[i].equals(that.m_tuple[i]))
62 return false; 79 return false;
63 return true; 80 return true;
64// return toString().equals(obj.toString()); 81// return toString().equals(obj.toString());
65 } 82 }
66 83
67 public String toString() { 84 public String toString() {
68 if (m_str != null) return m_str; 85 if(m_str != null) return m_str;
69 StringBuilder sb = new StringBuilder(); 86 StringBuilder sb = new StringBuilder();
70 for (int i = 0; i < m_tuple.length; ++i) { 87 for (int i = 0; i < m_tuple.length; ++i) {
71 if (sb.length() != 0) sb.append(SEPARATOR); 88 if (sb.length() != 0) sb.append(SEPARATOR);
72 if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual) 89 if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)
73 sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">"); 90 sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">");
74 else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) { 91 else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) {
75 sb.append(((uk.ac.ox.cs.JRDFox.model.BlankNode) m_tuple[i]).toString()); 92 sb.append(m_tuple[i].toString());
76 } 93 }
77 else { 94 else {
78 Literal l = (Literal) m_tuple[i]; 95 Literal l = (Literal) m_tuple[i];
79 sb.append('"').append(l.getLexicalForm()).append("\""); 96 sb.append('"').append(l.getLexicalForm()).append("\"");
80 if (!l.getDatatype().equals(Datatype.XSD_STRING) && !l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL)) 97 if (!l.getDatatype().equals(Datatype.XSD_STRING) && !l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL))
81 sb.append("^^<").append(l.getDatatype().getIRI()).append(">"); 98 sb.append("^^<").append(l.getDatatype().getIRI()).append(">");
82 } 99 }
83 } 100 }
84 return m_str = sb.toString(); 101 return m_str = sb.toString();
85 } 102 }
86 103
87 public GroundTerm getGroundTerm(int i) { 104 public GroundTerm getGroundTerm(int i) {
88 return m_tuple[i]; 105 return m_tuple[i];
89 } 106 }
90 107
91 public Map<Variable, Term> getAssignment(String[] vars) { 108 public Map<Variable, Term> getAssignment(String[] vars) {
92 Map<Variable, Term> map = new HashMap<Variable, Term>(); 109 Map<Variable, Term> map = new HashMap<Variable, Term>();
93 int index = 0; 110 int index = 0;
94 Term t; 111 Term t;
95 for (String var: vars) { 112 for (String var: vars) {
96 if (m_tuple[index] instanceof uk.ac.ox.cs.JRDFox.model.Individual) 113 if(m_tuple[index] instanceof uk.ac.ox.cs.JRDFox.model.Individual)
97 t = Individual.create((((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[index]).getIRI())); 114 t = Individual.create((((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[index]).getIRI()));
98 else { 115 else {
99 uk.ac.ox.cs.JRDFox.model.Literal l = (uk.ac.ox.cs.JRDFox.model.Literal) m_tuple[index]; 116 uk.ac.ox.cs.JRDFox.model.Literal l = (uk.ac.ox.cs.JRDFox.model.Literal) m_tuple[index];
100 t = Constant.create(l.getLexicalForm(), l.getDatatype().getIRI()); 117 t = Constant.create(l.getLexicalForm(), l.getDatatype().getIRI());
101 } 118 }
102 map.put(Variable.create(var), t); 119 map.put(Variable.create(var), t);
103 ++index; 120 ++index;
104 } 121 }
105 return map; 122 return map;
106 } 123 }
107 124
108 public boolean hasAuxPredicate() { 125 public boolean hasAuxPredicate() {
109 String iri; 126 String iri;
110 for (int i = 0; i < m_tuple.length; ++i) 127 for (int i = 0; i < m_tuple.length; ++i)
111 if ((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) { 128 if ((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) {
112 iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI(); 129 iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI();
113 if ( iri.startsWith(Namespace.PAGODA_AUX) || iri.contains("_AUX") || iri.contains("_neg") || iri.contains("internal:def")) 130 if(iri.startsWith(Namespace.PAGODA_AUX) || iri.contains("_AUX") || iri.contains("_neg") || iri.contains("internal:def"))
114 return true; 131 return true;
115 } 132 }
116 return false; 133 return false;
117 } 134 }
118 135
119 public boolean hasAnonyIndividual() { 136 public boolean hasAnonymousIndividual() {
120 String iri; 137 String iri;
121 for (int i = 0; i < m_tuple.length; ++i) 138 for(int i = 0; i < m_tuple.length; ++i)
122 if ((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) { 139 if((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) {
123 iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI(); 140 iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI();
124 if (iri.startsWith(Namespace.PAGODA_ANONY) || iri.startsWith(Namespace.KARMA_ANONY)) 141 if(iri.startsWith(Namespace.PAGODA_ANONY) || iri.startsWith(Namespace.KARMA_ANONY))
125 return true; 142 return true;
126 } 143 }
127 return false; 144 return false;
128 } 145 }
129 146
130 public static AnswerTuple create(AnswerTuple extendedTuple, int length) { 147 public static class AnswerTupleSerializer implements JsonSerializer<AnswerTuple> {
131 if (length == extendedTuple.getArity()) return extendedTuple; 148
132 else return new AnswerTuple(extendedTuple, length); 149 public JsonElement serialize(AnswerTuple src, Type typeOfSrc, JsonSerializationContext context) {
150 return new JsonPrimitive(src.toString());
151 }
152
133 } 153 }
134 154
155 public static class AnswerTupleDeserializer implements JsonDeserializer<AnswerTuple> {
156 public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
157 throws JsonParseException {
158 String tuplesString = json.getAsJsonPrimitive().getAsString();
159 StringTokenizer tokenizer = new StringTokenizer(SEPARATOR);
160 GroundTerm[] terms = new GroundTerm[tokenizer.countTokens()];
161
162 // TODO test parsing
163 for (int i = 0; i < tokenizer.countTokens(); i++) {
164 String token = tokenizer.nextToken();
165 if (token.charAt(0) == '<') {
166 terms[i] = uk.ac.ox.cs.JRDFox.model.Individual.create(token.substring(1,token.length()-1));
167 }
168 else if (token.charAt(0) == '"') {
169 Matcher matcher = owlLiteralRegex.matcher(token);
170 if(matcher.matches()) {
171 String lexicalForm = matcher.group("lexicalForm");
172 String dataTypeIRI = matcher.group("dataType");
173 Datatype dataType;
174 if (dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL;
175 else dataType = uk.ac.ox.cs.JRDFox.model.Datatype.value(dataTypeIRI);
176 terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, dataType);
177 }
178 else {
179 throw new IllegalArgumentException("The given json does not represent a valid AnswerTuple");
180 }
181 }
182 else {
183 terms[i] = uk.ac.ox.cs.JRDFox.model.BlankNode.create(token);
184 }
185 }
186 return new AnswerTuple(terms);
187 }
188 }
189
135} 190}
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/GapByTriple.java b/src/uk/ac/ox/cs/pagoda/query/GapByTriple.java
index d2e9b90..eaa629b 100644
--- a/src/uk/ac/ox/cs/pagoda/query/GapByTriple.java
+++ b/src/uk/ac/ox/cs/pagoda/query/GapByTriple.java
@@ -1,36 +1,29 @@
1package uk.ac.ox.cs.pagoda.query; 1package uk.ac.ox.cs.pagoda.query;
2 2
3import java.io.BufferedWriter; 3import org.semanticweb.HermiT.model.*;
4import java.io.FileOutputStream; 4import uk.ac.ox.cs.JRDFox.JRDFStoreException;
5import java.io.IOException; 5import uk.ac.ox.cs.JRDFox.Prefixes;
6import java.io.OutputStreamWriter; 6import uk.ac.ox.cs.JRDFox.store.DataStore;
7import java.util.Collection; 7import uk.ac.ox.cs.JRDFox.store.Parameters;
8 8import uk.ac.ox.cs.JRDFox.store.TupleIterator;
9import org.semanticweb.HermiT.model.Atom;
10import org.semanticweb.HermiT.model.AtomicConcept;
11import org.semanticweb.HermiT.model.AtomicRole;
12import org.semanticweb.HermiT.model.DLClause;
13import org.semanticweb.HermiT.model.Individual;
14
15import uk.ac.ox.cs.pagoda.MyPrefixes; 9import uk.ac.ox.cs.pagoda.MyPrefixes;
16import uk.ac.ox.cs.pagoda.owl.OWLHelper; 10import uk.ac.ox.cs.pagoda.owl.OWLHelper;
17import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; 11import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine;
18import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; 12import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager;
19import uk.ac.ox.cs.pagoda.util.Namespace; 13import uk.ac.ox.cs.pagoda.util.Namespace;
20import uk.ac.ox.cs.pagoda.util.Utility; 14import uk.ac.ox.cs.pagoda.util.Utility;
21import uk.ac.ox.cs.JRDFox.JRDFStoreException; 15
22import uk.ac.ox.cs.JRDFox.Prefixes; 16import java.io.BufferedWriter;
23import uk.ac.ox.cs.JRDFox.store.DataStore; 17import java.io.FileOutputStream;
24import uk.ac.ox.cs.JRDFox.store.Parameters; 18import java.io.IOException;
25import uk.ac.ox.cs.JRDFox.store.TupleIterator; 19import java.io.OutputStreamWriter;
20import java.util.Collection;
26 21
27public class GapByTriple extends GapTupleIterator<String> { 22public class GapByTriple extends GapTupleIterator<String> {
28 23
29 private static final String RDF_TYPE = Namespace.RDF_NS + "type";
30 private static final String BRIEF_RDF_TYPE = "rdf:type";
31
32 static final String allTripleQuery = "SELECT ?X ?Y ?Z WHERE { ?X ?Y ?Z }"; 24 static final String allTripleQuery = "SELECT ?X ?Y ?Z WHERE { ?X ?Y ?Z }";
33 25 private static final String RDF_TYPE = Namespace.RDF_NS + "type";
26 private static final String BRIEF_RDF_TYPE = "rdf:type";
34 DataStore lowerStore, upperStore; 27 DataStore lowerStore, upperStore;
35 long multi; 28 long multi;
36 TupleIterator iterator; 29 TupleIterator iterator;
diff --git a/src/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java b/src/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java
index 61b6364..bf11168 100644
--- a/src/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java
+++ b/src/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java
@@ -1,10 +1,10 @@
1package uk.ac.ox.cs.pagoda.query; 1package uk.ac.ox.cs.pagoda.query;
2 2
3import java.util.Iterator;
4
5import uk.ac.ox.cs.JRDFox.JRDFStoreException; 3import uk.ac.ox.cs.JRDFox.JRDFStoreException;
6import uk.ac.ox.cs.JRDFox.store.DataStore; 4import uk.ac.ox.cs.JRDFox.store.DataStore;
7 5
6import java.util.Iterator;
7
8public abstract class GapTupleIterator<T> implements Iterator<T> { 8public abstract class GapTupleIterator<T> implements Iterator<T> {
9 9
10 public static final String gapPredicateSuffix = "_AUXg"; 10 public static final String gapPredicateSuffix = "_AUXg";
diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
index ce92a67..fd20af1 100644
--- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
+++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java
@@ -1,311 +1,345 @@
1package uk.ac.ox.cs.pagoda.query; 1package uk.ac.ox.cs.pagoda.query;
2 2
3import java.io.BufferedWriter; 3import com.google.gson.*;
4import java.io.FileNotFoundException; 4import com.google.gson.reflect.TypeToken;
5import java.io.FileOutputStream; 5import org.semanticweb.HermiT.model.*;
6import java.io.IOException; 6import org.semanticweb.owlapi.model.*;
7import java.io.OutputStreamWriter;
8import java.util.Collection;
9import java.util.HashMap;
10import java.util.HashSet;
11import java.util.Iterator;
12import java.util.LinkedList;
13import java.util.Map;
14import java.util.Set;
15
16import org.semanticweb.HermiT.model.Atom;
17import org.semanticweb.HermiT.model.AtomicConcept;
18import org.semanticweb.HermiT.model.AtomicRole;
19import org.semanticweb.HermiT.model.DLClause;
20import org.semanticweb.HermiT.model.DLPredicate;
21import org.semanticweb.HermiT.model.Variable;
22import org.semanticweb.owlapi.model.OWLAxiom;
23import org.semanticweb.owlapi.model.OWLClass;
24import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
25import org.semanticweb.owlapi.model.OWLDataProperty;
26import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
27import org.semanticweb.owlapi.model.OWLIndividual;
28import org.semanticweb.owlapi.model.OWLLiteral;
29import org.semanticweb.owlapi.model.OWLObjectProperty;
30import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
31import org.semanticweb.owlapi.model.OWLOntology;
32import org.semanticweb.owlapi.model.OWLOntologyManager;
33import org.semanticweb.owlapi.model.OWLOntologyStorageException;
34
35import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; 7import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper;
36import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxAnswerTuples; 8import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxAnswerTuples;
37import uk.ac.ox.cs.pagoda.rules.GeneralProgram; 9import uk.ac.ox.cs.pagoda.rules.GeneralProgram;
38import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; 10import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper;
39import uk.ac.ox.cs.pagoda.util.Namespace; 11import uk.ac.ox.cs.pagoda.util.Namespace;
12import uk.ac.ox.cs.pagoda.util.PagodaProperties;
40import uk.ac.ox.cs.pagoda.util.Utility; 13import uk.ac.ox.cs.pagoda.util.Utility;
14import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
15import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder;
16
17import java.io.*;
18import java.lang.reflect.Type;
19import java.util.*;
41 20
42public class QueryRecord { 21public class QueryRecord {
43 22
44 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> }"; 23 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> }";
45 24 public static final String SEPARATOR = "----------------------------------------";
46 private Step diffculty; 25 private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString();
47 26 boolean processed = false;
48 private String queryText; 27 String stringQueryID = null;
49 private int queryID = -1; 28 OWLOntology relevantOntology = null;
50 private String[][] answerVariables = null; 29 Set<DLClause> relevantClauses = new HashSet<DLClause>();
51 private Set<AnswerTuple> soundAnswerTuples = new HashSet<AnswerTuple>(); 30 double[] timer;
31 int subID;
32 DLClause queryClause = null;
33 private Step difficulty;
34 private String queryText;
35 private int queryID = -1;
36 private String[][] answerVariables = null;
37 private Set<AnswerTuple> soundAnswerTuples = new HashSet<AnswerTuple>();
52 private Set<AnswerTuple> gapAnswerTuples = null; 38 private Set<AnswerTuple> gapAnswerTuples = null;
53 39 private QueryManager m_manager;
54 private QueryManager m_manager; 40
55 41 private QueryRecord() {
42 }
43
44// private boolean containsAuxPredicate(String str) {
45// return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") ||
46// str.contains("internal:def");
47// }
48
56 public QueryRecord(QueryManager manager, String text, int id, int subID) { 49 public QueryRecord(QueryManager manager, String text, int id, int subID) {
57 m_manager =manager; 50 m_manager = manager;
58 resetInfo(text, id, subID); 51 resetInfo(text, id, subID);
59 resetTimer(); 52 resetTimer();
60 } 53 }
61 54
55 public static Collection<String> collectQueryTexts(Collection<QueryRecord> queryRecords) {
56 Collection<String> texts = new LinkedList<String>();
57 for(QueryRecord record : queryRecords)
58 texts.add(record.queryText);
59 return texts;
60 }
61
62 public void resetInfo(String text, int id, int subid) { 62 public void resetInfo(String text, int id, int subid) {
63 queryID = id; 63 queryID = id;
64 subID = subid; 64 subID = subid;
65 stringQueryID = id + (subID == 0 ? "" : "_" + subID); 65 stringQueryID = id + (subID == 0 ? "" : "_" + subID);
66 m_manager.remove(queryText); 66 m_manager.remove(queryText);
67 m_manager.put(text, this); 67 m_manager.put(text, this);
68 queryClause = null; 68 queryClause = null;
69 answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text); 69 answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text);
70 queryText = text; // .replace("_:", "?"); 70 queryText = text; // .replace("_:", "?");
71 } 71 }
72 72
73 public void resetTimer() { 73 public void resetTimer() {
74 int length = Step.values().length; 74 int length = Step.values().length;
75 timer = new double[length]; 75 timer = new double[length];
76 for (int i = 0; i < length; ++i) timer[i] = 0; 76 for(int i = 0; i < length; ++i) timer[i] = 0;
77 } 77 }
78 78
79 public AnswerTuples getAnswers() { 79 public AnswerTuples getAnswers() {
80 if (processed()) 80 if(isProcessed())
81 return getLowerBoundAnswers(); 81 return getLowerBoundAnswers();
82 82
83 return getUpperBoundAnswers(); 83 return getUpperBoundAnswers();
84 } 84 }
85 85
86 public AnswerTuples getLowerBoundAnswers() { 86 public AnswerTuples getLowerBoundAnswers() {
87 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples); 87 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples);
88 } 88 }
89 89
90 public AnswerTuples getUpperBoundAnswers() { 90 public AnswerTuples getUpperBoundAnswers() {
91 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples); 91 return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples);
92 } 92 }
93 93
94 public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) { 94 public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) {
95 if (answerTuples == null) return false; 95 if(answerTuples == null) return false;
96 boolean update = false; 96 boolean update = false;
97 for (AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) { 97 for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) {
98 tuple = answerTuples.getTuple(); 98 tuple = answerTuples.getTuple();
99 if (!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) { 99 if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) {
100 soundAnswerTuples.add(tuple); 100 soundAnswerTuples.add(tuple);
101 if (gapAnswerTuples != null) 101 if(gapAnswerTuples != null)
102 gapAnswerTuples.remove(tuple); 102 gapAnswerTuples.remove(tuple);
103 update = true; 103 update = true;
104 } 104 }
105 } 105 }
106 Utility.logInfo("The number of answers in the lower bound: " + soundAnswerTuples.size());
107 106
108 return update; 107 if(soundAnswerTuples.isEmpty())
108 Utility.logInfo("Lower bound answers empty");
109 else if(update)
110 Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size());
111 else
112 Utility.logInfo("Lower bound answers unchanged");
113
114 return update;
109 } 115 }
110 116
111 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) { 117 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) {
112 return updateUpperBoundAnswers(answerTuples, false); 118 return updateUpperBoundAnswers(answerTuples, false);
113 } 119 }
114 120
115 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { 121 public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) {
116 RDFoxAnswerTuples rdfAnswerTuples; 122 if(!(answerTuples instanceof RDFoxAnswerTuples)) {
117 if (answerTuples instanceof RDFoxAnswerTuples) 123 String msg = "The upper bound must be computed by RDFox!";
118 rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples; 124 Utility.logError(msg);
119 else { 125 throw new IllegalArgumentException(msg);
120 Utility.logError("The upper bound must be computed by RDFox!");
121 return false;
122 } 126 }
123 127
124 if (soundAnswerTuples.size() > 0) { 128 RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples;
125 int number = 0; 129
126 for (; answerTuples.isValid(); answerTuples.moveNext()) { 130 Set<AnswerTuple> candidateGapAnswerTuples = new HashSet<AnswerTuple>();
127 ++number; 131 AnswerTuple tuple;
128 } 132 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
129 Utility.logInfo("The number of answers returned by the upper bound: " + number); 133 tuple = rdfoxAnswerTuples.getTuple();
130 if (number <= soundAnswerTuples.size()) { 134 if(isBottom() || !tuple.hasAnonymousIndividual())
131 if (gapAnswerTuples != null) gapAnswerTuples.clear(); 135 if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple))
132 else gapAnswerTuples = new HashSet<AnswerTuple>(); 136 candidateGapAnswerTuples.add(tuple);
133
134 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size()));
135 return false;
136 }
137 answerTuples.reset();
138 } 137 }
139 138
140 boolean justCheck = (answerTuples.getArity() != answerVariables[1].length); 139 /*** START: debugging ***/
141 140 if(PagodaProperties.isDebuggingMode()) {
142 Set<AnswerTuple> tupleSet = new HashSet<AnswerTuple>(); 141 if(rdfoxAnswerTuples.getArity() != getAnswerVariables().length)
143 AnswerTuple tuple, extendedTuple; 142 throw new IllegalArgumentException(
144 for (; answerTuples.isValid(); answerTuples.moveNext()) { 143 "The arity of answers (" + rdfoxAnswerTuples.getArity() + ") " +
145 extendedTuple = rdfAnswerTuples.getTuple(); 144 "is different from the number of answer variables (" +
146 if (isBottom() || !extendedTuple.hasAnonyIndividual()) { 145 getAnswerVariables().length + ")");
147 tuple = AnswerTuple.create(extendedTuple, answerVariables[0].length); 146
148 if ((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) { 147 Set<AnswerTuple> namedAnswerTuples = new HashSet<>();
149 if (!toCheckAux && justCheck) return false; 148 rdfoxAnswerTuples.reset();
150 tupleSet.add(extendedTuple); 149 for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) {
151 } 150 tuple = rdfoxAnswerTuples.getTuple();
151// if(isBottom() || !tuple.hasAnonymousIndividual()) {
152 namedAnswerTuples.add(tuple);
153// }
152 } 154 }
155 HashSet<AnswerTuple> difference = new HashSet<>(soundAnswerTuples);
156 difference.removeAll(namedAnswerTuples);
157 if(!difference.isEmpty())
158 throw new IllegalArgumentException("The upper bound does not contain the lower bound! Missing answers: " + difference
159 .size());
153 } 160 }
154 161 /*** END: debugging ***/
155 if (gapAnswerTuples == null) { 162
156 gapAnswerTuples = tupleSet; 163 boolean update;
157 164 if(gapAnswerTuples == null) {
158 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 165 gapAnswerTuples = candidateGapAnswerTuples;
159 return true; 166 update = true;
160 } 167 } else {
161 168 update = gapAnswerTuples.retainAll(candidateGapAnswerTuples);
162 boolean update = false;
163 for (Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) {
164 tuple = iter.next();
165 if (!tupleSet.contains(tuple)) {
166 iter.remove();
167 update = true;
168 }
169 } 169 }
170 170
171 Utility.logInfo("The number of answers in the upper bound: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); 171 if(update)
172 172 Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers());
173 return update; 173 else
174 Utility.logInfo("Upper bound answers unchanged");
175
176 return update;
177
178// boolean update = false;
179// for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) {
180// tuple = iter.next();
181// if(!candidateGapAnswerTuples.contains(tuple)) {
182// iter.remove();
183// update = true;
184// }
185// }
174 } 186 }
175
176// private boolean containsAuxPredicate(String str) {
177// return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") ||
178// str.contains("internal:def");
179// }
180 187
181 boolean processed = false; 188 public int getNumberOfAnswers() {
189 return soundAnswerTuples.size() + gapAnswerTuples.size();
190 }
182 191
183 public void markAsProcessed() { 192 public void markAsProcessed() {
184 processed = true; 193 processed = true;
185 } 194 }
186 195
187 public boolean processed() { 196 public boolean isProcessed() {
188 if (gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true; 197 if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true;
189 return processed; 198 return processed;
190 } 199 }
191 200
192 public String[] getDistinguishedVariables() { 201 public String[] getDistinguishedVariables() {
193 return answerVariables[1]; 202 return answerVariables[1];
194 } 203 }
195 204
196 public String[] getAnswerVariables() { 205 public String[] getAnswerVariables() {
197 return answerVariables[0]; 206 return answerVariables[0];
198 } 207 }
199 208
200 public String[][] getVariables() { 209 public String[][] getVariables() {
201 return answerVariables; 210 return answerVariables;
202 } 211 }
203 212
204 public String getQueryText() { 213 public String getQueryText() {
205 return queryText; 214 return queryText;
206 } 215 }
207 216
208 String stringQueryID = null;
209
210 public String getQueryID() { 217 public String getQueryID() {
211 return stringQueryID; 218 return stringQueryID;
212 } 219 }
213 220
214 public AnswerTuples getGapAnswers() { 221 public AnswerTuples getGapAnswers() {
215 return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples); 222 return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples);
216 } 223 }
217 224
218 public String toString() { 225 public String toString() {
219 return queryText; 226 return queryText;
220 } 227 }
221
222 public static final String SEPARATOR = "----------------------------------------";
223 228
224 public void outputAnswers(BufferedWriter writer) throws IOException { 229 public void outputAnswers(BufferedWriter writer) throws IOException {
225 230
226 int answerCounter = soundAnswerTuples.size(); 231 int answerCounter = soundAnswerTuples.size();
227 if (!processed()) answerCounter += gapAnswerTuples.size(); 232 if(!isProcessed()) answerCounter += gapAnswerTuples.size();
228 233
229 Utility.logInfo("The number of answer tuples: " + answerCounter); 234 Utility.logInfo("The number of answer tuples: " + answerCounter);
230 235
231 if (writer != null) { 236 if (writer != null) {
232 writer.write("-------------- Query " + queryID + " ---------------------"); 237 writer.write("-------------- Query " + queryID + " ---------------------");
233 writer.newLine(); 238 writer.newLine();
234 writer.write(queryText); 239 writer.write(queryText);
235 writer.newLine(); 240 writer.newLine();
236 StringBuilder space = new StringBuilder(); 241 StringBuilder space = new StringBuilder();
237 int arity = getArity(), varSpace = 0; 242 int arity = getArity(), varSpace = 0;
238 for (int i = 0; i < arity; ++i) 243 for (int i = 0; i < arity; ++i)
239 varSpace += answerVariables[0][i].length(); 244 varSpace += answerVariables[0][i].length();
240 for (int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i) 245 for (int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i)
241 space.append(" "); 246 space.append(" ");
242 for (int i = 0; i < getArity(); ++i) { 247 for (int i = 0; i < getArity(); ++i) {
243 writer.write(space.toString()); 248 writer.write(space.toString());
244 writer.write(answerVariables[0][i]); 249 writer.write(answerVariables[0][i]);
245 } 250 }
246 writer.newLine(); 251 writer.newLine();
247 writer.write(SEPARATOR); 252 writer.write(SEPARATOR);
248 writer.newLine(); 253 writer.newLine();
249 for (AnswerTuple tuple: soundAnswerTuples) { 254 for (AnswerTuple tuple: soundAnswerTuples) {
250 writer.write(tuple.toString()); 255 writer.write(tuple.toString());
251 writer.newLine(); 256 writer.newLine();
252 } 257 }
253 if (!processed()) 258 if(!isProcessed())
254 for (AnswerTuple tuple: gapAnswerTuples) { 259 for (AnswerTuple tuple: gapAnswerTuples) {
255 writer.write("*"); 260 writer.write("*");
256 writer.write(tuple.toString()); 261 writer.write(tuple.toString());
257 writer.newLine(); 262 writer.newLine();
258 } 263 }
259// writer.write(SEPARATOR); 264// writer.write(SEPARATOR);
260 writer.newLine(); 265 writer.newLine();
261 } 266 }
262 267
263 } 268 }
264 269
270 public void outputAnswerStatistics() {
271
272 int answerCounter = soundAnswerTuples.size();
273 if(!isProcessed()) answerCounter += gapAnswerTuples.size();
274
275 Utility.logInfo("The number of answer tuples: " + answerCounter);
276// if (jsonAnswers != null) {
277// JSONObject jsonAnswer = new JSONObject();
278//
279// jsonAnswer.put("queryID", queryID);
280// jsonAnswer.put("queryText", queryText);
281//
282// JSONArray answerVars = new JSONArray();
283// int arity = getArity(), varSpace = 0;
284// for (int i = 0; i < getArity(); i++)
285// answerVars.add(answerVariables[0][i]);
286// jsonAnswer.put("answerVars", answerVars);
287//
288// JSONArray answerTuples = new JSONArray();
289// soundAnswerTuples.stream().forEach(t -> answerTuples.add(t));
290// jsonAnswer.put("answerTuples", answerTuples);
291//
292// if (!processed) {
293// JSONArray gapAnswerTuples = new JSONArray();
294// gapAnswerTuples.stream().forEach(t -> gapAnswerTuples.add(t));
295// }
296// jsonAnswer.put("gapAnswerTuples", gapAnswerTuples);
297//
298// jsonAnswers.put(Integer.toString(queryID), jsonAnswer);
299// }
300 }
301
265 public void outputTimes() { 302 public void outputTimes() {
266 for (Step step: Step.values()) { 303 for (Step step: Step.values()) {
267 Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]); 304 Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]);
268 } 305 }
269 } 306 }
270 307
271 public String outputSoundAnswerTuple() { 308 public String outputSoundAnswerTuple() {
272 StringBuilder builder = new StringBuilder(); 309 StringBuilder builder = new StringBuilder();
273 for (AnswerTuple tuple: soundAnswerTuples) 310 for (AnswerTuple tuple: soundAnswerTuples)
274 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); 311 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR);
275 return builder.toString(); 312 return builder.toString();
276 } 313 }
277 314
278 public String outputGapAnswerTuple() { 315 public String outputGapAnswerTuple() {
279 StringBuilder builder = new StringBuilder(); 316 StringBuilder builder = new StringBuilder();
280 for (AnswerTuple tuple: gapAnswerTuples) 317 for(AnswerTuple tuple : gapAnswerTuples)
281 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); 318 builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR);
282 return builder.toString(); 319 return builder.toString();
283 }
284
285 public void setDifficulty(Step step) {
286 this.diffculty = step;
287 } 320 }
288 321
289 public Step getDifficulty() { 322 public Step getDifficulty() {
290 return diffculty; 323 return difficulty;
291 } 324 }
292 325
293 OWLOntology relevantOntology = null; 326 public void setDifficulty(Step step) {
294 Set<DLClause> relevantClauses = new HashSet<DLClause>(); 327 this.difficulty = step;
295
296 public void setRelevantOntology(OWLOntology knowledgebase) {
297 relevantOntology = knowledgebase;
298 } 328 }
299 329
300 public OWLOntology getRelevantOntology() { 330 public OWLOntology getRelevantOntology() {
301 return relevantOntology; 331 return relevantOntology;
332 }
333
334 public void setRelevantOntology(OWLOntology knowledgebase) {
335 relevantOntology = knowledgebase;
302 } 336 }
303 337
304 public void saveRelevantOntology(String filename) { 338 public void saveRelevantOntology(String filename) {
305 if (relevantOntology == null) return ; 339 if(relevantOntology == null) return;
306 OWLOntologyManager manager = relevantOntology.getOWLOntologyManager(); 340 OWLOntologyManager manager = relevantOntology.getOWLOntologyManager();
307 try { 341 try {
308 FileOutputStream outputStream = new FileOutputStream(filename); 342 FileOutputStream outputStream = new FileOutputStream(filename);
309 manager.saveOntology(relevantOntology, outputStream); 343 manager.saveOntology(relevantOntology, outputStream);
310 outputStream.close(); 344 outputStream.close();
311 } catch (OWLOntologyStorageException e) { 345 } catch (OWLOntologyStorageException e) {
@@ -318,12 +352,11 @@ public class QueryRecord {
318 } 352 }
319 353
320 public void saveRelevantClause() { 354 public void saveRelevantClause() {
321 if (relevantClauses == null) return ; 355 if(relevantClauses == null) return;
322 GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology); 356 GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology);
323 p.save(); 357 p.save();
324 } 358 }
325 359
326
327 public void removeUpperBoundAnswers(Collection<AnswerTuple> answers) { 360 public void removeUpperBoundAnswers(Collection<AnswerTuple> answers) {
328 for (AnswerTuple answer: answers) { 361 for (AnswerTuple answer: answers) {
329// if (soundAnswerTuples.contains(answer)) 362// if (soundAnswerTuples.contains(answer))
@@ -334,50 +367,37 @@ public class QueryRecord {
334 } 367 }
335 } 368 }
336 369
337
338 public void addLowerBoundAnswers(Collection<AnswerTuple> answers) { 370 public void addLowerBoundAnswers(Collection<AnswerTuple> answers) {
339 for (AnswerTuple answer: answers) { 371 for (AnswerTuple answer: answers) {
340 if (!gapAnswerTuples.contains(answer)) 372 if (!gapAnswerTuples.contains(answer))
341 Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); 373 Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound.");
342 gapAnswerTuples.remove(answer); 374 gapAnswerTuples.remove(answer);
343 375
344 answer = AnswerTuple.create(answer, answerVariables[0].length); 376 answer = AnswerTuple.getInstance(answer, answerVariables[0].length);
345// if (soundAnswerTuples.contains(answer)) 377// if (soundAnswerTuples.contains(answer))
346// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound."); 378// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound.");
347 soundAnswerTuples.add(answer); 379 soundAnswerTuples.add(answer);
348 } 380 }
349 } 381 }
350 382
351 public int getNoOfSoundAnswers() { 383 public int getNoOfSoundAnswers() {
352 return soundAnswerTuples.size(); 384 return soundAnswerTuples.size();
353 } 385 }
354
355 public enum Step {LowerBound, UpperBound, ELLowerBound,
356 Fragment, FragmentRefinement, Summarisation, Dependency, FullReasoning};
357
358 double[] timer;
359 386
360 public void addProcessingTime(Step step, double time) { 387 public void addProcessingTime(Step step, double time) {
361 timer[step.ordinal()] += time; 388 timer[step.ordinal()] += time;
362 } 389 }
363 390
364 public int getArity() { 391 public int getArity() {
365 return answerVariables[0].length; 392 return answerVariables[0].length;
366 } 393 }
367
368 public static Collection<String> collectQueryTexts(Collection<QueryRecord> queryRecords) {
369 Collection<String> texts = new LinkedList<String>();
370 for (QueryRecord record: queryRecords)
371 texts.add(record.queryText);
372 return texts;
373 }
374 394
375 public void addRelevantClauses(DLClause clause) { 395 public void addRelevantClauses(DLClause clause) {
376 relevantClauses.add(clause); 396 relevantClauses.add(clause);
377 } 397 }
378 398
379 public Set<DLClause> getRelevantClauses() { 399 public Set<DLClause> getRelevantClauses() {
380 return relevantClauses; 400 return relevantClauses;
381 } 401 }
382 402
383 public void clearClauses() { 403 public void clearClauses() {
@@ -388,36 +408,40 @@ public class QueryRecord {
388 for (DLClause clause: relevantClauses) 408 for (DLClause clause: relevantClauses)
389 if (clause.getHeadLength() > 1) 409 if (clause.getHeadLength() > 1)
390 return false; 410 return false;
391 return true; 411 return true;
392 } 412 }
393 413
394 public void saveABoxInTurtle(String filename) { 414 public void saveABoxInTurtle(String filename) {
395 try { 415 try {
396 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); 416 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
397 OWLIndividual a, b; 417 OWLIndividual a, b;
398 StringBuilder builder = new StringBuilder(); 418 StringBuilder builder = new StringBuilder();
399 for (OWLAxiom axiom: relevantOntology.getABoxAxioms(true)) { 419 for (OWLAxiom axiom: relevantOntology.getABoxAxioms(true)) {
400 if (axiom instanceof OWLClassAssertionAxiom) { 420 if (axiom instanceof OWLClassAssertionAxiom) {
401 OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom; 421 OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom;
402 OWLClass c = (OWLClass) classAssertion.getClassExpression(); 422 OWLClass c = (OWLClass) classAssertion.getClassExpression();
403 a = classAssertion.getIndividual(); 423 a = classAssertion.getIndividual();
404 builder.append(a.toString()).append(" <").append(Namespace.RDF_TYPE).append("> ").append(c.toString()); 424 builder.append(a.toString())
425 .append(" <")
426 .append(Namespace.RDF_TYPE)
427 .append("> ")
428 .append(c.toString());
405 } 429 }
406 else if (axiom instanceof OWLObjectPropertyAssertionAxiom) { 430 else if (axiom instanceof OWLObjectPropertyAssertionAxiom) {
407 OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom; 431 OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom;
408 OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty(); 432 OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty();
409 a = propertyAssertion.getSubject(); 433 a = propertyAssertion.getSubject();
410 b = propertyAssertion.getObject(); 434 b = propertyAssertion.getObject();
411 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString()); 435 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString());
412 } 436 }
413 else if (axiom instanceof OWLDataPropertyAssertionAxiom) { 437 else if (axiom instanceof OWLDataPropertyAssertionAxiom) {
414 OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom; 438 OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom;
415 OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty(); 439 OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty();
416 a = propertyAssertion.getSubject(); 440 a = propertyAssertion.getSubject();
417 OWLLiteral l = propertyAssertion.getObject(); 441 OWLLiteral l = propertyAssertion.getObject();
418 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString()); 442 builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString());
419 } 443 }
420 444
421 writer.write(builder.toString()); 445 writer.write(builder.toString());
422 writer.write(" ."); 446 writer.write(" .");
423 writer.newLine(); 447 writer.newLine();
@@ -427,23 +451,19 @@ public class QueryRecord {
427 } catch (IOException e) { 451 } catch (IOException e) {
428 e.printStackTrace(); 452 e.printStackTrace();
429 } finally { 453 } finally {
430 454
431 } 455 }
432 } 456 }
433
434 int subID;
435 457
436 public void updateSubID() { 458 public void updateSubID() {
437 ++subID; 459 ++subID;
438 stringQueryID = String.valueOf(queryID) + "_" + subID; 460 stringQueryID = String.valueOf(queryID) + "_" + subID;
439 } 461 }
440
441 DLClause queryClause = null;
442 462
443 public DLClause getClause() { 463 public DLClause getClause() {
444 if (queryClause != null) 464 if (queryClause != null)
445 return queryClause; 465 return queryClause;
446 return queryClause = DLClauseHelper.getQuery(queryText, null); 466 return queryClause = DLClauseHelper.getQuery(queryText, null);
447 } 467 }
448 468
449 public boolean isBottom() { 469 public boolean isBottom() {
@@ -453,19 +473,19 @@ public class QueryRecord {
453 public int getNoOfCompleteAnswers() { 473 public int getNoOfCompleteAnswers() {
454 return soundAnswerTuples.size() + gapAnswerTuples.size(); 474 return soundAnswerTuples.size() + gapAnswerTuples.size();
455 } 475 }
456 476
457 public int getSubID() { 477 public int getSubID() {
458 return subID; 478 return subID;
459 } 479 }
460 480
461 public boolean hasSameGapAnswers(QueryRecord that) { 481 public boolean hasSameGapAnswers(QueryRecord that) {
462 return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples); 482 return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples);
463 } 483 }
464 484
465 public void dispose() { 485 public void dispose() {
466 m_manager.remove(queryText); 486 m_manager.remove(queryText);
467 if (gapAnswerTuples != null) gapAnswerTuples = null; 487 if(gapAnswerTuples != null) gapAnswerTuples = null;
468 if (soundAnswerTuples != null) soundAnswerTuples = null; 488 if(soundAnswerTuples != null) soundAnswerTuples = null;
469 if (relevantClauses != null) relevantClauses.clear(); 489 if (relevantClauses != null) relevantClauses.clear();
470 if (relevantOntology != null) 490 if (relevantOntology != null)
471 relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology); 491 relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology);
@@ -473,75 +493,85 @@ public class QueryRecord {
473 } 493 }
474 494
475 public boolean canBeEncodedIntoAtom() { 495 public boolean canBeEncodedIntoAtom() {
476 // FIXME 496 // FIXME
477 return true; 497 return true;
478// return false; 498// return false;
479 } 499 }
480 500
481 public boolean isPredicate(AnswerTuple a, int i) { 501 public boolean isPredicate(AnswerTuple a, int i) {
482 Atom[] atoms = getClause().getBodyAtoms(); 502 Atom[] atoms = getClause().getBodyAtoms();
483 Variable v = Variable.create(answerVariables[1][i]); 503 Variable v = Variable.create(answerVariables[1][i]);
484 String iri; 504 String iri;
485 for (Atom atom: atoms) { 505 for(Atom atom : atoms) {
486 DLPredicate p = atom.getDLPredicate(); 506 DLPredicate p = atom.getDLPredicate();
487 if (p instanceof AtomicConcept) { 507 if (p instanceof AtomicConcept) {
488 if (((AtomicConcept) p).getIRI().equals(v.toString())) return true; 508 if(((AtomicConcept) p).getIRI().equals(v.toString())) return true;
489 } 509 }
490 else if (p instanceof AtomicRole) { 510 else if (p instanceof AtomicRole) {
491 iri = ((AtomicRole) p).getIRI(); 511 iri = ((AtomicRole) p).getIRI();
492 if (iri.equals(v.toString())) return true; 512 if (iri.equals(v.toString())) return true;
493 if (iri.startsWith("?")) 513 if(iri.startsWith("?"))
494 iri = a.getGroundTerm(i).toString(); 514 iri = a.getGroundTerm(i).toString();
495 if (iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true; 515 if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true;
496 } 516 }
497 } 517 }
498 return false; 518 return false;
499 } 519 }
500 520
501 public String[] getExtendedQueryText() { 521 // TODO remove fully extended query
502 String[] ret = new String[2]; 522 public Tuple<String> getExtendedQueryText() {
503 int index = queryText.toUpperCase().indexOf(" WHERE"); 523// String[] ret = new String[2];s
504 String extendedSelect = queryText.substring(0, index); 524 int index = queryText.toUpperCase().indexOf(" WHERE");
525 String extendedSelect = queryText.substring(0, index);
505 String extendedWhere= queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1); 526 String extendedWhere= queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1);
506 527
507 String sub, obj; 528 String sub, obj;
508 Map<String, Set<String>> links = new HashMap<String, Set<String>>(); 529 Map<String, Set<String>> links = new HashMap<String, Set<String>>();
509 Set<String> list; 530 Set<String> list;
510 for (Atom atom: getClause().getBodyAtoms()) 531 for (Atom atom: getClause().getBodyAtoms())
511 if (atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { 532 if (atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) {
512 sub = atom.getArgumentVariable(0).getName(); 533 sub = atom.getArgumentVariable(0).getName();
513 obj = atom.getArgumentVariable(1).getName(); 534 obj = atom.getArgumentVariable(1).getName();
514 if ((list = links.get(sub)) == null) 535 if((list = links.get(sub)) == null)
515 links.put(sub, list = new HashSet<String>()); 536 links.put(sub, list = new HashSet<String>());
516 list.add(obj); 537 list.add(obj);
517 if ((list = links.get(obj)) == null) 538 if((list = links.get(obj)) == null)
518 links.put(obj, list = new HashSet<String>()); 539 links.put(obj, list = new HashSet<String>());
519 list.add(sub); 540 list.add(sub);
520 } 541 }
521 542
522 StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder(); 543 StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder();
523// if (answerVariables[0] != answerVariables[1]) { 544// if (answerVariables[0] != answerVariables[1]) {
524 for (int i = answerVariables[0].length; i < answerVariables[1].length; ++i) { 545 for (int i = answerVariables[0].length; i < answerVariables[1].length; ++i) {
525// for (int i = 0; i < answerVariables[1].length; ++i) { 546// for (int i = 0; i < answerVariables[1].length; ++i) {
526 fullyExtra.append(" . ?").append(answerVariables[1][i]).append(" a <").append(Namespace.PAGODA_ORIGINAL).append(">"); 547 fullyExtra.append(" . ?")
548 .append(answerVariables[1][i])
549 .append(" " + RDF_TYPE + " <")
550 .append(Namespace.PAGODA_ORIGINAL)
551 .append(">");
527 if ((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ; 552 if ((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ;
528 else { 553 else {
529 extra.append(" . ?").append(answerVariables[1][i]).append(" a <").append(Namespace.PAGODA_ORIGINAL).append(">"); 554 extra.append(" . ?")
530 } 555 .append(answerVariables[1][i])
556 .append(" " + RDF_TYPE + " <")
557 .append(Namespace.PAGODA_ORIGINAL)
558 .append(">");
559 }
531 } 560 }
532 561
533 if (extra.length() > 0) { 562 if(extra.length() > 0) {
534 extra.append(" }"); 563 extra.append(" }");
535 extendedWhere = extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString()); 564 extendedWhere = extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString());
536 } 565 }
537 566
538 if (fullyExtra.length() > 0) { 567 if(fullyExtra.length() > 0) {
539 fullyExtra.append(" }"); 568 fullyExtra.append(" }");
540 fullyExtendedWhere = fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra.toString()); 569 fullyExtendedWhere = fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra.toString());
541 } 570 }
542// } 571// }
543 572
544 ret[0] = extendedSelect + " " + fullyExtendedWhere; 573 TupleBuilder result = new TupleBuilder();
574 result.append(extendedSelect + " " + fullyExtendedWhere);
545 575
546 extra.setLength(0); 576 extra.setLength(0);
547 if (answerVariables[0] != answerVariables[1]) { 577 if (answerVariables[0] != answerVariables[1]) {
@@ -549,14 +579,125 @@ public class QueryRecord {
549 extra.append(" ?").append(answerVariables[1][i]); 579 extra.append(" ?").append(answerVariables[1][i]);
550 extendedSelect = extendedSelect + extra.toString(); 580 extendedSelect = extendedSelect + extra.toString();
551 } 581 }
552 ret[1] = extendedSelect + " " + extendedWhere; 582 result.append(extendedSelect + " " + extendedWhere);
553 583
554 return ret; 584 return result.build();
555 } 585 }
556 586
557 public boolean hasNonAnsDistinguishedVariables() { 587 public boolean hasNonAnsDistinguishedVariables() {
558 return answerVariables[1].length > answerVariables[0].length; 588 return answerVariables[1].length > answerVariables[0].length;
559 } 589 }
560
561 590
591 /**
592 * Two <tt>QueryRecords</tt> are equal iff
593 * they have the same <tt>queryText</tt>,
594 * <tt>soundAnswerTuples</tt>.
595 */
596 @Override
597 public boolean equals(Object o) {
598 if(!o.getClass().equals(getClass())) return false;
599 QueryRecord that = (QueryRecord) o;
600 return this.queryText.equals(that.queryText)
601 && soundAnswerTuples.equals(that.soundAnswerTuples);
602 }
603
604 @Override
605 public int hashCode() {
606 return Objects.hash(queryText, soundAnswerTuples);
607 }
608
609 public enum Step {
610 LOWER_BOUND,
611 UPPER_BOUND,
612 SIMPLE_UPPER_BOUND,
613 LAZY_UPPER_BOUND,
614 L_SKOLEM_UPPER_BOUND,
615 EL_LOWER_BOUND,
616 FRAGMENT,
617 FRAGMENT_REFINEMENT,
618 SUMMARISATION,
619 DEPENDENCY,
620 FULL_REASONING
621 }
622
623 /**
624 * A Json serializer, which considers the main attributes.
625 */
626 public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> {
627 public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) {
628 Gson gson = new GsonBuilder().setPrettyPrinting().create();
629 JsonObject object = new JsonObject();
630 object.addProperty("queryID", src.queryID);
631 object.addProperty("queryText", src.queryText);
632// object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : "");
633
634 object.add("answerVariables", context.serialize(src.getAnswerVariables()));
635 object.add("answers", context.serialize(src.soundAnswerTuples));
636// object.add("gapAnswers", context.serialize(src.gapAnswerTuples));
637
638 return object;
639 }
640 }
641
642 /**
643 * A Json deserializer, compliant to the output of the serializer defined above.
644 */
645 public static class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> {
646 public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
647 throws JsonParseException {
648
649 QueryRecord record = new QueryRecord();
650 JsonObject object = json.getAsJsonObject();
651 record.queryID = object.getAsJsonPrimitive("queryID").getAsInt();
652 record.queryText = object.getAsJsonPrimitive("queryText").getAsString();
653// record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString());
654
655 JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables");
656 record.answerVariables = new String[2][];
657 record.answerVariables[0] = new String[answerVariablesJson.size()];
658 for(int i = 0; i < answerVariablesJson.size(); i++)
659 record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString();
660
661 record.soundAnswerTuples = new HashSet<>();
662// record.gapAnswerTuples = new HashSet<>();
663 Type type = new TypeToken<AnswerTuple>() { }.getType();
664 for (JsonElement answer : object.getAsJsonArray("answers")) {
665 record.soundAnswerTuples.add(context.deserialize(answer, type));
666 }
667// for (JsonElement answer : object.getAsJsonArray("gapAnswers")) {
668// record.soundAnswerTuples.add(context.deserialize(answer, type));
669// }
670
671 return record;
672 }
673 }
674
675 /**
676 * Provides an instance (singleton) of Gson, having a specific configuration.
677 * */
678 public static class GsonCreator {
679
680 private static Gson gson;
681
682 private GsonCreator() {}
683
684 public static Gson getInstance() {
685 if(gson == null) {
686 gson = new GsonBuilder()
687 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer())
688 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer())
689 .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer())
690 .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer())
691 .disableHtmlEscaping()
692 .setPrettyPrinting()
693 .create();
694 }
695 return gson;
696 }
697
698// public static void dispose() {
699// gson = null;
700// }
701
702 }
562} 703}