From 17bd9beaf7f358a44e5bf36a5855fe6727d506dc Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Tue, 10 May 2022 18:17:06 +0100 Subject: [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. --- .../java/uk/ac/ox/cs/pagoda/query/AnswerTuple.java | 191 +++++ .../uk/ac/ox/cs/pagoda/query/AnswerTuples.java | 22 + .../uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java | 89 +++ .../cs/pagoda/query/DeserializedQueryRecord.java | 9 + .../uk/ac/ox/cs/pagoda/query/GapByStore4ID.java | 191 +++++ .../uk/ac/ox/cs/pagoda/query/GapByStore4ID2.java | 146 ++++ .../java/uk/ac/ox/cs/pagoda/query/GapByTriple.java | 163 ++++ .../uk/ac/ox/cs/pagoda/query/GapTupleIterator.java | 28 + .../uk/ac/ox/cs/pagoda/query/QueryManager.java | 123 +++ .../java/uk/ac/ox/cs/pagoda/query/QueryRecord.java | 835 +++++++++++++++++++++ .../ac/ox/cs/pagoda/query/rollup/QueryGraph.java | 400 ++++++++++ .../cs/pagoda/query/rollup/VariableConstant.java | 221 ++++++ .../cs/pagoda/query/rollup/VariableIndividual.java | 410 ++++++++++ 13 files changed, 2828 insertions(+) create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuple.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuples.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/DeserializedQueryRecord.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/GapByStore4ID2.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/GapByTriple.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/GapTupleIterator.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/QueryManager.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/QueryRecord.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableConstant.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/query/rollup/VariableIndividual.java (limited to 'src/main/java/uk/ac/ox/cs/pagoda/query') 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import com.google.gson.*; +import org.semanticweb.HermiT.model.Constant; +import org.semanticweb.HermiT.model.Individual; +import org.semanticweb.HermiT.model.Term; +import org.semanticweb.HermiT.model.Variable; +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.model.Datatype; +import uk.ac.ox.cs.JRDFox.model.GroundTerm; +import uk.ac.ox.cs.JRDFox.model.Literal; +import uk.ac.ox.cs.JRDFox.store.TupleIterator; +import uk.ac.ox.cs.pagoda.util.Namespace; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +public class AnswerTuple { + + public static final String SEPARATOR = "\t"; + String m_str = null; + GroundTerm[] m_tuple; + + public AnswerTuple(TupleIterator iter, int arity) { + m_tuple = new GroundTerm[arity]; + try { + for (int i = 0; i < arity; ++i) + m_tuple[i] = iter.getGroundTerm(i); + } catch (JRDFStoreException e) { + e.printStackTrace(); + } + } + + public AnswerTuple(GroundTerm[] terms) { + m_tuple = terms; + } + +// private AnswerTuple(String m_str) { +// this.m_str = m_str; +// } + + private AnswerTuple(AnswerTuple sup, int arity) { + m_tuple = new GroundTerm[arity]; + for(int i = 0; i < arity; ++i) m_tuple[i] = sup.m_tuple[i]; + } + + /** + * It returns the first argument if its arity equals length, a new AnswerTuple otherwise. + */ + public static AnswerTuple create(AnswerTuple extendedTuple, int length) { + if(length == extendedTuple.getArity()) return extendedTuple; + else return new AnswerTuple(extendedTuple, length); + } + + public int getArity() { + return m_tuple.length; + } + + public int hashCode() { +// return toString().hashCode(); + int code = 0; + for (int i = 0; i < m_tuple.length; ++i) + code = code * 1997 + m_tuple[i].hashCode(); + return code; + } + + public boolean equals(Object obj) { + if (!(obj instanceof AnswerTuple)) return false; + AnswerTuple that = (AnswerTuple) obj; + if (m_tuple.length != that.m_tuple.length) return false; + for (int i = 0; i < m_tuple.length; ++i) + if (!m_tuple[i].equals(that.m_tuple[i])) + return false; + return true; +// return toString().equals(obj.toString()); + } + + public String toString() { + if(m_str != null) return m_str; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < m_tuple.length; ++i) { + if (sb.length() != 0) sb.append(SEPARATOR); + if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual) + sb.append("<").append(((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI()).append(">"); + else if (m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.BlankNode) { + sb.append(m_tuple[i].toString()); + } + else { + Literal l = (Literal) m_tuple[i]; + sb.append('"').append(l.getLexicalForm()).append("\""); + if (!l.getDatatype().equals(Datatype.XSD_STRING) && !l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL)) + sb.append("^^<").append(l.getDatatype().getIRI()).append(">"); + } + } + return m_str = sb.toString(); + } + + public GroundTerm getGroundTerm(int i) { + return m_tuple[i]; + } + + public Map getAssignment(String[] vars) { + Map map = new HashMap(); + int index = 0; + Term t; + for (String var: vars) { + if(m_tuple[index] instanceof uk.ac.ox.cs.JRDFox.model.Individual) + t = Individual.create((((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[index]).getIRI())); + else { + uk.ac.ox.cs.JRDFox.model.Literal l = (uk.ac.ox.cs.JRDFox.model.Literal) m_tuple[index]; + t = Constant.create(l.getLexicalForm(), l.getDatatype().getIRI()); + } + map.put(Variable.create(var), t); + ++index; + } + return map; + } + + public boolean hasAuxPredicate() { + String iri; + for (int i = 0; i < m_tuple.length; ++i) + if ((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) { + iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI(); + if(iri.startsWith(Namespace.PAGODA_AUX) || iri.contains("_AUX") || iri.contains("_neg") || iri.contains("internal:def")) + return true; + } + return false; + } + + public boolean hasAnonymousIndividual() { + String iri; + for(int i = 0; i < m_tuple.length; ++i) + if((m_tuple[i] instanceof uk.ac.ox.cs.JRDFox.model.Individual)) { + iri = ((uk.ac.ox.cs.JRDFox.model.Individual) m_tuple[i]).getIRI(); + if(iri.startsWith(Namespace.PAGODA_ANONY) || iri.startsWith(Namespace.KARMA_ANONY)) + return true; + } + return false; + } + + public static class AnswerTupleSerializer implements JsonSerializer { + + public JsonElement serialize(AnswerTuple src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.toString()); + } + + } + + public static class AnswerTupleDeserializer implements JsonDeserializer { + public AnswerTuple deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + String tuplesString = json.getAsJsonPrimitive().getAsString(); +// StringTokenizer tokenizer = new StringTokenizer(tuplesString, SEPARATOR); + StringTokenizer tokenizer = new StringTokenizer(tuplesString); + int tokensCount = tokenizer.countTokens(); + GroundTerm[] terms = new GroundTerm[tokensCount]; + + // TODO test parsing + for(int i = 0; i < tokensCount; i++) { + String token = tokenizer.nextToken(); + if (token.charAt(0) == '<') { + terms[i] = uk.ac.ox.cs.JRDFox.model.Individual.create(token.substring(1,token.length()-1)); + } + else if (token.charAt(0) == '"') { + Datatype datatype; + String lexicalForm; + if(token.contains("^^")) { + String[] lexicalFormAndType = token.split("^^"); + lexicalForm = lexicalFormAndType[0]; + datatype = Datatype.value(lexicalFormAndType[1]); + } + else { + lexicalForm = token.substring(1, token.length() - 1); + // TODO check +// datatype = token.contains("@") ? Datatype.RDF_PLAIN_LITERAL : Datatype.XSD_STRING; + datatype = Datatype.XSD_STRING; + } + terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, datatype); + } + else { + terms[i] = uk.ac.ox.cs.JRDFox.model.BlankNode.create(token); + } + } + + return new AnswerTuple(terms); + } + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; + +public abstract class AnswerTuples extends Disposable { + + public abstract void reset(); + + public abstract boolean isValid(); + + public abstract int getArity(); + + public abstract String[] getAnswerVariables(); + + public abstract void moveNext(); + + public abstract AnswerTuple getTuple(); + + public abstract boolean contains(AnswerTuple t); + + public abstract void remove(); +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import java.util.Iterator; +import java.util.Set; + +public class AnswerTuplesImp extends AnswerTuples { + + int m_index; + Iterator m_iter; + Set m_answers1, m_answers2; + String[] m_answerVars; + AnswerTuple m_tuple; + + public AnswerTuplesImp(String[] answerVars, Set answers) { + m_answers1 = answers; + m_answers2 = null; + m_answerVars = answerVars; + reset(); + } + + public AnswerTuplesImp(String[] answerVars, Set answers1, Set answers2) { + m_answers1 = answers1; + m_answers2 = answers2; + m_answerVars = answerVars; + reset(); + } + + @Override + public boolean isValid() { + return m_tuple != null; + } + + @Override + public int getArity() { + return m_answerVars.length; + } + + @Override + public void moveNext() { + if (m_iter != null && m_iter.hasNext()) { + m_tuple = m_iter.next(); + return ; + } + else if (m_answers2 != null && m_index == 1){ + ++m_index; + m_iter = m_answers2.iterator(); + if (m_iter.hasNext()) { + m_tuple = m_iter.next(); + return ; + } + } + else + m_tuple = null; + } + + @Override + public void reset() { + if (m_answers1 == null || m_answers1.isEmpty()) { + m_index = 2; + m_iter = m_answers2 == null ? null : m_answers2.iterator(); + } + else { + m_index = 1; + m_iter = m_answers1.iterator(); + } + moveNext(); + } + + @Override + public boolean contains(AnswerTuple t) { + return m_answers1.contains(t) || (m_answers2 != null && m_answers2.contains(t)); + } + + @Override + public AnswerTuple getTuple() { + return m_tuple; + } + + @Override + public String[] getAnswerVariables() { + return m_answerVars; + } + + @Override + public void remove() { + m_iter.remove(); + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +/* +* A light version of QueryRecord, +* which can be obtained easily from the Json serialization of QueryRecord. +* */ +public class DeserializedQueryRecord { + // TODO implement +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import uk.ac.ox.cs.pagoda.MyPrefixes; +//import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Timer; +import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.store.DataStore; +import uk.ac.ox.cs.JRDFox.store.TupleIterator; + +//public class GapByStore4ID extends GapTupleIterator { +public class GapByStore4ID extends GapTupleIterator { + + protected MyPrefixes prefixes = MyPrefixes.PAGOdAPrefixes; + protected TupleIterator iterator = null; + +// AnswerTupleID tuple; + protected int[] tuple; + protected BasicQueryEngine m_engine; + protected DataStore m_store; + protected RDFoxTripleManager tripleManager; + + public GapByStore4ID(BasicQueryEngine engine) { + m_engine = engine; + m_store = engine.getDataStore(); + tripleManager = new RDFoxTripleManager(m_store, false); + } + + protected long multi; + + @Override + public void compile(String program) throws JRDFStoreException { + clear(); + + boolean incrementally = true; + Timer t = new Timer(); + long oldTripleCount = m_store.getTriplesCount(); + + if (program != null) { +// m_store.addRules(new String[] {program}); + m_store.importRules(program); + incrementally = false; + } + + m_store.applyReasoning(incrementally); + + long tripleCount = m_store.getTriplesCount(); + + Utility.logDebug("current store after materialising upper related rules: " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)", + "current store finished the materialisation of upper related rules in " + t.duration() + " seconds."); + + m_engine.setExpandEquality(false); + iterator = m_engine.internal_evaluateAgainstIDBs("select ?x ?y ?z where { ?x ?y ?z . }"); + m_engine.setExpandEquality(true); + + multi = iterator.open(); + Utility.logDebug("gap query evaluted ..."); + } + + @Override + public boolean hasNext() { + if (iterator == null) return false; + try { +// tuple = new AnswerTupleID(3); + tuple = new int[3]; + Integer predicate; + for (; multi != 0; multi = iterator.getNext()) { + for (int i = 0; i < 3; ++i) +// tuple.setTerm(i, (int) iterator.getResourceID(i)); + tuple[i] = (int) iterator.getResourceID(i); + + if (isRDF_TYPE()) { +// predicate = getGapPredicateID(tuple.getTerm(2)); + predicate = getGapPredicateID(tuple[2]); + if (predicate == null) continue; +// tuple.setTerm(2, predicate); + tuple[2] = predicate; + } + else { +// predicate = getGapPredicateID(tuple.getTerm(1)); + predicate = getGapPredicateID(tuple[1]); + if (predicate == null) continue; +// tuple.setTerm(1, predicate); + tuple[1] = predicate; + } + return true; + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + return false; + } + return false; + } + + @Override +// public AnswerTupleID next() { + public int[] next() { + try { + multi = iterator.getNext(); + } catch (JRDFStoreException e) { + e.printStackTrace(); + } + + return tuple; + } + + Map original2gap = new HashMap(); + LinkedList predicatesWithGap = new LinkedList(); + + public LinkedList getPredicatesWithGap() { + return predicatesWithGap; + } + + protected Integer getGapPredicateID(int originalID) { + Integer gapID; + if ((gapID = original2gap.get(originalID)) != null) + return gapID; + + String originalPredicate = tripleManager.getRawTerm(originalID); + if (isAuxPredicate(originalPredicate)) { +// Utility.LOGS.info(originalPredicate); + return null; + } + + predicatesWithGap.add(originalPredicate); + String gapPredicate = prefixes.expandIRI(getGapPredicate(originalPredicate)); + gapID = tripleManager.getResourceID(gapPredicate); + original2gap.put(originalID, gapID); + + return gapID; + } + + protected boolean isAuxPredicate(String originalPredicate) { + if (originalPredicate.equals(Namespace.EQUALITY_QUOTED)) return false; + return originalPredicate.contains("_AUX") || + originalPredicate.startsWith("<" + Namespace.OWL_NS) || + originalPredicate.startsWith("<" + Namespace.PAGODA_ORIGINAL); + } + + protected boolean isRDF_TYPE() { +// return tripleManager.isRdfTypeID(tuple.getTerm(1)); + return tripleManager.isRdfTypeID(tuple[1]); + } + + @Override + public void remove() { + Utility.logError("Unsupported operation!"); + } + + @Override + public void save(String file) { + Utility.logError("Unsupported Operation..."); + } + + @Override + public void addBackTo() throws JRDFStoreException { + int tupleCounter = 0; + Timer t = new Timer(); + long oldTripleCounter; + Utility.logDebug("current store before importing gap tuples: " + (oldTripleCounter = m_store.getTriplesCount())); + while (hasNext()) { + next(); + ++tupleCounter; + tripleManager.addTripleByID(tuple); + } + + long tripleCounter = m_store.getTriplesCount(); + Utility.logDebug("There are " + tupleCounter + " tuples in the gap between lower and upper bound materialisation.", + "current store after importing gap tuples: " + tripleCounter + " (" + (tripleCounter - oldTripleCounter) + ").", + "current store finished importing gap tuples: " + tripleCounter + " in " + t.duration() + "."); + } + + public void clear() { + if (iterator != null) { + iterator.dispose(); + iterator = null; + } + } + + @Override + public void addTo(DataStore store) throws JRDFStoreException { + Utility.logError("Unsupported Operation..."); + } +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.util.UFS; +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.store.TupleIterator; + +public class GapByStore4ID2 extends GapByStore4ID { + + private BasicQueryEngine m_baseEngine; + private UFS m_equality = null, m_baseEquality = null; + + public GapByStore4ID2(BasicQueryEngine engine, BasicQueryEngine baseEngine) { + super(engine); + m_baseEngine = baseEngine; + } + + @Override + public boolean hasNext() { + if (getNewGapTuple(iterator, -1)) return true; + if (iterator != null) { + iterator.dispose(); + iterator = null; + } + return getNextGapFactAboutEquality(); + } + + private boolean getNewGapTuple(TupleIterator it, int firstElement) { + if (it == null) return false; + int firstIndex = 0; + tuple = new int[3]; + if (firstElement > 0) { + tuple[0] = firstElement; + firstIndex = 1; + } + Integer predicate; + try { + for (; multi != 0; multi = it.getNext()) { + for (int i = firstIndex; i < 3; ++i) + tuple[i] = (int) it.getResourceID(i - firstIndex); + + if (isRDF_TYPE()) { + predicate = getGapPredicateID(tuple[2]); + if (predicate == null) continue; + tuple[2] = predicate; + } + else { + predicate = getGapPredicateID(tuple[1]); + if (predicate == null) continue; + tuple[1] = predicate; + } + return true; + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + return false; + } + return false; + } + + private LinkedList toAddedIndividuals = null; + private TupleIterator iter_individual = null; + private int currentID = -1; + + private boolean getNextGapFactAboutEquality() { + if (toAddedIndividuals == null) { + m_equality = m_engine.getEqualityGroups(false); + m_baseEquality = m_baseEngine.getEqualityGroups(false); + toAddedIndividuals = new LinkedList(); + Map rep2cnt = new HashMap(); + Map rep2cnt_base = new HashMap(); + count(m_engine, m_equality, rep2cnt); + count(m_baseEngine, m_baseEquality, rep2cnt_base); + Set visitedrep = new HashSet(); + for (String individual : m_equality.keySet()) { + String rep = m_equality.find(individual); + if (visitedrep.contains(rep)) continue; + visitedrep.add(rep); + String rep_base = m_baseEquality.find(individual); + if (!rep2cnt.get(rep).equals(rep2cnt_base.get(rep_base))) { + toAddedIndividuals.add(rep); + } + } + + } + while (true) { + if (getNewGapTuple(iter_individual, currentID)) return true; + if (iter_individual != null) { + iter_individual.dispose(); + iter_individual = null; + } + if (toAddedIndividuals.isEmpty()) { + currentID = -1; + return false; + } + String individual = toAddedIndividuals.remove(); + currentID = tripleManager.getResourceID(individual); + try { + iter_individual = m_engine.internal_evaluateNotExpanded(String.format("select distinct ?y ?z where { <%s> ?y ?z }", individual)); + multi = iter_individual.open(); + } catch (JRDFStoreException e) { + e.printStackTrace(); + } + } + } + + private void count(BasicQueryEngine engine, UFS equality, Map map) { + for (String ind : equality.keySet()) { + Integer exist = map.get(ind); + if (exist == null) + map.put(equality.find(ind), 1); + else + map.put(equality.find(ind), ++exist); + } + } + + @Override + public int[] next() { + try { + if (iterator != null) + multi = iterator.getNext(); + else if (iter_individual != null) + multi = iter_individual.getNext(); + else + multi = 0; + } catch (JRDFStoreException e) { + e.printStackTrace(); + } + return tuple; + } + + public void clear() { + super.clear(); + if (iter_individual != null) { + iter_individual.dispose(); + iter_individual = null; + } + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import org.semanticweb.HermiT.model.*; +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.Prefixes; +import uk.ac.ox.cs.JRDFox.store.DataStore; +import uk.ac.ox.cs.JRDFox.store.Parameters; +import uk.ac.ox.cs.JRDFox.store.TupleIterator; +import uk.ac.ox.cs.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.owl.OWLHelper; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Utility; + +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Collection; + +public class GapByTriple extends GapTupleIterator { + + static final String allTripleQuery = "SELECT ?X ?Y ?Z WHERE { ?X ?Y ?Z }"; + private static final String RDF_TYPE = Namespace.RDF_NS + "type"; + private static final String BRIEF_RDF_TYPE = "rdf:type"; + DataStore lowerStore, upperStore; + long multi; + TupleIterator iterator; + String sub, obj, predicate; +// GroundTerm subTerm, objTerm; + Prefixes prefixes; + Parameters parameters; + + public GapByTriple(BasicQueryEngine lowerStore, BasicQueryEngine upperStore) { + this.lowerStore = lowerStore.getDataStore(); + this.upperStore = upperStore.getDataStore(); + prefixes = MyPrefixes.PAGOdAPrefixes.getRDFoxPrefixes(); + parameters = new Parameters(); + } + + public void compile(Collection clauses) throws JRDFStoreException { + iterator = this.upperStore.compileQuery(allTripleQuery, prefixes, parameters); + multi = iterator.open(); + } + + @Override + public boolean hasNext() { + TupleIterator iter = null; + boolean inGap; + StringBuffer queryBuffer = new StringBuffer(); + try { + for (; multi != 0; multi = iterator.getNext()) { +// iterator.getRawGroundTerm(0); +// iterator.getRawGroundTerm(1); +// iterator.getRawGroundTerm(2); + + sub = RDFoxTripleManager.getQuotedTerm(iterator.getResource(0)); + predicate = RDFoxTripleManager.getQuotedTerm(iterator.getResource(1)); + obj = RDFoxTripleManager.getQuotedTerm(iterator.getResource(2)); + + if (!obj.startsWith("<")) { + // This fragment of code ignores data types assertions. +// Utility.LOGS.info(sub + " " + predicate + " " + obj); + continue; + } + + queryBuffer.setLength(0); + queryBuffer.append("SELECT WHERE { ").append(sub).append(" ").append(predicate).append(" ").append(obj).append(" }"); + + try { + iter = lowerStore.compileQuery(queryBuffer.toString(), prefixes, parameters); + inGap = iter.open() != 0; + } finally { + if (iter != null) iter.dispose(); + iter = null; + } + if (inGap) + return true; + } + } catch (JRDFStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return false; + } + + @Override + public String next() { + try { + multi = iterator.getNext(); + } catch (JRDFStoreException e) { + e.printStackTrace(); + } + StringBuilder sb = new StringBuilder(); + if (isRDF_TYPE()) { + sb.append(sub).append(" ").append(predicate).append(" ").append(getGapPredicate(obj)).append("."); + } + else sb.append(sub).append(" ").append(getGapPredicate(predicate)).append(" ").append(obj).append("."); + return sb.toString(); + } + + private boolean isRDF_TYPE() { + return predicate.equals(RDF_TYPE) || predicate.equals(BRIEF_RDF_TYPE); + } + + @Override + public void remove() { + Utility.logError("Unsupported operation!"); + } + + public void save(String file) { + int tupleCounter = 0; + try { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))); + String tuple; + while (hasNext()) { + tuple = next(); + writer.write(tuple); + writer.newLine(); + ++tupleCounter; + } + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + Utility.logError("There are " + tupleCounter + " tuples in the gap between lower and upper bound materialisation."); + } + + public void addTo(DataStore store) throws JRDFStoreException { + int tupleCounter = 0; + RDFoxTripleManager tripleManager = new RDFoxTripleManager(store, false); + while (hasNext()) { + multi = iterator.getNext(); + ++tupleCounter; + if (isRDF_TYPE()) { + obj = OWLHelper.removeAngles(obj); + tripleManager.addTripleByTerm( + Atom.create(AtomicConcept.create(getGapPredicate(obj)), Individual.create(sub))); + } + else { + predicate = OWLHelper.removeAngles(predicate); + tripleManager.addTripleByTerm( + Atom.create(AtomicRole.create(getGapPredicate(predicate)), Individual.create(sub), Individual.create(obj))); + } + if (tupleCounter % 10000 == 0) + Utility.logDebug(tupleCounter); + } + + Utility.logDebug("There are " + tupleCounter + " tuples in the gap between lower and upper bound materialisation."); + } + + @Override + public void addBackTo() throws JRDFStoreException { + addTo(upperStore); + } + + @Override + public void clear() { + iterator.dispose(); + } +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.store.DataStore; + +import java.util.Iterator; + +public abstract class GapTupleIterator implements Iterator { + + public static final String gapPredicateSuffix = "_AUXg"; + + public static final String getGapPredicate(String predicateIRI) { + if (predicateIRI.startsWith("<")) + return predicateIRI.replace(">", gapPredicateSuffix + ">"); + return predicateIRI + gapPredicateSuffix; + } + + public void compile(String programText) throws JRDFStoreException {} + + public abstract void save(String file); + + public abstract void addBackTo() throws JRDFStoreException; + + public abstract void addTo(DataStore store) throws JRDFStoreException; + + public abstract void clear(); + +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Scanner; + +import uk.ac.ox.cs.pagoda.util.Utility; + +public class QueryManager { + + public Collection collectQueryRecords(String queryfile) { + Collection ret = new LinkedList(); + for (String queryText: collectQueryTexts(queryfile)) + ret.add(create(queryText)); + return ret; + } + + public static Collection collectQueryTexts(String queryfile) { + Scanner scanner = null; + try { + scanner = new Scanner(new File(queryfile)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } + Collection ret = new LinkedList(); + + StringBuilder sb = new StringBuilder(); + int leftToMatch; + String text; + while (scanner.hasNextLine()) { + leftToMatch = -1; + for (String line; scanner.hasNextLine(); ) { + line = scanner.nextLine(); + if (line.length() > 6 && line.substring(0, 6).equalsIgnoreCase("SELECT")) { + String next = line.split(" ")[1]; + if (!next.equalsIgnoreCase("distinct")) + line = line.substring(0, 6) + " distinct" + line.substring(6); + } + for (int i = 0; i < line.length(); ++i) + if (line.charAt(i) == '{') + if (leftToMatch == -1) leftToMatch = 1; + else ++leftToMatch; + else if (line.charAt(i) == '}') --leftToMatch; + +// if (line.isEmpty()) break; + + if (!line.isEmpty()) + sb.append(line).append(Utility.LINE_SEPARATOR); + + if (leftToMatch == 0) break; + } + + text = preprocess(sb.toString()); + if (!text.isEmpty()) + ret.add(text); + sb.setLength(0); + } + + scanner.close(); + return ret; + } + + private static String preprocess(String text) { + int index; + text = text.trim(); + while (text.startsWith("^") || text.startsWith("#") || text.startsWith("//") || text.startsWith("@")) + if ((index = text.indexOf("\n")) != -1) + text = text.substring(index + 1); + else { + text = ""; + break; + } + return text; // text.replace(" a ", " "); + } + + private Map allRecords = new HashMap(); + private int queryCounter = 0; + + public QueryRecord create(String text, int i, int j) { +// StringBuilder queryText = new StringBuilder(); +// for (String seq : text.split("\s")) { +// if (seq.length() == 0) continue; +// if (queryText.length() != 0) queryText.append(" "); +// queryText.append(seq); +// } +// text = queryText.toString(); + text = text.replaceAll("\\s+", " ").trim(); + QueryRecord ret = allRecords.get(text); + if (ret != null) return ret; + else { + if (i == -1) { + i = ++queryCounter; + } + + ret = new QueryRecord(this, text, i, j); + allRecords.put(text, ret); + return ret; + } + } + + public QueryRecord create(String text, int i) { + return create(text, i, 0); + } + + + public void remove(String queryText) { + allRecords.remove(queryText); + } + + public void put(String text, QueryRecord queryRecord) { + allRecords.put(text, queryRecord); + } + + public QueryRecord create(String queryText) { + return create(queryText, -1, 0); + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.query; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.lang.WordUtils; +import org.semanticweb.HermiT.model.*; +import org.semanticweb.owlapi.model.*; +import org.semanticweb.owlapi.model.parameters.Imports; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxAnswerTuples; +import uk.ac.ox.cs.pagoda.rules.GeneralProgram; +import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; +import uk.ac.ox.cs.pagoda.util.tuples.Tuple; +import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; + +import java.io.*; +import java.lang.reflect.Type; +import java.util.*; + +public class QueryRecord extends Disposable { + + public static final String botQueryText = + "SELECT ?X WHERE { ?X }"; + public static final String SEPARATOR = "----------------------------------------"; + private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString(); + boolean processed = false; + String stringQueryID = null; + OWLOntology relevantOntology = null; + Set relevantClauses = new HashSet(); + double[] timer; + int[] gapAnswersAtStep; + int subID; + DLClause queryClause = null; + int queryID = -1; + Set soundAnswerTuples = new HashSet(); + private Step difficulty; + private String queryText; + private String[][] answerVariables = null; + private Set gapAnswerTuples = null; + private QueryManager m_manager; + + private QueryRecord() { + } + +// private boolean containsAuxPredicate(String str) { +// return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") || +// str.contains("internal:def"); +// } + + public QueryRecord(QueryManager manager, String text, int id, int subID) { + m_manager = manager; + resetInfo(text, id, subID); + resetTimer(); + } + + public static Collection collectQueryTexts(Collection queryRecords) { + Collection texts = new LinkedList(); + for(QueryRecord record : queryRecords) + texts.add(record.queryText); + return texts; + } + + public void resetInfo(String text, int id, int subid) { + if(isDisposed()) throw new DisposedException(); + + queryID = id; + subID = subid; + stringQueryID = id + (subID == 0 ? "" : "_" + subID); + m_manager.remove(queryText); + m_manager.put(text, this); + queryClause = null; + answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text); + queryText = text; // .replace("_:", "?"); + } + + public void resetTimer() { + if(isDisposed()) throw new DisposedException(); + + int length = Step.values().length; + timer = new double[length]; + gapAnswersAtStep = new int[length]; + for(int i = 0; i < length; ++i) { + timer[i] = 0; + gapAnswersAtStep[i] = 0; + } + } + + public AnswerTuples getAnswers() { + if(isDisposed()) throw new DisposedException(); + + if(isProcessed()) + return getLowerBoundAnswers(); + + return getUpperBoundAnswers(); + } + + public AnswerTuples getLowerBoundAnswers() { + if(isDisposed()) throw new DisposedException(); + + return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples); + } + + public AnswerTuples getUpperBoundAnswers() { + if(isDisposed()) throw new DisposedException(); + + return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples); + } + + public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) { + if(isDisposed()) throw new DisposedException(); + + if(answerTuples == null) return false; + boolean update = false; + for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) { + tuple = answerTuples.getTuple(); + if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) { + soundAnswerTuples.add(tuple); + if(gapAnswerTuples != null) + gapAnswerTuples.remove(tuple); + update = true; + } + } + + if(soundAnswerTuples.isEmpty()) + Utility.logInfo("Lower bound answers empty"); + else if(update) + Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size()); + else + Utility.logInfo("Lower bound answers unchanged"); + + return update; + } + + public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) { + if(isDisposed()) throw new DisposedException(); + + return updateUpperBoundAnswers(answerTuples, false); + } + + public int getNumberOfAnswers() { + if(isDisposed()) throw new DisposedException(); + + return soundAnswerTuples.size() + gapAnswerTuples.size(); + } + + public void markAsProcessed() { + processed = true; + } + + public boolean isProcessed() { + if(isDisposed()) throw new DisposedException(); + + if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true; + return processed; + } + + public String[] getDistinguishedVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[1]; + } + + public String[] getAnswerVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[0]; + } + + public String[][] getVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables; + } + + public String getQueryText() { + return queryText; + } + + public String getQueryID() { + return stringQueryID; + } + + public AnswerTuples getGapAnswers() { + if(isDisposed()) throw new DisposedException(); + + return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples); + } + + public int getGapAnswersCount() { + return gapAnswerTuples.size(); + } + + public String toString() { + return queryText; + } + + public void outputAnswers(BufferedWriter writer) throws IOException { + if(isDisposed()) throw new DisposedException(); + + int answerCounter = soundAnswerTuples.size(); + if(!isProcessed()) answerCounter += gapAnswerTuples.size(); + + Utility.logInfo("The number of answer tuples: " + answerCounter); + + if(writer != null) { + writer.write("-------------- Query " + queryID + " ---------------------"); + writer.newLine(); + writer.write(queryText); + writer.newLine(); + StringBuilder space = new StringBuilder(); + int arity = getArity(), varSpace = 0; + for(int i = 0; i < arity; ++i) + varSpace += answerVariables[0][i].length(); + for(int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i) + space.append(" "); + for(int i = 0; i < getArity(); ++i) { + writer.write(space.toString()); + writer.write(answerVariables[0][i]); + } + writer.newLine(); + writer.write(SEPARATOR); + writer.newLine(); + for(AnswerTuple tuple : soundAnswerTuples) { + writer.write(tuple.toString()); + writer.newLine(); + } + if(!isProcessed()) + for(AnswerTuple tuple : gapAnswerTuples) { + writer.write("*"); + writer.write(tuple.toString()); + writer.newLine(); + } +// writer.write(SEPARATOR); + writer.newLine(); + } + + } + + public void outputAnswerStatistics() { + if(isDisposed()) throw new DisposedException(); + + int answerCounter = soundAnswerTuples.size(); + if(!isProcessed()) answerCounter += gapAnswerTuples.size(); + + Utility.logInfo("The number of answer tuples: " + answerCounter); +// if (jsonAnswers != null) { +// JSONObject jsonAnswer = new JSONObject(); +// +// jsonAnswer.put("queryID", queryID); +// jsonAnswer.put("queryText", queryText); +// +// JSONArray answerVars = new JSONArray(); +// int arity = getArity(), varSpace = 0; +// for (int i = 0; i < getArity(); i++) +// answerVars.add(answerVariables[0][i]); +// jsonAnswer.put("answerVars", answerVars); +// +// JSONArray answerTuples = new JSONArray(); +// soundAnswerTuples.stream().forEach(t -> answerTuples.add(t)); +// jsonAnswer.put("answerTuples", answerTuples); +// +// if (!processed) { +// JSONArray gapAnswerTuples = new JSONArray(); +// gapAnswerTuples.stream().forEach(t -> gapAnswerTuples.add(t)); +// } +// jsonAnswer.put("gapAnswerTuples", gapAnswerTuples); +// +// jsonAnswers.put(Integer.toString(queryID), jsonAnswer); +// } + } + + public void outputTimes() { + if(isDisposed()) throw new DisposedException(); + + for(Step step : Step.values()) { + Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]); + } + } + + public Map getStatistics() { + HashMap result = new HashMap<>(); + + double totalTime = 0.0; + for(Step step : Step.values()) { + result.put(step.toString() + "_time", Double.toString(timer[step.ordinal()])); + result.put(step.toString() + "_gap", Integer.toString(gapAnswersAtStep[step.ordinal()])); + totalTime += timer[step.ordinal()]; + } + result.put("totalTime", Double.toString(totalTime)); + result.put("difficulty", difficulty.toString()); + + return result; + } + + public String outputSoundAnswerTuple() { + if(isDisposed()) throw new DisposedException(); + + StringBuilder builder = new StringBuilder(); + for(AnswerTuple tuple : soundAnswerTuples) + builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); + return builder.toString(); + } + + public String outputGapAnswerTuple() { + if(isDisposed()) throw new DisposedException(); + + StringBuilder builder = new StringBuilder(); + for(AnswerTuple tuple : gapAnswerTuples) + builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); + return builder.toString(); + } + + public Step getDifficulty() { + if(isDisposed()) throw new DisposedException(); + + return difficulty; + } + + public void setDifficulty(Step step) { + if(isDisposed()) throw new DisposedException(); + + this.difficulty = step; + } + + public OWLOntology getRelevantOntology() { + if(isDisposed()) throw new DisposedException(); + + return relevantOntology; + } + + public void setRelevantOntology(OWLOntology knowledgebase) { + if(isDisposed()) throw new DisposedException(); + + relevantOntology = knowledgebase; + } + + public void saveRelevantOntology(String filename) { + if(isDisposed()) throw new DisposedException(); + + if(relevantOntology == null) return; + OWLOntologyManager manager = relevantOntology.getOWLOntologyManager(); + try { + FileOutputStream outputStream = new FileOutputStream(filename); + manager.saveOntology(relevantOntology, outputStream); + outputStream.close(); + } catch(OWLOntologyStorageException e) { + e.printStackTrace(); + } catch(FileNotFoundException e) { + e.printStackTrace(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + public void saveRelevantClause() { + if(isDisposed()) throw new DisposedException(); + + if(relevantClauses == null) return; + GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology); + p.save(); + } + + public void removeUpperBoundAnswers(Collection answers) { + if(isDisposed()) throw new DisposedException(); + + for(AnswerTuple answer : answers) { +// if (soundAnswerTuples.contains(answer)) +// Utility.logError("The answer (" + answer + ") cannot be removed, because it is in the lower bound."); + if(!gapAnswerTuples.contains(answer)) + Utility.logError("The answer (" + answer + ") cannot be removed, because it is not in the upper bound."); + gapAnswerTuples.remove(answer); + } + int numOfUpperBoundAnswers = soundAnswerTuples.size() + gapAnswerTuples.size(); + Utility.logInfo("Upper bound answers updated: " + numOfUpperBoundAnswers); + } + + public void addLowerBoundAnswers(Collection answers) { + if(isDisposed()) throw new DisposedException(); + + for(AnswerTuple answer : answers) { + if(!gapAnswerTuples.contains(answer)) + Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); + gapAnswerTuples.remove(answer); + + answer = AnswerTuple.create(answer, answerVariables[0].length); +// if (soundAnswerTuples.contains(answer)) +// Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound."); + soundAnswerTuples.add(answer); + } + } + + public int getNoOfSoundAnswers() { + if(isDisposed()) throw new DisposedException(); + + return soundAnswerTuples.size(); + } + + public void addProcessingTime(Step step, double time) { + if(isDisposed()) throw new DisposedException(); + + timer[step.ordinal()] += time; + if(gapAnswerTuples != null) + gapAnswersAtStep[step.ordinal()] = getGapAnswersCount(); + else + gapAnswersAtStep[step.ordinal()] = -1; + } + + public int getArity() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[0].length; + } + + public void addRelevantClauses(DLClause clause) { + if(isDisposed()) throw new DisposedException(); + + relevantClauses.add(clause); + } + + public Set getRelevantClauses() { + if(isDisposed()) throw new DisposedException(); + + return relevantClauses; + } + + public void clearClauses() { + if(isDisposed()) throw new DisposedException(); + + relevantClauses.clear(); + } + + public boolean isHorn() { + if(isDisposed()) throw new DisposedException(); + + for(DLClause clause : relevantClauses) + if(clause.getHeadLength() > 1) + return false; + return true; + } + + public void saveABoxInTurtle(String filename) { + if(isDisposed()) throw new DisposedException(); + + try { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); + OWLIndividual a, b; + StringBuilder builder = new StringBuilder(); + for(OWLAxiom axiom : relevantOntology.getABoxAxioms(Imports.INCLUDED)) { + if(axiom instanceof OWLClassAssertionAxiom) { + OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom; + OWLClass c = (OWLClass) classAssertion.getClassExpression(); + a = classAssertion.getIndividual(); + builder.append(a.toString()) + .append(" <") + .append(Namespace.RDF_TYPE) + .append("> ") + .append(c.toString()); + } + else if(axiom instanceof OWLObjectPropertyAssertionAxiom) { + OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom; + OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty(); + a = propertyAssertion.getSubject(); + b = propertyAssertion.getObject(); + builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString()); + } + else if(axiom instanceof OWLDataPropertyAssertionAxiom) { + OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom; + OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty(); + a = propertyAssertion.getSubject(); + OWLLiteral l = propertyAssertion.getObject(); + builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString()); + } + + writer.write(builder.toString()); + writer.write(" ."); + writer.newLine(); + builder.setLength(0); + } + writer.close(); + } catch(IOException e) { + e.printStackTrace(); + } finally { + + } + } + + public void updateSubID() { + if(isDisposed()) throw new DisposedException(); + + ++subID; + stringQueryID = String.valueOf(queryID) + "_" + subID; + } + + public DLClause getClause() { + if(isDisposed()) throw new DisposedException(); + + if(queryClause != null) + return queryClause; + return queryClause = DLClauseHelper.getQuery(queryText, null); + } + + public boolean isBottom() { + if(isDisposed()) throw new DisposedException(); + + return queryID == 0; + } + + public int getNoOfCompleteAnswers() { + if(isDisposed()) throw new DisposedException(); + + return soundAnswerTuples.size() + gapAnswerTuples.size(); + } + + public int getSubID() { + if(isDisposed()) throw new DisposedException(); + + return subID; + } + + public boolean hasSameGapAnswers(QueryRecord that) { + if(isDisposed()) throw new DisposedException(); + + return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples); + } + + @Override + public void dispose() { + super.dispose(); + m_manager.remove(queryText); + if(gapAnswerTuples != null) gapAnswerTuples = null; + if(soundAnswerTuples != null) soundAnswerTuples = null; + if(relevantClauses != null) relevantClauses.clear(); + if(relevantOntology != null) + relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology); + answerVariables = null; + } + + public boolean canBeEncodedIntoAtom() { + if(isDisposed()) throw new DisposedException(); + + // FIXME + return true; +// return false; + } + + public boolean isPredicate(AnswerTuple a, int i) { + if(isDisposed()) throw new DisposedException(); + + Atom[] atoms = getClause().getBodyAtoms(); + Variable v = Variable.create(answerVariables[1][i]); + String iri; + for(Atom atom : atoms) { + DLPredicate p = atom.getDLPredicate(); + if(p instanceof AtomicConcept) { + if(((AtomicConcept) p).getIRI().equals(v.toString())) return true; + } + else if(p instanceof AtomicRole) { + iri = ((AtomicRole) p).getIRI(); + if(iri.equals(v.toString())) return true; + if(iri.startsWith("?")) + iri = a.getGroundTerm(i).toString(); + if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true; + } + } + return false; + } + + public Tuple getExtendedQueryText() { + if(isDisposed()) throw new DisposedException(); + +// String[] ret = new String[2];s + int index = queryText.toUpperCase().indexOf(" WHERE"); + String extendedSelect = queryText.substring(0, index); + String extendedWhere = queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1); + + String sub, obj; + Map> links = new HashMap>(); + Set list; + for(Atom atom : getClause().getBodyAtoms()) + if(atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { + sub = atom.getArgumentVariable(0).getName(); + obj = atom.getArgumentVariable(1).getName(); + if((list = links.get(sub)) == null) + links.put(sub, list = new HashSet()); + list.add(obj); + if((list = links.get(obj)) == null) + links.put(obj, list = new HashSet()); + list.add(sub); + } + + StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder(); +// if (answerVariables[0] != answerVariables[1]) { + for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) { +// for (int i = 0; i < answerVariables[1].length; ++i) { + fullyExtra.append(" . ?") + .append(answerVariables[1][i]) + .append(" " + RDF_TYPE + " <") + .append(Namespace.PAGODA_ORIGINAL) + .append(">"); + if((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ; + else { + extra.append(" . ?") + .append(answerVariables[1][i]) + .append(" " + RDF_TYPE + " <") + .append(Namespace.PAGODA_ORIGINAL) + .append(">"); + } + } + + if(extra.length() > 0) { + extra.append(" }"); + extendedWhere = + extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString()); + } + + if(fullyExtra.length() > 0) { + fullyExtra.append(" }"); + fullyExtendedWhere = + fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra + .toString()); + } +// } + + TupleBuilder result = new TupleBuilder<>(); + result.append(extendedSelect + " " + fullyExtendedWhere); + + extra.setLength(0); + if(answerVariables[0] != answerVariables[1]) { + for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) + extra.append(" ?").append(answerVariables[1][i]); + extendedSelect = extendedSelect + extra.toString(); + } + result.append(extendedSelect + " " + extendedWhere); + + return result.build(); + } + + public boolean hasNonAnsDistinguishedVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[1].length > answerVariables[0].length; + } + + /** + * Two QueryRecords are equal iff + * they have the same queryText, + * soundAnswerTuples. + */ + @Override + public boolean equals(Object o) { + if(isDisposed()) throw new DisposedException(); + + if(!o.getClass().equals(getClass())) return false; + QueryRecord that = (QueryRecord) o; + return this.queryText.equals(that.queryText) + && soundAnswerTuples.equals(that.soundAnswerTuples); + } + + @Override + public int hashCode() { + if(isDisposed()) throw new DisposedException(); + + return Objects.hash(queryText, soundAnswerTuples); + } + + public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { + RDFoxAnswerTuples rdfAnswerTuples; + if(answerTuples instanceof RDFoxAnswerTuples) + rdfAnswerTuples = (RDFoxAnswerTuples) answerTuples; + else { + Utility.logError("The upper bound must be computed by RDFox!"); + return false; + } + + if(soundAnswerTuples.size() > 0) { + int number = 0; + for(; answerTuples.isValid(); answerTuples.moveNext()) { + ++number; + } + Utility.logDebug("The number of answers returned by an upper bound: " + number); + if(number <= soundAnswerTuples.size()) { + if(gapAnswerTuples != null) gapAnswerTuples.clear(); + else gapAnswerTuples = new HashSet(); + + Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); + return false; + } + answerTuples.reset(); + } + + boolean justCheck = (answerTuples.getArity() != answerVariables[1].length); + + Set tupleSet = new HashSet(); + AnswerTuple tuple, extendedTuple; + for(; answerTuples.isValid(); answerTuples.moveNext()) { + extendedTuple = rdfAnswerTuples.getTuple(); + if(isBottom() || !extendedTuple.hasAnonymousIndividual()) { + tuple = AnswerTuple.create(extendedTuple, answerVariables[0].length); + if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) { + if(!toCheckAux && justCheck) return false; + tupleSet.add(extendedTuple); + } + } + } + + if(gapAnswerTuples == null) { + gapAnswerTuples = tupleSet; + + Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); + return true; + } + + boolean update = false; + for(Iterator iter = gapAnswerTuples.iterator(); iter.hasNext(); ) { + tuple = iter.next(); + if(!tupleSet.contains(tuple)) { + iter.remove(); + update = true; + } + } + + Utility.logInfo("Upper bound answers updated: " + (soundAnswerTuples.size() + gapAnswerTuples.size())); + + return update; + } + + public enum Step { + LOWER_BOUND, + UPPER_BOUND, + SIMPLE_UPPER_BOUND, + LAZY_UPPER_BOUND, + SKOLEM_UPPER_BOUND, + EL_LOWER_BOUND, + FRAGMENT, +// FRAGMENT_REFINEMENT, + SUMMARISATION, +// DEPENDENCY, + FULL_REASONING; + + @Override + public String toString() { + String s = super.toString(); + if(s == null) return null; + return WordUtils.capitalizeFully(s, new char[]{'_'}).replace("_", ""); + } + } + + /** + * A Json serializer, which considers the main attributes. + */ + public static class QueryRecordSerializer implements JsonSerializer { + public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonObject object = new JsonObject(); + object.addProperty("queryID", src.queryID); + object.addProperty("queryText", src.queryText); +// object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : ""); + + object.add("answerVariables", context.serialize(src.getAnswerVariables())); + object.add("answers", context.serialize(src.soundAnswerTuples)); +// object.add("gapAnswers", context.serialize(src.gapAnswerTuples)); + + return object; + } + } + + /** + * A Json deserializer, compliant to the output of the serializer defined above. + */ + public static class QueryRecordDeserializer implements JsonDeserializer { + public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + + QueryRecord record = new QueryRecord(); + JsonObject object = json.getAsJsonObject(); + record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); + record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); +// record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString()); + + JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); + record.answerVariables = new String[2][]; + record.answerVariables[0] = new String[answerVariablesJson.size()]; + for(int i = 0; i < answerVariablesJson.size(); i++) + record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); + + record.soundAnswerTuples = new HashSet<>(); +// record.gapAnswerTuples = new HashSet<>(); + Type type = new TypeToken() { + }.getType(); + for(JsonElement answer : object.getAsJsonArray("answers")) { + record.soundAnswerTuples.add(context.deserialize(answer, type)); + } +// for (JsonElement answer : object.getAsJsonArray("gapAnswers")) { +// record.soundAnswerTuples.add(context.deserialize(answer, type)); +// } + + return record; + } + } + + /** + * Provides an instance (singleton) of Gson, having a specific configuration. + */ + public static class GsonCreator { + + private static Gson gson; + + private GsonCreator() { + } + + public static Gson getInstance() { + if (gson == null) { + gson = new GsonBuilder() + .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer()) + .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer()) + .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer()) + .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer()) + .disableHtmlEscaping() + .setPrettyPrinting() + .create(); + } + return gson; + } + +// public static void dispose() { +// gson = null; +// } + + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.query.rollup; + +import org.semanticweb.HermiT.model.*; +import org.semanticweb.owlapi.model.*; +import uk.ac.ox.cs.pagoda.util.Namespace; + +import java.util.*; + +public class QueryGraph { + + Set freeVars = new HashSet(); + Set existVars = new HashSet(); + Set constants = new HashSet(); + + MultiMap concepts = new MultiMap(); + MultiMap rollable_edges = new MultiMap(); + MultiMap edges = new MultiMap(); + OWLOntology ontology; + OWLDataFactory factory; + + public QueryGraph(Atom[] bodyAtoms, String[] distinguishedVars, OWLOntology onto) { + for (String vName: distinguishedVars) + freeVars.add(Variable.create(vName)); + + ontology = onto; + factory = onto.getOWLOntologyManager().getOWLDataFactory(); + + for (Atom atom: bodyAtoms) { + if (atom.getArity() == 1) { + updateExistentiallyVariables(atom.getArgumentVariable(0)); + String id = ((AtomicConcept) atom.getDLPredicate()).getIRI(); + if (!id.equals(Namespace.PAGODA_ORIGINAL)) + concepts.add(atom.getArgument(0), factory.getOWLClass(IRI.create(id))); + } + else if (atom.getArity() == 2) { + updateExistentiallyVariables(atom.getArgumentVariable(0)); + updateExistentiallyVariables(atom.getArgumentVariable(1)); + if (atom.getArgument(0).equals(atom.getArgument(1)) && atom.getArgument(0) instanceof Variable) { + concepts.add(atom.getArgument(0), factory.getOWLObjectHasSelf(factory.getOWLObjectProperty(IRI.create(((AtomicRole) atom.getDLPredicate()).getIRI())))); + } + else createEdges(atom.getArgument(0), (AtomicRole) atom.getDLPredicate(), atom.getArgument(1)); + } + } + + rollup(); + } + + public void createEdges(Term u, AtomicRole r, Term v) { + if(ontology.containsDataPropertyInSignature(IRI.create(r.getIRI()))) { +// edges.add(u, new DataEdge(r, v)); + Constant c = (Constant) v; + OWLLiteral l = factory.getOWLLiteral(c.getLexicalForm(), c.getDatatypeURI()); + concepts.add(u, factory.getOWLDataHasValue(factory.getOWLDataProperty(IRI.create(r.getIRI())), l)); + } + else { + boolean rollable = existVars.contains(u) || existVars.contains(v); + + ObjectEdge edge = new ObjectEdge(r, v, false); + if(rollable) { + rollable_edges.add(u, edge); + edge = new ObjectEdge(r, u, true); + rollable_edges.add(v, edge); + } + else edges.add(u, edge); + + } + } + + public Set getPropertyAssertions(Map assignment) { + OWLIndividual sub, obj; + Set axioms = new HashSet(); + for(Map.Entry> entry : edges.map.entrySet()) { + sub = factory.getOWLNamedIndividual(IRI.create(getIndividual(entry.getKey(), assignment).getIRI())); + for(ObjectEdge edge : entry.getValue()) { + Individual individual = getIndividual(edge.v, assignment); + String iri = individual.getIRI(); + obj = factory.getOWLNamedIndividual(IRI.create(iri)); + axioms.add(factory.getOWLObjectPropertyAssertionAxiom(edge.p, sub, obj)); + } + } + return axioms; + } + +// public Set getExistentialConditions(Map assignment) { +// if(!rollable_edges.isEmpty()) return null; +// +// OWLIndividual sub; +// Visitor visitor = new Visitor(factory, assignment); +// Set axioms = new HashSet<>(); +// for(Map.Entry> entry : concepts.map.entrySet()) { +// // TODO check correctness!!! +// if(existVars.contains(entry.getKey())) { +// OWLClassExpression conjunction = +// factory.getOWLObjectIntersectionOf(factory.getOWLThing()); +// for(OWLClassExpression owlClassExpression : entry.getValue()) { +// conjunction = factory.getOWLObjectIntersectionOf(conjunction, owlClassExpression.accept(visitor)); +// } +// axioms.add(conjunction); +//// continue; // previously the "then" contained only this +// } +// } +// return axioms; +// } + + public Set getExistentialAxioms(Map assignment) { + if(!rollable_edges.isEmpty()) return null; + + Visitor visitor = new Visitor(factory, assignment); + Set axioms = new HashSet<>(); + for(Map.Entry> entry : concepts.map.entrySet()) { + if(existVars.contains(entry.getKey())) { + OWLClassExpression conjunction = factory.getOWLThing(); + for(OWLClassExpression owlClassExpression : entry.getValue()) { + conjunction = factory.getOWLObjectIntersectionOf(conjunction, owlClassExpression.accept(visitor)); + } + axioms.add(factory.getOWLSubClassOfAxiom(conjunction, factory.getOWLNothing())); + } + } + return axioms; + } + + public Set getAssertions(Map assignment) { + if(!rollable_edges.isEmpty()) return null; + + OWLIndividual sub; + Visitor visitor = new Visitor(factory, assignment); + Set axioms = getPropertyAssertions(assignment); + for(Map.Entry> entry : concepts.map.entrySet()) { + // TODO check correctness!!! + if(existVars.contains(entry.getKey())) { +// OWLClassExpression conjunction = +// factory.getOWLObjectIntersectionOf(factory.getOWLThing()); +// for(OWLClassExpression owlClassExpression : entry.getValue()) { +// conjunction = factory.getOWLObjectIntersectionOf(conjunction, owlClassExpression.accept(visitor)); +// } +// axioms.add(factory.getOWLSubClassOfAxiom(conjunction, factory.getOWLNothing())); + continue; // previously the "then" contained only this + } + else { + sub = factory.getOWLNamedIndividual(IRI.create(getIndividual(entry.getKey(), assignment).getIRI())); + for(OWLClassExpression clsExp : entry.getValue()) { + axioms.add(factory.getOWLClassAssertionAxiom(clsExp.accept(visitor), sub)); + } + } + } + return axioms; + } + + private void updateExistentiallyVariables(Variable argumentVariable) { + if(freeVars.contains(argumentVariable)) return; + existVars.add(argumentVariable); + } + + private void rollup() { + for (boolean updated = true; updated; ) { + updated = false; + + Set set; + for (Variable var: existVars) { + if ((set = rollable_edges.map.get(var)) != null && set.size() == 1) { + updated = true; + ObjectEdge edge = set.iterator().next(); + rollupEdge(edge.v, edge.p.getInverseProperty().getSimplified(), var, true); + set.clear(); + } + } + if(updated) continue; + + for (Variable var: existVars) { + set = rollable_edges.map.get(var); + if(set == null) continue; + for (Iterator iter = set.iterator(); iter.hasNext(); ) { + ObjectEdge edge = iter.next(); + if (constants.contains(edge.v) || freeVars.contains(edge.v)) { + updated = true; + rollupEdge(var, edge.p, edge.v, false); + iter.remove(); + } + } + } + } + + } + + private void rollupEdge(Term u, OWLObjectPropertyExpression op, Term v, boolean inverse) { + if (existVars.contains(v)) { + Set exps = concepts.get(v); + if (exps == null) exps = new HashSet(); + concepts.add(u, factory.getOWLObjectSomeValuesFrom(op, factory.getOWLObjectIntersectionOf(exps))); + } + else { + OWLIndividual obj = getOWLIndividual(v); + concepts.add(u, factory.getOWLObjectHasValue(op, obj)); + } + + if(inverse) + removeRollableEdge(u, op, v); + else + removeRollableEdge(v, op.getInverseProperty().getSimplified(), u); + } + + private void removeRollableEdge(Term u, OWLObjectPropertyExpression op, Term v) { + Set set = rollable_edges.get(u); + ObjectEdge edge; + if (set != null) + for (Iterator iter = set.iterator(); iter.hasNext(); ) { + edge = iter.next(); + if(edge.p.equals(op) && edge.v.equals(v)) iter.remove(); + } + } + + OWLNamedIndividual getOWLIndividual(Term t) { + if (freeVars.contains(t)) + return new VariableIndividual((Variable) t); + else if (t instanceof Variable) + return null; + else + return factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI())); + } + + private Individual getIndividual(Term key, Map assignment) { + if(key instanceof Individual) + return (Individual) key; + else + return (Individual) assignment.get(key); + } + + class ObjectEdge { + OWLObjectPropertyExpression p; + Term v; + + public ObjectEdge(AtomicRole r, Term t, boolean inverse) { + p = factory.getOWLObjectProperty(IRI.create(r.getIRI())); + if(inverse) p = p.getInverseProperty(); + v = t; + + } + } + + class MultiMap { + + HashMap> map = new HashMap>(); + + public Set get(K v) { + return map.get(v); + } + + public boolean isEmpty() { + for(Map.Entry> entry : map.entrySet()) + if(!entry.getValue().isEmpty()) + return false; + return true; + } + + void add(K key, V value) { + Set list = map.get(key); + if(list == null) + map.put(key, list = new HashSet()); + list.add(value); + } + + } +} + +class Visitor implements OWLClassExpressionVisitorEx { + + OWLDataFactory factory; + Map assignment; + + public Visitor(OWLDataFactory factory, Map assignment) { + this.factory = factory; + this.assignment = assignment; + } + + @Override + public OWLClassExpression visit(OWLClass ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectIntersectionOf ce) { + Set clsExps = new HashSet(); + OWLClassExpression newExp; + boolean updated = false; + for (OWLClassExpression clsExp: ce.asConjunctSet()) { + clsExps.add(newExp = clsExp.accept(this)); + if (newExp != clsExp) updated = true; + } + + if (updated) return factory.getOWLObjectIntersectionOf(clsExps); + else return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectUnionOf ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectComplementOf ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectSomeValuesFrom ce) { + OWLClassExpression newFiller = ce.getFiller().accept(this); + if (newFiller == ce.getFiller()) return ce; + return factory.getOWLObjectSomeValuesFrom(ce.getProperty(), newFiller); + } + + @Override + public OWLClassExpression visit(OWLObjectAllValuesFrom ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectHasValue ce) { + if (ce.getValue() instanceof VariableIndividual) { + Individual c = (Individual) assignment.get(((VariableIndividual) ce.getValue()).var); + OWLIndividual l = factory.getOWLNamedIndividual(IRI.create(c.getIRI())); + return factory.getOWLObjectHasValue(ce.getProperty(), l); + } + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectMinCardinality ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectExactCardinality ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectMaxCardinality ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectHasSelf ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLObjectOneOf ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLDataSomeValuesFrom ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLDataAllValuesFrom ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLDataHasValue ce) { + if (ce.getValue() instanceof VariableConstant) { + Constant c = (Constant) assignment.get(((VariableConstant) ce.getValue()).var); + OWLLiteral l = factory.getOWLLiteral(c.getLexicalForm(), c.getDatatypeURI()); + return factory.getOWLDataHasValue(ce.getProperty(), l); + } + return ce; + } + + @Override + public OWLClassExpression visit(OWLDataMinCardinality ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLDataExactCardinality ce) { + // TODO Auto-generated method stub + return ce; + } + + @Override + public OWLClassExpression visit(OWLDataMaxCardinality ce) { + // TODO Auto-generated method stub + return ce; + } + +} \ 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 @@ +package uk.ac.ox.cs.pagoda.query.rollup; + +import java.util.Set; + +import org.semanticweb.HermiT.model.Variable; +import org.semanticweb.owlapi.model.OWLAnnotationValueVisitor; +import org.semanticweb.owlapi.model.OWLAnnotationValueVisitorEx; +import org.semanticweb.owlapi.model.OWLAnonymousIndividual; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLDataVisitor; +import org.semanticweb.owlapi.model.OWLDataVisitorEx; +import org.semanticweb.owlapi.model.OWLDatatype; +import org.semanticweb.owlapi.model.OWLEntity; +import org.semanticweb.owlapi.model.OWLLiteral; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLObject; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectVisitor; +import org.semanticweb.owlapi.model.OWLObjectVisitorEx; + +class VariableConstant implements OWLLiteral { + + /** + * + */ + private static final long serialVersionUID = 5089014375729171030L; + Variable var; + + public VariableConstant(Variable v) { + var = v; + } + + @Override + public Set getSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getAnonymousIndividuals() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getClassesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getDataPropertiesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getObjectPropertiesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getIndividualsInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getDatatypesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getNestedClassExpressions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void accept(OWLObjectVisitor visitor) { + // TODO Auto-generated method stub + + } + + @Override + public O accept(OWLObjectVisitorEx visitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isTopEntity() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isBottomEntity() { + // TODO Auto-generated method stub + return false; + } + + @Override + public int compareTo(OWLObject arg0) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void accept(OWLAnnotationValueVisitor visitor) { + // TODO Auto-generated method stub + + } + + @Override + public O accept(OWLAnnotationValueVisitorEx visitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isRDFPlainLiteral() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String getLiteral() { + // TODO Auto-generated method stub + return null; + } + + @Override + public OWLDatatype getDatatype() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasLang() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String getLang() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasLang(String lang) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isInteger() { + // TODO Auto-generated method stub + return false; + } + + @Override + public int parseInteger() throws NumberFormatException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public boolean isBoolean() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean parseBoolean() throws NumberFormatException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isDouble() { + // TODO Auto-generated method stub + return false; + } + + @Override + public double parseDouble() throws NumberFormatException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public boolean isFloat() { + // TODO Auto-generated method stub + return false; + } + + @Override + public float parseFloat() throws NumberFormatException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void accept(OWLDataVisitor visitor) { + // TODO Auto-generated method stub + + } + + @Override + public O accept(OWLDataVisitorEx visitor) { + // TODO Auto-generated method stub + return null; + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.query.rollup; + +import java.util.Map; +import java.util.Set; + +import org.semanticweb.HermiT.model.Variable; +import org.semanticweb.owlapi.model.EntityType; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAnnotation; +import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; +import org.semanticweb.owlapi.model.OWLAnnotationProperty; +import org.semanticweb.owlapi.model.OWLAnonymousIndividual; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLDataPropertyExpression; +import org.semanticweb.owlapi.model.OWLDatatype; +import org.semanticweb.owlapi.model.OWLEntity; +import org.semanticweb.owlapi.model.OWLEntityVisitor; +import org.semanticweb.owlapi.model.OWLEntityVisitorEx; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLIndividualVisitor; +import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; +import org.semanticweb.owlapi.model.OWLLiteral; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLNamedObjectVisitor; +import org.semanticweb.owlapi.model.OWLObject; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; +import org.semanticweb.owlapi.model.OWLObjectVisitor; +import org.semanticweb.owlapi.model.OWLObjectVisitorEx; +import org.semanticweb.owlapi.model.OWLOntology; + +class VariableIndividual implements OWLNamedIndividual { + + /** + * + */ + private static final long serialVersionUID = 3002966246639516395L; + Variable var; + + public VariableIndividual(Variable v) { + var = v; + } + + @Override + public boolean isNamed() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isAnonymous() { + // TODO Auto-generated method stub + return false; + } + + @Override + public OWLNamedIndividual asOWLNamedIndividual() { + // TODO Auto-generated method stub + return null; + } + + @Override + public OWLAnonymousIndividual asOWLAnonymousIndividual() { + // TODO Auto-generated method stub + return null; + } + + // @Override + // public Set getTypes(OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getTypes(Set ontologies) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Map> getObjectPropertyValues( + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getObjectPropertyValues( + // OWLObjectPropertyExpression property, OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public boolean hasObjectPropertyValue(OWLObjectPropertyExpression property, + // OWLIndividual individual, OWLOntology ontology) { + // // TODO Auto-generated method stub + // return false; + // } + + // @Override + // public boolean hasDataPropertyValue(OWLDataPropertyExpression property, + // OWLLiteral value, OWLOntology ontology) { + // // TODO Auto-generated method stub + // return false; + // } + + // @Override + // public boolean hasNegativeObjectPropertyValue( + // OWLObjectPropertyExpression property, OWLIndividual individual, + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return false; + // } + + // @Override + // public Map> getNegativeObjectPropertyValues( + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Map> getDataPropertyValues( + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getDataPropertyValues( + // OWLDataPropertyExpression property, OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Map> getNegativeDataPropertyValues( + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public boolean hasNegativeDataPropertyValue( + // OWLDataPropertyExpression property, OWLLiteral literal, + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return false; + // } + + // @Override + // public Set getSameIndividuals(OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getDifferentIndividuals(OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public String toStringID() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void accept(OWLIndividualVisitor visitor) { + // TODO Auto-generated method stub + + } + + @Override + public O accept(OWLIndividualVisitorEx visitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getAnonymousIndividuals() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getClassesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getDataPropertiesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getObjectPropertiesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getIndividualsInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getDatatypesInSignature() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getNestedClassExpressions() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void accept(OWLObjectVisitor visitor) { + // TODO Auto-generated method stub + + } + + @Override + public O accept(OWLObjectVisitorEx visitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isTopEntity() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isBottomEntity() { + // TODO Auto-generated method stub + return false; + } + + @Override + public int compareTo(OWLObject arg0) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public EntityType getEntityType() { + // TODO Auto-generated method stub + return null; + } + + // @Override + // public E getOWLEntity(EntityType entityType) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public boolean isType(EntityType entityType) { + // TODO Auto-generated method stub + return false; + } + + // @Override + // public Set getAnnotations(OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getAnnotations(OWLOntology ontology, + // OWLAnnotationProperty annotationProperty) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getAnnotationAssertionAxioms( + // OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public boolean isBuiltIn() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isOWLClass() { + // TODO Auto-generated method stub + return false; + } + + @Override + public OWLClass asOWLClass() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isOWLObjectProperty() { + // TODO Auto-generated method stub + return false; + } + + @Override + public OWLObjectProperty asOWLObjectProperty() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isOWLDataProperty() { + // TODO Auto-generated method stub + return false; + } + + @Override + public OWLDataProperty asOWLDataProperty() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isOWLNamedIndividual() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isOWLDatatype() { + // TODO Auto-generated method stub + return false; + } + + @Override + public OWLDatatype asOWLDatatype() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isOWLAnnotationProperty() { + // TODO Auto-generated method stub + return false; + } + + @Override + public OWLAnnotationProperty asOWLAnnotationProperty() { + // TODO Auto-generated method stub + return null; + } + + // @Override + // public Set getReferencingAxioms(OWLOntology ontology) { + // // TODO Auto-generated method stub + // return null; + // } + + // @Override + // public Set getReferencingAxioms(OWLOntology ontology, + // boolean includeImports) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public void accept(OWLEntityVisitor visitor) { + // TODO Auto-generated method stub + + } + + @Override + public O accept(OWLEntityVisitorEx visitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public IRI getIRI() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void accept(OWLNamedObjectVisitor visitor) { + // TODO Auto-generated method stub + + } + +} -- cgit v1.2.3