diff options
| author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2022-05-10 18:17:06 +0100 |
|---|---|---|
| committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2022-05-11 12:34:47 +0100 |
| commit | 17bd9beaf7f358a44e5bf36a5855fe6727d506dc (patch) | |
| tree | 47e9310a0cff869d9ec017dcb2c81876407782c8 /src/main/java/uk/ac/ox/cs/pagoda/query | |
| parent | 8651164cd632a5db310b457ce32d4fbc97bdc41c (diff) | |
| download | ACQuA-17bd9beaf7f358a44e5bf36a5855fe6727d506dc.tar.gz ACQuA-17bd9beaf7f358a44e5bf36a5855fe6727d506dc.zip | |
[pagoda] Move project to Scala
This commit includes a few changes:
- The repository still uses Maven to manage dependency but it is now a
Scala project.
- The code has been ported from OWLAPI 3.4.10 to 5.1.20
- A proof of concept program using both RSAComb and PAGOdA has been
added.
Diffstat (limited to 'src/main/java/uk/ac/ox/cs/pagoda/query')
13 files changed, 2828 insertions, 0 deletions
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuple.java new file mode 100644 index 0000000..1e5fbd4 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuple.java | |||
| @@ -0,0 +1,191 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import com.google.gson.*; | ||
| 4 | import org.semanticweb.HermiT.model.Constant; | ||
| 5 | import org.semanticweb.HermiT.model.Individual; | ||
| 6 | import org.semanticweb.HermiT.model.Term; | ||
| 7 | import org.semanticweb.HermiT.model.Variable; | ||
| 8 | import uk.ac.ox.cs.JRDFox.JRDFStoreException; | ||
| 9 | import uk.ac.ox.cs.JRDFox.model.Datatype; | ||
| 10 | import uk.ac.ox.cs.JRDFox.model.GroundTerm; | ||
| 11 | import uk.ac.ox.cs.JRDFox.model.Literal; | ||
| 12 | import uk.ac.ox.cs.JRDFox.store.TupleIterator; | ||
| 13 | import uk.ac.ox.cs.pagoda.util.Namespace; | ||
| 14 | |||
| 15 | import java.lang.reflect.Type; | ||
| 16 | import java.util.HashMap; | ||
| 17 | import java.util.Map; | ||
| 18 | import java.util.StringTokenizer; | ||
| 19 | |||
| 20 | public class AnswerTuple { | ||
| 21 | |||
| 22 | public static final String SEPARATOR = "\t"; | ||
| 23 | String m_str = null; | ||
| 24 | GroundTerm[] m_tuple; | ||
| 25 | |||
| 26 | public AnswerTuple(TupleIterator iter, int arity) { | ||
| 27 | m_tuple = new GroundTerm[arity]; | ||
| 28 | try { | ||
| 29 | for (int i = 0; i < arity; ++i) | ||
| 30 | m_tuple[i] = iter.getGroundTerm(i); | ||
| 31 | } catch (JRDFStoreException e) { | ||
| 32 | e.printStackTrace(); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | public AnswerTuple(GroundTerm[] terms) { | ||
| 37 | m_tuple = terms; | ||
| 38 | } | ||
| 39 | |||
| 40 | // private AnswerTuple(String m_str) { | ||
| 41 | // this.m_str = m_str; | ||
| 42 | // } | ||
| 43 | |||
| 44 | private AnswerTuple(AnswerTuple sup, int arity) { | ||
| 45 | m_tuple = new GroundTerm[arity]; | ||
| 46 | for(int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i]; | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * It returns the first argument if its arity equals length, a new AnswerTuple otherwise. | ||
| 51 | */ | ||
| 52 | public static AnswerTuple create(AnswerTuple extendedTuple, int length) { | ||
| 53 | if(length == extendedTuple.getArity()) return extendedTuple; | ||
| 54 | else return new AnswerTuple(extendedTuple, length); | ||
| 55 | } | ||
| 56 | |||
| 57 | public int getArity() { | ||
| 58 | return m_tuple.length; | ||
| 59 | } | ||
| 60 | |||
| 61 | public int hashCode() { | ||
| 62 | // return toString().hashCode(); | ||
| 63 | int code = 0; | ||
| 64 | for (int i = 0; i < m_tuple.length; ++i) | ||
| 65 | code = code * 1997 + m_tuple[i].hashCode(); | ||
| 66 | return code; | ||
| 67 | } | ||
| 68 | |||
| 69 | public boolean equals(Object obj) { | ||
| 70 | if (!(obj instanceof AnswerTuple)) return false; | ||
| 71 | AnswerTuple that = (AnswerTuple) obj; | ||
| 72 | if (m_tuple.length != that.m_tuple.length) return false; | ||
| 73 | for (int i = 0; i < m_tuple.length; ++i) | ||
| 74 | if (!m_tuple[i].equals(that.m_tuple[i])) | ||
| 75 | return false; | ||
| 76 | return true; | ||
| 77 | // return toString().equals(obj.toString()); | ||
| 78 | } | ||
| 79 | |||
| 80 | public String toString() { | ||
| 81 | if(m_str != null) return m_str; | ||
| 82 | StringBuilder sb = new StringBuilder(); | ||
| 83 | for (int i = 0; i < m_tuple.length; ++i) { | ||
| 84 | if (sb.length() != 0) sb.append(SEPARATOR); | ||
| 85 | if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual) | ||
| 86 | sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">"); | ||
| 87 | else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) { | ||
| 88 | sb.append(m_tuple[i].toString()); | ||
| 89 | } | ||
| 90 | else { | ||
| 91 | Literal l = (Literal) m_tuple[i]; | ||
| 92 | sb.append('"').append(l.getLexicalForm()).append("\""); | ||
| 93 | if (!l.getDatatype().equals(Datatype.XSD_STRING) && !l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL)) | ||
| 94 | sb.append("^^<").append(l.getDatatype().getIRI()).append(">"); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | return m_str = sb.toString(); | ||
| 98 | } | ||
| 99 | |||
| 100 | public GroundTerm getGroundTerm(int i) { | ||
| 101 | return m_tuple[i]; | ||
| 102 | } | ||
| 103 | |||
| 104 | public Map<Variable, Term> getAssignment(String[] vars) { | ||
| 105 | Map<Variable, Term> map = new HashMap<Variable, Term>(); | ||
| 106 | int index = 0; | ||
| 107 | Term t; | ||
| 108 | for (String var: vars) { | ||
| 109 | if(m_tuple[index] instanceof uk.ac.ox.cs.JRDFox.model.Individual) | ||
| 110 | t = Individual.create((((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[index]).getIRI())); | ||
| 111 | else { | ||
| 112 | uk.ac.ox.cs.JRDFox.model.Literal l = (uk.ac.ox.cs.JRDFox.model.Literal) m_tuple[index]; | ||
| 113 | t = Constant.create(l.getLexicalForm(), l.getDatatype().getIRI()); | ||
| 114 | } | ||
| 115 | map.put(Variable.create(var), t); | ||
| 116 | ++index; | ||
| 117 | } | ||
| 118 | return map; | ||
| 119 | } | ||
| 120 | |||
| 121 | public boolean hasAuxPredicate() { | ||
| 122 | String iri; | ||
| 123 | for (int i = 0; i < m_tuple.length; ++i) | ||
| 124 | if ((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) { | ||
| 125 | iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI(); | ||
| 126 | if(iri.startsWith(Namespace.PAGODA_AUX) || iri.contains("_AUX") || iri.contains("_neg") || iri.contains("internal:def")) | ||
| 127 | return true; | ||
| 128 | } | ||
| 129 | return false; | ||
| 130 | } | ||
| 131 | |||
| 132 | public boolean hasAnonymousIndividual() { | ||
| 133 | String iri; | ||
| 134 | for(int i = 0; i < m_tuple.length; ++i) | ||
| 135 | if((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) { | ||
| 136 | iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI(); | ||
| 137 | if(iri.startsWith(Namespace.PAGODA_ANONY) || iri.startsWith(Namespace.KARMA_ANONY)) | ||
| 138 | return true; | ||
| 139 | } | ||
| 140 | return false; | ||
| 141 | } | ||
| 142 | |||
| 143 | public static class AnswerTupleSerializer implements JsonSerializer<AnswerTuple> { | ||
| 144 | |||
| 145 | public JsonElement serialize(AnswerTuple src, Type typeOfSrc, JsonSerializationContext context) { | ||
| 146 | return new JsonPrimitive(src.toString()); | ||
| 147 | } | ||
| 148 | |||
| 149 | } | ||
| 150 | |||
| 151 | public static class AnswerTupleDeserializer implements JsonDeserializer<AnswerTuple> { | ||
| 152 | public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | ||
| 153 | throws JsonParseException { | ||
| 154 | String tuplesString = json.getAsJsonPrimitive().getAsString(); | ||
| 155 | // StringTokenizer tokenizer = new StringTokenizer(tuplesString, SEPARATOR); | ||
| 156 | StringTokenizer tokenizer = new StringTokenizer(tuplesString); | ||
| 157 | int tokensCount = tokenizer.countTokens(); | ||
| 158 | GroundTerm[] terms = new GroundTerm[tokensCount]; | ||
| 159 | |||
| 160 | // TODO test parsing | ||
| 161 | for(int i = 0; i < tokensCount; i++) { | ||
| 162 | String token = tokenizer.nextToken(); | ||
| 163 | if (token.charAt(0) == '<') { | ||
| 164 | terms[i] = uk.ac.ox.cs.JRDFox.model.Individual.create(token.substring(1,token.length()-1)); | ||
| 165 | } | ||
| 166 | else if (token.charAt(0) == '"') { | ||
| 167 | Datatype datatype; | ||
| 168 | String lexicalForm; | ||
| 169 | if(token.contains("^^")) { | ||
| 170 | String[] lexicalFormAndType = token.split("^^"); | ||
| 171 | lexicalForm = lexicalFormAndType[0]; | ||
| 172 | datatype = Datatype.value(lexicalFormAndType[1]); | ||
| 173 | } | ||
| 174 | else { | ||
| 175 | lexicalForm = token.substring(1, token.length() - 1); | ||
| 176 | // TODO check | ||
| 177 | // datatype = token.contains("@") ? Datatype.RDF_PLAIN_LITERAL : Datatype.XSD_STRING; | ||
| 178 | datatype = Datatype.XSD_STRING; | ||
| 179 | } | ||
| 180 | terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, datatype); | ||
| 181 | } | ||
| 182 | else { | ||
| 183 | terms[i] = uk.ac.ox.cs.JRDFox.model.BlankNode.create(token); | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | return new AnswerTuple(terms); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuples.java b/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuples.java new file mode 100644 index 0000000..81efed0 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuples.java | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import uk.ac.ox.cs.pagoda.util.disposable.Disposable; | ||
| 4 | |||
| 5 | public abstract class AnswerTuples extends Disposable { | ||
| 6 | |||
| 7 | public abstract void reset(); | ||
| 8 | |||
| 9 | public abstract boolean isValid(); | ||
| 10 | |||
| 11 | public abstract int getArity(); | ||
| 12 | |||
| 13 | public abstract String[] getAnswerVariables(); | ||
| 14 | |||
| 15 | public abstract void moveNext(); | ||
| 16 | |||
| 17 | public abstract AnswerTuple getTuple(); | ||
| 18 | |||
| 19 | public abstract boolean contains(AnswerTuple t); | ||
| 20 | |||
| 21 | public abstract void remove(); | ||
| 22 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java b/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java new file mode 100644 index 0000000..fd3fb1f --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import java.util.Iterator; | ||
| 4 | import java.util.Set; | ||
| 5 | |||
| 6 | public class AnswerTuplesImp extends AnswerTuples { | ||
| 7 | |||
| 8 | int m_index; | ||
| 9 | Iterator<AnswerTuple> m_iter; | ||
| 10 | Set<AnswerTuple> m_answers1, m_answers2; | ||
| 11 | String[] m_answerVars; | ||
| 12 | AnswerTuple m_tuple; | ||
| 13 | |||
| 14 | public AnswerTuplesImp(String[] answerVars, Set<AnswerTuple> answers) { | ||
| 15 | m_answers1 = answers; | ||
| 16 | m_answers2 = null; | ||
| 17 | m_answerVars = answerVars; | ||
| 18 | reset(); | ||
| 19 | } | ||
| 20 | |||
| 21 | public AnswerTuplesImp(String[] answerVars, Set<AnswerTuple> answers1, Set<AnswerTuple> answers2) { | ||
| 22 | m_answers1 = answers1; | ||
| 23 | m_answers2 = answers2; | ||
| 24 | m_answerVars = answerVars; | ||
| 25 | reset(); | ||
| 26 | } | ||
| 27 | |||
| 28 | @Override | ||
| 29 | public boolean isValid() { | ||
| 30 | return m_tuple != null; | ||
| 31 | } | ||
| 32 | |||
| 33 | @Override | ||
| 34 | public int getArity() { | ||
| 35 | return m_answerVars.length; | ||
| 36 | } | ||
| 37 | |||
| 38 | @Override | ||
| 39 | public void moveNext() { | ||
| 40 | if (m_iter != null && m_iter.hasNext()) { | ||
| 41 | m_tuple = m_iter.next(); | ||
| 42 | return ; | ||
| 43 | } | ||
| 44 | else if (m_answers2 != null && m_index == 1){ | ||
| 45 | ++m_index; | ||
| 46 | m_iter = m_answers2.iterator(); | ||
| 47 | if (m_iter.hasNext()) { | ||
| 48 | m_tuple = m_iter.next(); | ||
| 49 | return ; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | else | ||
| 53 | m_tuple = null; | ||
| 54 | } | ||
| 55 | |||
| 56 | @Override | ||
| 57 | public void reset() { | ||
| 58 | if (m_answers1 == null || m_answers1.isEmpty()) { | ||
| 59 | m_index = 2; | ||
| 60 | m_iter = m_answers2 == null ? null : m_answers2.iterator(); | ||
| 61 | } | ||
| 62 | else { | ||
| 63 | m_index = 1; | ||
| 64 | m_iter = m_answers1.iterator(); | ||
| 65 | } | ||
| 66 | moveNext(); | ||
| 67 | } | ||
| 68 | |||
| 69 | @Override | ||
| 70 | public boolean contains(AnswerTuple t) { | ||
| 71 | return m_answers1.contains(t) || (m_answers2 != null && m_answers2.contains(t)); | ||
| 72 | } | ||
| 73 | |||
| 74 | @Override | ||
| 75 | public AnswerTuple getTuple() { | ||
| 76 | return m_tuple; | ||
| 77 | } | ||
| 78 | |||
| 79 | @Override | ||
| 80 | public String[] getAnswerVariables() { | ||
| 81 | return m_answerVars; | ||
| 82 | } | ||
| 83 | |||
| 84 | @Override | ||
| 85 | public void remove() { | ||
| 86 | m_iter.remove(); | ||
| 87 | } | ||
| 88 | |||
| 89 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java b/src/main/java/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java new file mode 100644 index 0000000..3d25eaf --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | package 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 | * */ | ||
| 7 | public class DeserializedQueryRecord { | ||
| 8 | // TODO implement | ||
| 9 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID.java b/src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID.java new file mode 100644 index 0000000..84929ad --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID.java | |||
| @@ -0,0 +1,191 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import java.util.HashMap; | ||
| 4 | import java.util.LinkedList; | ||
| 5 | import java.util.Map; | ||
| 6 | |||
| 7 | import uk.ac.ox.cs.pagoda.MyPrefixes; | ||
| 8 | //import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID; | ||
| 9 | import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; | ||
| 10 | import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; | ||
| 11 | import uk.ac.ox.cs.pagoda.util.Namespace; | ||
| 12 | import uk.ac.ox.cs.pagoda.util.Timer; | ||
| 13 | import uk.ac.ox.cs.pagoda.util.Utility; | ||
| 14 | import uk.ac.ox.cs.JRDFox.JRDFStoreException; | ||
| 15 | import uk.ac.ox.cs.JRDFox.store.DataStore; | ||
| 16 | import uk.ac.ox.cs.JRDFox.store.TupleIterator; | ||
| 17 | |||
| 18 | //public class GapByStore4ID extends GapTupleIterator<AnswerTupleID> { | ||
| 19 | public class GapByStore4ID extends GapTupleIterator<int[]> { | ||
| 20 | |||
| 21 | protected MyPrefixes prefixes = MyPrefixes.PAGOdAPrefixes; | ||
| 22 | protected TupleIterator iterator = null; | ||
| 23 | |||
| 24 | // AnswerTupleID tuple; | ||
| 25 | protected int[] tuple; | ||
| 26 | protected BasicQueryEngine m_engine; | ||
| 27 | protected DataStore m_store; | ||
| 28 | protected RDFoxTripleManager tripleManager; | ||
| 29 | |||
| 30 | public GapByStore4ID(BasicQueryEngine engine) { | ||
| 31 | m_engine = engine; | ||
| 32 | m_store = engine.getDataStore(); | ||
| 33 | tripleManager = new RDFoxTripleManager(m_store, false); | ||
| 34 | } | ||
| 35 | |||
| 36 | protected long multi; | ||
| 37 | |||
| 38 | @Override | ||
| 39 | public void compile(String program) throws JRDFStoreException { | ||
| 40 | clear(); | ||
| 41 | |||
| 42 | boolean incrementally = true; | ||
| 43 | Timer t = new Timer(); | ||
| 44 | long oldTripleCount = m_store.getTriplesCount(); | ||
| 45 | |||
| 46 | if (program != null) { | ||
| 47 | // m_store.addRules(new String[] {program}); | ||
| 48 | m_store.importRules(program); | ||
| 49 | incrementally = false; | ||
| 50 | } | ||
| 51 | |||
| 52 | m_store.applyReasoning(incrementally); | ||
| 53 | |||
| 54 | long tripleCount = m_store.getTriplesCount(); | ||
| 55 | |||
| 56 | Utility.logDebug("current store after materialising upper related rules: " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)", | ||
| 57 | "current store finished the materialisation of upper related rules in " + t.duration() + " seconds."); | ||
| 58 | |||
| 59 | m_engine.setExpandEquality(false); | ||
| 60 | iterator = m_engine.internal_evaluateAgainstIDBs("select ?x ?y ?z where { ?x ?y ?z . }"); | ||
| 61 | m_engine.setExpandEquality(true); | ||
| 62 | |||
| 63 | multi = iterator.open(); | ||
| 64 | Utility.logDebug("gap query evaluted ..."); | ||
| 65 | } | ||
| 66 | |||
| 67 | @Override | ||
| 68 | public boolean hasNext() { | ||
| 69 | if (iterator == null) return false; | ||
| 70 | try { | ||
| 71 | // tuple = new AnswerTupleID(3); | ||
| 72 | tuple = new int[3]; | ||
| 73 | Integer predicate; | ||
| 74 | for (; multi != 0; multi = iterator.getNext()) { | ||
| 75 | for (int i = 0; i < 3; ++i) | ||
| 76 | // tuple.setTerm(i, (int) iterator.getResourceID(i)); | ||
| 77 | tuple[i] = (int) iterator.getResourceID(i); | ||
| 78 | |||
| 79 | if (isRDF_TYPE()) { | ||
| 80 | // predicate = getGapPredicateID(tuple.getTerm(2)); | ||
| 81 | predicate = getGapPredicateID(tuple[2]); | ||
| 82 | if (predicate == null) continue; | ||
| 83 | // tuple.setTerm(2, predicate); | ||
| 84 | tuple[2] = predicate; | ||
| 85 | } | ||
| 86 | else { | ||
| 87 | // predicate = getGapPredicateID(tuple.getTerm(1)); | ||
| 88 | predicate = getGapPredicateID(tuple[1]); | ||
| 89 | if (predicate == null) continue; | ||
| 90 | // tuple.setTerm(1, predicate); | ||
| 91 | tuple[1] = predicate; | ||
| 92 | } | ||
| 93 | return true; | ||
| 94 | } | ||
| 95 | } catch (JRDFStoreException e) { | ||
| 96 | e.printStackTrace(); | ||
| 97 | return false; | ||
| 98 | } | ||
| 99 | return false; | ||
| 100 | } | ||
| 101 | |||
| 102 | @Override | ||
| 103 | // public AnswerTupleID next() { | ||
| 104 | public int[] next() { | ||
| 105 | try { | ||
| 106 | multi = iterator.getNext(); | ||
| 107 | } catch (JRDFStoreException e) { | ||
| 108 | e.printStackTrace(); | ||
| 109 | } | ||
| 110 | |||
| 111 | return tuple; | ||
| 112 | } | ||
| 113 | |||
| 114 | Map<Integer, Integer> original2gap = new HashMap<Integer, Integer>(); | ||
| 115 | LinkedList<String> predicatesWithGap = new LinkedList<String>(); | ||
| 116 | |||
| 117 | public LinkedList<String> getPredicatesWithGap() { | ||
| 118 | return predicatesWithGap; | ||
| 119 | } | ||
| 120 | |||
| 121 | protected Integer getGapPredicateID(int originalID) { | ||
| 122 | Integer gapID; | ||
| 123 | if ((gapID = original2gap.get(originalID)) != null) | ||
| 124 | return gapID; | ||
| 125 | |||
| 126 | String originalPredicate = tripleManager.getRawTerm(originalID); | ||
| 127 | if (isAuxPredicate(originalPredicate)) { | ||
| 128 | // Utility.LOGS.info(originalPredicate); | ||
| 129 | return null; | ||
| 130 | } | ||
| 131 | |||
| 132 | predicatesWithGap.add(originalPredicate); | ||
| 133 | String gapPredicate = prefixes.expandIRI(getGapPredicate(originalPredicate)); | ||
| 134 | gapID = tripleManager.getResourceID(gapPredicate); | ||
| 135 | original2gap.put(originalID, gapID); | ||
| 136 | |||
| 137 | return gapID; | ||
| 138 | } | ||
| 139 | |||
| 140 | protected boolean isAuxPredicate(String originalPredicate) { | ||
| 141 | if (originalPredicate.equals(Namespace.EQUALITY_QUOTED)) return false; | ||
| 142 | return originalPredicate.contains("_AUX") || | ||
| 143 | originalPredicate.startsWith("<" + Namespace.OWL_NS) || | ||
| 144 | originalPredicate.startsWith("<" + Namespace.PAGODA_ORIGINAL); | ||
| 145 | } | ||
| 146 | |||
| 147 | protected boolean isRDF_TYPE() { | ||
| 148 | // return tripleManager.isRdfTypeID(tuple.getTerm(1)); | ||
| 149 | return tripleManager.isRdfTypeID(tuple[1]); | ||
| 150 | } | ||
| 151 | |||
| 152 | @Override | ||
| 153 | public void remove() { | ||
| 154 | Utility.logError("Unsupported operation!"); | ||
| 155 | } | ||
| 156 | |||
| 157 | @Override | ||
| 158 | public void save(String file) { | ||
| 159 | Utility.logError("Unsupported Operation..."); | ||
| 160 | } | ||
| 161 | |||
| 162 | @Override | ||
| 163 | public void addBackTo() throws JRDFStoreException { | ||
| 164 | int tupleCounter = 0; | ||
| 165 | Timer t = new Timer(); | ||
| 166 | long oldTripleCounter; | ||
| 167 | Utility.logDebug("current store before importing gap tuples: " + (oldTripleCounter = m_store.getTriplesCount())); | ||
| 168 | while (hasNext()) { | ||
| 169 | next(); | ||
| 170 | ++tupleCounter; | ||
| 171 | tripleManager.addTripleByID(tuple); | ||
| 172 | } | ||
| 173 | |||
| 174 | long tripleCounter = m_store.getTriplesCount(); | ||
| 175 | Utility.logDebug("There are " + tupleCounter + " tuples in the gap between lower and upper bound materialisation.", | ||
| 176 | "current store after importing gap tuples: " + tripleCounter + " (" + (tripleCounter - oldTripleCounter) + ").", | ||
| 177 | "current store finished importing gap tuples: " + tripleCounter + " in " + t.duration() + "."); | ||
| 178 | } | ||
| 179 | |||
| 180 | public void clear() { | ||
| 181 | if (iterator != null) { | ||
| 182 | iterator.dispose(); | ||
| 183 | iterator = null; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | @Override | ||
| 188 | public void addTo(DataStore store) throws JRDFStoreException { | ||
| 189 | Utility.logError("Unsupported Operation..."); | ||
| 190 | } | ||
| 191 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID2.java b/src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID2.java new file mode 100644 index 0000000..f8e1709 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID2.java | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import java.util.HashMap; | ||
| 4 | import java.util.HashSet; | ||
| 5 | import java.util.LinkedList; | ||
| 6 | import java.util.Map; | ||
| 7 | import java.util.Set; | ||
| 8 | |||
| 9 | import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; | ||
| 10 | import uk.ac.ox.cs.pagoda.util.UFS; | ||
| 11 | import uk.ac.ox.cs.JRDFox.JRDFStoreException; | ||
| 12 | import uk.ac.ox.cs.JRDFox.store.TupleIterator; | ||
| 13 | |||
| 14 | public class GapByStore4ID2 extends GapByStore4ID { | ||
| 15 | |||
| 16 | private BasicQueryEngine m_baseEngine; | ||
| 17 | private UFS<String> m_equality = null, m_baseEquality = null; | ||
| 18 | |||
| 19 | public GapByStore4ID2(BasicQueryEngine engine, BasicQueryEngine baseEngine) { | ||
| 20 | super(engine); | ||
| 21 | m_baseEngine = baseEngine; | ||
| 22 | } | ||
| 23 | |||
| 24 | @Override | ||
| 25 | public boolean hasNext() { | ||
| 26 | if (getNewGapTuple(iterator, -1)) return true; | ||
| 27 | if (iterator != null) { | ||
| 28 | iterator.dispose(); | ||
| 29 | iterator = null; | ||
| 30 | } | ||
| 31 | return getNextGapFactAboutEquality(); | ||
| 32 | } | ||
| 33 | |||
| 34 | private boolean getNewGapTuple(TupleIterator it, int firstElement) { | ||
| 35 | if (it == null) return false; | ||
| 36 | int firstIndex = 0; | ||
| 37 | tuple = new int[3]; | ||
| 38 | if (firstElement > 0) { | ||
| 39 | tuple[0] = firstElement; | ||
| 40 | firstIndex = 1; | ||
| 41 | } | ||
| 42 | Integer predicate; | ||
| 43 | try { | ||
| 44 | for (; multi != 0; multi = it.getNext()) { | ||
| 45 | for (int i = firstIndex; i < 3; ++i) | ||
| 46 | tuple[i] = (int) it.getResourceID(i - firstIndex); | ||
| 47 | |||
| 48 | if (isRDF_TYPE()) { | ||
| 49 | predicate = getGapPredicateID(tuple[2]); | ||
| 50 | if (predicate == null) continue; | ||
| 51 | tuple[2] = predicate; | ||
| 52 | } | ||
| 53 | else { | ||
| 54 | predicate = getGapPredicateID(tuple[1]); | ||
| 55 | if (predicate == null) continue; | ||
| 56 | tuple[1] = predicate; | ||
| 57 | } | ||
| 58 | return true; | ||
| 59 | } | ||
| 60 | } catch (JRDFStoreException e) { | ||
| 61 | e.printStackTrace(); | ||
| 62 | return false; | ||
| 63 | } | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | |||
| 67 | private LinkedList<String> toAddedIndividuals = null; | ||
| 68 | private TupleIterator iter_individual = null; | ||
| 69 | private int currentID = -1; | ||
| 70 | |||
| 71 | private boolean getNextGapFactAboutEquality() { | ||
| 72 | if (toAddedIndividuals == null) { | ||
| 73 | m_equality = m_engine.getEqualityGroups(false); | ||
| 74 | m_baseEquality = m_baseEngine.getEqualityGroups(false); | ||
| 75 | toAddedIndividuals = new LinkedList<String>(); | ||
| 76 | Map<String, Integer> rep2cnt = new HashMap<String, Integer>(); | ||
| 77 | Map<String, Integer> rep2cnt_base = new HashMap<String, Integer>(); | ||
| 78 | count(m_engine, m_equality, rep2cnt); | ||
| 79 | count(m_baseEngine, m_baseEquality, rep2cnt_base); | ||
| 80 | Set<String> visitedrep = new HashSet<String>(); | ||
| 81 | for (String individual : m_equality.keySet()) { | ||
| 82 | String rep = m_equality.find(individual); | ||
| 83 | if (visitedrep.contains(rep)) continue; | ||
| 84 | visitedrep.add(rep); | ||
| 85 | String rep_base = m_baseEquality.find(individual); | ||
| 86 | if (!rep2cnt.get(rep).equals(rep2cnt_base.get(rep_base))) { | ||
| 87 | toAddedIndividuals.add(rep); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | } | ||
| 92 | while (true) { | ||
| 93 | if (getNewGapTuple(iter_individual, currentID)) return true; | ||
| 94 | if (iter_individual != null) { | ||
| 95 | iter_individual.dispose(); | ||
| 96 | iter_individual = null; | ||
| 97 | } | ||
| 98 | if (toAddedIndividuals.isEmpty()) { | ||
| 99 | currentID = -1; | ||
| 100 | return false; | ||
| 101 | } | ||
| 102 | String individual = toAddedIndividuals.remove(); | ||
| 103 | currentID = tripleManager.getResourceID(individual); | ||
| 104 | try { | ||
| 105 | iter_individual = m_engine.internal_evaluateNotExpanded(String.format("select distinct ?y ?z where { <%s> ?y ?z }", individual)); | ||
| 106 | multi = iter_individual.open(); | ||
| 107 | } catch (JRDFStoreException e) { | ||
| 108 | e.printStackTrace(); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | private void count(BasicQueryEngine engine, UFS<String> equality, Map<String, Integer> map) { | ||
| 114 | for (String ind : equality.keySet()) { | ||
| 115 | Integer exist = map.get(ind); | ||
| 116 | if (exist == null) | ||
| 117 | map.put(equality.find(ind), 1); | ||
| 118 | else | ||
| 119 | map.put(equality.find(ind), ++exist); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | @Override | ||
| 124 | public int[] next() { | ||
| 125 | try { | ||
| 126 | if (iterator != null) | ||
| 127 | multi = iterator.getNext(); | ||
| 128 | else if (iter_individual != null) | ||
| 129 | multi = iter_individual.getNext(); | ||
| 130 | else | ||
| 131 | multi = 0; | ||
| 132 | } catch (JRDFStoreException e) { | ||
| 133 | e.printStackTrace(); | ||
| 134 | } | ||
| 135 | return tuple; | ||
| 136 | } | ||
| 137 | |||
| 138 | public void clear() { | ||
| 139 | super.clear(); | ||
| 140 | if (iter_individual != null) { | ||
| 141 | iter_individual.dispose(); | ||
| 142 | iter_individual = null; | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/GapByTriple.java b/src/main/java/uk/ac/ox/cs/pagoda/query/GapByTriple.java new file mode 100644 index 0000000..eaa629b --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/GapByTriple.java | |||
| @@ -0,0 +1,163 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import org.semanticweb.HermiT.model.*; | ||
| 4 | import uk.ac.ox.cs.JRDFox.JRDFStoreException; | ||
| 5 | import uk.ac.ox.cs.JRDFox.Prefixes; | ||
| 6 | import uk.ac.ox.cs.JRDFox.store.DataStore; | ||
| 7 | import uk.ac.ox.cs.JRDFox.store.Parameters; | ||
| 8 | import uk.ac.ox.cs.JRDFox.store.TupleIterator; | ||
| 9 | import uk.ac.ox.cs.pagoda.MyPrefixes; | ||
| 10 | import uk.ac.ox.cs.pagoda.owl.OWLHelper; | ||
| 11 | import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; | ||
| 12 | import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; | ||
| 13 | import uk.ac.ox.cs.pagoda.util.Namespace; | ||
| 14 | import uk.ac.ox.cs.pagoda.util.Utility; | ||
| 15 | |||
| 16 | import java.io.BufferedWriter; | ||
| 17 | import java.io.FileOutputStream; | ||
| 18 | import java.io.IOException; | ||
| 19 | import java.io.OutputStreamWriter; | ||
| 20 | import java.util.Collection; | ||
| 21 | |||
| 22 | public class GapByTriple extends GapTupleIterator<String> { | ||
| 23 | |||
| 24 | static final String allTripleQuery = "SELECT ?X ?Y ?Z WHERE { ?X ?Y ?Z }"; | ||
| 25 | private static final String RDF_TYPE = Namespace.RDF_NS + "type"; | ||
| 26 | private static final String BRIEF_RDF_TYPE = "rdf:type"; | ||
| 27 | DataStore lowerStore, upperStore; | ||
| 28 | long multi; | ||
| 29 | TupleIterator iterator; | ||
| 30 | String sub, obj, predicate; | ||
| 31 | // GroundTerm subTerm, objTerm; | ||
| 32 | Prefixes prefixes; | ||
| 33 | Parameters parameters; | ||
| 34 | |||
| 35 | public GapByTriple(BasicQueryEngine lowerStore, BasicQueryEngine upperStore) { | ||
| 36 | this.lowerStore = lowerStore.getDataStore(); | ||
| 37 | this.upperStore = upperStore.getDataStore(); | ||
| 38 | prefixes = MyPrefixes.PAGOdAPrefixes.getRDFoxPrefixes(); | ||
| 39 | parameters = new Parameters(); | ||
| 40 | } | ||
| 41 | |||
| 42 | public void compile(Collection<DLClause> clauses) throws JRDFStoreException { | ||
| 43 | iterator = this.upperStore.compileQuery(allTripleQuery, prefixes, parameters); | ||
| 44 | multi = iterator.open(); | ||
| 45 | } | ||
| 46 | |||
| 47 | @Override | ||
| 48 | public boolean hasNext() { | ||
| 49 | TupleIterator iter = null; | ||
| 50 | boolean inGap; | ||
| 51 | StringBuffer queryBuffer = new StringBuffer(); | ||
| 52 | try { | ||
| 53 | for (; multi != 0; multi = iterator.getNext()) { | ||
| 54 | // iterator.getRawGroundTerm(0); | ||
| 55 | // iterator.getRawGroundTerm(1); | ||
| 56 | // iterator.getRawGroundTerm(2); | ||
| 57 | |||
| 58 | sub = RDFoxTripleManager.getQuotedTerm(iterator.getResource(0)); | ||
| 59 | predicate = RDFoxTripleManager.getQuotedTerm(iterator.getResource(1)); | ||
| 60 | obj = RDFoxTripleManager.getQuotedTerm(iterator.getResource(2)); | ||
| 61 | |||
| 62 | if (!obj.startsWith("<")) { | ||
| 63 | // This fragment of code ignores data types assertions. | ||
| 64 | // Utility.LOGS.info(sub + " " + predicate + " " + obj); | ||
| 65 | continue; | ||
| 66 | } | ||
| 67 | |||
| 68 | queryBuffer.setLength(0); | ||
| 69 | queryBuffer.append("SELECT WHERE { ").append(sub).append(" ").append(predicate).append(" ").append(obj).append(" }"); | ||
| 70 | |||
| 71 | try { | ||
| 72 | iter = lowerStore.compileQuery(queryBuffer.toString(), prefixes, parameters); | ||
| 73 | inGap = iter.open() != 0; | ||
| 74 | } finally { | ||
| 75 | if (iter != null) iter.dispose(); | ||
| 76 | iter = null; | ||
| 77 | } | ||
| 78 | if (inGap) | ||
| 79 | return true; | ||
| 80 | } | ||
| 81 | } catch (JRDFStoreException e) { | ||
| 82 | // TODO Auto-generated catch block | ||
| 83 | e.printStackTrace(); | ||
| 84 | } | ||
| 85 | return false; | ||
| 86 | } | ||
| 87 | |||
| 88 | @Override | ||
| 89 | public String next() { | ||
| 90 | try { | ||
| 91 | multi = iterator.getNext(); | ||
| 92 | } catch (JRDFStoreException e) { | ||
| 93 | e.printStackTrace(); | ||
| 94 | } | ||
| 95 | StringBuilder sb = new StringBuilder(); | ||
| 96 | if (isRDF_TYPE()) { | ||
| 97 | sb.append(sub).append(" ").append(predicate).append(" ").append(getGapPredicate(obj)).append("."); | ||
| 98 | } | ||
| 99 | else sb.append(sub).append(" ").append(getGapPredicate(predicate)).append(" ").append(obj).append("."); | ||
| 100 | return sb.toString(); | ||
| 101 | } | ||
| 102 | |||
| 103 | private boolean isRDF_TYPE() { | ||
| 104 | return predicate.equals(RDF_TYPE) || predicate.equals(BRIEF_RDF_TYPE); | ||
| 105 | } | ||
| 106 | |||
| 107 | @Override | ||
| 108 | public void remove() { | ||
| 109 | Utility.logError("Unsupported operation!"); | ||
| 110 | } | ||
| 111 | |||
| 112 | public void save(String file) { | ||
| 113 | int tupleCounter = 0; | ||
| 114 | try { | ||
| 115 | BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))); | ||
| 116 | String tuple; | ||
| 117 | while (hasNext()) { | ||
| 118 | tuple = next(); | ||
| 119 | writer.write(tuple); | ||
| 120 | writer.newLine(); | ||
| 121 | ++tupleCounter; | ||
| 122 | } | ||
| 123 | writer.close(); | ||
| 124 | } catch (IOException e) { | ||
| 125 | e.printStackTrace(); | ||
| 126 | } | ||
| 127 | |||
| 128 | Utility.logError("There are " + tupleCounter + " tuples in the gap between lower and upper bound materialisation."); | ||
| 129 | } | ||
| 130 | |||
| 131 | public void addTo(DataStore store) throws JRDFStoreException { | ||
| 132 | int tupleCounter = 0; | ||
| 133 | RDFoxTripleManager tripleManager = new RDFoxTripleManager(store, false); | ||
| 134 | while (hasNext()) { | ||
| 135 | multi = iterator.getNext(); | ||
| 136 | ++tupleCounter; | ||
| 137 | if (isRDF_TYPE()) { | ||
| 138 | obj = OWLHelper.removeAngles(obj); | ||
| 139 | tripleManager.addTripleByTerm( | ||
| 140 | Atom.create(AtomicConcept.create(getGapPredicate(obj)), Individual.create(sub))); | ||
| 141 | } | ||
| 142 | else { | ||
| 143 | predicate = OWLHelper.removeAngles(predicate); | ||
| 144 | tripleManager.addTripleByTerm( | ||
| 145 | Atom.create(AtomicRole.create(getGapPredicate(predicate)), Individual.create(sub), Individual.create(obj))); | ||
| 146 | } | ||
| 147 | if (tupleCounter % 10000 == 0) | ||
| 148 | Utility.logDebug(tupleCounter); | ||
| 149 | } | ||
| 150 | |||
| 151 | Utility.logDebug("There are " + tupleCounter + " tuples in the gap between lower and upper bound materialisation."); | ||
| 152 | } | ||
| 153 | |||
| 154 | @Override | ||
| 155 | public void addBackTo() throws JRDFStoreException { | ||
| 156 | addTo(upperStore); | ||
| 157 | } | ||
| 158 | |||
| 159 | @Override | ||
| 160 | public void clear() { | ||
| 161 | iterator.dispose(); | ||
| 162 | } | ||
| 163 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java b/src/main/java/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java new file mode 100644 index 0000000..bf11168 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import uk.ac.ox.cs.JRDFox.JRDFStoreException; | ||
| 4 | import uk.ac.ox.cs.JRDFox.store.DataStore; | ||
| 5 | |||
| 6 | import java.util.Iterator; | ||
| 7 | |||
| 8 | public abstract class GapTupleIterator<T> implements Iterator<T> { | ||
| 9 | |||
| 10 | public static final String gapPredicateSuffix = "_AUXg"; | ||
| 11 | |||
| 12 | public static final String getGapPredicate(String predicateIRI) { | ||
| 13 | if (predicateIRI.startsWith("<")) | ||
| 14 | return predicateIRI.replace(">", gapPredicateSuffix + ">"); | ||
| 15 | return predicateIRI + gapPredicateSuffix; | ||
| 16 | } | ||
| 17 | |||
| 18 | public void compile(String programText) throws JRDFStoreException {} | ||
| 19 | |||
| 20 | public abstract void save(String file); | ||
| 21 | |||
| 22 | public abstract void addBackTo() throws JRDFStoreException; | ||
| 23 | |||
| 24 | public abstract void addTo(DataStore store) throws JRDFStoreException; | ||
| 25 | |||
| 26 | public abstract void clear(); | ||
| 27 | |||
| 28 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/QueryManager.java b/src/main/java/uk/ac/ox/cs/pagoda/query/QueryManager.java new file mode 100644 index 0000000..419cb97 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/QueryManager.java | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import java.io.File; | ||
| 4 | import java.io.FileNotFoundException; | ||
| 5 | import java.util.Collection; | ||
| 6 | import java.util.HashMap; | ||
| 7 | import java.util.LinkedList; | ||
| 8 | import java.util.Map; | ||
| 9 | import java.util.Scanner; | ||
| 10 | |||
| 11 | import uk.ac.ox.cs.pagoda.util.Utility; | ||
| 12 | |||
| 13 | public class QueryManager { | ||
| 14 | |||
| 15 | public Collection<QueryRecord> collectQueryRecords(String queryfile) { | ||
| 16 | Collection<QueryRecord> ret = new LinkedList<QueryRecord>(); | ||
| 17 | for (String queryText: collectQueryTexts(queryfile)) | ||
| 18 | ret.add(create(queryText)); | ||
| 19 | return ret; | ||
| 20 | } | ||
| 21 | |||
| 22 | public static Collection<String> collectQueryTexts(String queryfile) { | ||
| 23 | Scanner scanner = null; | ||
| 24 | try { | ||
| 25 | scanner = new Scanner(new File(queryfile)); | ||
| 26 | } catch (FileNotFoundException e) { | ||
| 27 | e.printStackTrace(); | ||
| 28 | return null; | ||
| 29 | } | ||
| 30 | Collection<String> ret = new LinkedList<String>(); | ||
| 31 | |||
| 32 | StringBuilder sb = new StringBuilder(); | ||
| 33 | int leftToMatch; | ||
| 34 | String text; | ||
| 35 | while (scanner.hasNextLine()) { | ||
| 36 | leftToMatch = -1; | ||
| 37 | for (String line; scanner.hasNextLine(); ) { | ||
| 38 | line = scanner.nextLine(); | ||
| 39 | if (line.length() > 6 && line.substring(0, 6).equalsIgnoreCase("SELECT")) { | ||
| 40 | String next = line.split(" ")[1]; | ||
| 41 | if (!next.equalsIgnoreCase("distinct")) | ||
| 42 | line = line.substring(0, 6) + " distinct" + line.substring(6); | ||
| 43 | } | ||
| 44 | for (int i = 0; i < line.length(); ++i) | ||
| 45 | if (line.charAt(i) == '{') | ||
| 46 | if (leftToMatch == -1) leftToMatch = 1; | ||
| 47 | else ++leftToMatch; | ||
| 48 | else if (line.charAt(i) == '}') --leftToMatch; | ||
| 49 | |||
| 50 | // if (line.isEmpty()) break; | ||
| 51 | |||
| 52 | if (!line.isEmpty()) | ||
| 53 | sb.append(line).append(Utility.LINE_SEPARATOR); | ||
| 54 | |||
| 55 | if (leftToMatch == 0) break; | ||
| 56 | } | ||
| 57 | |||
| 58 | text = preprocess(sb.toString()); | ||
| 59 | if (!text.isEmpty()) | ||
| 60 | ret.add(text); | ||
| 61 | sb.setLength(0); | ||
| 62 | } | ||
| 63 | |||
| 64 | scanner.close(); | ||
| 65 | return ret; | ||
| 66 | } | ||
| 67 | |||
| 68 | private static String preprocess(String text) { | ||
| 69 | int index; | ||
| 70 | text = text.trim(); | ||
| 71 | while (text.startsWith("^") || text.startsWith("#") || text.startsWith("//") || text.startsWith("@")) | ||
| 72 | if ((index = text.indexOf("\n")) != -1) | ||
| 73 | text = text.substring(index + 1); | ||
| 74 | else { | ||
| 75 | text = ""; | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | return text; // text.replace(" a ", " <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> "); | ||
| 79 | } | ||
| 80 | |||
| 81 | private Map<String, QueryRecord> allRecords = new HashMap<String, QueryRecord>(); | ||
| 82 | private int queryCounter = 0; | ||
| 83 | |||
| 84 | public QueryRecord create(String text, int i, int j) { | ||
| 85 | // StringBuilder queryText = new StringBuilder(); | ||
| 86 | // for (String seq : text.split("\s")) { | ||
| 87 | // if (seq.length() == 0) continue; | ||
| 88 | // if (queryText.length() != 0) queryText.append(" "); | ||
| 89 | // queryText.append(seq); | ||
| 90 | // } | ||
| 91 | // text = queryText.toString(); | ||
| 92 | text = text.replaceAll("\\s+", " ").trim(); | ||
| 93 | QueryRecord ret = allRecords.get(text); | ||
| 94 | if (ret != null) return ret; | ||
| 95 | else { | ||
| 96 | if (i == -1) { | ||
| 97 | i = ++queryCounter; | ||
| 98 | } | ||
| 99 | |||
| 100 | ret = new QueryRecord(this, text, i, j); | ||
| 101 | allRecords.put(text, ret); | ||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | public QueryRecord create(String text, int i) { | ||
| 107 | return create(text, i, 0); | ||
| 108 | } | ||
| 109 | |||
| 110 | |||
| 111 | public void remove(String queryText) { | ||
| 112 | allRecords.remove(queryText); | ||
| 113 | } | ||
| 114 | |||
| 115 | public void put(String text, QueryRecord queryRecord) { | ||
| 116 | allRecords.put(text, queryRecord); | ||
| 117 | } | ||
| 118 | |||
| 119 | public QueryRecord create(String queryText) { | ||
| 120 | return create(queryText, -1, 0); | ||
| 121 | } | ||
| 122 | |||
| 123 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/main/java/uk/ac/ox/cs/pagoda/query/QueryRecord.java new file mode 100644 index 0000000..5fa1b23 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/QueryRecord.java | |||
| @@ -0,0 +1,835 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query; | ||
| 2 | |||
| 3 | import com.google.gson.*; | ||
| 4 | import com.google.gson.reflect.TypeToken; | ||
| 5 | import org.apache.commons.lang.WordUtils; | ||
| 6 | import org.semanticweb.HermiT.model.*; | ||
| 7 | import org.semanticweb.owlapi.model.*; | ||
| 8 | import org.semanticweb.owlapi.model.parameters.Imports; | ||
| 9 | import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; | ||
| 10 | import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxAnswerTuples; | ||
| 11 | import uk.ac.ox.cs.pagoda.rules.GeneralProgram; | ||
| 12 | import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; | ||
| 13 | import uk.ac.ox.cs.pagoda.util.Namespace; | ||
| 14 | import uk.ac.ox.cs.pagoda.util.Utility; | ||
| 15 | import uk.ac.ox.cs.pagoda.util.disposable.Disposable; | ||
| 16 | import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; | ||
| 17 | import uk.ac.ox.cs.pagoda.util.tuples.Tuple; | ||
| 18 | import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; | ||
| 19 | |||
| 20 | import java.io.*; | ||
| 21 | import java.lang.reflect.Type; | ||
| 22 | import java.util.*; | ||
| 23 | |||
| 24 | public class QueryRecord extends Disposable { | ||
| 25 | |||
| 26 | public static final String botQueryText = | ||
| 27 | "SELECT ?X WHERE { ?X <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Nothing> }"; | ||
| 28 | public static final String SEPARATOR = "----------------------------------------"; | ||
| 29 | private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString(); | ||
| 30 | boolean processed = false; | ||
| 31 | String stringQueryID = null; | ||
| 32 | OWLOntology relevantOntology = null; | ||
| 33 | Set<DLClause> relevantClauses = new HashSet<DLClause>(); | ||
| 34 | double[] timer; | ||
| 35 | int[] gapAnswersAtStep; | ||
| 36 | int subID; | ||
| 37 | DLClause queryClause = null; | ||
| 38 | int queryID = -1; | ||
| 39 | Set<AnswerTuple> soundAnswerTuples = new HashSet<AnswerTuple>(); | ||
| 40 | private Step difficulty; | ||
| 41 | private String queryText; | ||
| 42 | private String[][] answerVariables = null; | ||
| 43 | private Set<AnswerTuple> gapAnswerTuples = null; | ||
| 44 | private QueryManager m_manager; | ||
| 45 | |||
| 46 | private QueryRecord() { | ||
| 47 | } | ||
| 48 | |||
| 49 | // private boolean containsAuxPredicate(String str) { | ||
| 50 | // return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") || | ||
| 51 | // str.contains("internal:def"); | ||
| 52 | // } | ||
| 53 | |||
| 54 | public QueryRecord(QueryManager manager, String text, int id, int subID) { | ||
| 55 | m_manager = manager; | ||
| 56 | resetInfo(text, id, subID); | ||
| 57 | resetTimer(); | ||
| 58 | } | ||
| 59 | |||
| 60 | public static Collection<String> collectQueryTexts(Collection<QueryRecord> queryRecords) { | ||
| 61 | Collection<String> texts = new LinkedList<String>(); | ||
| 62 | for(QueryRecord record : queryRecords) | ||
| 63 | texts.add(record.queryText); | ||
| 64 | return texts; | ||
| 65 | } | ||
| 66 | |||
| 67 | public void resetInfo(String text, int id, int subid) { | ||
| 68 | if(isDisposed()) throw new DisposedException(); | ||
| 69 | |||
| 70 | queryID = id; | ||
| 71 | subID = subid; | ||
| 72 | stringQueryID = id + (subID == 0 ? "" : "_" + subID); | ||
| 73 | m_manager.remove(queryText); | ||
| 74 | m_manager.put(text, this); | ||
| 75 | queryClause = null; | ||
| 76 | answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text); | ||
| 77 | queryText = text; // .replace("_:", "?"); | ||
| 78 | } | ||
| 79 | |||
| 80 | public void resetTimer() { | ||
| 81 | if(isDisposed()) throw new DisposedException(); | ||
| 82 | |||
| 83 | int length = Step.values().length; | ||
| 84 | timer = new double[length]; | ||
| 85 | gapAnswersAtStep = new int[length]; | ||
| 86 | for(int i = 0; i < length; ++i) { | ||
| 87 | timer[i] = 0; | ||
| 88 | gapAnswersAtStep[i] = 0; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | public AnswerTuples getAnswers() { | ||
| 93 | if(isDisposed()) throw new DisposedException(); | ||
| 94 | |||
| 95 | if(isProcessed()) | ||
| 96 | return getLowerBoundAnswers(); | ||
| 97 | |||
| 98 | return getUpperBoundAnswers(); | ||
| 99 | } | ||
| 100 | |||
| 101 | public AnswerTuples getLowerBoundAnswers() { | ||
| 102 | if(isDisposed()) throw new DisposedException(); | ||
| 103 | |||
| 104 | return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples); | ||
| 105 | } | ||
| 106 | |||
| 107 | public AnswerTuples getUpperBoundAnswers() { | ||
| 108 | if(isDisposed()) throw new DisposedException(); | ||
| 109 | |||
| 110 | return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples); | ||
| 111 | } | ||
| 112 | |||
| 113 | public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) { | ||
| 114 | if(isDisposed()) throw new DisposedException(); | ||
| 115 | |||
| 116 | if(answerTuples == null) return false; | ||
| 117 | boolean update = false; | ||
| 118 | for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) { | ||
| 119 | tuple = answerTuples.getTuple(); | ||
| 120 | if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) { | ||
| 121 | soundAnswerTuples.add(tuple); | ||
| 122 | if(gapAnswerTuples != null) | ||
| 123 | gapAnswerTuples.remove(tuple); | ||
| 124 | update = true; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | if(soundAnswerTuples.isEmpty()) | ||
| 129 | Utility.logInfo("Lower bound answers empty"); | ||
| 130 | else if(update) | ||
| 131 | Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size()); | ||
| 132 | else | ||
| 133 | Utility.logInfo("Lower bound answers unchanged"); | ||
| 134 | |||
| 135 | return update; | ||
| 136 | } | ||
| 137 | |||
| 138 | public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) { | ||
| 139 | if(isDisposed()) throw new DisposedException(); | ||
| 140 | |||
| 141 | return updateUpperBoundAnswers(answerTuples, false); | ||
| 142 | } | ||
| 143 | |||
| 144 | public int getNumberOfAnswers() { | ||
| 145 | if(isDisposed()) throw new DisposedException(); | ||
| 146 | |||
| 147 | return soundAnswerTuples.size() + gapAnswerTuples.size(); | ||
| 148 | } | ||
| 149 | |||
| 150 | public void markAsProcessed() { | ||
| 151 | processed = true; | ||
| 152 | } | ||
| 153 | |||
| 154 | public boolean isProcessed() { | ||
| 155 | if(isDisposed()) throw new DisposedException(); | ||
| 156 | |||
| 157 | if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true; | ||
| 158 | return processed; | ||
| 159 | } | ||
| 160 | |||
| 161 | public String[] getDistinguishedVariables() { | ||
| 162 | if(isDisposed()) throw new DisposedException(); | ||
| 163 | |||
| 164 | return answerVariables[1]; | ||
| 165 | } | ||
| 166 | |||
| 167 | public String[] getAnswerVariables() { | ||
| 168 | if(isDisposed()) throw new DisposedException(); | ||
| 169 | |||
| 170 | return answerVariables[0]; | ||
| 171 | } | ||
| 172 | |||
| 173 | public String[][] getVariables() { | ||
| 174 | if(isDisposed()) throw new DisposedException(); | ||
| 175 | |||
| 176 | return answerVariables; | ||
| 177 | } | ||
| 178 | |||
| 179 | public String getQueryText() { | ||
| 180 | return queryText; | ||
| 181 | } | ||
| 182 | |||
| 183 | public String getQueryID() { | ||
| 184 | return stringQueryID; | ||
| 185 | } | ||
| 186 | |||
| 187 | public AnswerTuples getGapAnswers() { | ||
| 188 | if(isDisposed()) throw new DisposedException(); | ||
| 189 | |||
| 190 | return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples); | ||
| 191 | } | ||
| 192 | |||
| 193 | public int getGapAnswersCount() { | ||
| 194 | return gapAnswerTuples.size(); | ||
| 195 | } | ||
| 196 | |||
| 197 | public String toString() { | ||
| 198 | return queryText; | ||
| 199 | } | ||
| 200 | |||
| 201 | public void outputAnswers(BufferedWriter writer) throws IOException { | ||
| 202 | if(isDisposed()) throw new DisposedException(); | ||
| 203 | |||
| 204 | int answerCounter = soundAnswerTuples.size(); | ||
| 205 | if(!isProcessed()) answerCounter += gapAnswerTuples.size(); | ||
| 206 | |||
| 207 | Utility.logInfo("The number of answer tuples: " + answerCounter); | ||
| 208 | |||
| 209 | if(writer != null) { | ||
| 210 | writer.write("-------------- Query " + queryID + " ---------------------"); | ||
| 211 | writer.newLine(); | ||
| 212 | writer.write(queryText); | ||
| 213 | writer.newLine(); | ||
| 214 | StringBuilder space = new StringBuilder(); | ||
| 215 | int arity = getArity(), varSpace = 0; | ||
| 216 | for(int i = 0; i < arity; ++i) | ||
| 217 | varSpace += answerVariables[0][i].length(); | ||
| 218 | for(int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i) | ||
| 219 | space.append(" "); | ||
| 220 | for(int i = 0; i < getArity(); ++i) { | ||
| 221 | writer.write(space.toString()); | ||
| 222 | writer.write(answerVariables[0][i]); | ||
| 223 | } | ||
| 224 | writer.newLine(); | ||
| 225 | writer.write(SEPARATOR); | ||
| 226 | writer.newLine(); | ||
| 227 | for(AnswerTuple tuple : soundAnswerTuples) { | ||
| 228 | writer.write(tuple.toString()); | ||
| 229 | writer.newLine(); | ||
| 230 | } | ||
| 231 | if(!isProcessed()) | ||
| 232 | for(AnswerTuple tuple : gapAnswerTuples) { | ||
| 233 | writer.write("*"); | ||
| 234 | writer.write(tuple.toString()); | ||
| 235 | writer.newLine(); | ||
| 236 | } | ||
| 237 | // writer.write(SEPARATOR); | ||
| 238 | writer.newLine(); | ||
| 239 | } | ||
| 240 | |||
| 241 | } | ||
| 242 | |||
| 243 | public void outputAnswerStatistics() { | ||
| 244 | if(isDisposed()) throw new DisposedException(); | ||
| 245 | |||
| 246 | int answerCounter = soundAnswerTuples.size(); | ||
| 247 | if(!isProcessed()) answerCounter += gapAnswerTuples.size(); | ||
| 248 | |||
| 249 | Utility.logInfo("The number of answer tuples: " + answerCounter); | ||
| 250 | // if (jsonAnswers != null) { | ||
| 251 | // JSONObject jsonAnswer = new JSONObject(); | ||
| 252 | // | ||
| 253 | // jsonAnswer.put("queryID", queryID); | ||
| 254 | // jsonAnswer.put("queryText", queryText); | ||
| 255 | // | ||
| 256 | // JSONArray answerVars = new JSONArray(); | ||
| 257 | // int arity = getArity(), varSpace = 0; | ||
| 258 | // for (int i = 0; i < getArity(); i++) | ||
| 259 | // answerVars.add(answerVariables[0][i]); | ||
| 260 | // jsonAnswer.put("answerVars", answerVars); | ||
| 261 | // | ||
| 262 | // JSONArray answerTuples = new JSONArray(); | ||
| 263 | // soundAnswerTuples.stream().forEach(t -> answerTuples.add(t)); | ||
| 264 | // jsonAnswer.put("answerTuples", answerTuples); | ||
| 265 | // | ||
| 266 | // if (!processed) { | ||
| 267 | // JSONArray gapAnswerTuples = new JSONArray(); | ||
| 268 | // gapAnswerTuples.stream().forEach(t -> gapAnswerTuples.add(t)); | ||
| 269 | // } | ||
| 270 | // jsonAnswer.put("gapAnswerTuples", gapAnswerTuples); | ||
| 271 | // | ||
| 272 | // jsonAnswers.put(Integer.toString(queryID), jsonAnswer); | ||
| 273 | // } | ||
| 274 | } | ||
| 275 | |||
| 276 | public void outputTimes() { | ||
| 277 | if(isDisposed()) throw new DisposedException(); | ||
| 278 | |||
| 279 | for(Step step : Step.values()) { | ||
| 280 | Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]); | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | public Map<String, String> getStatistics() { | ||
| 285 | HashMap<String, String> result = new HashMap<>(); | ||
| 286 | |||
| 287 | double totalTime = 0.0; | ||
| 288 | for(Step step : Step.values()) { | ||
| 289 | result.put(step.toString() + "_time", Double.toString(timer[step.ordinal()])); | ||
| 290 | result.put(step.toString() + "_gap", Integer.toString(gapAnswersAtStep[step.ordinal()])); | ||
| 291 | totalTime += timer[step.ordinal()]; | ||
| 292 | } | ||
| 293 | result.put("totalTime", Double.toString(totalTime)); | ||
| 294 | result.put("difficulty", difficulty.toString()); | ||
| 295 | |||
| 296 | return result; | ||
| 297 | } | ||
| 298 | |||
| 299 | public String outputSoundAnswerTuple() { | ||
| 300 | if(isDisposed()) throw new DisposedException(); | ||
| 301 | |||
| 302 | StringBuilder builder = new StringBuilder(); | ||
| 303 | for(AnswerTuple tuple : soundAnswerTuples) | ||
| 304 | builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); | ||
| 305 | return builder.toString(); | ||
| 306 | } | ||
| 307 | |||
| 308 | public String outputGapAnswerTuple() { | ||
| 309 | if(isDisposed()) throw new DisposedException(); | ||
| 310 | |||
| 311 | StringBuilder builder = new StringBuilder(); | ||
| 312 | for(AnswerTuple tuple : gapAnswerTuples) | ||
| 313 | builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); | ||
| 314 | return builder.toString(); | ||
| 315 | } | ||
| 316 | |||
| 317 | public Step getDifficulty() { | ||
| 318 | if(isDisposed()) throw new DisposedException(); | ||
| 319 | |||
| 320 | return difficulty; | ||
| 321 | } | ||
| 322 | |||
| 323 | public void setDifficulty(Step step) { | ||
| 324 | if(isDisposed()) throw new DisposedException(); | ||
| 325 | |||
| 326 | this.difficulty = step; | ||
| 327 | } | ||
| 328 | |||
| 329 | public OWLOntology getRelevantOntology() { | ||
| 330 | if(isDisposed()) throw new DisposedException(); | ||
| 331 | |||
| 332 | return relevantOntology; | ||
| 333 | } | ||
| 334 | |||
| 335 | public void setRelevantOntology(OWLOntology knowledgebase) { | ||
| 336 | if(isDisposed()) throw new DisposedException(); | ||
| 337 | |||
| 338 | relevantOntology = knowledgebase; | ||
| 339 | } | ||
| 340 | |||
| 341 | public void saveRelevantOntology(String filename) { | ||
| 342 | if(isDisposed()) throw new DisposedException(); | ||
| 343 | |||
| 344 | if(relevantOntology == null) return; | ||
| 345 | OWLOntologyManager manager = relevantOntology.getOWLOntologyManager(); | ||
| 346 | try { | ||
| 347 | FileOutputStream outputStream = new FileOutputStream(filename); | ||
| 348 | manager.saveOntology(relevantOntology, outputStream); | ||
| 349 | outputStream.close(); | ||
| 350 | } catch(OWLOntologyStorageException e) { | ||
| 351 | e.printStackTrace(); | ||
| 352 | } catch(FileNotFoundException e) { | ||
| 353 | e.printStackTrace(); | ||
| 354 | } catch(IOException e) { | ||
| 355 | e.printStackTrace(); | ||
| 356 | } | ||
| 357 | } | ||
| 358 | |||
| 359 | public void saveRelevantClause() { | ||
| 360 | if(isDisposed()) throw new DisposedException(); | ||
| 361 | |||
| 362 | if(relevantClauses == null) return; | ||
| 363 | GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology); | ||
| 364 | p.save(); | ||
| 365 | } | ||
| 366 | |||
| 367 | public void removeUpperBoundAnswers(Collection<AnswerTuple> answers) { | ||
| 368 | if(isDisposed()) throw new DisposedException(); | ||
| 369 | |||
| 370 | for(AnswerTuple answer : answers) { | ||
| 371 | // if (soundAnswerTuples.contains(answer)) | ||
| 372 | // Utility.logError("The answer (" + answer + ") cannot be removed, because it is in the lower bound."); | ||
| 373 | if(!gapAnswerTuples.contains(answer)) | ||
| 374 | Utility.logError("The answer (" + answer + ") cannot be removed, because it is not in the upper bound."); | ||
| 375 | gapAnswerTuples.remove(answer); | ||
| 376 | } | ||
| 377 | int numOfUpperBoundAnswers = soundAnswerTuples.size() + gapAnswerTuples.size(); | ||
| 378 | Utility.logInfo("Upper bound answers updated: " + numOfUpperBoundAnswers); | ||
| 379 | } | ||
| 380 | |||
| 381 | public void addLowerBoundAnswers(Collection<AnswerTuple> answers) { | ||
| 382 | if(isDisposed()) throw new DisposedException(); | ||
| 383 | |||
| 384 | for(AnswerTuple answer : answers) { | ||
| 385 | if(!gapAnswerTuples.contains(answer)) | ||
| 386 | Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); | ||
| 387 | gapAnswerTuples.remove(answer); | ||
| 388 | |||
| 389 | answer = AnswerTuple.create(answer, answerVariables[0].length); | ||
| 390 | // if (soundAnswerTuples.contains(answer)) | ||
| 391 | // Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound."); | ||
| 392 | soundAnswerTuples.add(answer); | ||
| 393 | } | ||
| 394 | } | ||
| 395 | |||
| 396 | public int getNoOfSoundAnswers() { | ||
| 397 | if(isDisposed()) throw new DisposedException(); | ||
| 398 | |||
| 399 | return soundAnswerTuples.size(); | ||
| 400 | } | ||
| 401 | |||
| 402 | public void addProcessingTime(Step step, double time) { | ||
| 403 | if(isDisposed()) throw new DisposedException(); | ||
| 404 | |||
| 405 | timer[step.ordinal()] += time; | ||
| 406 | if(gapAnswerTuples != null) | ||
| 407 | gapAnswersAtStep[step.ordinal()] = getGapAnswersCount(); | ||
| 408 | else | ||
| 409 | gapAnswersAtStep[step.ordinal()] = -1; | ||
| 410 | } | ||
| 411 | |||
| 412 | public int getArity() { | ||
| 413 | if(isDisposed()) throw new DisposedException(); | ||
| 414 | |||
| 415 | return answerVariables[0].length; | ||
| 416 | } | ||
| 417 | |||
| 418 | public void addRelevantClauses(DLClause clause) { | ||
| 419 | if(isDisposed()) throw new DisposedException(); | ||
| 420 | |||
| 421 | relevantClauses.add(clause); | ||
| 422 | } | ||
| 423 | |||
| 424 | public Set<DLClause> getRelevantClauses() { | ||
| 425 | if(isDisposed()) throw new DisposedException(); | ||
| 426 | |||
| 427 | return relevantClauses; | ||
| 428 | } | ||
| 429 | |||
| 430 | public void clearClauses() { | ||
| 431 | if(isDisposed()) throw new DisposedException(); | ||
| 432 | |||
| 433 | relevantClauses.clear(); | ||
| 434 | } | ||
| 435 | |||
| 436 | public boolean isHorn() { | ||
| 437 | if(isDisposed()) throw new DisposedException(); | ||
| 438 | |||
| 439 | for(DLClause clause : relevantClauses) | ||
| 440 | if(clause.getHeadLength() > 1) | ||
| 441 | return false; | ||
| 442 | return true; | ||
| 443 | } | ||
| 444 | |||
| 445 | public void saveABoxInTurtle(String filename) { | ||
| 446 | if(isDisposed()) throw new DisposedException(); | ||
| 447 | |||
| 448 | try { | ||
| 449 | BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); | ||
| 450 | OWLIndividual a, b; | ||
| 451 | StringBuilder builder = new StringBuilder(); | ||
| 452 | for(OWLAxiom axiom : relevantOntology.getABoxAxioms(Imports.INCLUDED)) { | ||
| 453 | if(axiom instanceof OWLClassAssertionAxiom) { | ||
| 454 | OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom; | ||
| 455 | OWLClass c = (OWLClass) classAssertion.getClassExpression(); | ||
| 456 | a = classAssertion.getIndividual(); | ||
| 457 | builder.append(a.toString()) | ||
| 458 | .append(" <") | ||
| 459 | .append(Namespace.RDF_TYPE) | ||
| 460 | .append("> ") | ||
| 461 | .append(c.toString()); | ||
| 462 | } | ||
| 463 | else if(axiom instanceof OWLObjectPropertyAssertionAxiom) { | ||
| 464 | OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom; | ||
| 465 | OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty(); | ||
| 466 | a = propertyAssertion.getSubject(); | ||
| 467 | b = propertyAssertion.getObject(); | ||
| 468 | builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString()); | ||
| 469 | } | ||
| 470 | else if(axiom instanceof OWLDataPropertyAssertionAxiom) { | ||
| 471 | OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom; | ||
| 472 | OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty(); | ||
| 473 | a = propertyAssertion.getSubject(); | ||
| 474 | OWLLiteral l = propertyAssertion.getObject(); | ||
| 475 | builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString()); | ||
| 476 | } | ||
| 477 | |||
| 478 | writer.write(builder.toString()); | ||
| 479 | writer.write(" ."); | ||
| 480 | writer.newLine(); | ||
| 481 | builder.setLength(0); | ||
| 482 | } | ||
| 483 | writer.close(); | ||
| 484 | } catch(IOException e) { | ||
| 485 | e.printStackTrace(); | ||
| 486 | } finally { | ||
| 487 | |||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | public void updateSubID() { | ||
| 492 | if(isDisposed()) throw new DisposedException(); | ||
| 493 | |||
| 494 | ++subID; | ||
| 495 | stringQueryID = String.valueOf(queryID) + "_" + subID; | ||
| 496 | } | ||
| 497 | |||
| 498 | public DLClause getClause() { | ||
| 499 | if(isDisposed()) throw new DisposedException(); | ||
| 500 | |||
| 501 | if(queryClause != null) | ||
| 502 | return queryClause; | ||
| 503 | return queryClause = DLClauseHelper.getQuery(queryText, null); | ||
| 504 | } | ||
| 505 | |||
| 506 | public boolean isBottom() { | ||
| 507 | if(isDisposed()) throw new DisposedException(); | ||
| 508 | |||
| 509 | return queryID == 0; | ||
| 510 | } | ||
| 511 | |||
| 512 | public int getNoOfCompleteAnswers() { | ||
| 513 | if(isDisposed()) throw new DisposedException(); | ||
| 514 | |||
| 515 | return soundAnswerTuples.size() + gapAnswerTuples.size(); | ||
| 516 | } | ||
| 517 | |||
| 518 | public int getSubID() { | ||
| 519 | if(isDisposed()) throw new DisposedException(); | ||
| 520 | |||
| 521 | return subID; | ||
| 522 | } | ||
| 523 | |||
| 524 | public boolean hasSameGapAnswers(QueryRecord that) { | ||
| 525 | if(isDisposed()) throw new DisposedException(); | ||
| 526 | |||
| 527 | return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples); | ||
| 528 | } | ||
| 529 | |||
| 530 | @Override | ||
| 531 | public void dispose() { | ||
| 532 | super.dispose(); | ||
| 533 | m_manager.remove(queryText); | ||
| 534 | if(gapAnswerTuples != null) gapAnswerTuples = null; | ||
| 535 | if(soundAnswerTuples != null) soundAnswerTuples = null; | ||
| 536 | if(relevantClauses != null) relevantClauses.clear(); | ||
| 537 | if(relevantOntology != null) | ||
| 538 | relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology); | ||
| 539 | answerVariables = null; | ||
| 540 | } | ||
| 541 | |||
| 542 | public boolean canBeEncodedIntoAtom() { | ||
| 543 | if(isDisposed()) throw new DisposedException(); | ||
| 544 | |||
| 545 | // FIXME | ||
| 546 | return true; | ||
| 547 | // return false; | ||
| 548 | } | ||
| 549 | |||
| 550 | public boolean isPredicate(AnswerTuple a, int i) { | ||
| 551 | if(isDisposed()) throw new DisposedException(); | ||
| 552 | |||
| 553 | Atom[] atoms = getClause().getBodyAtoms(); | ||
| 554 | Variable v = Variable.create(answerVariables[1][i]); | ||
| 555 | String iri; | ||
| 556 | for(Atom atom : atoms) { | ||
| 557 | DLPredicate p = atom.getDLPredicate(); | ||
| 558 | if(p instanceof AtomicConcept) { | ||
| 559 | if(((AtomicConcept) p).getIRI().equals(v.toString())) return true; | ||
| 560 | } | ||
| 561 | else if(p instanceof AtomicRole) { | ||
| 562 | iri = ((AtomicRole) p).getIRI(); | ||
| 563 | if(iri.equals(v.toString())) return true; | ||
| 564 | if(iri.startsWith("?")) | ||
| 565 | iri = a.getGroundTerm(i).toString(); | ||
| 566 | if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true; | ||
| 567 | } | ||
| 568 | } | ||
| 569 | return false; | ||
| 570 | } | ||
| 571 | |||
| 572 | public Tuple<String> getExtendedQueryText() { | ||
| 573 | if(isDisposed()) throw new DisposedException(); | ||
| 574 | |||
| 575 | // String[] ret = new String[2];s | ||
| 576 | int index = queryText.toUpperCase().indexOf(" WHERE"); | ||
| 577 | String extendedSelect = queryText.substring(0, index); | ||
| 578 | String extendedWhere = queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1); | ||
| 579 | |||
| 580 | String sub, obj; | ||
| 581 | Map<String, Set<String>> links = new HashMap<String, Set<String>>(); | ||
| 582 | Set<String> list; | ||
| 583 | for(Atom atom : getClause().getBodyAtoms()) | ||
| 584 | if(atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { | ||
| 585 | sub = atom.getArgumentVariable(0).getName(); | ||
| 586 | obj = atom.getArgumentVariable(1).getName(); | ||
| 587 | if((list = links.get(sub)) == null) | ||
| 588 | links.put(sub, list = new HashSet<String>()); | ||
| 589 | list.add(obj); | ||
| 590 | if((list = links.get(obj)) == null) | ||
| 591 | links.put(obj, list = new HashSet<String>()); | ||
| 592 | list.add(sub); | ||
| 593 | } | ||
| 594 | |||
| 595 | StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder(); | ||
| 596 | // if (answerVariables[0] != answerVariables[1]) { | ||
| 597 | for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) { | ||
| 598 | // for (int i = 0; i < answerVariables[1].length; ++i) { | ||
| 599 | fullyExtra.append(" . ?") | ||
| 600 | .append(answerVariables[1][i]) | ||
| 601 | .append(" " + RDF_TYPE + " <") | ||
| 602 | .append(Namespace.PAGODA_ORIGINAL) | ||
| 603 | .append(">"); | ||
| 604 | if((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ; | ||
| 605 | else { | ||
| 606 | extra.append(" . ?") | ||
| 607 | .append(answerVariables[1][i]) | ||
| 608 | .append(" " + RDF_TYPE + " <") | ||
| 609 | .append(Namespace.PAGODA_ORIGINAL) | ||
| 610 | .append(">"); | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 614 | if(extra.length() > 0) { | ||
| 615 | extra.append(" }"); | ||
| 616 | extendedWhere = | ||
| 617 | extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString()); | ||
| 618 | } | ||
| 619 | |||
| 620 | if(fullyExtra.length() > 0) { | ||
| 621 | fullyExtra.append(" }"); | ||
| 622 | fullyExtendedWhere = | ||
| 623 | fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra | ||
| 624 | .toString()); | ||
| 625 | } | ||
| 626 | // } | ||
| 627 | |||
| 628 | TupleBuilder<String> result = new TupleBuilder<>(); | ||
| 629 | result.append(extendedSelect + " " + fullyExtendedWhere); | ||
| 630 | |||
| 631 | extra.setLength(0); | ||
| 632 | if(answerVariables[0] != answerVariables[1]) { | ||
| 633 | for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) | ||
| 634 | extra.append(" ?").append(answerVariables[1][i]); | ||
| 635 | extendedSelect = extendedSelect + extra.toString(); | ||
| 636 | } | ||
| 637 | result.append(extendedSelect + " " + extendedWhere); | ||
| 638 | |||
| 639 | return result.build(); | ||
| 640 | } | ||
| 641 | |||
| 642 | public boolean hasNonAnsDistinguishedVariables() { | ||
| 643 | if(isDisposed()) throw new DisposedException(); | ||
| 644 | |||
| 645 | return answerVariables[1].length > answerVariables[0].length; | ||
| 646 | } | ||
| 647 | |||
| 648 | /** | ||
| 649 | * Two <tt>QueryRecords</tt> are equal iff | ||
| 650 | * they have the same <tt>queryText</tt>, | ||
| 651 | * <tt>soundAnswerTuples</tt>. | ||
| 652 | */ | ||
| 653 | @Override | ||
| 654 | public boolean equals(Object o) { | ||
| 655 | if(isDisposed()) throw new DisposedException(); | ||
| 656 | |||
| 657 | if(!o.getClass().equals(getClass())) return false; | ||
| 658 | QueryRecord that = (QueryRecord) o; | ||
| 659 | return this.queryText.equals(that.queryText) | ||
| 660 | && soundAnswerTuples.equals(that.soundAnswerTuples); | ||
| 661 | } | ||
| 662 | |||
| 663 | @Override | ||
| 664 | public int hashCode() { | ||
| 665 | if(isDisposed()) throw new DisposedException(); | ||
| 666 | |||
| 667 | return Objects.hash(queryText, soundAnswerTuples); | ||
| 668 | } | ||
| 669 | |||
| 670 | public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { | ||
| 671 | RDFoxAnswerTuples rdfAnswerTuples; | ||
| 672 | if(answerTuples instanceof RDFoxAnswerTuples) | ||
| 673 | rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples; | ||
| 674 | else { | ||
| 675 | Utility.logError("The upper bound must be computed by RDFox!"); | ||
| 676 | return false; | ||
| 677 | } | ||
| 678 | |||
| 679 | if(soundAnswerTuples.size() > 0) { | ||
| 680 | int number = 0; | ||
| 681 | for(; answerTuples.isValid(); answerTuples.moveNext()) { | ||
| 682 | ++number; | ||
| 683 | } | ||
| 684 | Utility.logDebug("The number of answers returned by an upper bound: " + number); | ||
| 685 | if(number <= soundAnswerTuples.size()) { | ||
| 686 | if(gapAnswerTuples != null) gapAnswerTuples.clear(); | ||
| 687 | else gapAnswerTuples = new HashSet<AnswerTuple>(); | ||
| 688 | |||
| 689 | Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); | ||
| 690 | return false; | ||
| 691 | } | ||
| 692 | answerTuples.reset(); | ||
| 693 | } | ||
| 694 | |||
| 695 | boolean justCheck = (answerTuples.getArity() != answerVariables[1].length); | ||
| 696 | |||
| 697 | Set<AnswerTuple> tupleSet = new HashSet<AnswerTuple>(); | ||
| 698 | AnswerTuple tuple, extendedTuple; | ||
| 699 | for(; answerTuples.isValid(); answerTuples.moveNext()) { | ||
| 700 | extendedTuple = rdfAnswerTuples.getTuple(); | ||
| 701 | if(isBottom() || !extendedTuple.hasAnonymousIndividual()) { | ||
| 702 | tuple = AnswerTuple.create(extendedTuple, answerVariables[0].length); | ||
| 703 | if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) { | ||
| 704 | if(!toCheckAux && justCheck) return false; | ||
| 705 | tupleSet.add(extendedTuple); | ||
| 706 | } | ||
| 707 | } | ||
| 708 | } | ||
| 709 | |||
| 710 | if(gapAnswerTuples == null) { | ||
| 711 | gapAnswerTuples = tupleSet; | ||
| 712 | |||
| 713 | Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); | ||
| 714 | return true; | ||
| 715 | } | ||
| 716 | |||
| 717 | boolean update = false; | ||
| 718 | for(Iterator<AnswerTuple> iter = gapAnswerTuples.iterator(); iter.hasNext(); ) { | ||
| 719 | tuple = iter.next(); | ||
| 720 | if(!tupleSet.contains(tuple)) { | ||
| 721 | iter.remove(); | ||
| 722 | update = true; | ||
| 723 | } | ||
| 724 | } | ||
| 725 | |||
| 726 | Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); | ||
| 727 | |||
| 728 | return update; | ||
| 729 | } | ||
| 730 | |||
| 731 | public enum Step { | ||
| 732 | LOWER_BOUND, | ||
| 733 | UPPER_BOUND, | ||
| 734 | SIMPLE_UPPER_BOUND, | ||
| 735 | LAZY_UPPER_BOUND, | ||
| 736 | SKOLEM_UPPER_BOUND, | ||
| 737 | EL_LOWER_BOUND, | ||
| 738 | FRAGMENT, | ||
| 739 | // FRAGMENT_REFINEMENT, | ||
| 740 | SUMMARISATION, | ||
| 741 | // DEPENDENCY, | ||
| 742 | FULL_REASONING; | ||
| 743 | |||
| 744 | @Override | ||
| 745 | public String toString() { | ||
| 746 | String s = super.toString(); | ||
| 747 | if(s == null) return null; | ||
| 748 | return WordUtils.capitalizeFully(s, new char[]{'_'}).replace("_", ""); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | |||
| 752 | /** | ||
| 753 | * A Json serializer, which considers the main attributes. | ||
| 754 | */ | ||
| 755 | public static class QueryRecordSerializer implements JsonSerializer<QueryRecord> { | ||
| 756 | public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { | ||
| 757 | Gson gson = new GsonBuilder().setPrettyPrinting().create(); | ||
| 758 | JsonObject object = new JsonObject(); | ||
| 759 | object.addProperty("queryID", src.queryID); | ||
| 760 | object.addProperty("queryText", src.queryText); | ||
| 761 | // object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : ""); | ||
| 762 | |||
| 763 | object.add("answerVariables", context.serialize(src.getAnswerVariables())); | ||
| 764 | object.add("answers", context.serialize(src.soundAnswerTuples)); | ||
| 765 | // object.add("gapAnswers", context.serialize(src.gapAnswerTuples)); | ||
| 766 | |||
| 767 | return object; | ||
| 768 | } | ||
| 769 | } | ||
| 770 | |||
| 771 | /** | ||
| 772 | * A Json deserializer, compliant to the output of the serializer defined above. | ||
| 773 | */ | ||
| 774 | public static class QueryRecordDeserializer implements JsonDeserializer<QueryRecord> { | ||
| 775 | public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | ||
| 776 | throws JsonParseException { | ||
| 777 | |||
| 778 | QueryRecord record = new QueryRecord(); | ||
| 779 | JsonObject object = json.getAsJsonObject(); | ||
| 780 | record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); | ||
| 781 | record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); | ||
| 782 | // record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString()); | ||
| 783 | |||
| 784 | JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); | ||
| 785 | record.answerVariables = new String[2][]; | ||
| 786 | record.answerVariables[0] = new String[answerVariablesJson.size()]; | ||
| 787 | for(int i = 0; i < answerVariablesJson.size(); i++) | ||
| 788 | record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); | ||
| 789 | |||
| 790 | record.soundAnswerTuples = new HashSet<>(); | ||
| 791 | // record.gapAnswerTuples = new HashSet<>(); | ||
| 792 | Type type = new TypeToken<AnswerTuple>() { | ||
| 793 | }.getType(); | ||
| 794 | for(JsonElement answer : object.getAsJsonArray("answers")) { | ||
| 795 | record.soundAnswerTuples.add(context.deserialize(answer, type)); | ||
| 796 | } | ||
| 797 | // for (JsonElement answer : object.getAsJsonArray("gapAnswers")) { | ||
| 798 | // record.soundAnswerTuples.add(context.deserialize(answer, type)); | ||
| 799 | // } | ||
| 800 | |||
| 801 | return record; | ||
| 802 | } | ||
| 803 | } | ||
| 804 | |||
| 805 | /** | ||
| 806 | * Provides an instance (singleton) of Gson, having a specific configuration. | ||
| 807 | */ | ||
| 808 | public static class GsonCreator { | ||
| 809 | |||
| 810 | private static Gson gson; | ||
| 811 | |||
| 812 | private GsonCreator() { | ||
| 813 | } | ||
| 814 | |||
| 815 | public static Gson getInstance() { | ||
| 816 | if (gson == null) { | ||
| 817 | gson = new GsonBuilder() | ||
| 818 | .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer()) | ||
| 819 | .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer()) | ||
| 820 | .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer()) | ||
| 821 | .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer()) | ||
| 822 | .disableHtmlEscaping() | ||
| 823 | .setPrettyPrinting() | ||
| 824 | .create(); | ||
| 825 | } | ||
| 826 | return gson; | ||
| 827 | } | ||
| 828 | |||
| 829 | // public static void dispose() { | ||
| 830 | // gson = null; | ||
| 831 | // } | ||
| 832 | |||
| 833 | } | ||
| 834 | |||
| 835 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java b/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java new file mode 100644 index 0000000..9b4ce01 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java | |||
| @@ -0,0 +1,400 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query.rollup; | ||
| 2 | |||
| 3 | import org.semanticweb.HermiT.model.*; | ||
| 4 | import org.semanticweb.owlapi.model.*; | ||
| 5 | import uk.ac.ox.cs.pagoda.util.Namespace; | ||
| 6 | |||
| 7 | import java.util.*; | ||
| 8 | |||
| 9 | public class QueryGraph { | ||
| 10 | |||
| 11 | Set<Variable> freeVars = new HashSet<Variable>(); | ||
| 12 | Set<Variable> existVars = new HashSet<Variable>(); | ||
| 13 | Set<Individual> constants = new HashSet<Individual>(); | ||
| 14 | |||
| 15 | MultiMap<Term, OWLClassExpression> concepts = new MultiMap<Term, OWLClassExpression>(); | ||
| 16 | MultiMap<Term, ObjectEdge> rollable_edges = new MultiMap<Term, ObjectEdge>(); | ||
| 17 | MultiMap<Term, ObjectEdge> edges = new MultiMap<Term, ObjectEdge>(); | ||
| 18 | OWLOntology ontology; | ||
| 19 | OWLDataFactory factory; | ||
| 20 | |||
| 21 | public QueryGraph(Atom[] bodyAtoms, String[] distinguishedVars, OWLOntology onto) { | ||
| 22 | for (String vName: distinguishedVars) | ||
| 23 | freeVars.add(Variable.create(vName)); | ||
| 24 | |||
| 25 | ontology = onto; | ||
| 26 | factory = onto.getOWLOntologyManager().getOWLDataFactory(); | ||
| 27 | |||
| 28 | for (Atom atom: bodyAtoms) { | ||
| 29 | if (atom.getArity() == 1) { | ||
| 30 | updateExistentiallyVariables(atom.getArgumentVariable(0)); | ||
| 31 | String id = ((AtomicConcept) atom.getDLPredicate()).getIRI(); | ||
| 32 | if (!id.equals(Namespace.PAGODA_ORIGINAL)) | ||
| 33 | concepts.add(atom.getArgument(0), factory.getOWLClass(IRI.create(id))); | ||
| 34 | } | ||
| 35 | else if (atom.getArity() == 2) { | ||
| 36 | updateExistentiallyVariables(atom.getArgumentVariable(0)); | ||
| 37 | updateExistentiallyVariables(atom.getArgumentVariable(1)); | ||
| 38 | if (atom.getArgument(0).equals(atom.getArgument(1)) && atom.getArgument(0) instanceof Variable) { | ||
| 39 | concepts.add(atom.getArgument(0), factory.getOWLObjectHasSelf(factory.getOWLObjectProperty(IRI.create(((AtomicRole) atom.getDLPredicate()).getIRI())))); | ||
| 40 | } | ||
| 41 | else createEdges(atom.getArgument(0), (AtomicRole) atom.getDLPredicate(), atom.getArgument(1)); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | rollup(); | ||
| 46 | } | ||
| 47 | |||
| 48 | public void createEdges(Term u, AtomicRole r, Term v) { | ||
| 49 | if(ontology.containsDataPropertyInSignature(IRI.create(r.getIRI()))) { | ||
| 50 | // edges.add(u, new DataEdge(r, v)); | ||
| 51 | Constant c = (Constant) v; | ||
| 52 | OWLLiteral l = factory.getOWLLiteral(c.getLexicalForm(), c.getDatatypeURI()); | ||
| 53 | concepts.add(u, factory.getOWLDataHasValue(factory.getOWLDataProperty(IRI.create(r.getIRI())), l)); | ||
| 54 | } | ||
| 55 | else { | ||
| 56 | boolean rollable = existVars.contains(u) || existVars.contains(v); | ||
| 57 | |||
| 58 | ObjectEdge edge = new ObjectEdge(r, v, false); | ||
| 59 | if(rollable) { | ||
| 60 | rollable_edges.add(u, edge); | ||
| 61 | edge = new ObjectEdge(r, u, true); | ||
| 62 | rollable_edges.add(v, edge); | ||
| 63 | } | ||
| 64 | else edges.add(u, edge); | ||
| 65 | |||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | public Set<OWLAxiom> getPropertyAssertions(Map<Variable, Term> assignment) { | ||
| 70 | OWLIndividual sub, obj; | ||
| 71 | Set<OWLAxiom> axioms = new HashSet<OWLAxiom>(); | ||
| 72 | for(Map.Entry<Term, Set<ObjectEdge>> entry : edges.map.entrySet()) { | ||
| 73 | sub = factory.getOWLNamedIndividual(IRI.create(getIndividual(entry.getKey(), assignment).getIRI())); | ||
| 74 | for(ObjectEdge edge : entry.getValue()) { | ||
| 75 | Individual individual = getIndividual(edge.v, assignment); | ||
| 76 | String iri = individual.getIRI(); | ||
| 77 | obj = factory.getOWLNamedIndividual(IRI.create(iri)); | ||
| 78 | axioms.add(factory.getOWLObjectPropertyAssertionAxiom(edge.p, sub, obj)); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | return axioms; | ||
| 82 | } | ||
| 83 | |||
| 84 | // public Set<OWLClassExpression> getExistentialConditions(Map<Variable, Term> assignment) { | ||
| 85 | // if(!rollable_edges.isEmpty()) return null; | ||
| 86 | // | ||
| 87 | // OWLIndividual sub; | ||
| 88 | // Visitor visitor = new Visitor(factory, assignment); | ||
| 89 | // Set<OWLClassExpression> axioms = new HashSet<>(); | ||
| 90 | // for(Map.Entry<Term, Set<OWLClassExpression>> entry : concepts.map.entrySet()) { | ||
| 91 | // // TODO check correctness!!! | ||
| 92 | // if(existVars.contains(entry.getKey())) { | ||
| 93 | // OWLClassExpression conjunction = | ||
| 94 | // factory.getOWLObjectIntersectionOf(factory.getOWLThing()); | ||
| 95 | // for(OWLClassExpression owlClassExpression : entry.getValue()) { | ||
| 96 | // conjunction = factory.getOWLObjectIntersectionOf(conjunction, owlClassExpression.accept(visitor)); | ||
| 97 | // } | ||
| 98 | // axioms.add(conjunction); | ||
| 99 | //// continue; // previously the "then" contained only this | ||
| 100 | // } | ||
| 101 | // } | ||
| 102 | // return axioms; | ||
| 103 | // } | ||
| 104 | |||
| 105 | public Set<OWLAxiom> getExistentialAxioms(Map<Variable, Term> assignment) { | ||
| 106 | if(!rollable_edges.isEmpty()) return null; | ||
| 107 | |||
| 108 | Visitor visitor = new Visitor(factory, assignment); | ||
| 109 | Set<OWLAxiom> axioms = new HashSet<>(); | ||
| 110 | for(Map.Entry<Term, Set<OWLClassExpression>> entry : concepts.map.entrySet()) { | ||
| 111 | if(existVars.contains(entry.getKey())) { | ||
| 112 | OWLClassExpression conjunction = factory.getOWLThing(); | ||
| 113 | for(OWLClassExpression owlClassExpression : entry.getValue()) { | ||
| 114 | conjunction = factory.getOWLObjectIntersectionOf(conjunction, owlClassExpression.accept(visitor)); | ||
| 115 | } | ||
| 116 | axioms.add(factory.getOWLSubClassOfAxiom(conjunction, factory.getOWLNothing())); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | return axioms; | ||
| 120 | } | ||
| 121 | |||
| 122 | public Set<OWLAxiom> getAssertions(Map<Variable, Term> assignment) { | ||
| 123 | if(!rollable_edges.isEmpty()) return null; | ||
| 124 | |||
| 125 | OWLIndividual sub; | ||
| 126 | Visitor visitor = new Visitor(factory, assignment); | ||
| 127 | Set<OWLAxiom> axioms = getPropertyAssertions(assignment); | ||
| 128 | for(Map.Entry<Term, Set<OWLClassExpression>> entry : concepts.map.entrySet()) { | ||
| 129 | // TODO check correctness!!! | ||
| 130 | if(existVars.contains(entry.getKey())) { | ||
| 131 | // OWLClassExpression conjunction = | ||
| 132 | // factory.getOWLObjectIntersectionOf(factory.getOWLThing()); | ||
| 133 | // for(OWLClassExpression owlClassExpression : entry.getValue()) { | ||
| 134 | // conjunction = factory.getOWLObjectIntersectionOf(conjunction, owlClassExpression.accept(visitor)); | ||
| 135 | // } | ||
| 136 | // axioms.add(factory.getOWLSubClassOfAxiom(conjunction, factory.getOWLNothing())); | ||
| 137 | continue; // previously the "then" contained only this | ||
| 138 | } | ||
| 139 | else { | ||
| 140 | sub = factory.getOWLNamedIndividual(IRI.create(getIndividual(entry.getKey(), assignment).getIRI())); | ||
| 141 | for(OWLClassExpression clsExp : entry.getValue()) { | ||
| 142 | axioms.add(factory.getOWLClassAssertionAxiom(clsExp.accept(visitor), sub)); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | ||
| 146 | return axioms; | ||
| 147 | } | ||
| 148 | |||
| 149 | private void updateExistentiallyVariables(Variable argumentVariable) { | ||
| 150 | if(freeVars.contains(argumentVariable)) return; | ||
| 151 | existVars.add(argumentVariable); | ||
| 152 | } | ||
| 153 | |||
| 154 | private void rollup() { | ||
| 155 | for (boolean updated = true; updated; ) { | ||
| 156 | updated = false; | ||
| 157 | |||
| 158 | Set<ObjectEdge> set; | ||
| 159 | for (Variable var: existVars) { | ||
| 160 | if ((set = rollable_edges.map.get(var)) != null && set.size() == 1) { | ||
| 161 | updated = true; | ||
| 162 | ObjectEdge edge = set.iterator().next(); | ||
| 163 | rollupEdge(edge.v, edge.p.getInverseProperty().getSimplified(), var, true); | ||
| 164 | set.clear(); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | if(updated) continue; | ||
| 168 | |||
| 169 | for (Variable var: existVars) { | ||
| 170 | set = rollable_edges.map.get(var); | ||
| 171 | if(set == null) continue; | ||
| 172 | for (Iterator<ObjectEdge> iter = set.iterator(); iter.hasNext(); ) { | ||
| 173 | ObjectEdge edge = iter.next(); | ||
| 174 | if (constants.contains(edge.v) || freeVars.contains(edge.v)) { | ||
| 175 | updated = true; | ||
| 176 | rollupEdge(var, edge.p, edge.v, false); | ||
| 177 | iter.remove(); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | } | ||
| 184 | |||
| 185 | private void rollupEdge(Term u, OWLObjectPropertyExpression op, Term v, boolean inverse) { | ||
| 186 | if (existVars.contains(v)) { | ||
| 187 | Set<OWLClassExpression> exps = concepts.get(v); | ||
| 188 | if (exps == null) exps = new HashSet<OWLClassExpression>(); | ||
| 189 | concepts.add(u, factory.getOWLObjectSomeValuesFrom(op, factory.getOWLObjectIntersectionOf(exps))); | ||
| 190 | } | ||
| 191 | else { | ||
| 192 | OWLIndividual obj = getOWLIndividual(v); | ||
| 193 | concepts.add(u, factory.getOWLObjectHasValue(op, obj)); | ||
| 194 | } | ||
| 195 | |||
| 196 | if(inverse) | ||
| 197 | removeRollableEdge(u, op, v); | ||
| 198 | else | ||
| 199 | removeRollableEdge(v, op.getInverseProperty().getSimplified(), u); | ||
| 200 | } | ||
| 201 | |||
| 202 | private void removeRollableEdge(Term u, OWLObjectPropertyExpression op, Term v) { | ||
| 203 | Set<ObjectEdge> set = rollable_edges.get(u); | ||
| 204 | ObjectEdge edge; | ||
| 205 | if (set != null) | ||
| 206 | for (Iterator<ObjectEdge> iter = set.iterator(); iter.hasNext(); ) { | ||
| 207 | edge = iter.next(); | ||
| 208 | if(edge.p.equals(op) && edge.v.equals(v)) iter.remove(); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | OWLNamedIndividual getOWLIndividual(Term t) { | ||
| 213 | if (freeVars.contains(t)) | ||
| 214 | return new VariableIndividual((Variable) t); | ||
| 215 | else if (t instanceof Variable) | ||
| 216 | return null; | ||
| 217 | else | ||
| 218 | return factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI())); | ||
| 219 | } | ||
| 220 | |||
| 221 | private Individual getIndividual(Term key, Map<Variable, Term> assignment) { | ||
| 222 | if(key instanceof Individual) | ||
| 223 | return (Individual) key; | ||
| 224 | else | ||
| 225 | return (Individual) assignment.get(key); | ||
| 226 | } | ||
| 227 | |||
| 228 | class ObjectEdge { | ||
| 229 | OWLObjectPropertyExpression p; | ||
| 230 | Term v; | ||
| 231 | |||
| 232 | public ObjectEdge(AtomicRole r, Term t, boolean inverse) { | ||
| 233 | p = factory.getOWLObjectProperty(IRI.create(r.getIRI())); | ||
| 234 | if(inverse) p = p.getInverseProperty(); | ||
| 235 | v = t; | ||
| 236 | |||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | class MultiMap<K, V> { | ||
| 241 | |||
| 242 | HashMap<K, Set<V>> map = new HashMap<K, Set<V>>(); | ||
| 243 | |||
| 244 | public Set<V> get(K v) { | ||
| 245 | return map.get(v); | ||
| 246 | } | ||
| 247 | |||
| 248 | public boolean isEmpty() { | ||
| 249 | for(Map.Entry<K, Set<V>> entry : map.entrySet()) | ||
| 250 | if(!entry.getValue().isEmpty()) | ||
| 251 | return false; | ||
| 252 | return true; | ||
| 253 | } | ||
| 254 | |||
| 255 | void add(K key, V value) { | ||
| 256 | Set<V> list = map.get(key); | ||
| 257 | if(list == null) | ||
| 258 | map.put(key, list = new HashSet<V>()); | ||
| 259 | list.add(value); | ||
| 260 | } | ||
| 261 | |||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | class Visitor implements OWLClassExpressionVisitorEx<OWLClassExpression> { | ||
| 266 | |||
| 267 | OWLDataFactory factory; | ||
| 268 | Map<Variable, Term> assignment; | ||
| 269 | |||
| 270 | public Visitor(OWLDataFactory factory, Map<Variable, Term> assignment) { | ||
| 271 | this.factory = factory; | ||
| 272 | this.assignment = assignment; | ||
| 273 | } | ||
| 274 | |||
| 275 | @Override | ||
| 276 | public OWLClassExpression visit(OWLClass ce) { | ||
| 277 | // TODO Auto-generated method stub | ||
| 278 | return ce; | ||
| 279 | } | ||
| 280 | |||
| 281 | @Override | ||
| 282 | public OWLClassExpression visit(OWLObjectIntersectionOf ce) { | ||
| 283 | Set<OWLClassExpression> clsExps = new HashSet<OWLClassExpression>(); | ||
| 284 | OWLClassExpression newExp; | ||
| 285 | boolean updated = false; | ||
| 286 | for (OWLClassExpression clsExp: ce.asConjunctSet()) { | ||
| 287 | clsExps.add(newExp = clsExp.accept(this)); | ||
| 288 | if (newExp != clsExp) updated = true; | ||
| 289 | } | ||
| 290 | |||
| 291 | if (updated) return factory.getOWLObjectIntersectionOf(clsExps); | ||
| 292 | else return ce; | ||
| 293 | } | ||
| 294 | |||
| 295 | @Override | ||
| 296 | public OWLClassExpression visit(OWLObjectUnionOf ce) { | ||
| 297 | // TODO Auto-generated method stub | ||
| 298 | return ce; | ||
| 299 | } | ||
| 300 | |||
| 301 | @Override | ||
| 302 | public OWLClassExpression visit(OWLObjectComplementOf ce) { | ||
| 303 | // TODO Auto-generated method stub | ||
| 304 | return ce; | ||
| 305 | } | ||
| 306 | |||
| 307 | @Override | ||
| 308 | public OWLClassExpression visit(OWLObjectSomeValuesFrom ce) { | ||
| 309 | OWLClassExpression newFiller = ce.getFiller().accept(this); | ||
| 310 | if (newFiller == ce.getFiller()) return ce; | ||
| 311 | return factory.getOWLObjectSomeValuesFrom(ce.getProperty(), newFiller); | ||
| 312 | } | ||
| 313 | |||
| 314 | @Override | ||
| 315 | public OWLClassExpression visit(OWLObjectAllValuesFrom ce) { | ||
| 316 | // TODO Auto-generated method stub | ||
| 317 | return ce; | ||
| 318 | } | ||
| 319 | |||
| 320 | @Override | ||
| 321 | public OWLClassExpression visit(OWLObjectHasValue ce) { | ||
| 322 | if (ce.getValue() instanceof VariableIndividual) { | ||
| 323 | Individual c = (Individual) assignment.get(((VariableIndividual) ce.getValue()).var); | ||
| 324 | OWLIndividual l = factory.getOWLNamedIndividual(IRI.create(c.getIRI())); | ||
| 325 | return factory.getOWLObjectHasValue(ce.getProperty(), l); | ||
| 326 | } | ||
| 327 | return ce; | ||
| 328 | } | ||
| 329 | |||
| 330 | @Override | ||
| 331 | public OWLClassExpression visit(OWLObjectMinCardinality ce) { | ||
| 332 | // TODO Auto-generated method stub | ||
| 333 | return ce; | ||
| 334 | } | ||
| 335 | |||
| 336 | @Override | ||
| 337 | public OWLClassExpression visit(OWLObjectExactCardinality ce) { | ||
| 338 | // TODO Auto-generated method stub | ||
| 339 | return ce; | ||
| 340 | } | ||
| 341 | |||
| 342 | @Override | ||
| 343 | public OWLClassExpression visit(OWLObjectMaxCardinality ce) { | ||
| 344 | // TODO Auto-generated method stub | ||
| 345 | return ce; | ||
| 346 | } | ||
| 347 | |||
| 348 | @Override | ||
| 349 | public OWLClassExpression visit(OWLObjectHasSelf ce) { | ||
| 350 | // TODO Auto-generated method stub | ||
| 351 | return ce; | ||
| 352 | } | ||
| 353 | |||
| 354 | @Override | ||
| 355 | public OWLClassExpression visit(OWLObjectOneOf ce) { | ||
| 356 | // TODO Auto-generated method stub | ||
| 357 | return ce; | ||
| 358 | } | ||
| 359 | |||
| 360 | @Override | ||
| 361 | public OWLClassExpression visit(OWLDataSomeValuesFrom ce) { | ||
| 362 | // TODO Auto-generated method stub | ||
| 363 | return ce; | ||
| 364 | } | ||
| 365 | |||
| 366 | @Override | ||
| 367 | public OWLClassExpression visit(OWLDataAllValuesFrom ce) { | ||
| 368 | // TODO Auto-generated method stub | ||
| 369 | return ce; | ||
| 370 | } | ||
| 371 | |||
| 372 | @Override | ||
| 373 | public OWLClassExpression visit(OWLDataHasValue ce) { | ||
| 374 | if (ce.getValue() instanceof VariableConstant) { | ||
| 375 | Constant c = (Constant) assignment.get(((VariableConstant) ce.getValue()).var); | ||
| 376 | OWLLiteral l = factory.getOWLLiteral(c.getLexicalForm(), c.getDatatypeURI()); | ||
| 377 | return factory.getOWLDataHasValue(ce.getProperty(), l); | ||
| 378 | } | ||
| 379 | return ce; | ||
| 380 | } | ||
| 381 | |||
| 382 | @Override | ||
| 383 | public OWLClassExpression visit(OWLDataMinCardinality ce) { | ||
| 384 | // TODO Auto-generated method stub | ||
| 385 | return ce; | ||
| 386 | } | ||
| 387 | |||
| 388 | @Override | ||
| 389 | public OWLClassExpression visit(OWLDataExactCardinality ce) { | ||
| 390 | // TODO Auto-generated method stub | ||
| 391 | return ce; | ||
| 392 | } | ||
| 393 | |||
| 394 | @Override | ||
| 395 | public OWLClassExpression visit(OWLDataMaxCardinality ce) { | ||
| 396 | // TODO Auto-generated method stub | ||
| 397 | return ce; | ||
| 398 | } | ||
| 399 | |||
| 400 | } \ No newline at end of file | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableConstant.java b/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableConstant.java new file mode 100644 index 0000000..b8035c5 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableConstant.java | |||
| @@ -0,0 +1,221 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query.rollup; | ||
| 2 | |||
| 3 | import java.util.Set; | ||
| 4 | |||
| 5 | import org.semanticweb.HermiT.model.Variable; | ||
| 6 | import org.semanticweb.owlapi.model.OWLAnnotationValueVisitor; | ||
| 7 | import org.semanticweb.owlapi.model.OWLAnnotationValueVisitorEx; | ||
| 8 | import org.semanticweb.owlapi.model.OWLAnonymousIndividual; | ||
| 9 | import org.semanticweb.owlapi.model.OWLClass; | ||
| 10 | import org.semanticweb.owlapi.model.OWLClassExpression; | ||
| 11 | import org.semanticweb.owlapi.model.OWLDataProperty; | ||
| 12 | import org.semanticweb.owlapi.model.OWLDataVisitor; | ||
| 13 | import org.semanticweb.owlapi.model.OWLDataVisitorEx; | ||
| 14 | import org.semanticweb.owlapi.model.OWLDatatype; | ||
| 15 | import org.semanticweb.owlapi.model.OWLEntity; | ||
| 16 | import org.semanticweb.owlapi.model.OWLLiteral; | ||
| 17 | import org.semanticweb.owlapi.model.OWLNamedIndividual; | ||
| 18 | import org.semanticweb.owlapi.model.OWLObject; | ||
| 19 | import org.semanticweb.owlapi.model.OWLObjectProperty; | ||
| 20 | import org.semanticweb.owlapi.model.OWLObjectVisitor; | ||
| 21 | import org.semanticweb.owlapi.model.OWLObjectVisitorEx; | ||
| 22 | |||
| 23 | class VariableConstant implements OWLLiteral { | ||
| 24 | |||
| 25 | /** | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | private static final long serialVersionUID = 5089014375729171030L; | ||
| 29 | Variable var; | ||
| 30 | |||
| 31 | public VariableConstant(Variable v) { | ||
| 32 | var = v; | ||
| 33 | } | ||
| 34 | |||
| 35 | @Override | ||
| 36 | public Set<OWLEntity> getSignature() { | ||
| 37 | // TODO Auto-generated method stub | ||
| 38 | return null; | ||
| 39 | } | ||
| 40 | |||
| 41 | @Override | ||
| 42 | public Set<OWLAnonymousIndividual> getAnonymousIndividuals() { | ||
| 43 | // TODO Auto-generated method stub | ||
| 44 | return null; | ||
| 45 | } | ||
| 46 | |||
| 47 | @Override | ||
| 48 | public Set<OWLClass> getClassesInSignature() { | ||
| 49 | // TODO Auto-generated method stub | ||
| 50 | return null; | ||
| 51 | } | ||
| 52 | |||
| 53 | @Override | ||
| 54 | public Set<OWLDataProperty> getDataPropertiesInSignature() { | ||
| 55 | // TODO Auto-generated method stub | ||
| 56 | return null; | ||
| 57 | } | ||
| 58 | |||
| 59 | @Override | ||
| 60 | public Set<OWLObjectProperty> getObjectPropertiesInSignature() { | ||
| 61 | // TODO Auto-generated method stub | ||
| 62 | return null; | ||
| 63 | } | ||
| 64 | |||
| 65 | @Override | ||
| 66 | public Set<OWLNamedIndividual> getIndividualsInSignature() { | ||
| 67 | // TODO Auto-generated method stub | ||
| 68 | return null; | ||
| 69 | } | ||
| 70 | |||
| 71 | @Override | ||
| 72 | public Set<OWLDatatype> getDatatypesInSignature() { | ||
| 73 | // TODO Auto-generated method stub | ||
| 74 | return null; | ||
| 75 | } | ||
| 76 | |||
| 77 | @Override | ||
| 78 | public Set<OWLClassExpression> getNestedClassExpressions() { | ||
| 79 | // TODO Auto-generated method stub | ||
| 80 | return null; | ||
| 81 | } | ||
| 82 | |||
| 83 | @Override | ||
| 84 | public void accept(OWLObjectVisitor visitor) { | ||
| 85 | // TODO Auto-generated method stub | ||
| 86 | |||
| 87 | } | ||
| 88 | |||
| 89 | @Override | ||
| 90 | public <O> O accept(OWLObjectVisitorEx<O> visitor) { | ||
| 91 | // TODO Auto-generated method stub | ||
| 92 | return null; | ||
| 93 | } | ||
| 94 | |||
| 95 | @Override | ||
| 96 | public boolean isTopEntity() { | ||
| 97 | // TODO Auto-generated method stub | ||
| 98 | return false; | ||
| 99 | } | ||
| 100 | |||
| 101 | @Override | ||
| 102 | public boolean isBottomEntity() { | ||
| 103 | // TODO Auto-generated method stub | ||
| 104 | return false; | ||
| 105 | } | ||
| 106 | |||
| 107 | @Override | ||
| 108 | public int compareTo(OWLObject arg0) { | ||
| 109 | // TODO Auto-generated method stub | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | @Override | ||
| 114 | public void accept(OWLAnnotationValueVisitor visitor) { | ||
| 115 | // TODO Auto-generated method stub | ||
| 116 | |||
| 117 | } | ||
| 118 | |||
| 119 | @Override | ||
| 120 | public <O> O accept(OWLAnnotationValueVisitorEx<O> visitor) { | ||
| 121 | // TODO Auto-generated method stub | ||
| 122 | return null; | ||
| 123 | } | ||
| 124 | |||
| 125 | @Override | ||
| 126 | public boolean isRDFPlainLiteral() { | ||
| 127 | // TODO Auto-generated method stub | ||
| 128 | return false; | ||
| 129 | } | ||
| 130 | |||
| 131 | @Override | ||
| 132 | public String getLiteral() { | ||
| 133 | // TODO Auto-generated method stub | ||
| 134 | return null; | ||
| 135 | } | ||
| 136 | |||
| 137 | @Override | ||
| 138 | public OWLDatatype getDatatype() { | ||
| 139 | // TODO Auto-generated method stub | ||
| 140 | return null; | ||
| 141 | } | ||
| 142 | |||
| 143 | @Override | ||
| 144 | public boolean hasLang() { | ||
| 145 | // TODO Auto-generated method stub | ||
| 146 | return false; | ||
| 147 | } | ||
| 148 | |||
| 149 | @Override | ||
| 150 | public String getLang() { | ||
| 151 | // TODO Auto-generated method stub | ||
| 152 | return null; | ||
| 153 | } | ||
| 154 | |||
| 155 | @Override | ||
| 156 | public boolean hasLang(String lang) { | ||
| 157 | // TODO Auto-generated method stub | ||
| 158 | return false; | ||
| 159 | } | ||
| 160 | |||
| 161 | @Override | ||
| 162 | public boolean isInteger() { | ||
| 163 | // TODO Auto-generated method stub | ||
| 164 | return false; | ||
| 165 | } | ||
| 166 | |||
| 167 | @Override | ||
| 168 | public int parseInteger() throws NumberFormatException { | ||
| 169 | // TODO Auto-generated method stub | ||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | @Override | ||
| 174 | public boolean isBoolean() { | ||
| 175 | // TODO Auto-generated method stub | ||
| 176 | return false; | ||
| 177 | } | ||
| 178 | |||
| 179 | @Override | ||
| 180 | public boolean parseBoolean() throws NumberFormatException { | ||
| 181 | // TODO Auto-generated method stub | ||
| 182 | return false; | ||
| 183 | } | ||
| 184 | |||
| 185 | @Override | ||
| 186 | public boolean isDouble() { | ||
| 187 | // TODO Auto-generated method stub | ||
| 188 | return false; | ||
| 189 | } | ||
| 190 | |||
| 191 | @Override | ||
| 192 | public double parseDouble() throws NumberFormatException { | ||
| 193 | // TODO Auto-generated method stub | ||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | @Override | ||
| 198 | public boolean isFloat() { | ||
| 199 | // TODO Auto-generated method stub | ||
| 200 | return false; | ||
| 201 | } | ||
| 202 | |||
| 203 | @Override | ||
| 204 | public float parseFloat() throws NumberFormatException { | ||
| 205 | // TODO Auto-generated method stub | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | @Override | ||
| 210 | public void accept(OWLDataVisitor visitor) { | ||
| 211 | // TODO Auto-generated method stub | ||
| 212 | |||
| 213 | } | ||
| 214 | |||
| 215 | @Override | ||
| 216 | public <O> O accept(OWLDataVisitorEx<O> visitor) { | ||
| 217 | // TODO Auto-generated method stub | ||
| 218 | return null; | ||
| 219 | } | ||
| 220 | |||
| 221 | } | ||
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableIndividual.java b/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableIndividual.java new file mode 100644 index 0000000..de302b5 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableIndividual.java | |||
| @@ -0,0 +1,410 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query.rollup; | ||
| 2 | |||
| 3 | import java.util.Map; | ||
| 4 | import java.util.Set; | ||
| 5 | |||
| 6 | import org.semanticweb.HermiT.model.Variable; | ||
| 7 | import org.semanticweb.owlapi.model.EntityType; | ||
| 8 | import org.semanticweb.owlapi.model.IRI; | ||
| 9 | import org.semanticweb.owlapi.model.OWLAnnotation; | ||
| 10 | import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; | ||
| 11 | import org.semanticweb.owlapi.model.OWLAnnotationProperty; | ||
| 12 | import org.semanticweb.owlapi.model.OWLAnonymousIndividual; | ||
| 13 | import org.semanticweb.owlapi.model.OWLAxiom; | ||
| 14 | import org.semanticweb.owlapi.model.OWLClass; | ||
| 15 | import org.semanticweb.owlapi.model.OWLClassExpression; | ||
| 16 | import org.semanticweb.owlapi.model.OWLDataProperty; | ||
| 17 | import org.semanticweb.owlapi.model.OWLDataPropertyExpression; | ||
| 18 | import org.semanticweb.owlapi.model.OWLDatatype; | ||
| 19 | import org.semanticweb.owlapi.model.OWLEntity; | ||
| 20 | import org.semanticweb.owlapi.model.OWLEntityVisitor; | ||
| 21 | import org.semanticweb.owlapi.model.OWLEntityVisitorEx; | ||
| 22 | import org.semanticweb.owlapi.model.OWLIndividual; | ||
| 23 | import org.semanticweb.owlapi.model.OWLIndividualVisitor; | ||
| 24 | import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; | ||
| 25 | import org.semanticweb.owlapi.model.OWLLiteral; | ||
| 26 | import org.semanticweb.owlapi.model.OWLNamedIndividual; | ||
| 27 | import org.semanticweb.owlapi.model.OWLNamedObjectVisitor; | ||
| 28 | import org.semanticweb.owlapi.model.OWLObject; | ||
| 29 | import org.semanticweb.owlapi.model.OWLObjectProperty; | ||
| 30 | import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; | ||
| 31 | import org.semanticweb.owlapi.model.OWLObjectVisitor; | ||
| 32 | import org.semanticweb.owlapi.model.OWLObjectVisitorEx; | ||
| 33 | import org.semanticweb.owlapi.model.OWLOntology; | ||
| 34 | |||
| 35 | class VariableIndividual implements OWLNamedIndividual { | ||
| 36 | |||
| 37 | /** | ||
| 38 | * | ||
| 39 | */ | ||
| 40 | private static final long serialVersionUID = 3002966246639516395L; | ||
| 41 | Variable var; | ||
| 42 | |||
| 43 | public VariableIndividual(Variable v) { | ||
| 44 | var = v; | ||
| 45 | } | ||
| 46 | |||
| 47 | @Override | ||
| 48 | public boolean isNamed() { | ||
| 49 | // TODO Auto-generated method stub | ||
| 50 | return false; | ||
| 51 | } | ||
| 52 | |||
| 53 | @Override | ||
| 54 | public boolean isAnonymous() { | ||
| 55 | // TODO Auto-generated method stub | ||
| 56 | return false; | ||
| 57 | } | ||
| 58 | |||
| 59 | @Override | ||
| 60 | public OWLNamedIndividual asOWLNamedIndividual() { | ||
| 61 | // TODO Auto-generated method stub | ||
| 62 | return null; | ||
| 63 | } | ||
| 64 | |||
| 65 | @Override | ||
| 66 | public OWLAnonymousIndividual asOWLAnonymousIndividual() { | ||
| 67 | // TODO Auto-generated method stub | ||
| 68 | return null; | ||
| 69 | } | ||
| 70 | |||
| 71 | // @Override | ||
| 72 | // public Set<OWLClassExpression> getTypes(OWLOntology ontology) { | ||
| 73 | // // TODO Auto-generated method stub | ||
| 74 | // return null; | ||
| 75 | // } | ||
| 76 | |||
| 77 | // @Override | ||
| 78 | // public Set<OWLClassExpression> getTypes(Set<OWLOntology> ontologies) { | ||
| 79 | // // TODO Auto-generated method stub | ||
| 80 | // return null; | ||
| 81 | // } | ||
| 82 | |||
| 83 | // @Override | ||
| 84 | // public Map<OWLObjectPropertyExpression, Set<OWLIndividual>> getObjectPropertyValues( | ||
| 85 | // OWLOntology ontology) { | ||
| 86 | // // TODO Auto-generated method stub | ||
| 87 | // return null; | ||
| 88 | // } | ||
| 89 | |||
| 90 | // @Override | ||
| 91 | // public Set<OWLIndividual> getObjectPropertyValues( | ||
| 92 | // OWLObjectPropertyExpression property, OWLOntology ontology) { | ||
| 93 | // // TODO Auto-generated method stub | ||
| 94 | // return null; | ||
| 95 | // } | ||
| 96 | |||
| 97 | // @Override | ||
| 98 | // public boolean hasObjectPropertyValue(OWLObjectPropertyExpression property, | ||
| 99 | // OWLIndividual individual, OWLOntology ontology) { | ||
| 100 | // // TODO Auto-generated method stub | ||
| 101 | // return false; | ||
| 102 | // } | ||
| 103 | |||
| 104 | // @Override | ||
| 105 | // public boolean hasDataPropertyValue(OWLDataPropertyExpression property, | ||
| 106 | // OWLLiteral value, OWLOntology ontology) { | ||
| 107 | // // TODO Auto-generated method stub | ||
| 108 | // return false; | ||
| 109 | // } | ||
| 110 | |||
| 111 | // @Override | ||
| 112 | // public boolean hasNegativeObjectPropertyValue( | ||
| 113 | // OWLObjectPropertyExpression property, OWLIndividual individual, | ||
| 114 | // OWLOntology ontology) { | ||
| 115 | // // TODO Auto-generated method stub | ||
| 116 | // return false; | ||
| 117 | // } | ||
| 118 | |||
| 119 | // @Override | ||
| 120 | // public Map<OWLObjectPropertyExpression, Set<OWLIndividual>> getNegativeObjectPropertyValues( | ||
| 121 | // OWLOntology ontology) { | ||
| 122 | // // TODO Auto-generated method stub | ||
| 123 | // return null; | ||
| 124 | // } | ||
| 125 | |||
| 126 | // @Override | ||
| 127 | // public Map<OWLDataPropertyExpression, Set<OWLLiteral>> getDataPropertyValues( | ||
| 128 | // OWLOntology ontology) { | ||
| 129 | // // TODO Auto-generated method stub | ||
| 130 | // return null; | ||
| 131 | // } | ||
| 132 | |||
| 133 | // @Override | ||
| 134 | // public Set<OWLLiteral> getDataPropertyValues( | ||
| 135 | // OWLDataPropertyExpression property, OWLOntology ontology) { | ||
| 136 | // // TODO Auto-generated method stub | ||
| 137 | // return null; | ||
| 138 | // } | ||
| 139 | |||
| 140 | // @Override | ||
| 141 | // public Map<OWLDataPropertyExpression, Set<OWLLiteral>> getNegativeDataPropertyValues( | ||
| 142 | // OWLOntology ontology) { | ||
| 143 | // // TODO Auto-generated method stub | ||
| 144 | // return null; | ||
| 145 | // } | ||
| 146 | |||
| 147 | // @Override | ||
| 148 | // public boolean hasNegativeDataPropertyValue( | ||
| 149 | // OWLDataPropertyExpression property, OWLLiteral literal, | ||
| 150 | // OWLOntology ontology) { | ||
| 151 | // // TODO Auto-generated method stub | ||
| 152 | // return false; | ||
| 153 | // } | ||
| 154 | |||
| 155 | // @Override | ||
| 156 | // public Set<OWLIndividual> getSameIndividuals(OWLOntology ontology) { | ||
| 157 | // // TODO Auto-generated method stub | ||
| 158 | // return null; | ||
| 159 | // } | ||
| 160 | |||
| 161 | // @Override | ||
| 162 | // public Set<OWLIndividual> getDifferentIndividuals(OWLOntology ontology) { | ||
| 163 | // // TODO Auto-generated method stub | ||
| 164 | // return null; | ||
| 165 | // } | ||
| 166 | |||
| 167 | @Override | ||
| 168 | public String toStringID() { | ||
| 169 | // TODO Auto-generated method stub | ||
| 170 | return null; | ||
| 171 | } | ||
| 172 | |||
| 173 | @Override | ||
| 174 | public void accept(OWLIndividualVisitor visitor) { | ||
| 175 | // TODO Auto-generated method stub | ||
| 176 | |||
| 177 | } | ||
| 178 | |||
| 179 | @Override | ||
| 180 | public <O> O accept(OWLIndividualVisitorEx<O> visitor) { | ||
| 181 | // TODO Auto-generated method stub | ||
| 182 | return null; | ||
| 183 | } | ||
| 184 | |||
| 185 | @Override | ||
| 186 | public Set<OWLEntity> getSignature() { | ||
| 187 | // TODO Auto-generated method stub | ||
| 188 | return null; | ||
| 189 | } | ||
| 190 | |||
| 191 | @Override | ||
| 192 | public Set<OWLAnonymousIndividual> getAnonymousIndividuals() { | ||
| 193 | // TODO Auto-generated method stub | ||
| 194 | return null; | ||
| 195 | } | ||
| 196 | |||
| 197 | @Override | ||
| 198 | public Set<OWLClass> getClassesInSignature() { | ||
| 199 | // TODO Auto-generated method stub | ||
| 200 | return null; | ||
| 201 | } | ||
| 202 | |||
| 203 | @Override | ||
| 204 | public Set<OWLDataProperty> getDataPropertiesInSignature() { | ||
| 205 | // TODO Auto-generated method stub | ||
| 206 | return null; | ||
| 207 | } | ||
| 208 | |||
| 209 | @Override | ||
| 210 | public Set<OWLObjectProperty> getObjectPropertiesInSignature() { | ||
| 211 | // TODO Auto-generated method stub | ||
| 212 | return null; | ||
| 213 | } | ||
| 214 | |||
| 215 | @Override | ||
| 216 | public Set<OWLNamedIndividual> getIndividualsInSignature() { | ||
| 217 | // TODO Auto-generated method stub | ||
| 218 | return null; | ||
| 219 | } | ||
| 220 | |||
| 221 | @Override | ||
| 222 | public Set<OWLDatatype> getDatatypesInSignature() { | ||
| 223 | // TODO Auto-generated method stub | ||
| 224 | return null; | ||
| 225 | } | ||
| 226 | |||
| 227 | @Override | ||
| 228 | public Set<OWLClassExpression> getNestedClassExpressions() { | ||
| 229 | // TODO Auto-generated method stub | ||
| 230 | return null; | ||
| 231 | } | ||
| 232 | |||
| 233 | @Override | ||
| 234 | public void accept(OWLObjectVisitor visitor) { | ||
| 235 | // TODO Auto-generated method stub | ||
| 236 | |||
| 237 | } | ||
| 238 | |||
| 239 | @Override | ||
| 240 | public <O> O accept(OWLObjectVisitorEx<O> visitor) { | ||
| 241 | // TODO Auto-generated method stub | ||
| 242 | return null; | ||
| 243 | } | ||
| 244 | |||
| 245 | @Override | ||
| 246 | public boolean isTopEntity() { | ||
| 247 | // TODO Auto-generated method stub | ||
| 248 | return false; | ||
| 249 | } | ||
| 250 | |||
| 251 | @Override | ||
| 252 | public boolean isBottomEntity() { | ||
| 253 | // TODO Auto-generated method stub | ||
| 254 | return false; | ||
| 255 | } | ||
| 256 | |||
| 257 | @Override | ||
| 258 | public int compareTo(OWLObject arg0) { | ||
| 259 | // TODO Auto-generated method stub | ||
| 260 | return 0; | ||
| 261 | } | ||
| 262 | |||
| 263 | @Override | ||
| 264 | public EntityType<?> getEntityType() { | ||
| 265 | // TODO Auto-generated method stub | ||
| 266 | return null; | ||
| 267 | } | ||
| 268 | |||
| 269 | // @Override | ||
| 270 | // public <E extends OWLEntity> E getOWLEntity(EntityType<E> entityType) { | ||
| 271 | // // TODO Auto-generated method stub | ||
| 272 | // return null; | ||
| 273 | // } | ||
| 274 | |||
| 275 | @Override | ||
| 276 | public boolean isType(EntityType<?> entityType) { | ||
| 277 | // TODO Auto-generated method stub | ||
| 278 | return false; | ||
| 279 | } | ||
| 280 | |||
| 281 | // @Override | ||
| 282 | // public Set<OWLAnnotation> getAnnotations(OWLOntology ontology) { | ||
| 283 | // // TODO Auto-generated method stub | ||
| 284 | // return null; | ||
| 285 | // } | ||
| 286 | |||
| 287 | // @Override | ||
| 288 | // public Set<OWLAnnotation> getAnnotations(OWLOntology ontology, | ||
| 289 | // OWLAnnotationProperty annotationProperty) { | ||
| 290 | // // TODO Auto-generated method stub | ||
| 291 | // return null; | ||
| 292 | // } | ||
| 293 | |||
| 294 | // @Override | ||
| 295 | // public Set<OWLAnnotationAssertionAxiom> getAnnotationAssertionAxioms( | ||
| 296 | // OWLOntology ontology) { | ||
| 297 | // // TODO Auto-generated method stub | ||
| 298 | // return null; | ||
| 299 | // } | ||
| 300 | |||
| 301 | @Override | ||
| 302 | public boolean isBuiltIn() { | ||
| 303 | // TODO Auto-generated method stub | ||
| 304 | return false; | ||
| 305 | } | ||
| 306 | |||
| 307 | @Override | ||
| 308 | public boolean isOWLClass() { | ||
| 309 | // TODO Auto-generated method stub | ||
| 310 | return false; | ||
| 311 | } | ||
| 312 | |||
| 313 | @Override | ||
| 314 | public OWLClass asOWLClass() { | ||
| 315 | // TODO Auto-generated method stub | ||
| 316 | return null; | ||
| 317 | } | ||
| 318 | |||
| 319 | @Override | ||
| 320 | public boolean isOWLObjectProperty() { | ||
| 321 | // TODO Auto-generated method stub | ||
| 322 | return false; | ||
| 323 | } | ||
| 324 | |||
| 325 | @Override | ||
| 326 | public OWLObjectProperty asOWLObjectProperty() { | ||
| 327 | // TODO Auto-generated method stub | ||
| 328 | return null; | ||
| 329 | } | ||
| 330 | |||
| 331 | @Override | ||
| 332 | public boolean isOWLDataProperty() { | ||
| 333 | // TODO Auto-generated method stub | ||
| 334 | return false; | ||
| 335 | } | ||
| 336 | |||
| 337 | @Override | ||
| 338 | public OWLDataProperty asOWLDataProperty() { | ||
| 339 | // TODO Auto-generated method stub | ||
| 340 | return null; | ||
| 341 | } | ||
| 342 | |||
| 343 | @Override | ||
| 344 | public boolean isOWLNamedIndividual() { | ||
| 345 | // TODO Auto-generated method stub | ||
| 346 | return false; | ||
| 347 | } | ||
| 348 | |||
| 349 | @Override | ||
| 350 | public boolean isOWLDatatype() { | ||
| 351 | // TODO Auto-generated method stub | ||
| 352 | return false; | ||
| 353 | } | ||
| 354 | |||
| 355 | @Override | ||
| 356 | public OWLDatatype asOWLDatatype() { | ||
| 357 | // TODO Auto-generated method stub | ||
| 358 | return null; | ||
| 359 | } | ||
| 360 | |||
| 361 | @Override | ||
| 362 | public boolean isOWLAnnotationProperty() { | ||
| 363 | // TODO Auto-generated method stub | ||
| 364 | return false; | ||
| 365 | } | ||
| 366 | |||
| 367 | @Override | ||
| 368 | public OWLAnnotationProperty asOWLAnnotationProperty() { | ||
| 369 | // TODO Auto-generated method stub | ||
| 370 | return null; | ||
| 371 | } | ||
| 372 | |||
| 373 | // @Override | ||
| 374 | // public Set<OWLAxiom> getReferencingAxioms(OWLOntology ontology) { | ||
| 375 | // // TODO Auto-generated method stub | ||
| 376 | // return null; | ||
| 377 | // } | ||
| 378 | |||
| 379 | // @Override | ||
| 380 | // public Set<OWLAxiom> getReferencingAxioms(OWLOntology ontology, | ||
| 381 | // boolean includeImports) { | ||
| 382 | // // TODO Auto-generated method stub | ||
| 383 | // return null; | ||
| 384 | // } | ||
| 385 | |||
| 386 | @Override | ||
| 387 | public void accept(OWLEntityVisitor visitor) { | ||
| 388 | // TODO Auto-generated method stub | ||
| 389 | |||
| 390 | } | ||
| 391 | |||
| 392 | @Override | ||
| 393 | public <O> O accept(OWLEntityVisitorEx<O> visitor) { | ||
| 394 | // TODO Auto-generated method stub | ||
| 395 | return null; | ||
| 396 | } | ||
| 397 | |||
| 398 | @Override | ||
| 399 | public IRI getIRI() { | ||
| 400 | // TODO Auto-generated method stub | ||
| 401 | return null; | ||
| 402 | } | ||
| 403 | |||
| 404 | @Override | ||
| 405 | public void accept(OWLNamedObjectVisitor visitor) { | ||
| 406 | // TODO Auto-generated method stub | ||
| 407 | |||
| 408 | } | ||
| 409 | |||
| 410 | } | ||
