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. --- .../ac/ox/cs/pagoda/owl/EqualitiesEliminator.java | 136 ++++++ .../ac/ox/cs/pagoda/owl/MyHornAxiomVisitorEx.java | 493 +++++++++++++++++++++ .../java/uk/ac/ox/cs/pagoda/owl/OWLHelper.java | 471 ++++++++++++++++++++ .../java/uk/ac/ox/cs/pagoda/owl/QueryRoller.java | 227 ++++++++++ 4 files changed, 1327 insertions(+) create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/owl/EqualitiesEliminator.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/owl/MyHornAxiomVisitorEx.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/owl/OWLHelper.java create mode 100644 src/main/java/uk/ac/ox/cs/pagoda/owl/QueryRoller.java (limited to 'src/main/java/uk/ac/ox/cs/pagoda/owl') diff --git a/src/main/java/uk/ac/ox/cs/pagoda/owl/EqualitiesEliminator.java b/src/main/java/uk/ac/ox/cs/pagoda/owl/EqualitiesEliminator.java new file mode 100644 index 0000000..50865d4 --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/owl/EqualitiesEliminator.java @@ -0,0 +1,136 @@ +package uk.ac.ox.cs.pagoda.owl; + +import java.io.File; +import java.io.IOException; + +import org.semanticweb.HermiT.Configuration; +import org.semanticweb.HermiT.model.AnnotatedEquality; +import org.semanticweb.HermiT.model.AtLeast; +import org.semanticweb.HermiT.model.Atom; +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.HermiT.model.DLOntology; +import org.semanticweb.HermiT.model.DLPredicate; +import org.semanticweb.HermiT.model.Equality; +import org.semanticweb.HermiT.model.Inequality; +import org.semanticweb.HermiT.structural.OWLClausification; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAnnotationAxiom; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLDeclarationAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.OWLOntologyStorageException; +import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom; +import org.semanticweb.owlapi.model.UnknownOWLOntologyException; + +import uk.ac.ox.cs.pagoda.hermit.TermGraph; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class EqualitiesEliminator { + + String fileName; + OWLOntologyManager manager; + OWLOntology inputOntology, outputOntology = null; + + public EqualitiesEliminator(OWLOntology o) { + this.fileName = OWLHelper.getOntologyPath(o); + inputOntology = o; + manager = inputOntology.getOWLOntologyManager(); + } + + public void removeEqualities() throws OWLOntologyCreationException { + outputOntology = manager.createOntology(IRI.create(inputOntology.getOntologyID().getOntologyIRI().toString().replace(".owl", "-minus.owl"))); + try { + manager.setOntologyDocumentIRI(outputOntology, IRI.create(Utility.toFileIRI(getOutputFile().getCanonicalPath()))); + } catch (UnknownOWLOntologyException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + for (OWLOntology onto: inputOntology.getImportsClosure()) + for (OWLAxiom axiom: onto.getAxioms()) { + if (axiom instanceof OWLAnnotationAxiom + || axiom instanceof OWLDeclarationAxiom + || axiom instanceof OWLTransitiveObjectPropertyAxiom + || axiom instanceof OWLClassAssertionAxiom + || axiom instanceof OWLObjectPropertyAssertionAxiom + || axiom instanceof OWLDataPropertyAssertionAxiom + ) { + manager.removeAxiom(onto, axiom); + manager.addAxiom(outputOntology, axiom); + } + } + + Configuration conf = new Configuration(); + OWLClausification clausifier = new OWLClausification(conf); + DLOntology dlOntology = (DLOntology)clausifier.preprocessAndClausify(inputOntology, null)[1]; + + TermGraph termGraph; + for (DLClause dlClause: dlOntology.getDLClauses()) { + if (!containsEqualities(dlClause)) { + termGraph = new TermGraph(dlClause); + manager.addAxiom(outputOntology, OWLHelper.getOWLAxiom(inputOntology, termGraph.simplify())); + } + } + } + + private boolean containsEqualities(DLClause dlClause) { + DLPredicate predicate; + for (Atom headAtom: dlClause.getHeadAtoms()) { + predicate = headAtom.getDLPredicate(); + if (predicate instanceof Equality || predicate instanceof AnnotatedEquality || predicate instanceof Inequality) { + return true; + } + + if (predicate instanceof AtLeast) { + AtLeast atLeast = (AtLeast) predicate; + if (atLeast.getNumber() >= 2) + return true; + } + } + return false; + } + + public void save() { + if (outputOntology == null) + try { + removeEqualities(); + } catch (OWLOntologyCreationException e) { + e.printStackTrace(); + return ; + } + try { + manager.saveOntology(outputOntology, IRI.create(getOutputFile())); + } catch (OWLOntologyStorageException e) { + e.printStackTrace(); + } + } + + public File getOutputFile() { + return new File(fileName.replace(".owl", "-minus.owl")); + } + + public OWLOntology getOutputOntology() { + if (outputOntology == null) + try { + removeEqualities(); + } catch (OWLOntologyCreationException e) { + e.printStackTrace(); + } + return outputOntology; + } + + public static void main(String[] args) throws OWLOntologyCreationException, OWLOntologyStorageException { + args = ("/home/yzhou/ontologies/uobm/univ-bench-dl.owl").split("\\ "); + + EqualitiesEliminator eliminator = new EqualitiesEliminator(OWLHelper.loadOntology(args[0])); + eliminator.save(); + + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/owl/MyHornAxiomVisitorEx.java b/src/main/java/uk/ac/ox/cs/pagoda/owl/MyHornAxiomVisitorEx.java new file mode 100644 index 0000000..be22ded --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/owl/MyHornAxiomVisitorEx.java @@ -0,0 +1,493 @@ +package uk.ac.ox.cs.pagoda.owl; + +import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; +import org.semanticweb.owlapi.model.OWLAnnotationPropertyDomainAxiom; +import org.semanticweb.owlapi.model.OWLAnnotationPropertyRangeAxiom; +import org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLAxiomVisitorEx; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx; +import org.semanticweb.owlapi.model.OWLDataAllValuesFrom; +import org.semanticweb.owlapi.model.OWLDataExactCardinality; +import org.semanticweb.owlapi.model.OWLDataHasValue; +import org.semanticweb.owlapi.model.OWLDataMaxCardinality; +import org.semanticweb.owlapi.model.OWLDataMinCardinality; +import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom; +import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom; +import org.semanticweb.owlapi.model.OWLDataSomeValuesFrom; +import org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom; +import org.semanticweb.owlapi.model.OWLDeclarationAxiom; +import org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom; +import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom; +import org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom; +import org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom; +import org.semanticweb.owlapi.model.OWLDisjointUnionAxiom; +import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom; +import org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom; +import org.semanticweb.owlapi.model.OWLEquivalentObjectPropertiesAxiom; +import org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom; +import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLHasKeyAxiom; +import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLInverseObjectPropertiesAxiom; +import org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom; +import org.semanticweb.owlapi.model.OWLObjectComplementOf; +import org.semanticweb.owlapi.model.OWLObjectExactCardinality; +import org.semanticweb.owlapi.model.OWLObjectHasSelf; +import org.semanticweb.owlapi.model.OWLObjectHasValue; +import org.semanticweb.owlapi.model.OWLObjectIntersectionOf; +import org.semanticweb.owlapi.model.OWLObjectMaxCardinality; +import org.semanticweb.owlapi.model.OWLObjectMinCardinality; +import org.semanticweb.owlapi.model.OWLObjectOneOf; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom; +import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; +import org.semanticweb.owlapi.model.OWLObjectUnionOf; +import org.semanticweb.owlapi.model.OWLReflexiveObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLSameIndividualAxiom; +import org.semanticweb.owlapi.model.OWLSubAnnotationPropertyOfAxiom; +import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; +import org.semanticweb.owlapi.model.OWLSubDataPropertyOfAxiom; +import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom; +import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom; +import org.semanticweb.owlapi.model.OWLSymmetricObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom; +import org.semanticweb.owlapi.model.SWRLRule; + +public class MyHornAxiomVisitorEx implements OWLAxiomVisitorEx { + final PositiveAppearanceVisitorEx positive = new PositiveAppearanceVisitorEx(); + final NegativeAppearanceVisitorEx negative = new NegativeAppearanceVisitorEx(); + + @Override + public Boolean visit(OWLSubAnnotationPropertyOfAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLAnnotationPropertyDomainAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLAnnotationPropertyRangeAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLSubClassOfAxiom axiom) { + return Boolean.valueOf(axiom.getSubClass().accept(negative).booleanValue() + && axiom.getSuperClass().accept(positive).booleanValue()); + } + + @Override + public Boolean visit(OWLNegativeObjectPropertyAssertionAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLAsymmetricObjectPropertyAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLReflexiveObjectPropertyAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDisjointClassesAxiom axiom) { + for (OWLClassExpression c : axiom.getClassExpressions()) { + if (!c.accept(negative).booleanValue()) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataPropertyDomainAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLObjectPropertyDomainAxiom axiom) { + return axiom.getDomain().accept(positive); + } + + @Override + public Boolean visit(OWLEquivalentObjectPropertiesAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLNegativeDataPropertyAssertionAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDifferentIndividualsAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDisjointDataPropertiesAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDisjointObjectPropertiesAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectPropertyRangeAxiom axiom) { + return axiom.getRange().accept(positive); + } + + @Override + public Boolean visit(OWLObjectPropertyAssertionAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLFunctionalObjectPropertyAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLSubObjectPropertyOfAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDisjointUnionAxiom axiom) { + OWLClassExpression c1 = axiom.getOWLClass(); + if (!c1.accept(positive).booleanValue() || !c1.accept(negative).booleanValue()) { + return Boolean.FALSE; + } + for (OWLClassExpression c : axiom.getClassExpressions()) { + if (!c.accept(positive).booleanValue() || !c.accept(negative).booleanValue()) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDeclarationAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLAnnotationAssertionAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLSymmetricObjectPropertyAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataPropertyRangeAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLFunctionalDataPropertyAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLEquivalentDataPropertiesAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLClassAssertionAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLEquivalentClassesAxiom axiom) { + for (OWLClassExpression c : axiom.getClassExpressions()) { + if (!c.accept(positive).booleanValue() || !c.accept(negative).booleanValue()) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataPropertyAssertionAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLTransitiveObjectPropertyAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLIrreflexiveObjectPropertyAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLSubDataPropertyOfAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLInverseFunctionalObjectPropertyAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLSameIndividualAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLSubPropertyChainOfAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLInverseObjectPropertiesAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLHasKeyAxiom axiom) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDatatypeDefinitionAxiom axiom) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(SWRLRule rule) { + return Boolean.FALSE; + } + + private class PositiveAppearanceVisitorEx implements + OWLClassExpressionVisitorEx { + public PositiveAppearanceVisitorEx() { + } + + @Override + public Boolean visit(OWLClass ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLObjectIntersectionOf ce) { + for (OWLClassExpression c : ce.getOperands()) { + if (c.accept(this).equals(Boolean.FALSE)) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLObjectUnionOf ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectComplementOf ce) { + return ce.getOperand().accept(negative); + } + + @Override + public Boolean visit(OWLObjectSomeValuesFrom ce) { + return ce.getFiller().accept(this); + } + + @Override + public Boolean visit(OWLObjectAllValuesFrom ce) { + return ce.getFiller().accept(this); + } + + @Override + public Boolean visit(OWLObjectHasValue ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectMinCardinality ce) { + return ce.getFiller().accept(this); + } + + @Override + public Boolean visit(OWLObjectExactCardinality ce) { + return Boolean.valueOf(ce.getCardinality() <= 1 + && ce.getFiller().accept(this).booleanValue() + && ce.getFiller().accept(negative).booleanValue()); + } + + @Override + public Boolean visit(OWLObjectMaxCardinality ce) { + return Boolean.valueOf(ce.getCardinality() <= 1 + && ce.getFiller().accept(negative).booleanValue()); + } + + @Override + public Boolean visit(OWLObjectHasSelf ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectOneOf ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDataSomeValuesFrom ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataAllValuesFrom ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataHasValue ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataMinCardinality ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataExactCardinality ce) { + return ce.getCardinality() <= 1; + } + + @Override + public Boolean visit(OWLDataMaxCardinality ce) { + return ce.getCardinality() <= 1; + } + } + + private class NegativeAppearanceVisitorEx implements + OWLClassExpressionVisitorEx { + public NegativeAppearanceVisitorEx() { + } + + @Override + public Boolean visit(OWLClass ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLObjectIntersectionOf ce) { + for (OWLClassExpression c : ce.getOperands()) { + if (c.accept(this).equals(Boolean.FALSE)) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLObjectUnionOf ce) { + for (OWLClassExpression c : ce.getOperands()) { + if (c.accept(this).equals(Boolean.FALSE)) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLObjectComplementOf ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectSomeValuesFrom ce) { + return ce.getFiller().accept(this); + } + + @Override + public Boolean visit(OWLObjectAllValuesFrom ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectHasValue ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectMinCardinality ce) { + return Boolean.valueOf(ce.getCardinality() <= 1 + && ce.getFiller().accept(this).booleanValue()); + } + + @Override + public Boolean visit(OWLObjectExactCardinality ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectMaxCardinality ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectHasSelf ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLObjectOneOf ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDataSomeValuesFrom ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataAllValuesFrom ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDataHasValue ce) { + return Boolean.TRUE; + } + + @Override + public Boolean visit(OWLDataMinCardinality ce) { + return ce.getCardinality() <= 1; + } + + @Override + public Boolean visit(OWLDataExactCardinality ce) { + return Boolean.FALSE; + } + + @Override + public Boolean visit(OWLDataMaxCardinality ce) { + return Boolean.FALSE; + } + } +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/owl/OWLHelper.java b/src/main/java/uk/ac/ox/cs/pagoda/owl/OWLHelper.java new file mode 100644 index 0000000..e7be96b --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/owl/OWLHelper.java @@ -0,0 +1,471 @@ +package uk.ac.ox.cs.pagoda.owl; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.semanticweb.HermiT.model.Atom; +import org.semanticweb.HermiT.model.AtomicConcept; +import org.semanticweb.HermiT.model.AtomicRole; +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.HermiT.model.Individual; +import org.semanticweb.karma2.profile.ELHOProfile; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.AddImport; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; +import org.semanticweb.owlapi.model.OWLAnnotationSubject; +import org.semanticweb.owlapi.model.OWLAnnotationValue; +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.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLDatatype; +import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom; +import org.semanticweb.owlapi.model.OWLInverseObjectPropertiesAxiom; +import org.semanticweb.owlapi.model.OWLObjectMaxCardinality; +import org.semanticweb.owlapi.model.OWLObjectMinCardinality; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; +import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom; +import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.OWLOntologyStorageException; +import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; +import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom; +import org.semanticweb.owlapi.model.UnknownOWLOntologyException; +import org.semanticweb.owlapi.profiles.OWL2RLProfile; +import org.semanticweb.owlapi.profiles.OWLProfileReport; +import org.semanticweb.owlapi.profiles.OWLProfileViolation; +import org.semanticweb.owlapi.profiles.violations.UseOfUndeclaredClass; +import org.semanticweb.owlapi.profiles.violations.UseOfUndeclaredDataProperty; +import org.semanticweb.owlapi.profiles.violations.UseOfUndeclaredObjectProperty; +import org.semanticweb.owlapi.util.OWLOntologyMerger; + +import uk.ac.ox.cs.pagoda.approx.Clause; +import uk.ac.ox.cs.pagoda.approx.Clausifier; +import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class OWLHelper { + + public static OWLOntology loadOntology(OWLOntologyManager manager, String fileName) { + // TODO to be uncommented to set silent missing imports ... +// manager.setSilentMissingImportsHandling(true); + OWLOntology ontology = null; + File file = new File(fileName); + try { + ontology = manager.loadOntologyFromOntologyDocument(file); + } catch (OWLOntologyCreationException e) { + e.printStackTrace(); + } catch (UnknownOWLOntologyException e) { + e.printStackTrace(); + } + return ontology; + } + + public static OWLOntology loadOntology(String fileName) { + return loadOntology(OWLManager.createOWLOntologyManager(), fileName); + + } + + public static OWLOntology getImportedOntology(OWLOntology tbox, String... dataFiles) throws OWLOntologyCreationException, OWLOntologyStorageException, IOException { + if (dataFiles == null || dataFiles.length == 0 || dataFiles.length == 1 && (dataFiles[0] == null || dataFiles[0].isEmpty())) return tbox; + + OWLOntologyManager manager = tbox.getOWLOntologyManager(); + OWLOntology importedOntology = manager.createOntology(); + + for (String dataFile: dataFiles) { + File data = new File(dataFile); + if (!data.exists()) + Utility.logError(dataFile.toString() + " doesn't exist."); + +// importDeclaration(manager, importedOntology, tbox.getOntologyID().getOntologyIRI().toString()); + importDeclaration(manager, importedOntology, Utility.toFileIRI(getOntologyPath(tbox))); + if (data.isDirectory()) { + for (File file: data.listFiles()) { + importDeclaration(manager, importedOntology, Utility.toFileIRI(file.getCanonicalPath())); + } + } + else { + importDeclaration(manager, importedOntology, Utility.toFileIRI(new File(dataFile).getCanonicalPath())); + } + } + + String path = "./imported.owl"; + FileOutputStream out = new FileOutputStream(path); + manager.saveOntology(importedOntology, out); + out.close(); + + System.out.println("In the closure: " + importedOntology.getImportsClosure().size()); + for (OWLOntology onto: importedOntology.getImportsClosure()) { + System.out.println(onto.getOntologyID().toString()); + } + manager.removeOntology(importedOntology); + manager.removeOntology(tbox); + System.out.println("Removed imported and tbox ontology."); + OWLOntologyManager newManager = OWLManager.createOWLOntologyManager(); + importedOntology = loadOntology(newManager, path); + newManager.setOntologyDocumentIRI(importedOntology, IRI.create(Utility.toFileIRI(new File(path).getCanonicalPath()))); + System.out.println("In the closure: " + importedOntology.getImportsClosure().size()); + for (OWLOntology onto: importedOntology.getImportsClosure()) { + System.out.println(onto.getOntologyID().toString()); + } + return importedOntology; + } + + public static OWLOntology getMergedOntology(String ontologyFile, String dataFile) throws OWLOntologyCreationException, IOException, OWLOntologyStorageException { + OWLOntology tbox = loadOntology(ontologyFile); + OWLOntologyManager manager = tbox.getOWLOntologyManager(); + OWLOntology mergedOntology = new OWLOntologyMerger(manager).createMergedOntology(manager, null); + for (OWLOntology o: manager.getOntologies()) + if (o != mergedOntology) { + for (OWLAxiom axiom: o.getAxioms()) + manager.addAxiom(mergedOntology, axiom); + } + Utility.logDebug("loaded and merged the ontology and the dataset: "); + return mergedOntology; + } + + public static boolean removeAnnotations(OWLOntology inputOntology) { + OWLOntologyManager manager = inputOntology.getOWLOntologyManager(); + boolean updated = false; + for (OWLAxiom axiom: inputOntology.getAxioms()) + if (axiom.toString().contains("Annotation")) { + manager.removeAxiom(inputOntology, axiom); + updated = true; + } + return updated; + } + + public static boolean correctDataTypeRangeAxioms(OWLOntology inputOntology) { + OWLOntologyManager manager = inputOntology.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + boolean updated = false; + OWLClass cls; + OWLDatatype datatype; + for (OWLOntology onto: inputOntology.getImportsClosure()) + for (OWLAxiom axiom: onto.getAxioms()) + if (axiom instanceof OWLObjectPropertyRangeAxiom) { + OWLObjectPropertyRangeAxiom a = (OWLObjectPropertyRangeAxiom) axiom; + if (a.getRange() instanceof OWLClass && a.getProperty() instanceof OWLObjectProperty && (cls = (OWLClass) a.getRange()).toString().contains("datatype")) { + manager.removeAxiom(onto, axiom); + manager.removeAxiom(onto, factory.getOWLDeclarationAxiom(cls)); + + datatype = factory.getOWLDatatype(cls.getIRI()); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(datatype)); + manager.addAxiom(onto, factory.getOWLDataPropertyRangeAxiom( + factory.getOWLDataProperty(((OWLObjectProperty) a.getProperty()).getIRI()), + datatype)); + } + } + + return updated; + } + + private static void importDeclaration(OWLOntologyManager manager, OWLOntology ontology, String location) { + AddImport change = new AddImport(ontology, manager.getOWLDataFactory().getOWLImportsDeclaration(IRI.create(location))); + manager.applyChange(change); + } + + public static OWLClassExpression getSimplifiedDisjunction(OWLDataFactory factory, Set set) { + if (set.size() == 0) + return factory.getOWLNothing(); + else if (set.size() == 1) + return set.iterator().next(); + else return factory.getOWLObjectUnionOf(set); + } + + public static OWLClassExpression getSimplifiedConjunction(OWLDataFactory factory, Set set) { + if (set.size() == 0) + return factory.getOWLThing(); + else if (set.size() == 1) + return set.iterator().next(); + else return factory.getOWLObjectIntersectionOf(set); + } + + public static OWLAxiom getOWLAxiom(OWLOntology ontology, DLClause dlClause) { + OWLAxiom owlAxiom; + OWLDataFactory factory = ontology.getOWLOntologyManager().getOWLDataFactory(); + + dlClause = DLClauseHelper.replaceOtherBottom(dlClause); + + if (dlClause.isAtomicConceptInclusion()) { + OWLClass subClass = factory.getOWLClass(IRI.create(((AtomicConcept) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + OWLClass superClass = factory.getOWLClass(IRI.create(((AtomicConcept) dlClause.getHeadAtom(0).getDLPredicate()).getIRI())); + return factory.getOWLSubClassOfAxiom(subClass, superClass); + } + else if (dlClause.isAtomicRoleInclusion()) { + OWLObjectProperty subProp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + OWLObjectProperty superProp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getHeadAtom(0).getDLPredicate()).getIRI())); + return factory.getOWLSubObjectPropertyOfAxiom(subProp, superProp); + } + else if (dlClause.isAtomicRoleInverseInclusion()) { + OWLObjectProperty subProp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + OWLObjectProperty superProp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getHeadAtom(0).getDLPredicate()).getIRI())); + return factory.getOWLSubObjectPropertyOfAxiom(subProp, superProp.getInverseProperty()); + } + else if (dlClause.isFunctionalityAxiom()) { + OWLObjectProperty prop = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + return factory.getOWLFunctionalObjectPropertyAxiom(prop); + } + else if (dlClause.isInverseFunctionalityAxiom()) { + OWLObjectProperty prop = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + return factory.getOWLInverseFunctionalObjectPropertyAxiom(prop); + } + else if (DLClauseHelper.isFunctionalDataPropertyAxioms(dlClause)) { + OWLDataProperty prop = factory.getOWLDataProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + return factory.getOWLFunctionalDataPropertyAxiom(prop); + } + int flag; + if ((flag = DLClauseHelper.isRoleCompositionAxioms(dlClause)) >= 0) { + OWLObjectPropertyExpression R = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(0).getDLPredicate()).getIRI())); + OWLObjectPropertyExpression S = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getBodyAtom(1).getDLPredicate()).getIRI())); + OWLObjectPropertyExpression T = factory.getOWLObjectProperty(IRI.create(((AtomicRole) dlClause.getHeadAtom(0).getDLPredicate()).getIRI())); + + if (flag % 2 != 0) T = T.getInverseProperty(); flag /= 2; + if (flag % 2 != 0) S = S.getInverseProperty(); flag /= 2; + if (flag % 2 != 0) R = R.getInverseProperty(); + if (R.equals(S) && S.equals(T)) + return factory.getOWLTransitiveObjectPropertyAxiom(R); + else { + List list = new LinkedList(); + list.add(R); list.add(S); + return factory.getOWLSubPropertyChainOfAxiom(list, T); + } + } + else { + Clausifier clausifier = Clausifier.getInstance(ontology); +// if (dlClause.isGeneralConceptInclusion()) { + + Clause myClause = new Clause(clausifier, dlClause); + owlAxiom = getSimplifiedGCI(factory, myClause.getSubClasses(), myClause.getSuperClasses()); + + + if (owlAxiom == null) + Utility.logError("more kinds of DLClause: " + dlClause.toString()); + + return owlAxiom; + } + + } + + private static OWLAxiom getSimplifiedGCI(OWLDataFactory factory, Set subClasses, Set superClasses) { + if (superClasses.size() > 1) { + Set toRemoved = new HashSet(); + for (OWLClassExpression cls: new HashSet(superClasses)) + if (cls instanceof OWLObjectMaxCardinality) { + OWLObjectMaxCardinality maxCard = (OWLObjectMaxCardinality) cls; + OWLObjectMinCardinality minCard = factory.getOWLObjectMinCardinality(maxCard.getCardinality() + 1, maxCard.getProperty()); + for (OWLClassExpression exp: subClasses) + if (isSubsumedByMinCard(exp, minCard)) + toRemoved.add(exp); + subClasses.add(minCard); + superClasses.remove(maxCard); + } + subClasses.removeAll(toRemoved); + } + + return factory.getOWLSubClassOfAxiom(getSimplifiedConjunction(factory, subClasses), getSimplifiedDisjunction(factory, superClasses)); + } + + public static OWLAxiom getABoxAssertion(OWLDataFactory factory, Atom atom) { + if (atom.getDLPredicate().toString().contains("internal:nom#")) + return null; + try { + if (atom.getArity() == 1) + return factory.getOWLClassAssertionAxiom( + factory.getOWLClass(IRI.create(((AtomicConcept) atom.getDLPredicate()).getIRI())), + factory.getOWLNamedIndividual(IRI.create(((Individual) atom.getArgument(0)).getIRI())) + ); + else + return factory.getOWLObjectPropertyAssertionAxiom( + factory.getOWLObjectProperty(IRI.create(((AtomicRole) atom.getDLPredicate()).getIRI())), + factory.getOWLNamedIndividual(IRI.create(((Individual) atom.getArgument(0)).getIRI())), + factory.getOWLNamedIndividual(IRI.create(((Individual) atom.getArgument(1)).getIRI())) + ); + } catch (Exception e) { + return null; + } + } + + private static boolean isSubsumedByMinCard(OWLClassExpression exp, OWLObjectMinCardinality minCard) { + if (exp instanceof OWLObjectSomeValuesFrom) { + OWLObjectSomeValuesFrom someValuesFrom = (OWLObjectSomeValuesFrom) exp; + return minCard.getCardinality() > 0 && + minCard.getProperty().equals(someValuesFrom.getProperty()) && + minCard.getFiller().equals(someValuesFrom.getFiller()); + } + + if (exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard2 = (OWLObjectMinCardinality) exp; + return minCard.getCardinality() >= minCard2.getCardinality() && + minCard.getProperty().equals(minCard2.getProperty()) && + minCard.getFiller().equals(minCard2.getFiller()); + } + return false; + } + + public static String removeAngles(String quotedString) { + if (quotedString.startsWith("<") && quotedString.endsWith(">")) + return quotedString.substring(1, quotedString.length() - 1); + else if (quotedString.contains(":")) + return quotedString; + else + Utility.logError("paused here due to the action to remove Angle in an unquotedString"); + return quotedString; + } + + public static String addAngles(String name) { + StringBuilder sb = new StringBuilder(); + sb.append("<").append(name).append(">"); + return sb.toString(); + } + + public static boolean isContradiction(OWLDataFactory factory, OWLAxiom axiom) { + if (!(axiom instanceof OWLSubClassOfAxiom)) + return false; + OWLSubClassOfAxiom subClassAxiom = (OWLSubClassOfAxiom) axiom; + return subClassAxiom.getSubClass().equals(factory.getOWLThing()) && subClassAxiom.getSuperClass().equals(factory.getOWLNothing()); + } + + static MyHornAxiomVisitorEx visitor = new MyHornAxiomVisitorEx(); + + public static boolean isDisjunctiveAxiom(OWLAxiom axiom) { + boolean isHorn = false; + if (axiom instanceof OWLSubClassOfAxiom) + isHorn = visitor.visit((OWLSubClassOfAxiom) axiom); + else if (axiom instanceof OWLSubObjectPropertyOfAxiom) + isHorn = visitor.visit((OWLSubObjectPropertyOfAxiom) axiom); + else if (axiom instanceof OWLInverseObjectPropertiesAxiom) + isHorn = visitor.visit((OWLInverseObjectPropertiesAxiom) axiom); + else if (axiom instanceof OWLObjectPropertyDomainAxiom) + isHorn = visitor.visit((OWLObjectPropertyDomainAxiom) axiom); + else if (axiom instanceof OWLFunctionalObjectPropertyAxiom) + isHorn = visitor.visit((OWLFunctionalObjectPropertyAxiom) axiom); + else if (axiom instanceof OWLInverseFunctionalObjectPropertyAxiom) + isHorn = visitor.visit((OWLInverseFunctionalObjectPropertyAxiom) axiom); + else { + Utility.logError(axiom); + } + + if (isHorn) + Utility.logDebug(axiom.toString() + " is NOT a disjunctive axiom."); + else + Utility.logDebug(axiom.toString() + " is a disjunctive axiom."); + + return !isHorn; + } + + public boolean isELHO(OWLOntology ontology) { + Utility.logDebug("checking whether ELHO ... "); + ELHOProfile profile = new ELHOProfile(); + OWLProfileReport report = profile.checkOntology(ontology); + for (OWLProfileViolation v: report.getViolations()) + if (v instanceof UseOfUndeclaredClass || + v instanceof UseOfUndeclaredObjectProperty || + v instanceof UseOfUndeclaredDataProperty); + else { + Utility.logDebug(v.toString(), "not ELHO"); + return false; + } + return true; + } + + public static void identifyAndChangeAnnotationAssertions(OWLOntology ontology) { + OWLOntologyManager manager = ontology.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + + Set objectProperties = new HashSet(); + for (OWLOntology onto: ontology.getImportsClosure()) { + for (OWLObjectProperty prop: onto.getObjectPropertiesInSignature()) { + objectProperties.add(prop.toStringID()); + } + } + + Set toRemove = new HashSet(); + Set toAdd = new HashSet(); + OWLAnnotationAssertionAxiom assertion; + OWLAnnotationSubject anSub; + OWLAnnotationValue anValue; + + OWLObjectPropertyAssertionAxiom newAssertion; + String property; + OWLIndividual sub, obj; + + for (OWLOntology onto: ontology.getImportsClosure()) { + for (OWLAxiom axiom: onto.getAxioms()) + if (axiom instanceof OWLAnnotationAssertionAxiom) { + assertion = (OWLAnnotationAssertionAxiom) axiom; + if (objectProperties.contains(property = assertion.getProperty().toStringID())) { + if ((anSub = assertion.getSubject()) instanceof OWLAnonymousIndividual) + sub = (OWLAnonymousIndividual) anSub; + else + sub = factory.getOWLNamedIndividual((IRI) anSub); + + if ((anValue = assertion.getValue()) instanceof OWLAnonymousIndividual) + obj = (OWLAnonymousIndividual) anValue; + else if (anValue instanceof IRI) + obj = factory.getOWLNamedIndividual((IRI) anValue); + else + continue; + + newAssertion = factory.getOWLObjectPropertyAssertionAxiom( + factory.getOWLObjectProperty(IRI.create(property)), sub, obj); + toRemove.add(assertion); + toAdd.add(newAssertion); + } + } + manager.removeAxioms(onto, toRemove); + manager.addAxioms(onto, toAdd); + } + } + + public static String getOntologyPath(OWLOntology o) { + return getDocumentIRI(o).substring(5); + } + + public static String getDocumentIRI(OWLOntology o) { + return o.getOWLOntologyManager().getOntologyDocumentIRI(o).toString(); + } + + public static boolean isInOWL2RL(OWLOntology o) { + OWL2RLProfile profile = new OWL2RLProfile(); + return profile.checkOntology(o).isInProfile(); + } + + public static boolean isInELHO(OWLOntology o) { + ELHOProfile profile = new ELHOProfile(); + return profile.checkOntology(o).isInProfile(); + } + + public static String getOriginalMarkProgram(OWLOntology ontology) { + String originalConcept = Namespace.PAGODA_ORIGINAL; + StringBuilder sb = new StringBuilder(); + for (OWLDataProperty p: ontology.getDataPropertiesInSignature()) { + sb.append("<").append(originalConcept).append(">(?x) :- <").append(p.toStringID()).append(">(?x,?y) .\n"); + sb.append("<").append(originalConcept).append(">(?y) :- <").append(p.toStringID()).append(">(?x,?y) .\n"); + } + for (OWLObjectProperty p: ontology.getObjectPropertiesInSignature()) { + sb.append("<").append(originalConcept).append(">(?x) :- <").append(p.toStringID()).append(">(?x,?y) .\n"); + sb.append("<").append(originalConcept).append(">(?y) :- <").append(p.toStringID()).append(">(?x,?y) .\n"); + } + for (OWLClass c: ontology.getClassesInSignature()) + sb.append("<").append(originalConcept).append(">(?x) :- <").append(c.toStringID()).append(">(?x) .\n"); + return sb.toString(); + } + +} diff --git a/src/main/java/uk/ac/ox/cs/pagoda/owl/QueryRoller.java b/src/main/java/uk/ac/ox/cs/pagoda/owl/QueryRoller.java new file mode 100644 index 0000000..f486bbf --- /dev/null +++ b/src/main/java/uk/ac/ox/cs/pagoda/owl/QueryRoller.java @@ -0,0 +1,227 @@ +package uk.ac.ox.cs.pagoda.owl; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import org.semanticweb.HermiT.model.AnnotatedEquality; +import org.semanticweb.HermiT.model.Atom; +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.HermiT.model.Equality; +import org.semanticweb.HermiT.model.Inequality; +import org.semanticweb.HermiT.model.Term; +import org.semanticweb.HermiT.model.Variable; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLObjectHasValue; +import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; +import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; + +import uk.ac.ox.cs.pagoda.summary.Summary; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class QueryRoller { + + private OWLDataFactory factory; + + protected Map> edges, concepts; + + public QueryRoller(OWLDataFactory factory) { + this.factory = factory; + } + + private OWLClassExpression getOWLClassExpression(String u, String father, Set visited) { + visited.add(u); + String[] temp; + Set exps = new HashSet(); + OWLObjectPropertyExpression prop; + if (concepts.containsKey(u)) + for (String concept: concepts.get(u)) { + exps.add(factory.getOWLClass(IRI.create(concept))); + } + + if (edges.containsKey(u)) + for (String pair: edges.get(u)) { + temp = pair.split(" "); + if (temp[0].startsWith("-")) + prop = factory.getOWLObjectInverseOf(factory.getOWLObjectProperty(IRI.create(temp[0].substring(1)))); + else + prop = factory.getOWLObjectProperty(IRI.create(temp[0])); + + if (temp[1].startsWith("@")) + exps.add(factory.getOWLObjectHasValue(prop, factory.getOWLNamedIndividual(IRI.create(OWLHelper.removeAngles(temp[1].substring(1)))))); + else if (visited.contains(temp[1])) { + if (father != null && father.equals(temp[1])) + continue; + if (!u.equals(temp[1])) { + Utility.logError("The query cannot be rolled up!"); + return null; + } + exps.add(factory.getOWLObjectHasSelf(prop)); + } + else + exps.add(factory.getOWLObjectSomeValuesFrom(prop, getOWLClassExpression(temp[1], u, visited))); + } + + if (exps.size() == 0) + return factory.getOWLThing(); + if (exps.size() == 1) + return exps.iterator().next(); + else + return factory.getOWLObjectIntersectionOf(exps); + } + + String currentMainVariable; + + public OWLClassExpression rollUp(DLClause query, String var) { + currentMainVariable = var; + query = removeSameAs(query); + edges = new HashMap>(); + concepts = new HashMap>(); + String arg1, arg2, predicate; + DLPredicate dlPredicate; + Term t1, t2; + for (Atom atom: query.getBodyAtoms()) { + dlPredicate = atom.getDLPredicate(); + if (dlPredicate instanceof AtomicRole) { + arg1 = (t1 = atom.getArgument(0)).toString(); + arg2 = (t2 = atom.getArgument(1)).toString(); + predicate = ((AtomicRole) dlPredicate).getIRI(); + if (!predicate.equals(Namespace.RDF_TYPE)) { + if (t1 instanceof Variable) + if (t2 instanceof Variable) { + addEntry(edges, arg1, predicate + " " + arg2); + addEntry(edges, arg2, "-" + predicate + " " + arg1); + } + else + addEntry(edges, arg1, predicate + " @" + arg2); + else + addEntry(edges, arg2, "-" + predicate + " @" + arg1); + } + else { + if (t2 instanceof Variable) return null; + addEntry(concepts, arg1, arg2); + } + } + else + addEntry(concepts, atom.getArgument(0).toString(), ((AtomicConcept) dlPredicate).getIRI()); + } + + return getOWLClassExpression(var, null, new HashSet()); + } + + private DLClause removeSameAs(DLClause query) { + int equalityStatement = 0; + + Map ufs = new HashMap(); + for (Atom atom: query.getBodyAtoms()) + if (isEquality(atom.getDLPredicate())) { + ++equalityStatement; + merge(ufs, atom.getArgument(0), atom.getArgument(1)); + } + + if (equalityStatement == 0) return query; + + Atom[] bodyAtoms = new Atom[query.getBodyLength() - equalityStatement]; + int index = 0; + for (Atom atom: query.getBodyAtoms()) + if (!isEquality(atom.getDLPredicate())) { + if (atom.getArity() == 1) + bodyAtoms[index++] = Atom.create(atom.getDLPredicate(), find(ufs, atom.getArgument(0))); + else + bodyAtoms[index++] = Atom.create(atom.getDLPredicate(), find(ufs, atom.getArgument(0)), find (ufs, atom.getArgument(1))); + } + + return DLClause.create(query.getHeadAtoms(), bodyAtoms); + } + + private boolean isEquality(DLPredicate p) { + return p instanceof Equality || p instanceof AnnotatedEquality || p instanceof Inequality + || p.toString().equals(Namespace.EQUALITY_QUOTED) + || p.toString().equals(Namespace.EQUALITY_ABBR); + } + + private Term find(Map ufs, Term u) { + Term v = u, w; + while ((w = ufs.get(v)) != null) v = w; + while ((w = ufs.get(u)) != null) { + ufs.put(u, v); + u = w; + } + return v; + } + + private void merge(Map ufs, Term u, Term v) { + u = find(ufs, u); + v = find(ufs, v); + if (compare(u, v) <= 0) ufs.put(v, u); + else ufs.put(u, v); + } + + private int compare(Term u, Term v) { + int ret = rank(u) - rank(v); + if (ret != 0) return ret; + else + return u.toString().compareTo(v.toString()); + } + + private int rank(Term u) { + if (u instanceof Variable) { + Variable v = (Variable) u; + if (v.getName().equals(currentMainVariable)) + return 0; + else + return 2; + } + return 1; + } + + private void addEntry(Map> map, String key, String value) { + LinkedList list; + if ((list = map.get(key)) == null) { + list = new LinkedList(); + map.put(key, list); + } + list.add(value); + } + + @Deprecated + public OWLClassExpression summarise(Summary sum, OWLClassExpression exp) { + if (exp == null) return null; + + Set exps = exp.asConjunctSet(); + if (exps.size() == 1) { + OWLClassExpression tempExp = exps.iterator().next(); + + // TODO reference: getOWLClassExpression(String) + + if (tempExp instanceof OWLObjectHasValue) { + OWLObjectHasValue hasValue = (OWLObjectHasValue) tempExp; + OWLNamedIndividual individual = sum.getRepresentativeIndividual(hasValue.getValue().toStringID()); + return factory.getOWLObjectHasValue(hasValue.getProperty(), individual); + + } + if (tempExp instanceof OWLObjectSomeValuesFrom) { + OWLObjectSomeValuesFrom someValuesFrom = (OWLObjectSomeValuesFrom) tempExp; + return factory.getOWLObjectSomeValuesFrom(someValuesFrom.getProperty(), summarise(sum, someValuesFrom.getFiller())); + } + return tempExp; + } + + Set newExps = new HashSet(); + for (OWLClassExpression clsExp: exps) + newExps.add(summarise(sum, clsExp)); + + return factory.getOWLObjectIntersectionOf(newExps); + } + + +} -- cgit v1.2.3