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. --- .../ox/cs/pagoda/tracking/AnswerTuplesWriter.java | 59 +++ .../cs/pagoda/tracking/BottomFragmentManager.java | 101 +++++ .../uk/ac/ox/cs/pagoda/tracking/QueryTracker.java | 440 +++++++++++++++++++++ .../ox/cs/pagoda/tracking/TrackingRuleEncoder.java | 387 ++++++++++++++++++ .../pagoda/tracking/TrackingRuleEncoderDisj.java | 163 ++++++++ .../pagoda/tracking/TrackingRuleEncoderDisj1.java | 175 ++++++++ .../pagoda/tracking/TrackingRuleEncoderDisj2.java | 112 ++++++ .../tracking/TrackingRuleEncoderDisjVar1.java | 425 ++++++++++++++++++++ .../tracking/TrackingRuleEncoderDisjVar2.java | 230 +++++++++++ .../tracking/TrackingRuleEncoderWithGap.java | 116 ++++++ .../tracking/TrackingRuleEncoderWithoutGap.java | 103 +++++ 11 files changed, 2311 insertions(+) create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/AnswerTuplesWriter.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/BottomFragmentManager.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/QueryTracker.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj1.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj2.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar1.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar2.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java (limited to 'src/main/java/uk/ac/ox/cs/pagoda/tracking') diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/AnswerTuplesWriter.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/AnswerTuplesWriter.java new file mode 100644 index 0000000..a83a4e9 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/AnswerTuplesWriter.java @@ -0,0 +1,59 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Collection; + +import uk.ac.ox.cs.pagoda.query.AnswerTuples; + +public class AnswerTuplesWriter { + + private static final String QUERY_SEPARATOR = "---------------------------------------------"; + + BufferedWriter writer = null; + + public AnswerTuplesWriter(String fileName) { + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + public void write(String[] answerVariables, Collection answerTuples)throws IOException { + for (int i = 0; i < answerVariables.length; ++i) + writer.write(answerVariables[i] + "\t"); + writer.newLine(); + writer.write(QUERY_SEPARATOR); + writer.newLine(); + + if (answerTuples == null) { + writer.newLine(); + return ; + } + + for (String answerTuple: answerTuples) { + writer.write(answerTuple); + writer.newLine(); + } + writer.newLine(); + } + + public void close() { + if (writer != null) + try { + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void write(String[] answerVariables, AnswerTuples answerTuples) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/BottomFragmentManager.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/BottomFragmentManager.java new file mode 100644 index 0000000..6521e72 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/BottomFragmentManager.java @@ -0,0 +1,101 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import java.util.HashSet; +import java.util.Set; + +import org.semanticweb.HermiT.model.AtomicConcept; +import org.semanticweb.HermiT.model.AtomicRole; +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.HermiT.model.DLPredicate; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.parameters.Imports; + +import uk.ac.ox.cs.pagoda.constraints.PredicateDependency; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +import uk.ac.ox.cs.pagoda.rules.ApproxProgram; +import uk.ac.ox.cs.pagoda.rules.GeneralProgram; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class BottomFragmentManager { + + QueryRecord m_record; + GeneralProgram m_program; + PredicateDependency m_graph; + + public BottomFragmentManager(QueryRecord record) { + m_record = record; + m_program = new GeneralProgram(record.getRelevantClauses(), record.getRelevantOntology()); + m_graph = m_program.buildDependencyGraph(); + } + + public Set relevantClauses(Set disjuntiveRules) { + Set relevant = new HashSet(); + Set now = new HashSet(); + Set last = new HashSet(); + + for (DLClause rule: disjuntiveRules) + for (DLPredicate p: m_graph.collectPredicate(rule.getHeadAtoms())) + now.addAll(m_graph.pathToBottom(p)); + + while (!relevant.containsAll(now)) { + relevant.addAll(now); + last.clear(); + last = now; + now = new HashSet(); + + for (DLClause rule: last) { + for (DLPredicate p: m_graph.collectPredicate(rule.getHeadAtoms())) + now.addAll(m_graph.pathToBottom(p)); + for (DLPredicate p: m_graph.collectPredicate(rule.getBodyAtoms())) + now.addAll(m_graph.pathTo(p)); + } + } + + Utility.logDebug("There are " + relevant.size() + " clauses in the bottom fragment related to this query."); + return relevant; + } + + public Set relevantOntology(Set clauses, ApproxProgram upperProgram) { + Set axioms = new HashSet(); + Set predicates = new HashSet(); + for (DLClause clause: clauses) { + OWLAxiom axiom = upperProgram.getEquivalentAxiom(clause); + axioms.add(axiom); + predicates.addAll(m_graph.collectPredicate(clause.getHeadAtoms())); + predicates.addAll(m_graph.collectPredicate(clause.getBodyAtoms())); + } + + int tboxCounter = axioms.size(); + Utility.logDebug("There are " + tboxCounter + " TBox axioms in the bottom fragment related to this query."); + String name; + for (OWLAxiom axiom: m_record.getRelevantOntology().getABoxAxioms(Imports.INCLUDED)) { + if (axiom instanceof OWLClassAssertionAxiom) { + OWLClass cls = (OWLClass) ((OWLClassAssertionAxiom) axiom).getClassExpression(); + name = cls.getIRI().toString(); + if (predicates.contains(AtomicConcept.create(name))) + axioms.add(axiom); + } + else if (axiom instanceof OWLObjectPropertyAssertionAxiom) { + OWLObjectProperty prop = (OWLObjectProperty) ((OWLObjectPropertyAssertionAxiom) axiom).getProperty(); + name = prop.getIRI().toString(); + if (predicates.contains(AtomicRole.create(name))) + axioms.add(axiom); + } + else if (axiom instanceof OWLDataPropertyAssertionAxiom) { + OWLDataProperty prop = (OWLDataProperty) ((OWLDataPropertyAssertionAxiom) axiom).getProperty(); + name = prop.getIRI().toString(); + if (predicates.contains(AtomicRole.create(name))) + axioms.add(axiom); + } + } + + Utility.logDebug("There are " + (axioms.size() - tboxCounter) + " ABox axioms in the bottom fragment related to this query."); + return axioms; + } +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/QueryTracker.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/QueryTracker.java new file mode 100644 index 0000000..27d3a53 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/QueryTracker.java @@ -0,0 +1,440 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.owlapi.model.*; +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.model.Datatype; +import uk.ac.ox.cs.JRDFox.store.DataStore; +import uk.ac.ox.cs.JRDFox.store.DataStore.UpdateType; +import uk.ac.ox.cs.JRDFox.store.Resource; +import uk.ac.ox.cs.JRDFox.store.TupleIterator; +import uk.ac.ox.cs.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.owl.OWLHelper; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +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.UFS; +import uk.ac.ox.cs.pagoda.util.Utility; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Set; + +public class QueryTracker { + + QueryRecord m_record; + BasicQueryEngine m_dataStore; + TrackingRuleEncoder m_encoder; + + OWLOntologyManager m_manager; + Set m_tBoxAxioms; + + UFS equalityGroups; + + public QueryTracker(TrackingRuleEncoder encoder, BasicQueryEngine lowerStore, QueryRecord queryRecord) { + m_encoder = encoder; + m_dataStore = lowerStore; + m_record = queryRecord; + + m_manager = m_encoder.getOntology().getOWLOntologyManager(); + equalityGroups = m_dataStore.getEqualityGroups(true); + + } + + public OWLOntology extract(BasicQueryEngine trackingStore, QueryRecord[] botQuerRecords, boolean incrementally) { + try { + if (m_record.getRelevantOntology() != null) { + m_manager.removeOntology(m_record.getRelevantOntology()); + m_record.setRelevantOntology(null); + m_record.clearClauses(); + } + m_record.setRelevantOntology(m_manager.createOntology()); + } catch (OWLOntologyCreationException e) { + e.printStackTrace(); + } + + m_encoder.setCurrentQuery(m_record); + +// m_encoder.encodingQuery(botQuerRecords); +// m_encoder.saveTrackingRules("tracking_query" + m_record.getQueryID() + ".dlog"); + + DataStore store = trackingStore.getDataStore(); + long oldTripleCount, tripleCount; + try { + Timer t1 = new Timer(); + oldTripleCount = store.getTriplesCount(); + // store.addRules(new String[] {m_encoder.getTrackingProgram()}); + store.importRules(m_encoder.getTrackingProgram(), UpdateType.ScheduleForAddition); + store.applyReasoning(incrementally); + tripleCount = store.getTriplesCount(); + + Utility.logDebug("tracking store after materialising tracking program: " + + tripleCount + + " (" + + (tripleCount - oldTripleCount) + + " new)"); + Utility.logDebug("tracking store finished the materialisation of tracking program in " + + t1.duration() + " seconds."); + } catch (JRDFStoreException e) { + e.printStackTrace(); + } + extractAxioms(trackingStore); + + trackingStore.clearRulesAndIDBFacts(m_encoder.getAddedData()); + + if (!m_record.isBottom() + && !(m_encoder instanceof TrackingRuleEncoderDisj2)) + addRelatedAxiomsAndClauses(botQuerRecords); + + return m_record.getRelevantOntology(); + } + + public void extractAxioms(BasicQueryEngine trackingStore) { + Set unaryPredicates = new HashSet(); + Set binaryPredicates = new HashSet(); + + getDerivedPredicates(trackingStore, unaryPredicates, binaryPredicates); + + /** + * To add all the relavant ABox assertions to the fragment + */ + + int aboxAxiomCounter = extractUnaryTuples(trackingStore, + m_manager.getOWLDataFactory(), unaryPredicates) + + extractBinaryTuples(trackingStore, + m_manager.getOWLDataFactory(), binaryPredicates); + + /** + * To all all the relavant TBox rules to the fragment + */ + String queryText = m_encoder.getSelectedSPARQLQuery(); + + DLClause clause; + m_tBoxAxioms = new HashSet(); + OWLAxiom tBoxAxiom; + TupleIterator answers = null; + String answer; + try { + answers = trackingStore.internal_evaluate(queryText); + for (long multi = answers.open(); multi != 0; multi = answers.getNext()) { + answer = answers.getResource(0).m_lexicalForm; + clause = m_encoder.getSelectedClause(MyPrefixes.PAGOdAPrefixes.expandIRI(answer)); + if (DLClauseHelper.isTautologyAboutDifferentFrom(clause)) + continue; + tBoxAxiom = m_encoder.getProgram().getEquivalentAxiom(clause); + m_record.addRelevantClauses(clause); + m_tBoxAxioms.add(tBoxAxiom); + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + } finally { + if (answers != null) answers.dispose(); + } + + Utility.logTrace("Extracted TBox axioms: "); + for (OWLAxiom axiom : m_tBoxAxioms) { + Utility.logTrace(axiom); + m_manager.addAxiom(m_record.getRelevantOntology(), axiom); + } + Utility.logDebug("TBox extraction Done"); + + Utility.logDebug("Before adding bottom fragment:\nABoxAxiomsCount = " + + aboxAxiomCounter + ", TBoxAxiomsCount = " + + m_tBoxAxioms.size()); + + } + + public void addRelatedAxiomsAndClauses(QueryRecord[] botQueryRecords) { + LinkedList toAddedRecords = new LinkedList(); + + for(QueryRecord botQueryRecord : botQueryRecords) + if(overlappingDisjunctiveClauses(botQueryRecord) != null) + toAddedRecords.add(botQueryRecord); + + for(QueryRecord botQueryRecord : toAddedRecords) { + m_manager.addAxioms(m_record.getRelevantOntology(), botQueryRecord.getRelevantOntology().getAxioms()); + for(DLClause clause : botQueryRecord.getRelevantClauses()) + m_record.addRelevantClauses(clause); + } + + if(!toAddedRecords.isEmpty()) + Utility.logDebug("Part of bottom fragments is added for this query."); + else + Utility.logDebug("None of bottom fragments is added for this query."); + } + + private int extractBinaryTuples(BasicQueryEngine trackingStore, OWLDataFactory factory, Set binaryPredicates) { + OWLOntology fragment = m_record.getRelevantOntology(); + int count; + int aboxAxiomCounter = 0; + Resource sub, obj; + OWLAxiom aboxAxiom; + String trackingIRI; + Set trackedIDEqualities = new HashSet(); + Set trackedEntityEqualities = new HashSet(); + TupleIterator trackingAnswers, lowerAnswers; + + for (Iterator iter = binaryPredicates.iterator(); iter.hasNext(); ) { + trackingIRI = iter.next(); + String propIRI = m_encoder.getOriginalPredicate(trackingIRI); + if(propIRI == null) continue; + if (!propIRI.equals(Namespace.EQUALITY_QUOTED)) continue; + trackingAnswers = null; + try { + trackingAnswers = trackingStore.internal_evaluateAgainstIDBs(getSPARQLQuery4Binary(trackingIRI)); + for (long multi = trackingAnswers.open(); multi != 0; multi = trackingAnswers.getNext()) { + if (trackingAnswers.getResourceID(0) != trackingAnswers.getResourceID(1)) { + for(int i = 0; i < 2; ++i) + if (trackedIDEqualities.add(trackingAnswers.getResourceID(i))) { + trackedEntityEqualities.add(trackingAnswers.getResource(i).m_lexicalForm); + } + } + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(trackingAnswers != null) trackingAnswers.dispose(); + } + iter.remove(); + break; + } + + String sub_rep, obj_rep; + + for (Iterator iter = binaryPredicates.iterator(); iter.hasNext(); ) { + trackingIRI = iter.next(); + count = 0; + String propIRI = m_encoder.getOriginalPredicate(trackingIRI); + if(propIRI == null) continue; + iter.remove(); + lowerAnswers = null; + trackingAnswers = null; + Set lower = new HashSet(); + OWLObject prop = null; + try { + trackingAnswers = trackingStore.internal_evaluateAgainstIDBs(getSPARQLQuery4Binary(trackingIRI)); + trackingAnswers.open(); + if(trackingAnswers.getMultiplicity() == 0) continue; + + lowerAnswers = m_dataStore.internal_evaluateNotExpanded(getSPARQLQuery4Binary(propIRI)); + lowerAnswers.open(); + if(lowerAnswers.getMultiplicity() == 0) continue; + + StringBuilder builder = new StringBuilder(); + for (long multi = lowerAnswers.getMultiplicity(); multi != 0; multi = lowerAnswers.getNext()) { + sub = lowerAnswers.getResource(0); + obj = lowerAnswers.getResource(1); + builder.setLength(0); + builder.append(equalityGroups.find(sub.m_lexicalForm)) + .append(AnswerTuple.SEPARATOR) + .append(equalityGroups.find(obj.m_lexicalForm)); + lower.add(builder.toString()); + } + + for (long multi = trackingAnswers.getMultiplicity(); multi != 0; multi = trackingAnswers.getNext()) { + sub = trackingAnswers.getResource(0); + obj = trackingAnswers.getResource(1); + builder.setLength(0); + sub_rep = equalityGroups.find(sub.m_lexicalForm); + obj_rep = equalityGroups.find(obj.m_lexicalForm); + if (!sub_rep.equals(sub.m_lexicalForm) || !obj_rep.equals(obj.m_lexicalForm)) continue; + + builder.append(sub_rep).append(AnswerTuple.SEPARATOR).append(obj_rep); + if (lower.contains(builder.toString())) { + OWLObject owlObj = getOWLObject(obj, factory); + if (owlObj instanceof OWLIndividual) { + if (prop == null) + prop = factory.getOWLObjectProperty(IRI.create(propIRI.startsWith("<") ? OWLHelper.removeAngles(propIRI) : propIRI)); + aboxAxiom = factory.getOWLObjectPropertyAssertionAxiom( + (OWLObjectProperty) prop, + factory.getOWLNamedIndividual(IRI.create(sub_rep)), + factory.getOWLNamedIndividual(IRI.create(obj_rep))); + } + else if (owlObj instanceof OWLLiteral) { + if (prop == null) + prop = factory.getOWLDataProperty(IRI.create(propIRI.startsWith("<") ? OWLHelper.removeAngles(propIRI) : propIRI)); + aboxAxiom = factory.getOWLDataPropertyAssertionAxiom( + (OWLDataProperty) prop, + factory.getOWLNamedIndividual(IRI.create(sub_rep)), + (OWLLiteral) owlObj); + } + else { + Utility.logError("There might be an error here ... "); + continue; + } + if (!fragment.containsAxiom(aboxAxiom)) { + m_manager.addAxiom(fragment, aboxAxiom); + ++aboxAxiomCounter; + ++count; + } + } + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + } finally { + if (trackingAnswers != null) trackingAnswers.dispose(); + if (lowerAnswers != null) lowerAnswers.dispose(); + lower.clear(); + } + Utility.logDebug("property: " + propIRI + " " + count); + } + + count = 0; + String value; + OWLObjectProperty sameAs = factory.getOWLObjectProperty(IRI.create(Namespace.EQUALITY)); + for (String key: equalityGroups.keySet()) { + if(!trackedEntityEqualities.contains(key)) continue; + value = equalityGroups.find(key); + m_manager.addAxiom(fragment, factory.getOWLObjectPropertyAssertionAxiom( + sameAs, + factory.getOWLNamedIndividual(IRI.create(key)), + factory.getOWLNamedIndividual(IRI.create(value)))); + ++aboxAxiomCounter; + ++count; + } + Utility.logDebug("property: " + Namespace.EQUALITY_QUOTED + " " + count); + + trackedEntityEqualities.clear(); + trackedIDEqualities.clear(); + Utility.logTrace(Namespace.EQUALITY_QUOTED + " " + count); + + Utility.logDebug("ABox extraction Done"); + return aboxAxiomCounter; + } + + private OWLObject getOWLObject(Resource rdfoxTerm, OWLDataFactory factory) { + if (rdfoxTerm.m_datatype.equals(Datatype.IRI_REFERENCE)) + return factory.getOWLNamedIndividual(IRI.create(rdfoxTerm.m_lexicalForm)); +// if (rdfoxTerm.m_datatype.equals(Datatype.OWL_REAL) || rdfoxTerm.m_datatype.equals(Datatype.OWL_RATIONAL) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_DECIMAL) || rdfoxTerm.m_datatype.equals(Datatype.XSD_INTEGER) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_NON_NEGATIVE_INTEGER) || rdfoxTerm.m_datatype.equals(Datatype.XSD_POSITIVE_INTEGER) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_NEGATIVE_INTEGER) || rdfoxTerm.m_datatype.equals(Datatype.XSD_LONG) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_INT) || rdfoxTerm.m_datatype.equals(Datatype.XSD_SHORT) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_BYTE) || rdfoxTerm.m_datatype.equals(Datatype.XSD_UNSIGNED_LONG) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_UNSIGNED_INT) || rdfoxTerm.m_datatype.equals(Datatype.XSD_UNSIGNED_SHORT) || +// rdfoxTerm.m_datatype.equals(Datatype.XSD_UNSIGNED_BYTE)) + if (rdfoxTerm.m_datatype.equals(Datatype.XSD_DATE)) + return factory.getOWLLiteral(rdfoxTerm.m_lexicalForm, factory.getOWLDatatype(IRI.create(Namespace.XSD_STRING))); + + else + return factory.getOWLLiteral(rdfoxTerm.m_lexicalForm, factory.getOWLDatatype(IRI.create(rdfoxTerm.m_datatype + .getIRI()))); + } + + private int extractUnaryTuples(BasicQueryEngine trackingStore, OWLDataFactory factory, Set unaryPredicates) { + OWLOntology fragment = m_record.getRelevantOntology(); + int count; + int aboxAxiomCounter = 0; + String answer; + OWLAxiom aboxAxiom; + for (String trackingIRI : unaryPredicates) { + count = 0; + String clsIRI = m_encoder.getOriginalPredicate(trackingIRI); + if (clsIRI == null) + continue; + TupleIterator answers = null, lowerAnswers = null; + Set lower = new HashSet(); + OWLClass cls = factory.getOWLClass(IRI.create(clsIRI.startsWith("<") ? OWLHelper.removeAngles(clsIRI) : clsIRI)); + try { + answers = trackingStore.internal_evaluateAgainstIDBs(getSPARQLQuery4Unary(trackingIRI)); + answers.open(); + if(answers.getMultiplicity() == 0) continue; + + lowerAnswers = m_dataStore.internal_evaluateNotExpanded(getSPARQLQuery4Unary(clsIRI)); + lowerAnswers.open(); + if (lowerAnswers.getMultiplicity() == 0) continue; + + for (long multi = lowerAnswers.getMultiplicity(); multi != 0; multi = lowerAnswers.getNext()) + lower.add(equalityGroups.find(lowerAnswers.getResource(0).m_lexicalForm)); + + for (long multi = answers.getMultiplicity(); multi != 0; multi = answers.getNext()) { + answer = equalityGroups.find(answers.getResource(0).m_lexicalForm); + if (lower.contains(answer)) { + OWLIndividual instance = factory.getOWLNamedIndividual(IRI.create(answer)); + aboxAxiom = factory.getOWLClassAssertionAxiom(cls,instance); + if (!fragment.containsAxiom(aboxAxiom)) { + m_manager.addAxiom(fragment, aboxAxiom); + ++aboxAxiomCounter; + ++count; + } + } + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + } finally { + if (answers != null) answers.dispose(); + if (lowerAnswers != null) lowerAnswers.dispose(); + lower.clear(); + } + Utility.logDebug("class: " + clsIRI + " " + count); + } + return aboxAxiomCounter; + } + + private void getDerivedPredicates(BasicQueryEngine trackingStore, Set unaryPredicates, Set binaryPredicates) { + TupleIterator derivedTuples = null; + String selectedPredicate = OWLHelper.addAngles(m_encoder.getSelectedPredicate()); + try { + derivedTuples = trackingStore.internal_evaluateAgainstIDBs("select distinct ?z where { ?x <" + Namespace.RDF_TYPE + "> ?z . }"); + for (long multi = derivedTuples.open(); multi != 0; multi = derivedTuples.getNext()) { + String p = RDFoxTripleManager.getQuotedTerm(derivedTuples.getResource(0)); + if (p.equals(selectedPredicate)) ; + else if (m_encoder.isAuxPredicate(p)) ; + else unaryPredicates.add(p); + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + } finally { + if (derivedTuples != null) derivedTuples.dispose(); + } + + derivedTuples = null; + try { + derivedTuples = trackingStore.internal_evaluateAgainstIDBs("select distinct ?y where { ?x ?y ?z . }"); + for (long multi = derivedTuples.open(); multi != 0; multi = derivedTuples.getNext()) { + String p = RDFoxTripleManager.getQuotedTerm(derivedTuples.getResource(0)); + if (p.equals(Namespace.RDF_TYPE_ABBR) || p.equals(Namespace.RDF_TYPE_QUOTED)) ; + else if (p.equals(Namespace.EQUALITY_ABBR) || p.equals(Namespace.EQUALITY_QUOTED)) ; + else if (m_encoder.isAuxPredicate(p)) ; + else binaryPredicates.add(p); + } + } catch (JRDFStoreException e) { + e.printStackTrace(); + } finally { + if (derivedTuples != null) derivedTuples.dispose(); + } + } + + private Set overlappingDisjunctiveClauses( + QueryRecord botQueryRecord) { + if (m_tBoxAxioms == null) + return null; + + Set disjunctiveRules = new HashSet(); + Set clauses = m_record.getRelevantClauses(); + for (DLClause clause : botQueryRecord.getRelevantClauses()) + if (clause.getHeadLength() > 1 && clauses.contains(clause)) + disjunctiveRules.add(clause); + + return disjunctiveRules.isEmpty() ? null : disjunctiveRules; + } + + private String getSPARQLQuery4Unary(String p) { + StringBuilder builder = new StringBuilder(); + builder.append("select ?x where { ?x <").append(Namespace.RDF_TYPE).append("> "); + builder.append(p).append(" . }"); + return builder.toString(); + } + + private String getSPARQLQuery4Binary(String p) { + StringBuilder builder = new StringBuilder(); + builder.append("select ?x ?y where { ?x ").append(p).append(" ?y . }"); + return builder.toString(); + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java new file mode 100644 index 0000000..d05731a --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java @@ -0,0 +1,387 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import org.semanticweb.owlapi.model.OWLOntology; +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.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; +import uk.ac.ox.cs.pagoda.query.AnswerTuples; +import uk.ac.ox.cs.pagoda.query.GapTupleIterator; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +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 java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.*; + +public abstract class TrackingRuleEncoder extends Disposable { + public static final String trackingPredicateRelation = Namespace.PAGODA_AUX + "isTrackingPredicateFor"; + public static final String QueryPredicate = Namespace.PAGODA_AUX + "Query"; + protected BasicQueryEngine store; + protected QueryRecord currentQuery; + protected Set unaryPredicates = new HashSet(); + protected Set binaryPredicates = new HashSet(); + UpperDatalogProgram program; + Collection trackingClauses = new HashSet(); + Collection queryClauses = new LinkedList(); + Map index2clause = new HashMap(); + Map clause2index = new HashMap(); + String equalityRelatedRuleText = null; + boolean ruleEncoded = false; + DLPredicate selected; + private boolean queryEncoded = false; + private LinkedList addedData = new LinkedList(); + private String trackingSuffix; + + public TrackingRuleEncoder(UpperDatalogProgram program, BasicQueryEngine store) { + this.program = program; + this.store = store; + } + + public static String getRawTerm(GroundTerm r) { + if(r instanceof uk.ac.ox.cs.JRDFox.model.Individual) + return ((uk.ac.ox.cs.JRDFox.model.Individual) r).getIRI(); + else { + Literal l = (Literal) r; + if(l.getDatatype().equals(Datatype.XSD_STRING) && l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL)) + return "\"" + l.getLexicalForm() + "\""; + else + return "\"" + l.getLexicalForm() + "\"^^<" + l.getDatatype().getIRI() + ">"; + } + } + + protected static String getTrackingSuffix(String queryID) { + return "_AUXt" + queryID; + } + + public boolean encodingRules() { + if(isDisposed()) throw new DisposedException(); + if(ruleEncoded) return false; + ruleEncoded = true; + +// for (DLClause clause: program.getClauses(currentQuery.getClause())) { + for(DLClause clause : program.getClauses()) { + encodingRule(clause); + } + return true; + } + + public Collection getAddedData() { + if(isDisposed()) throw new DisposedException(); + return addedData; + } + + public String getTrackingPredicate(String predicateIRI) { + if(isDisposed()) throw new DisposedException(); + if(predicateIRI.startsWith("<")) + return predicateIRI.replace(">", getTrackingSuffix(currentQuery.getQueryID()) + ">"); + else + return predicateIRI + getTrackingSuffix(currentQuery.getQueryID()); + } + + public void setCurrentQuery(QueryRecord record) { + if(isDisposed()) throw new DisposedException(); + deprecateTrackingAndQueryRules(); + currentQuery = record; + selected = AtomicConcept.create(getSelectedPredicate()); + trackingSuffix = "_AUXt" + currentQuery.getQueryID(); + } + + @Override + public void dispose() { + super.dispose(); + deprecateTrackingAndQueryRules(); + } + + public String getTrackingProgram() { + if(isDisposed()) throw new DisposedException(); + StringBuilder sb = getTrackingProgramBody(); + sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); + return sb.toString(); + } + + public void saveTrackingRules(String fileName) { + if(isDisposed()) throw new DisposedException(); + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))); + writer.write(getTrackingProgram()); + writer.close(); + } catch(IOException e) { + e.printStackTrace(); + return; + } + Utility.logDebug("The tracking rules are saved in " + fileName + "."); + } + + public String getSelectedPredicate() { + if(isDisposed()) throw new DisposedException(); + return getIRI("_selected" + currentQuery.getQueryID()); + } + + public DLClause getSelectedClause(String iri) { + if(isDisposed()) throw new DisposedException(); + int index = iri.lastIndexOf("_r") + 2; + int ruleIndex = Integer.parseInt(iri.substring(index)); + return index2clause.get(ruleIndex); + } + + /** + * SELECT ?X + * WHERE { + * ?X :_selected? + * } + */ + public String getSelectedSPARQLQuery() { + if(isDisposed()) throw new DisposedException(); + StringBuilder builder = new StringBuilder(); + builder.append("SELECT ?X\nWHERE {\n?X "); + builder.append(selected.toString()).append("\n}"); + return builder.toString(); + } + + public OWLOntology getOntology() { + if(isDisposed()) throw new DisposedException(); + return program.getOntology(); + } + + public UpperDatalogProgram getProgram() { + if(isDisposed()) throw new DisposedException(); + return program; + } + + public String getOriginalPredicate(String p) { + if(isDisposed()) throw new DisposedException(); + if(p.startsWith("<")) { + if(!p.endsWith(trackingSuffix + ">")) return null; + } + else if(!p.endsWith(trackingSuffix)) return null; + + return p.replace(trackingSuffix, ""); + } + + public boolean isAuxPredicate(String p) { + if(isDisposed()) throw new DisposedException(); + return false; + } + + protected abstract String getEqualityRelatedRuleText(); + + protected String getIRI(String name) { + return program.getOntology().getOntologyID().getOntologyIRI().toString() + "#" + name; + } + + protected abstract void encodingRule(DLClause clause); + + protected Individual getIndividual4GeneralRule(DLClause clause) { + clause = program.getCorrespondingClause(clause); +// if (clause == null) +// return Individual.create(getIRI("_r0")); + + int index; + if(clause2index.containsKey(clause)) + index = clause2index.get(clause); + else { + index = clause2index.size() + 1; + index2clause.put(index, clause); + clause2index.put(clause, index); + } + + return Individual.create(getIRI("_r" + index)); + } + + private void encodingQuery(QueryRecord[] botQuerRecords) { + if(queryEncoded) return; + queryEncoded = true; + + if(currentQuery.getArity() > 0 && currentQuery.getArity() < 3) { + encodingAtomicQuery(botQuerRecords); + + } + else { + DLClause queryClause = currentQuery.getClause(); + Atom[] bodyAtoms = queryClause.getBodyAtoms(); + for(Atom bodyAtom : bodyAtoms) + addQueryRule(bodyAtom, bodyAtoms); + } + } + + private void addQueryRule(Atom atom, Atom[] atoms) { + DLClause newClause; + Atom headAtom; + + headAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newClause = DLClause.create(new Atom[]{headAtom}, atoms); + queryClauses.add(newClause); + } + + protected String getCurrentQueryPredicate() { + return QueryPredicate + currentQuery.getQueryID(); + } + + protected void encodingAtomicQuery(QueryRecord[] botQuerRecords) { + encodingAtomicQuery(botQuerRecords, false); + } + + protected void encodingAtomicQuery(QueryRecord[] botQuerRecords, boolean includingBottom) { + DLClause queryClause = currentQuery.getClause(); + AnswerTuples answerTuples = currentQuery.getGapAnswers(); + String[] answerVariables = currentQuery.getAnswerVariables(); + + String currentQueryPredicate = getCurrentQueryPredicate(); + Atom newAtom; + if(answerVariables.length == 1) { + AtomicConcept queryConcept = AtomicConcept.create(currentQueryPredicate); + newAtom = Atom.create(queryConcept, Variable.create(answerVariables[0])); + } + else { + AtomicRole queryRole = AtomicRole.create(currentQueryPredicate); + newAtom = Atom.create(queryRole, Variable.create(answerVariables[0]), Variable.create(answerVariables[1])); + } + + Atom[] bodyAtoms = queryClause.getBodyAtoms(); + Atom[] newBodyAtoms = new Atom[queryClause.getBodyLength() + 1]; + for(int i = 0; i < bodyAtoms.length; ++i) + newBodyAtoms[i + 1] = bodyAtoms[i]; + newBodyAtoms[0] = newAtom; + + for(Atom bodyAtom : bodyAtoms) + addQueryRule(bodyAtom, newBodyAtoms); + + RDFoxTripleManager tripleManager = new RDFoxTripleManager(store.getDataStore(), true); +// MyPrefixes prefixes = MyPrefixes.PAGOdAPrefixes; + int[] triple; + int predicate = tripleManager.getResourceID(AtomicConcept.create(currentQueryPredicate)); + int rdftype = tripleManager.getResourceID(AtomicRole.create(Namespace.RDF_TYPE)); + if(answerVariables.length == 1) { + for(AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { + answer = answerTuples.getTuple(); + triple = + new int[]{tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(0))), rdftype, predicate}; + addedData.add(triple); + tripleManager.addTripleByID(triple); +// System.out.println("To be removed ... \n" + tripleManager.getRawTerm(tripleManager.getResourceID(prefixes.expandIRI(answer.getRawTerm(0)))) + " " + tripleManager.getRawTerm(rdftype) + " " + tripleManager.getRawTerm(predicate)); + } + } + else { + for(AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { + answer = answerTuples.getTuple(); + triple = + new int[]{tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(0))), predicate, tripleManager + .getResourceID(getRawTerm(answer.getGroundTerm(1)))}; + addedData.add(triple); + tripleManager.addTripleByID(triple); + } + } +// answerTuples.dispose(); + + if(includingBottom && botQuerRecords != null) { + int index = 0; + GroundTerm t; + String raw; + for(QueryRecord botQueryRecord : botQuerRecords) { + answerTuples = botQueryRecord.getGapAnswers(); + int subID = 0;//botQueryRecord.getSubID(); + String p = subID == 0 ? AtomicConcept.NOTHING.getIRI() : Namespace.OWL_NS + "Nothing_final" + (++index); + predicate = tripleManager.getResourceID(AtomicConcept.create(p = getTrackingPredicate(p))); + for(AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { + answer = answerTuples.getTuple(); +// System.out.println("To be removed ... " + answer.getRawTerm(0)); + raw = ((t = + answer.getGroundTerm(0)) instanceof uk.ac.ox.cs.JRDFox.model.Individual) ? ((uk.ac.ox.cs.JRDFox.model.Individual) t) + .getIRI() : t.toString(); + triple = new int[]{tripleManager.getResourceID(raw), rdftype, predicate}; + addedData.add(triple); + tripleManager.addTripleByID(triple); + } +// answerTuples.dispose(); + } + } + + Utility.logDebug(addedData.size() + " triples are added into the store."); + } + + protected DLPredicate getGapDLPredicate(DLPredicate dlPredicate) { + return getDLPredicate(dlPredicate, GapTupleIterator.gapPredicateSuffix); + } + + DLPredicate getDLPredicate(DLPredicate p, String suffix) { + if(isDisposed()) throw new DisposedException(); + if(p instanceof AtomicConcept) + return AtomicConcept.create(((AtomicConcept) p).getIRI() + suffix); + else if(p instanceof DatatypeRestriction) { + DatatypeRestriction restriction = (DatatypeRestriction) p; + String newURI = restriction.getDatatypeURI() + suffix; + return getDatatypeRestriction(restriction, newURI); + } + else if(p instanceof AtomicRole) + return AtomicRole.create(((AtomicRole) p).getIRI() + suffix); + else if(p instanceof AnnotatedEquality || p instanceof Equality) + return AtomicRole.create(Namespace.EQUALITY + suffix); + else if(p instanceof Inequality) + return AtomicRole.create(Namespace.INEQUALITY + suffix); + else if(p instanceof DatatypeRestriction) + return AtomicConcept.create(((DatatypeRestriction) p).getDatatypeURI() + suffix); + else { + Utility.logDebug("strange DL predicate appeared ... " + p, + "the program paused here in TrackingRuleEncoderDisj.java"); + return null; + } + } + + protected DLPredicate getTrackingDLPredicate(DLPredicate dlPredicate) { + return getDLPredicate(dlPredicate, getTrackingSuffix(currentQuery.getQueryID())); + } + + protected DLPredicate getDatatypeRestriction(DatatypeRestriction restriction, String newName) { + int length = restriction.getNumberOfFacetRestrictions(); + String[] facets = new String[length]; + Constant[] values = new Constant[length]; + for(int i = 0; i < length; ++i) { + facets[i] = restriction.getFacetURI(i); + values[i] = restriction.getFacetValue(i); + } + return DatatypeRestriction.create(newName, facets, values); + } + + private String getTrackingRuleText() { + return DLClauseHelper.toString(trackingClauses); + } + + private String getQueryRuleText() { + return DLClauseHelper.toString(queryClauses); + } + + protected StringBuilder getTrackingProgramBody() { + encodingRules(); + encodingQuery(new QueryRecord[0]); + + StringBuilder sb = new StringBuilder(); + sb.append(getTrackingRuleText()); + sb.append(getEqualityRelatedRuleText()); + sb.append(getQueryRuleText()); + return sb; + } + + private void deprecateTrackingAndQueryRules() { + trackingClauses.clear(); + queryClauses.clear(); + addedData.clear(); + ruleEncoded = false; + queryEncoded = false; + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java new file mode 100644 index 0000000..b169053 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java @@ -0,0 +1,163 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.rules.approximators.SkolemTermsManager; +import uk.ac.ox.cs.pagoda.util.Namespace; + +import java.util.*; + +public abstract class TrackingRuleEncoderDisj extends TrackingRuleEncoderWithGap { + + public TrackingRuleEncoderDisj(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + protected Map> disjunctiveRules = new HashMap>(); + + /** + * + */ + protected void processDisjunctiveRules() { + Map> auxiliaryAtoms = new HashMap>(); + Map> skolemisedAtoms = new HashMap>(); + SkolemTermsManager termsManager = SkolemTermsManager.getInstance(); + + for (Map.Entry> entry: disjunctiveRules.entrySet()) { + DLClause original = entry.getKey(); + Collection overClauses = entry.getValue(); + + int index = 0; + for (Iterator iter = overClauses.iterator(); iter.hasNext();) { + DLClause subClause = iter.next(); + if (DLClauseHelper.hasSubsetBodyAtoms(subClause, original)) { + Atom headAtom = subClause.getHeadAtom(0); + if ((index = SkolemTermsManager.indexOfSkolemisedIndividual(headAtom)) != -1) { + Individual i = (Individual) headAtom.getArgument(index); + Collection clauses = skolemisedAtoms.get(i); + if (clauses == null) { + clauses = new HashSet(); + skolemisedAtoms.put(i, clauses); + } + clauses.add(subClause); + } + else + auxiliaryAtoms.put(getAuxiliaryAtom(original, subClause.getHeadAtom(0)), Collections.singleton(subClause)); + } + else + super.encodingRule(subClause); + } + + for (Atom headAtom: original.getHeadAtoms()) + if (headAtom.getDLPredicate() instanceof AtLeastConcept) { + AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate(); + Collection clauses = new HashSet(); + Individual[] individuals = new Individual[alc.getNumber()]; + for (int i = 0; i < alc.getNumber(); ++i) { + individuals[i] = termsManager.getFreshIndividual(original, i); + clauses.addAll(skolemisedAtoms.get(individuals[i])); + } + auxiliaryAtoms.put(getAuxiliaryAtom(original, headAtom, individuals), clauses); + } + + index = 0; + Atom[] auxAtoms = auxiliaryAtoms.keySet().toArray(new Atom[0]); + for (Atom atom: auxAtoms) { + for (DLClause subClause: auxiliaryAtoms.get(atom)) + encodingDisjunctiveRule(subClause, index, auxAtoms); + index++; + } + + auxiliaryAtoms.clear(); + } + } + + private Atom getAuxiliaryAtom(DLClause original, Atom headAtom, Individual... individuals) { + DLPredicate p = headAtom.getDLPredicate(); + if (p instanceof AtLeastConcept) { +// AtLeastConcept alc = (AtLeastConcept) p; +// Individual[] individuals = new Individual[alc.getNumber()]; +// for (int i = 0; i < alc.getNumber(); ++i) +// individuals[i] = OverApproxExist.getNewIndividual(original, i); + return Atom.create(generateAuxiliaryRule((AtLeastConcept) p, original, individuals), headAtom.getArgument(0)); + } + if (p instanceof AtomicConcept) + return Atom.create(generateAuxiliaryRule((AtomicConcept) p), headAtom.getArgument(0)); + if (p instanceof AtomicRole) + return Atom.create(generateAuxiliaryRule((AtomicRole) p), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof Equality || p instanceof AnnotatedEquality) + return Atom.create(generateAuxiliaryRule(Equality.INSTANCE), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof Inequality) + return Atom.create(generateAuxiliaryRule((Inequality) p), headAtom.getArgument(0), headAtom.getArgument(1)); + + return null; + } + + private void encodingDisjunctiveRule(DLClause clause, int index, Atom[] auxAtoms) { + int validHeadLength = auxAtoms.length; + Atom headAtom = clause.getHeadAtom(0); + Atom[] bodyAtoms = clause.getBodyAtoms(); + + LinkedList newHeadAtoms = new LinkedList(); + DLPredicate selected = AtomicConcept.create(getSelectedPredicate()); + newHeadAtoms.add(Atom.create(selected, getIndividual4GeneralRule(clause))); + + for (Atom atom: bodyAtoms) { + Atom newAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newHeadAtoms.add(newAtom); + } + + DLClause newClause; + Atom[] newBodyAtoms = new Atom[bodyAtoms.length + validHeadLength + 1]; + + newBodyAtoms[0] = Atom.create( + getTrackingDLPredicate(headAtom.getDLPredicate()), + DLClauseHelper.getArguments(headAtom)); + + newBodyAtoms[1] = Atom.create( + getGapDLPredicate(headAtom.getDLPredicate()), + DLClauseHelper.getArguments(headAtom)); + + for (int i = 0; i < validHeadLength; ++i) + if (i != index) + newBodyAtoms[i + (i < index ? 2 : 1)] = auxAtoms[i]; + + for (int i = 0; i < bodyAtoms.length; ++i) + newBodyAtoms[i + validHeadLength + 1] = bodyAtoms[i]; + + for (Atom atom: newHeadAtoms) { + newClause = DLClause.create(new Atom[] {atom}, newBodyAtoms); + addTrackingClause(newClause); + } + } + + protected void addTrackingClause(DLClause clause) { + trackingClauses.add(clause); + } + + protected void addDisjunctiveRule(DLClause key, DLClause clause) { + Collection value = disjunctiveRules.get(key); + if (value == null) { + value = new LinkedList(); + disjunctiveRules.put(key, value); + } + value.add(clause); + } + + protected abstract DLPredicate generateAuxiliaryRule(AtLeastConcept p, DLClause original, Individual[] individuals); + + protected abstract DLPredicate generateAuxiliaryRule(AtomicRole p); + + protected abstract DLPredicate generateAuxiliaryRule(AtomicConcept p); + + protected DLPredicate generateAuxiliaryRule(Equality instance) { + return generateAuxiliaryRule(AtomicRole.create(Namespace.EQUALITY)); + } + + protected abstract DLPredicate generateAuxiliaryRule(Inequality instance); + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj1.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj1.java new file mode 100644 index 0000000..d6b5e8b --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj1.java @@ -0,0 +1,175 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import uk.ac.ox.cs.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.multistage.Normalisation; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; + +import java.util.LinkedList; + +public class TrackingRuleEncoderDisj1 extends TrackingRuleEncoderDisj { + + public TrackingRuleEncoderDisj1(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + @Override + public boolean encodingRules() { + if (super.encodingRules()) { + processDisjunctiveRules(); + return true; + } + return false; + } + + @Override + protected void encodingRule(DLClause clause) { + if (currentQuery.isBottom()) { + super.encodingRule(clause); + return ; + } + + DLClause original = program.getCorrespondingClause(clause); + if (original.getHeadLength() <= 1) { + super.encodingRule(clause); + } + else addDisjunctiveRule(original, clause); + } + + private DLPredicate getAuxPredicate(DLPredicate p, Individual... individuals) { + if (p instanceof AtLeastConcept) { + StringBuilder builder = new StringBuilder( + Normalisation.getAuxiliaryConcept4Disjunct((AtLeastConcept) p, individuals)); + builder.append("_AUXa").append(currentQuery.getQueryID()); + return AtomicConcept.create(builder.toString()); + } + + return getDLPredicate(p, "_AUXa" + currentQuery.getQueryID()); + } + + private DLPredicate getTrackingBottomDLPredicate(DLPredicate p) { + return getDLPredicate(p, getTrackingSuffix("0")); + } + + protected DLPredicate generateAuxiliaryRule(AtLeastConcept p, DLClause original, Individual[] individuals) { + DLPredicate ret = getAuxPredicate(p, individuals); + Atom[] headAtom = new Atom[] {Atom.create(ret, X)}; + + AtomicRole role = p.getOnRole() instanceof AtomicRole ? + (AtomicRole) p.getOnRole(): + ((InverseRole) p.getOnRole()).getInverseOf(); + + AtomicConcept concept = p.getToConcept() instanceof AtomicConcept ? + (AtomicConcept) p.getToConcept() : + OverApproxExist.getNegationConcept(((AtomicNegationConcept) p.getToConcept()).getNegatedAtomicConcept()); + + Term[] roleArgs, conceptArg; + for (Individual i: individuals) { +// Variable i = Variable.create("Y"); + if (p.getOnRole() instanceof AtomicRole) { + roleArgs = new Term[] {X, i}; + conceptArg = new Term[] {i}; + } + else { + roleArgs = new Term[] {i, X}; + conceptArg = new Term[] {i}; + } + + addTrackingClause( + DLClause.create(headAtom, + new Atom[] {Atom.create(getTrackingDLPredicate(role), roleArgs)})); + + addTrackingClause( + DLClause.create(headAtom, + new Atom[] {Atom.create(getTrackingBottomDLPredicate(role), roleArgs)})); + + Atom guard = Atom.create(role, roleArgs); + + if (!concept.equals(AtomicConcept.THING)) { + addTrackingClause( + DLClause.create(headAtom, + new Atom[] {guard, Atom.create(getTrackingDLPredicate(concept), conceptArg)})); + + addTrackingClause( + DLClause.create(headAtom, + new Atom[] {guard, Atom.create(getTrackingBottomDLPredicate(concept), conceptArg)})); + } + } + + return ret; + } + + protected DLPredicate generateAuxiliaryRule(AtomicRole p) { + DLPredicate ret = getAuxPredicate(p); + Atom[] headAtom = new Atom[] {Atom.create(ret, X, Y)}; + + addTrackingClause( + DLClause.create(headAtom, new Atom[] {Atom.create(getTrackingDLPredicate(p), X, Y)})); + addTrackingClause( + DLClause.create(headAtom, new Atom[] {Atom.create(getTrackingBottomDLPredicate(p), X, Y)})); + + return ret; + } + + private Variable X = Variable.create("X"), Y = Variable.create("Y"); + + protected DLPredicate generateAuxiliaryRule(AtomicConcept p) { + DLPredicate ret = getAuxPredicate(p); + Atom[] headAtom = new Atom[] {Atom.create(ret, X)}; + addTrackingClause( + DLClause.create(headAtom, + new Atom[] { Atom.create(getTrackingDLPredicate(p), X)})); + addTrackingClause( + DLClause.create(headAtom, + new Atom[] { Atom.create(getTrackingBottomDLPredicate(p), X)})); + + return ret; + } + + protected DLPredicate generateAuxiliaryRule(Inequality instance) { + // TODO: + return null; + } + + @Override + public boolean isAuxPredicate(String iri) { + return iri.contains("_AUXa"); +// if (iri.startsWith("<")) +// return iri.endsWith("_AUXa" + currentQuery.getQueryID() + ">"); +// return iri.endsWith("_AUXa" + currentQuery.getQueryID()); + } + + @Override + public String getTrackingProgram() { + StringBuilder sb = getTrackingProgramBody(); + if (currentQuery.isBottom()) + sb.append(getBottomTrackingProgram()); + sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); + return sb.toString(); + } + + private String bottomTrackingProgram = null; + + private String getBottomTrackingProgram() { + if (bottomTrackingProgram != null) return bottomTrackingProgram.replace("_tn", getTrackingPredicate("")); + + String bottomSuffix = getTrackingSuffix("0"); + LinkedList clauses = new LinkedList(); + Variable X = Variable.create("X"); + for (String concept: unaryPredicates) + clauses.add(DLClause.create(new Atom[] {Atom.create(AtomicConcept.create(concept + bottomSuffix) , X)}, + new Atom[] {Atom.create(AtomicConcept.create(concept + "_tn"), X)})); + Variable Y = Variable.create("Y"); + for (String role: binaryPredicates) + clauses.add(DLClause.create(new Atom[] {Atom.create(AtomicRole.create(role + bottomSuffix) , X, Y)}, + new Atom[] {Atom.create(AtomicRole.create(role + "_tn"), X, Y) })); + + StringBuilder builder = new StringBuilder(DLClauseHelper.toString(clauses)); + bottomTrackingProgram = builder.toString(); + return bottomTrackingProgram.replace("_tn", getTrackingPredicate("")); + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj2.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj2.java new file mode 100644 index 0000000..8d79090 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj2.java @@ -0,0 +1,112 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import uk.ac.ox.cs.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.multistage.Normalisation; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; + +public class TrackingRuleEncoderDisj2 extends TrackingRuleEncoderDisj { + + public TrackingRuleEncoderDisj2(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + @Override + public boolean encodingRules() { + if (ruleEncoded) return false; + ruleEncoded = true; + + for (DLClause clause: program.getClauses()) { + encodingRule(clause); + } + + if (disjunctiveRules.isEmpty()) + return true; + + processDisjunctiveRules(); + return false; + } + + @Override + protected DLPredicate generateAuxiliaryRule(AtomicConcept p) { + return getTrackingDLPredicate(p); + } + + @Override + protected DLPredicate generateAuxiliaryRule(AtomicRole p) { + return getTrackingDLPredicate(p); + } + + private Variable X = Variable.create("X"); + + @Override + protected DLPredicate generateAuxiliaryRule(AtLeastConcept p, DLClause original, Individual[] individuals) { + DLPredicate ret = AtomicConcept.create(getTrackingPredicate(Normalisation.getAuxiliaryConcept4Disjunct(p, individuals))); + Atom[] headAtom = new Atom[] {Atom.create(ret, X)}; + + AtomicRole role = p.getOnRole() instanceof AtomicRole ? + (AtomicRole) p.getOnRole(): + ((InverseRole) p.getOnRole()).getInverseOf(); + + AtomicConcept concept = p.getToConcept() instanceof AtomicConcept ? + (AtomicConcept) p.getToConcept() : + OverApproxExist.getNegationConcept(((AtomicNegationConcept) p.getToConcept()).getNegatedAtomicConcept()); + + Term[] roleArgs, conceptArg; + for (Individual i: individuals) { +// Variable i = Variable.create("Y"); + if (p.getOnRole() instanceof AtomicRole) { + roleArgs = new Term[] {X, i}; + conceptArg = new Term[] {i}; + } + else { + roleArgs = new Term[] {i, X}; + conceptArg = new Term[] {i}; + } + + addTrackingClause( + DLClause.create(headAtom, + new Atom[] {Atom.create(getTrackingDLPredicate(role), roleArgs)})); + + Atom guard = Atom.create(role, roleArgs); + + if (!concept.equals(AtomicConcept.THING)) { + addTrackingClause( + DLClause.create(headAtom, + new Atom[] {guard, Atom.create(getTrackingDLPredicate(concept), conceptArg)})); + } + } + + return ret; + } + + @Override + protected void encodingRule(DLClause clause) { + DLClause original = program.getCorrespondingClause(clause); + if (original.getHeadLength() <= 1) { + super.encodingRule(clause); + } + else addDisjunctiveRule(original, clause); + } + + @Override + public String getTrackingProgram() { + StringBuilder sb = getTrackingProgramBody(); + sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); + return sb.toString(); + } + + @Override + protected void encodingAtomicQuery(QueryRecord[] botQuerRecords) { + super.encodingAtomicQuery(botQuerRecords, true); + } + + @Override + protected DLPredicate generateAuxiliaryRule(Inequality instance) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar1.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar1.java new file mode 100644 index 0000000..d96c747 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar1.java @@ -0,0 +1,425 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import uk.ac.ox.cs.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.multistage.Normalisation; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Utility; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +public class TrackingRuleEncoderDisjVar1 extends TrackingRuleEncoderWithGap { + + private Set disjunctiveRules = new HashSet(); + private Variable X = Variable.create("X"), Y = Variable.create("Y"); + private String bottomTrackingProgram = null; + + public TrackingRuleEncoderDisjVar1(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + @Override + public boolean encodingRules() { + if (super.encodingRules()) { + processDisjunctiveRules(); + return true; + } + return false; + } + + @Override + protected void encodingRule(DLClause clause) { + if (currentQuery.isBottom()) { +// super.encodingRule(clause); + encodingBottomQueryClause(clause); + return; + } + + DLClause original = program.getCorrespondingClause(clause); + if (original.getHeadLength() <= 1) { + super.encodingRule(clause); + } + else { + if (!DLClauseHelper.hasSubsetBodyAtoms(clause, original)) + super.encodingRule(clause); + addDisjunctiveRule(original); + } + + } + + private void processDisjunctiveRules() { + for (DLClause clause: disjunctiveRules) + encodingDisjunctiveRule(clause); + } + + private Atom getAuxiliaryAtom(Atom headAtom) { + DLPredicate p = headAtom.getDLPredicate(); + if (p instanceof AtLeast || p instanceof AtLeast) { + return Atom.create(generateAuxiliaryRule((AtLeast) p, true), headAtom.getArgument(0)); + } + if(p instanceof AtomicConcept) + return Atom.create(generateAuxiliaryRule((AtomicConcept) p), headAtom.getArgument(0)); + if(p instanceof AtomicRole) + return Atom.create(generateAuxiliaryRule((AtomicRole) p), headAtom.getArgument(0), headAtom.getArgument(1)); + if(p instanceof Equality || p instanceof AnnotatedEquality) + return Atom.create(generateAuxiliaryRule(Equality.INSTANCE), headAtom.getArgument(0), headAtom.getArgument(1)); + if(p instanceof Inequality) + return Atom.create(generateAuxiliaryRule((Inequality) p), headAtom.getArgument(0), headAtom.getArgument(1)); + + return null; + } + + private Atom getTrackingAtom(Atom headAtom) { + DLPredicate p = headAtom.getDLPredicate(); + if (p instanceof AtLeast) { + p = Normalisation.toAtLeastConcept((AtLeast) p); + return Atom.create(getTrackingDLPredicate(AtomicConcept.create(Normalisation.getAuxiliaryConcept4Disjunct((AtLeastConcept) p))), headAtom + .getArgument(0)); + } + if(p instanceof AtomicConcept) + return Atom.create(getTrackingDLPredicate(p), headAtom.getArgument(0)); + if(p instanceof AtomicRole) + return Atom.create(getTrackingDLPredicate(p), headAtom.getArgument(0), headAtom.getArgument(1)); + if(p instanceof Equality || p instanceof AnnotatedEquality) + return Atom.create(getTrackingDLPredicate(Equality.INSTANCE), headAtom.getArgument(0), headAtom.getArgument(1)); + if(p instanceof Inequality) + return Atom.create(getTrackingDLPredicate(p), headAtom.getArgument(0), headAtom.getArgument(1)); + + return null; + } + + private Atom getGapAtom(Atom headAtom) { + DLPredicate p = headAtom.getDLPredicate(); + if (p instanceof AtLeast) { + p = Normalisation.toAtLeastConcept((AtLeast) p); + return Atom.create(getGapDLPredicate(AtomicConcept.create(Normalisation.getAuxiliaryConcept4Disjunct((AtLeastConcept) p))), headAtom + .getArgument(0)); + } + if(p instanceof AtomicConcept) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0)); + if(p instanceof AtomicRole) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0), headAtom.getArgument(1)); + if(p instanceof Equality || p instanceof AnnotatedEquality) + return Atom.create(getGapDLPredicate(Equality.INSTANCE), headAtom.getArgument(0), headAtom.getArgument(1)); + if(p instanceof Inequality) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof DatatypeRestriction) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0)); + Utility.logError(p + " is not recognised."); + return null; + } + + private void encodingDisjunctiveRule(DLClause clause) { + int headLength = clause.getHeadLength(); + + Atom[] auxAtoms = new Atom[headLength]; + for (int i = 0; i < headLength; ++i) + auxAtoms[i] = getAuxiliaryAtom(clause.getHeadAtom(i)); + + Atom[] trackingAtoms = new Atom[headLength]; + for (int i = 0; i < headLength; ++i) + trackingAtoms[i] = getTrackingAtom(clause.getHeadAtom(i)); + + Atom[] gapAtoms = new Atom[headLength]; + for (int i = 0; i < headLength; ++i) + gapAtoms[i] = getGapAtom(clause.getHeadAtom(i)); + + Atom[] bodyAtoms = clause.getBodyAtoms(); + + LinkedList newHeadAtoms = new LinkedList(); + DLPredicate selected = AtomicConcept.create(getSelectedPredicate()); + newHeadAtoms.add(Atom.create(selected, getIndividual4GeneralRule(clause))); + + for (Atom atom: bodyAtoms) { + Atom newAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newHeadAtoms.add(newAtom); + } + + DLClause newClause; + int index; + for (int j = 0; j < headLength; ++j) { + Atom[] newBodyAtoms = new Atom[headLength * 2 + bodyAtoms.length]; + index = 0; + for (int i = 0; i < headLength; ++i, ++index) + newBodyAtoms[index] = gapAtoms[i]; + for (int i = 0; i < headLength; ++i, ++index) + if (i != j) + newBodyAtoms[index] = auxAtoms[i]; + else + newBodyAtoms[index] = trackingAtoms[i]; + + for (int i = 0; i < bodyAtoms.length; ++i, ++index) + newBodyAtoms[index] = bodyAtoms[i]; + + for (Atom atom: newHeadAtoms) { + newClause = DLClause.create(new Atom[]{atom}, newBodyAtoms); + addTrackingClause(newClause); + } + } + } + + private void addTrackingClause(DLClause clause) { + trackingClauses.add(clause); + } + + private void addDisjunctiveRule(DLClause clause) { + disjunctiveRules.add(clause); + } + + private DLPredicate getAuxPredicate(DLPredicate p) { + if (p instanceof AtLeastConcept) { + StringBuilder builder = new StringBuilder( + Normalisation.getAuxiliaryConcept4Disjunct((AtLeastConcept) p)); + builder.append("_AUXa").append(currentQuery.getQueryID()); + return AtomicConcept.create(builder.toString()); + } + + return getDLPredicate(p, "_AUXa" + currentQuery.getQueryID()); + } + + private DLPredicate getTrackingBottomDLPredicate(DLPredicate p) { + return getDLPredicate(p, getTrackingSuffix("0")); + } + + private DLPredicate generateAuxiliaryRule(AtLeast p1, boolean withAux) { + AtLeastConcept p = Normalisation.toAtLeastConcept(p1); + + int num = p.getNumber(); + Variable[] Ys = new Variable[num]; + if (num > 1) + for(int i = 0; i < num; ++i) + Ys[i] = Variable.create("Y" + (i + 1)); + else + Ys[0] = Y; + + Collection expandedAtom = new LinkedList(); + Collection representativeAtom = new LinkedList(); + if (p.getOnRole() instanceof AtomicRole) { + AtomicRole r = (AtomicRole) p.getOnRole(); + for(int i = 0; i < num; ++i) + expandedAtom.add(Atom.create(r, X, Ys[i])); + representativeAtom.add(Atom.create(r, X, Ys[0])); + } + else { + AtomicRole r = ((InverseRole) p.getOnRole()).getInverseOf(); + for(int i = 0; i < num; ++i) + expandedAtom.add(Atom.create(r, Ys[i], X)); + representativeAtom.add(Atom.create(r, Ys[0], X)); + } + + if (num > 1) { + representativeAtom.add(Atom.create(Inequality.INSTANCE, Ys[0], Ys[1])); + } + for (int i = 0; i < num; ++i) + for (int j = i + 1; j < num; ++j) + expandedAtom.add(Atom.create(Inequality.INSTANCE, Ys[i], Ys[j])); + + if (!p.getToConcept().equals(AtomicConcept.THING)) { + AtomicConcept c; + if(p.getToConcept() instanceof AtomicConcept) + c = (AtomicConcept) p.getToConcept(); + else { + c = OverApproxExist.getNegationConcept(((AtomicNegationConcept) p.getToConcept()).getNegatedAtomicConcept()); + } + for (int i = 0; i < num; ++i) + expandedAtom.add(Atom.create(c, Ys[i])); + representativeAtom.add(Atom.create(c, Ys[0])); + } + + AtomicConcept ac = AtomicConcept.create(Normalisation.getAuxiliaryConcept4Disjunct(p)); + DLPredicate trackingPredicate = getTrackingDLPredicate(ac); + DLPredicate gapPredicate = getGapDLPredicate(ac); + DLPredicate auxPredicate = withAux ? getAuxPredicate(p) : null; + + for (Atom atom: representativeAtom) { + Atom[] bodyAtoms = new Atom[expandedAtom.size() + 1]; + if (atom.getArity() == 1) + bodyAtoms[0] = Atom.create(getTrackingDLPredicate(atom.getDLPredicate()), atom.getArgument(0)); + else + bodyAtoms[0] = Atom.create(getTrackingDLPredicate(atom.getDLPredicate()), atom.getArgument(0), atom.getArgument(1)); + int i = 0; + for (Atom bodyAtom: expandedAtom) + bodyAtoms[++i] = bodyAtom; + addTrackingClause(DLClause.create(new Atom[] {Atom.create(trackingPredicate, X)}, bodyAtoms)); + + bodyAtoms = new Atom[expandedAtom.size() + 1]; + if (atom.getArity() == 1) + bodyAtoms[0] = Atom.create(getGapDLPredicate(atom.getDLPredicate()), atom.getArgument(0)); + else + bodyAtoms[0] = Atom.create(getGapDLPredicate(atom.getDLPredicate()), atom.getArgument(0), atom.getArgument(1)); + i = 0; + for (Atom bodyAtom: expandedAtom) + bodyAtoms[++i] = bodyAtom; + addTrackingClause(DLClause.create(new Atom[] {Atom.create(gapPredicate, X)}, bodyAtoms)); + + if (withAux) { + bodyAtoms = new Atom[expandedAtom.size() + 1]; + bodyAtoms[0] = getAuxiliaryAtom(atom); + i = 0; + for (Atom bodyAtom: expandedAtom) + bodyAtoms[++i] = bodyAtom; + addTrackingClause(DLClause.create(new Atom[] {Atom.create(auxPredicate, X)}, bodyAtoms)); + } + } + + return withAux ? auxPredicate : trackingPredicate; + } + + private DLPredicate generateAuxiliaryRule(AtomicRole p) { + if(currentQuery.isBottom()) + return getTrackingDLPredicate(p); + + DLPredicate ret = getAuxPredicate(p); + Atom[] headAtom = new Atom[] {Atom.create(ret, X, Y)}; + + addTrackingClause( + DLClause.create(headAtom, new Atom[]{Atom.create(getTrackingDLPredicate(p), X, Y)})); + addTrackingClause( + DLClause.create(headAtom, new Atom[]{Atom.create(getTrackingBottomDLPredicate(p), X, Y)})); + + return ret; + } + + private DLPredicate generateAuxiliaryRule(AtomicConcept p) { + if (currentQuery.isBottom()) + return getTrackingDLPredicate(p); + + DLPredicate ret = getAuxPredicate(p); + Atom[] headAtom = new Atom[]{Atom.create(ret, X)}; + addTrackingClause( + DLClause.create(headAtom, + new Atom[]{Atom.create(getTrackingDLPredicate(p), X)})); + addTrackingClause( + DLClause.create(headAtom, + new Atom[] { Atom.create(getTrackingBottomDLPredicate(p), X)})); + + return ret; + } + + private DLPredicate generateAuxiliaryRule(Equality instance) { + return generateAuxiliaryRule(AtomicRole.create(Namespace.EQUALITY)); + } + + private DLPredicate generateAuxiliaryRule(Inequality instance) { + return generateAuxiliaryRule(AtomicRole.create(Namespace.INEQUALITY)); + } + + @Override + public String getTrackingProgram() { + StringBuilder sb = getTrackingProgramBody(); + if (currentQuery.isBottom()) + sb.append(getBottomTrackingProgram()); + sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); + return sb.toString(); + } + + private String getBottomTrackingProgram() { + if (bottomTrackingProgram != null) return bottomTrackingProgram.replace("_tn", getTrackingPredicate("")); + + String bottomSuffix = getTrackingSuffix("0"); + LinkedList clauses = new LinkedList(); + Variable X = Variable.create("X"); + for (String concept: unaryPredicates) + clauses.add(DLClause.create(new Atom[] {Atom.create(AtomicConcept.create(concept + bottomSuffix) , X)}, + new Atom[] {Atom.create(AtomicConcept.create(concept + "_tn"), X)})); + Variable Y = Variable.create("Y"); + for (String role: binaryPredicates) + clauses.add(DLClause.create(new Atom[] {Atom.create(AtomicRole.create(role + bottomSuffix) , X, Y)}, + new Atom[] {Atom.create(AtomicRole.create(role + "_tn"), X, Y) })); + + StringBuilder builder = new StringBuilder(DLClauseHelper.toString(clauses)); + bottomTrackingProgram = builder.toString(); + return bottomTrackingProgram.replace("_tn", getTrackingPredicate("")); + } + + private void encodingBottomQueryClause(DLClause clause) { + if (!clause.toString().contains("owl:Nothing")) + clause = program.getCorrespondingClause(clause); + +// Term t; +// for (Atom tAtom: clause.getHeadAtoms()) { +// for (int i = 0; i < tAtom.getArity(); ++i) +// if ((t = tAtom.getArgument(i)) instanceof Individual) +// if (((Individual) t).getIRI().startsWith(OverApproxExist.SKOLEMISED_INDIVIDUAL_PREFIX)) +// clause = program.getCorrespondingClause(clause); +// } + + LinkedList newHeadAtoms = new LinkedList(); + Atom selectAtom = Atom.create(selected, getIndividual4GeneralRule(program.getCorrespondingClause(clause))); + + for (Atom atom: clause.getBodyAtoms()) { + atom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newHeadAtoms.add(atom); + } + + DLClause newClause; + + boolean botInHead = clause.getBodyLength() == 1 && clause.getBodyAtom(0).getDLPredicate().toString().contains("owl:Nothing"); + + DLPredicate[] trackingPredicates = new DLPredicate[clause.getHeadLength()]; + DLPredicate[] predicates = new DLPredicate[clause.getHeadLength()]; + int headIndex = 0; + DLPredicate trackingPredicate, p; + for (Atom headAtom: clause.getHeadAtoms()) { + if ((p = headAtom.getDLPredicate()) instanceof AtLeastConcept) { + trackingPredicate = generateAuxiliaryRule((AtLeastConcept) p, false); + p = AtomicConcept.create(Normalisation.getAuxiliaryConcept4Disjunct((AtLeastConcept) p)); + trackingClauses.add(DLClause.create( + new Atom[] { Atom.create(getDLPredicate(p, getTrackingSuffix("0")), X) }, + new Atom[] { Atom.create(trackingPredicate, X) })); + } + else + trackingPredicate = getTrackingDLPredicate(p); + + trackingPredicates[headIndex] = trackingPredicate; + predicates[headIndex] = p; + ++headIndex; + } + + headIndex = 0; + int headLength = clause.getHeadLength(); + Atom[] gapAtoms = new Atom[headLength]; + for (int i = 0; i < headLength; ++i) + gapAtoms[i] = getGapAtom(clause.getHeadAtom(i)); +// Atom.create(getGapDLPredicate(predicates[headIndex]), DLClauseHelper.getArguments(clause.getHeadAtom(i))); + int index, selectIndex; + for (Atom headAtom: clause.getHeadAtoms()) { + index = 0; selectIndex = 0; + Atom[] newBodyAtoms = new Atom[clause.getBodyLength() + 1 + headLength - 1 + (botInHead ? 0 : headLength)]; + Atom[] selectBodyAtoms = new Atom[clause.getBodyLength() + 1 + (botInHead ? 0 : headLength)]; + newBodyAtoms[index++] = selectBodyAtoms[selectIndex++] = Atom.create(trackingPredicates[headIndex], DLClauseHelper.getArguments(headAtom)); + + if (!botInHead) { + for (int i = 0; i < headLength; ++i) + newBodyAtoms[index++] = selectBodyAtoms[selectIndex++] = gapAtoms[i]; + } + + for (int i = 0; i < headLength; ++i) + if (i != headIndex) { + newBodyAtoms[index++] = Atom.create(getDLPredicate(predicates[i], getTrackingSuffix("0")), DLClauseHelper.getArguments(clause.getHeadAtom(i))); + } + + for (int i = 0; i < clause.getBodyLength(); ++i) + newBodyAtoms[index++] = selectBodyAtoms[selectIndex++] = clause.getBodyAtom(i); + + for (Atom atom: newHeadAtoms) { + newClause = DLClause.create(new Atom[] {atom}, newBodyAtoms); + trackingClauses.add(newClause); + } + trackingClauses.add(DLClause.create(new Atom[] {selectAtom}, selectBodyAtoms)); + ++headIndex; + } + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar2.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar2.java new file mode 100644 index 0000000..7311a86 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisjVar2.java @@ -0,0 +1,230 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.multistage.Normalisation; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; +import uk.ac.ox.cs.pagoda.util.Namespace; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +public class TrackingRuleEncoderDisjVar2 extends TrackingRuleEncoderWithGap { + + public TrackingRuleEncoderDisjVar2(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + private Set disjunctiveRules = new HashSet(); + + @Override + public boolean encodingRules() { + if (ruleEncoded) return false; + ruleEncoded = true; + + for (DLClause clause: program.getClauses()) { + encodingRule(clause); + } + + if (disjunctiveRules.isEmpty()) + return true; + + processDisjunctiveRules(); + return false; + } + + @Override + protected void encodingRule(DLClause clause) { + DLClause original = program.getCorrespondingClause(clause); + if (original.getHeadLength() <= 1) { + super.encodingRule(clause); + } + else { + if (!DLClauseHelper.hasSubsetBodyAtoms(clause, original)) + super.encodingRule(clause); + addDisjunctiveRule(original); + } + } + + private void processDisjunctiveRules() { + for (DLClause clause: disjunctiveRules) + encodingDisjunctiveRule(clause); + } + + private Atom getAuxiliaryAtom(Atom headAtom) { + DLPredicate p = headAtom.getDLPredicate(); + if (p instanceof AtLeastConcept) { + return Atom.create(generateAuxiliaryRule((AtLeastConcept) p), headAtom.getArgument(0)); + } + if (p instanceof AtomicConcept) + return Atom.create(generateAuxiliaryRule((AtomicConcept) p), headAtom.getArgument(0)); + if (p instanceof AtomicRole) + return Atom.create(generateAuxiliaryRule((AtomicRole) p), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof Equality || p instanceof AnnotatedEquality) + return Atom.create(generateAuxiliaryRule(Equality.INSTANCE), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof Inequality) + return Atom.create(generateAuxiliaryRule((Inequality) p), headAtom.getArgument(0), headAtom.getArgument(1)); + + return null; + } + + private Atom getGapAtom(Atom headAtom) { + DLPredicate p = headAtom.getDLPredicate(); + if (p instanceof AtLeastConcept) { + return Atom.create(getGapDLPredicate(AtomicConcept.create(Normalisation.getAuxiliaryConcept4Disjunct((AtLeastConcept) p))), headAtom.getArgument(0)); + } + if (p instanceof AtomicConcept) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0)); + if (p instanceof AtomicRole) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof Equality || p instanceof AnnotatedEquality) + return Atom.create(getGapDLPredicate(Equality.INSTANCE), headAtom.getArgument(0), headAtom.getArgument(1)); + if (p instanceof Inequality) + return Atom.create(getGapDLPredicate(p), headAtom.getArgument(0), headAtom.getArgument(1)); + + return null; + } + + private void encodingDisjunctiveRule(DLClause clause) { + int headLength = clause.getHeadLength(); + + Atom[] auxAtoms = new Atom[headLength]; + for (int i = 0; i < headLength; ++i) + auxAtoms[i] = getAuxiliaryAtom(clause.getHeadAtom(i)); + + Atom[] gapAtoms = new Atom[headLength]; + for (int i = 0; i < headLength; ++i) + gapAtoms[i] = getGapAtom(clause.getHeadAtom(i)); + + Atom[] bodyAtoms = clause.getBodyAtoms(); + + LinkedList newHeadAtoms = new LinkedList(); + DLPredicate selected = AtomicConcept.create(getSelectedPredicate()); + newHeadAtoms.add(Atom.create(selected, getIndividual4GeneralRule(clause))); + + for (Atom atom: bodyAtoms) { + Atom newAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newHeadAtoms.add(newAtom); + } + + DLClause newClause; + for (int j = 0; j < headLength; ++j) { + Atom[] newBodyAtoms = new Atom[headLength + bodyAtoms.length + 1]; + newBodyAtoms[0] = gapAtoms[j]; + + for (int i = 0; i < headLength; ++i) +// newBodyAtoms[i] = auxAtoms[i]; + newBodyAtoms[i + 1] = auxAtoms[i]; + + for (int i = 0; i < bodyAtoms.length; ++i) +// newBodyAtoms[i + headLength] = bodyAtoms[i]; + newBodyAtoms[i + headLength + 1] = bodyAtoms[i]; + + for (Atom atom: newHeadAtoms) { + newClause = DLClause.create(new Atom[] {atom}, newBodyAtoms); + addTrackingClause(newClause); + } + } + } + + private void addTrackingClause(DLClause clause) { + trackingClauses.add(clause); + } + + private void addDisjunctiveRule(DLClause clause) { + disjunctiveRules.add(clause); + } + + protected DLPredicate generateAuxiliaryRule(AtLeastConcept p) { + AtomicConcept ac = AtomicConcept.create(Normalisation.getAuxiliaryConcept4Disjunct(p)); + int num = p.getNumber(); + Variable X = Variable.create("X"); + Variable[] Ys = new Variable[num]; + for (int i = 0; i < num; ++i) Ys[i] = Variable.create("Y" + (i + 1)); + Collection expandedAtom = new LinkedList(); + Collection representativeAtom = new LinkedList(); + if (p.getOnRole() instanceof AtomicRole) { + AtomicRole r = (AtomicRole) p.getOnRole(); + for (int i = 0; i < num; ++i) + expandedAtom.add(Atom.create(r, X, Ys[i])); + representativeAtom.add(Atom.create(r, X, Ys[0])); + } + else { + AtomicRole r = ((InverseRole) p.getOnRole()).getInverseOf(); + for (int i = 0; i < num; ++i) + expandedAtom.add(Atom.create(r, Ys[i], X)); + representativeAtom.add(Atom.create(r, Ys[0], X)); + + } + + if (num > 1) { + representativeAtom.add(Atom.create(Inequality.INSTANCE, Ys[0], Ys[1])); + } + for (int i = 0; i < num; ++i) + for (int j = i + 1; j < num; ++i) + expandedAtom.add(Atom.create(Inequality.INSTANCE, Ys[i], Ys[j])); + + if (!p.getToConcept().equals(AtomicConcept.THING)) { + AtomicConcept c; + if (p.getToConcept() instanceof AtomicConcept) + c = (AtomicConcept) p.getToConcept(); + else + c = OverApproxExist.getNegationConcept(((AtomicNegationConcept) p.getToConcept()).getNegatedAtomicConcept()); + for (int i = 0; i < num; ++i) + expandedAtom.add(Atom.create(c, Ys[i])); + representativeAtom.add(Atom.create(c, Ys[0])); + } + + DLPredicate auxPredicate = getTrackingDLPredicate(ac); + DLPredicate gapPredicate = getGapDLPredicate(ac); + for (Atom atom: representativeAtom) { + Atom[] bodyAtoms = new Atom[expandedAtom.size() + 1]; + bodyAtoms[0] = getAuxiliaryAtom(atom); + int i = 0; + for (Atom bodyAtom: expandedAtom) + bodyAtoms[++i] = bodyAtom; + addTrackingClause(DLClause.create(new Atom[] {Atom.create(auxPredicate, X)}, bodyAtoms)); + + bodyAtoms = new Atom[expandedAtom.size() + 1]; + if (atom.getArity() == 1) + bodyAtoms[0] = Atom.create(getGapDLPredicate(atom.getDLPredicate()), atom.getArgument(0)); + else + bodyAtoms[0] = Atom.create(getGapDLPredicate(atom.getDLPredicate()), atom.getArgument(0), atom.getArgument(1)); + i = 0; + for (Atom bodyAtom: expandedAtom) + bodyAtoms[++i] = bodyAtom; + addTrackingClause(DLClause.create(new Atom[] {Atom.create(gapPredicate, X)}, bodyAtoms)); + } + + return auxPredicate; + } + + private DLPredicate generateAuxiliaryRule(AtomicConcept p) { + return getTrackingDLPredicate(p); + } + + private DLPredicate generateAuxiliaryRule(AtomicRole p) { + return getTrackingDLPredicate(p); + } + + protected DLPredicate generateAuxiliaryRule(Equality instance) { + return getTrackingDLPredicate(AtomicRole.create(Namespace.EQUALITY)); + } + + protected DLPredicate generateAuxiliaryRule(Inequality instance) { + return getTrackingDLPredicate(AtomicRole.create(Namespace.INEQUALITY)); + } + + @Override + protected void encodingAtomicQuery(QueryRecord[] botQuerRecords) { + encodingAtomicQuery(botQuerRecords, true); + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java new file mode 100644 index 0000000..4ece796 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java @@ -0,0 +1,116 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLOntology; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.query.GapTupleIterator; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.util.Namespace; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +public class TrackingRuleEncoderWithGap extends TrackingRuleEncoder { + + public TrackingRuleEncoderWithGap(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + @Override + protected String getEqualityRelatedRuleText() { + if (equalityRelatedRuleText != null) return equalityRelatedRuleText.replace("_tn", getTrackingPredicate("")); + + Collection equalityRelatedClauses = new LinkedList(); + Variable X = Variable.create("X"); + AtomicRole trackingSameAs = AtomicRole.create(Namespace.EQUALITY + "_tn"); + OWLOntology onto = program.getOntology(); + Atom[] headAtom = new Atom[]{Atom.create(trackingSameAs, X, X)}, bodyAtom; + for(OWLOntology o : onto.getImportsClosure()) + for(OWLClass cls : o.getClassesInSignature()) { + String clsIRI = cls.getIRI().toString(); + unaryPredicates.add(clsIRI); + bodyAtom = new Atom[] { + Atom.create(AtomicConcept.create(clsIRI + "_tn"), X), + Atom.create(AtomicConcept.create(GapTupleIterator.getGapPredicate(clsIRI)), X)}; + equalityRelatedClauses.add(DLClause.create(headAtom, bodyAtom)); + } + + Variable Y = Variable.create("Y"); + Set setOfProperties = new HashSet(); + for(OWLOntology o : onto.getImportsClosure()) + for(OWLObjectProperty prop : o.getObjectPropertiesInSignature()) + setOfProperties.add(prop); + setOfProperties.add(onto.getOWLOntologyManager() + .getOWLDataFactory() + .getOWLObjectProperty(IRI.create(Namespace.INEQUALITY))); + for(OWLObjectProperty prop : setOfProperties) { + String propIRI = prop.getIRI().toString(); + binaryPredicates.add(propIRI); + AtomicRole trackingRole = AtomicRole.create(propIRI + "_tn"); + AtomicRole gapRole = AtomicRole.create(GapTupleIterator.getGapPredicate(propIRI)); +// AtomicRole role = AtomicRole.create(propIRI); + bodyAtom = new Atom[] { + Atom.create(trackingRole, X, Y), + Atom.create(gapRole, X, Y)}; + equalityRelatedClauses.add(DLClause.create(headAtom, bodyAtom)); + + bodyAtom = new Atom[] { + Atom.create(trackingRole, Y, X), + Atom.create(gapRole, Y, X)}; + equalityRelatedClauses.add(DLClause.create(headAtom, bodyAtom)); + } + + equalityRelatedClauses.add( + DLClause.create( + new Atom[] {Atom.create(trackingSameAs, Y, X)}, + new Atom[] {Atom.create(trackingSameAs, X, Y)})); + + equalityRelatedRuleText = DLClauseHelper.toString(equalityRelatedClauses).toString(); + return equalityRelatedRuleText.replace("_tn", getTrackingPredicate("")); + } + + @Override + protected void encodingRule(DLClause clause) { + LinkedList newHeadAtoms = new LinkedList(); + newHeadAtoms.add(Atom.create(selected, getIndividual4GeneralRule(clause))); + + Atom headAtom; + for (Atom atom: clause.getBodyAtoms()) { + headAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newHeadAtoms.add(headAtom); + } + + DLClause newClause; + headAtom = clause.getHeadAtom(0); + + boolean equalityHead = headAtom.getDLPredicate() instanceof Equality || headAtom.getDLPredicate() instanceof AnnotatedEquality; + int offset = (equalityHead || (clause.getBodyLength() == 1 && clause.getBodyAtom(0).getDLPredicate().toString().contains("owl:Nothing"))) ? 1 : 2; + + Atom[] newBodyAtoms = new Atom[clause.getBodyLength() + offset]; + newBodyAtoms[0] = Atom.create( + getTrackingDLPredicate(headAtom.getDLPredicate()), + DLClauseHelper.getArguments(headAtom)); + + if (offset == 2) + newBodyAtoms[1] = Atom.create( + getGapDLPredicate(headAtom.getDLPredicate()), + DLClauseHelper.getArguments(headAtom)); + + for (int i = 0; i < clause.getBodyLength(); ++i) + newBodyAtoms[i + offset] = clause.getBodyAtom(i); + + for (Atom atom: newHeadAtoms) { + newClause = DLClause.create(new Atom[] {atom}, newBodyAtoms); + trackingClauses.add(newClause); + } + + } +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java new file mode 100644 index 0000000..f898114 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java @@ -0,0 +1,103 @@ +package uk.ac.ox.cs.pagoda.tracking; + +import org.semanticweb.HermiT.model.*; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLOntology; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; +import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; +import uk.ac.ox.cs.pagoda.util.Namespace; + +import java.util.Collection; +import java.util.LinkedList; + +public class TrackingRuleEncoderWithoutGap extends TrackingRuleEncoder { + + public TrackingRuleEncoderWithoutGap(UpperDatalogProgram program, BasicQueryEngine store) { + super(program, store); + } + + @Override + protected String getEqualityRelatedRuleText() { + if (equalityRelatedRuleText != null) return equalityRelatedRuleText.replace("_tn", getTrackingPredicate("")); + + Collection equalityRelatedClauses = new LinkedList(); + Variable X = Variable.create("X"); + AtomicRole trackingSameAs = AtomicRole.create(Namespace.EQUALITY + "_tn"); + OWLOntology onto = program.getOntology(); + Atom[] headAtom, bodyAtom; + for (OWLClass cls: onto.getClassesInSignature(true)) { + String clsIRI = cls.getIRI().toString(); + unaryPredicates.add(clsIRI); + headAtom = new Atom[] {Atom.create(trackingSameAs, X, X)}; + bodyAtom = new Atom[] { + Atom.create(AtomicConcept.create(clsIRI + "_tn"), X), +// Atom.create(AtomicConcept.create(GapTupleIterator.getGapPredicate(clsIRI)), X1), + Atom.create(AtomicConcept.create(clsIRI), X)}; + equalityRelatedClauses.add(DLClause.create(headAtom, bodyAtom)); + } + Variable Y = Variable.create("Y"); + for (OWLObjectProperty prop: onto.getObjectPropertiesInSignature(true)) { + String propIRI = prop.getIRI().toString(); + binaryPredicates.add(propIRI); + AtomicRole trackingRole = AtomicRole.create(propIRI + "_tn"); +// AtomicRole gapRole = AtomicRole.create(GapTupleIterator.getGapPredicate(propIRI)); + AtomicRole role = AtomicRole.create(propIRI); + headAtom = new Atom[] {Atom.create(trackingSameAs, X, X)}; + bodyAtom = new Atom[] { + Atom.create(trackingRole, X, Y), +// Atom.create(gapRole, X1, Y), + Atom.create(role, X, Y)}; + equalityRelatedClauses.add(DLClause.create(headAtom, bodyAtom)); + + bodyAtom = new Atom[] { + Atom.create(trackingRole, Y, X), +// Atom.create(gapRole, Y, X1), + Atom.create(role, Y, X)}; + equalityRelatedClauses.add(DLClause.create(headAtom, bodyAtom)); + } + + equalityRelatedClauses.add( + DLClause.create( + new Atom[] {Atom.create(trackingSameAs, Y, X)}, + new Atom[] {Atom.create(trackingSameAs, X, Y)})); + + equalityRelatedRuleText = DLClauseHelper.toString(equalityRelatedClauses).toString(); + return equalityRelatedRuleText.replace("_tn", getTrackingPredicate("")); + } + + @Override + protected void encodingRule(DLClause clause) { + LinkedList newHeadAtoms = new LinkedList(); + newHeadAtoms.add(Atom.create(selected, getIndividual4GeneralRule(clause))); + + Atom headAtom; + for (Atom atom: clause.getBodyAtoms()) { + headAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newHeadAtoms.add(headAtom); + } + + DLClause newClause; + Atom[] newBodyAtoms = new Atom[clause.getBodyLength() + 1]; + headAtom = clause.getHeadAtom(0); + newBodyAtoms[0] = Atom.create( + getTrackingDLPredicate(headAtom.getDLPredicate()), + DLClauseHelper.getArguments(headAtom)); + +// newBodyAtoms[1] = Atom.create( +// getGapDLPredicate(headAtom.getDLPredicate()), +// DLClauseHelper.getArguments(headAtom)); + + for (int i = 0; i < clause.getBodyLength(); ++i) + newBodyAtoms[i + 1] = clause.getBodyAtom(i); + + for (Atom atom: newHeadAtoms) { + newClause = DLClause.create(new Atom[] {atom}, newBodyAtoms); + trackingClauses.add(newClause); + } + + } +} -- cgit v1.2.3