From 9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8 Mon Sep 17 00:00:00 2001 From: yzhou Date: Tue, 21 Apr 2015 10:34:27 +0100 Subject: initial version --- src/uk/ac/ox/cs/pagoda/approx/Clause.java | 722 ++++++++++++++++++++++ src/uk/ac/ox/cs/pagoda/approx/Clausifier.java | 37 ++ src/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java | 18 + src/uk/ac/ox/cs/pagoda/approx/RLOntology.java | 190 ++++++ src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java | 608 ++++++++++++++++++ 5 files changed, 1575 insertions(+) create mode 100644 src/uk/ac/ox/cs/pagoda/approx/Clause.java create mode 100644 src/uk/ac/ox/cs/pagoda/approx/Clausifier.java create mode 100644 src/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java create mode 100644 src/uk/ac/ox/cs/pagoda/approx/RLOntology.java create mode 100644 src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java (limited to 'src/uk/ac/ox/cs/pagoda/approx') diff --git a/src/uk/ac/ox/cs/pagoda/approx/Clause.java b/src/uk/ac/ox/cs/pagoda/approx/Clause.java new file mode 100644 index 0000000..9c3f5d0 --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/approx/Clause.java @@ -0,0 +1,722 @@ +package uk.ac.ox.cs.pagoda.approx; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.semanticweb.HermiT.model.*; +import org.semanticweb.owlapi.model.*; + +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 Clause { + + Set headAtoms; + Set bodyAtoms; + + Set dataProperties; + OWLDataFactory factory; + // OWLClass top = null; + + private Set superClasses = new HashSet(); + private Set subClasses = new HashSet(); + + public Clause(Clausifier clausifier, DLClause clause) { + this.dataProperties = clausifier.dataProperties; + this.factory = clausifier.factory; + // top = ontology.top; + + headAtoms = Utility.toSet(clause.getHeadAtoms()); + bodyAtoms = Utility.toSet(clause.getBodyAtoms()); + + rollingUp(); + } + + private static final Variable X = Variable.create("X"); + + private void rollingUp() { + Map> varCliques = new HashMap>(); + + for (Iterator iter = bodyAtoms.iterator(); iter.hasNext();) { + Atom atom = iter.next(); + if (atom.getDLPredicate() instanceof Inequality) + if (atom.getArgument(0) instanceof Variable + && atom.getArgument(1) instanceof Variable) { + Variable var1 = atom.getArgumentVariable(0), var2 = atom + .getArgumentVariable(1); + Set rep; + if ((rep = varCliques.get(var1)) == null) + if ((rep = varCliques.get(var2)) == null) + rep = new HashSet(); + rep.add(var1); + rep.add(var2); + varCliques.put(var1, rep); + varCliques.put(var2, rep); + iter.remove(); + } + } + + eliminateEquality(); + + Map var2atom = new HashMap(); + + getVariableOccurrence(var2atom, headAtoms); + getVariableOccurrence(var2atom, bodyAtoms); + + DLPredicate predicate; + Variable W = null; + + Map nom2iri = new HashMap(); + Map nom2datatype = new HashMap(); + + for (Iterator iter = headAtoms.iterator(); iter.hasNext();) { + Atom tAtom = iter.next(); + predicate = tAtom.getDLPredicate(); + if (predicate instanceof AtomicNegationDataRange) { + AtomicNegationDataRange andr = (AtomicNegationDataRange) predicate; + AtomicDataRange adr = andr.getNegatedDataRange(); + if (adr instanceof ConstantEnumeration) { + ConstantEnumeration e = (ConstantEnumeration) adr; + if (e.getNumberOfConstants() == 1) { + Variable v = tAtom.getArgumentVariable(0); + nom2datatype.put(v, e.getConstant(0)); + iter.remove(); + continue; + } + } + } + } + + for (Atom atom : bodyAtoms) { + predicate = atom.getDLPredicate(); + if (predicate instanceof AtomicConcept) { + AtomicConcept concept = (AtomicConcept) predicate; + Variable v = atom.getArgumentVariable(0); + if (v == X) + subClasses.add(factory.getOWLClass(IRI.create(concept + .getIRI()))); + else if (predicate.toString().startsWith(" set = varCliques.get(W); + if (set != null) + number = set.size(); + + if (var2atom.containsKey(W)) { + Atom tAtom = var2atom.get(W); + DLPredicate tPredicate = tAtom.getDLPredicate(); + if (tPredicate instanceof AtomicConcept) { + concept = (AtomicConcept) tPredicate; + clsExp = factory.getOWLClass(IRI.create(concept + .getIRI())); + if (headAtoms.contains(tAtom)) { + superClasses.add(factory.getOWLObjectAllValuesFrom( + roleExp, clsExp)); + subClasses.add(factory.getOWLObjectSomeValuesFrom( + roleExp, factory.getOWLThing())); + headAtoms.remove(tAtom); + } else { + if (number == 1) + subClasses.add(factory + .getOWLObjectSomeValuesFrom(roleExp, + clsExp)); + else + subClasses.add(factory + .getOWLObjectMinCardinality(number, + roleExp, clsExp)); + } + } else { + Utility.logDebug(tAtom, "strange ... -___-|||"); + } + } else { + if (number == 1) + subClasses.add(factory.getOWLObjectSomeValuesFrom( + roleExp, factory.getOWLThing())); + else + subClasses.add(factory.getOWLObjectMinCardinality( + number, roleExp)); + } + } + } + + OWLObjectPropertyExpression objExp; + for (Atom atom : headAtoms) { + predicate = atom.getDLPredicate(); + if (predicate instanceof AtomicConcept) { + if (atom.getArgumentVariable(0) == X) + superClasses + .add(getClassExpression((AtomicConcept) predicate)); + } else if (predicate instanceof AtomicRole) { + if (!dataProperties.contains(((AtomicRole) predicate).getIRI())) { + objExp = factory.getOWLObjectProperty(IRI + .create(((AtomicRole) predicate).getIRI())); + Term V = atom.getArgument(1); + if (V == X) { + objExp = factory.getOWLObjectInverseOf(objExp); + V = atom.getArgument(0); + } + + if (V == X) + superClasses.add(factory.getOWLObjectHasSelf(objExp)); + else if (V instanceof Individual) { + superClasses.add(factory.getOWLObjectHasValue(objExp, + factory.getOWLNamedIndividual(IRI + .create(((Individual) V).getIRI())))); + } else + superClasses.add(factory.getOWLObjectHasValue(objExp, + factory.getOWLNamedIndividual(IRI.create(nom2iri + .get((Variable) V))))); + } + else { + Constant c = (Constant) atom.getArgument(1); + OWLDataProperty dataProp = factory.getOWLDataProperty(IRI.create(((AtomicRole) predicate).getIRI())); + superClasses.add(factory.getOWLDataHasValue(dataProp, getOWLLiteral(c))); + } + } else if (predicate instanceof AtLeastConcept) + superClasses + .add(getMinCardinalityExpression((AtLeastConcept) predicate)); + else if (predicate instanceof AtLeastDataRange) + superClasses + .add(getDataMinCardinalityExpression((AtLeastDataRange) predicate)); + + else { + Utility.logError(atom.toString(), + "strange head atoms left here~~~~~"); + // superClasses.add(getDataRange(getDataRange((LiteralDataRange) + // predicate))); + } + } + } + + private OWLLiteral getOWLLiteral(Constant constant) { + if (!constant.getDatatypeURI().equals(Namespace.RDF_PLAIN_LITERAL)) + return factory.getOWLLiteral(constant.getLexicalForm(), factory + .getOWLDatatype(IRI.create(constant.getDatatypeURI()))); + else { + String lexicalForm = constant.getLexicalForm(); + int index = lexicalForm.indexOf("@"); + return factory.getOWLLiteral(lexicalForm.substring(0, index), + lexicalForm.substring(index + 1)); + } + } + + // private OWLObjectSomeValuesFrom + // addSomeValuesFromAxiom(OWLObjectPropertyExpression roleExp, + // OWLClassExpression classExp) { + // return factory.getOWLObjectSomeValuesFrom(roleExp, classExp); + // } + + private void getVariableOccurrence(Map var2atom, + Set atoms) { + for (Atom atom : atoms) + if (atom.getArity() == 1 && atom.getArgument(0) instanceof Variable + && !atom.getArgument(0).equals(X)) + var2atom.put((Variable) atom.getArgumentVariable(0), atom); + } + + private OWLClassExpression getMinCardinalityExpression( + AtLeastConcept atLeast) { + OWLObjectPropertyExpression propExp = getObjectPropertyExpression(atLeast + .getOnRole()); + OWLClassExpression clsExp = getClassExpression(atLeast.getToConcept()); + if (atLeast.getNumber() == 1) + return factory.getOWLObjectSomeValuesFrom(propExp, clsExp); + else + return factory.getOWLObjectMinCardinality(atLeast.getNumber(), + propExp, clsExp); + } + + private OWLClassExpression getDataMinCardinalityExpression( + AtLeastDataRange atLeast) { + OWLDataPropertyExpression propExp = getDataPropertyExpression(atLeast + .getOnRole()); + OWLDataRange dataRange = getDataRange(atLeast.getToDataRange()); + if (atLeast.getNumber() == 1) + return factory.getOWLDataSomeValuesFrom(propExp, dataRange); + else + return factory.getOWLDataMinCardinality(atLeast.getNumber(), + propExp, dataRange); + } + + public Set getSuperClasses() { + return superClasses; + } + + public Set getSubClasses() { + return subClasses; + } + + // public OWLClassExpression getSubClass() { + // if (subClasses.isEmpty()) + // return factory.getOWLThing(); + // if (subClasses.size() == 1) + // return subClasses.iterator().next(); + // + // return factory.getOWLObjectIntersectionOf(subClasses); + // } + + private void eliminateEquality() { + Set eHeadAtoms = new HashSet(); + Set eBodyAtoms = new HashSet(); + Set eVariables = new HashSet(); + seperateEquality4Clause(eBodyAtoms, eHeadAtoms, eVariables); + + OWLNamedIndividual individual; + /* + * remove equalities that are introduced by MaxCardinalityConstraints + */ + DLPredicate predicate; + Map> groups = new HashMap>(); + OWLObjectMaxCardinality maxCardinality; + OWLClassExpression exp; + Set mVariables = new HashSet(); + Variable tVar, tVar1, tVar2; + Set tVariables; + + for (Iterator iter = eHeadAtoms.iterator(); iter.hasNext(); ){ + Atom atom = iter.next(); + predicate = atom.getDLPredicate(); + if (predicate instanceof AnnotatedEquality) { + superClasses.add(maxCardinality = getMaxCardinalityExpression((AnnotatedEquality)predicate)); + if (!((exp = maxCardinality.getFiller()) instanceof OWLObjectComplementOf)) + subClasses.add(factory.getOWLObjectSomeValuesFrom(maxCardinality.getProperty(), exp)); + else + subClasses.add(factory.getOWLObjectSomeValuesFrom(maxCardinality.getProperty(), factory.getOWLThing())); + mVariables.add(atom.getArgumentVariable(0)); + mVariables.add(atom.getArgumentVariable(1)); + iter.remove(); + } + else if (predicate instanceof Equality) { + if (atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { + mVariables.add(tVar1 = atom.getArgumentVariable(0)); + mVariables.add(tVar2 = atom.getArgumentVariable(1)); + iter.remove(); + + if (tVar1.getName().compareTo(tVar2.getName()) > 0) { + tVar = tVar1; tVar1 = tVar2; tVar2 = tVar; + } + tVariables = groups.get(tVar1); + if (groups.containsKey(tVar2)) { + if (tVariables == null) + groups.put(tVar1, tVariables = groups.get(tVar2)); + else { + tVariables.addAll(groups.get(tVar2)); + groups.get(tVar2).clear(); + groups.put(tVar2, tVariables); + } + } + if (tVariables == null) { + groups.put(tVar1, tVariables = new HashSet()); + groups.put(tVar2, tVariables); + } + tVariables.add(tVar1); + tVariables.add(tVar2); + } + } + } + + Map maxCardToConcepts = new HashMap(); + + for (Iterator iter = eBodyAtoms.iterator(); iter.hasNext(); ) { + Atom atom = iter.next(); + if (atom.getArity() == 1 && atom.getArgument(0) instanceof Variable) { + if (mVariables.contains(tVar = atom.getArgumentVariable(0))) { + maxCardToConcepts.put(tVar, atom.getDLPredicate()); + iter.remove(); + } + } + } + + for (Iterator iter = eHeadAtoms.iterator(); iter.hasNext(); ) { + Atom atom = iter.next(); + if (atom.getArity() == 1 && atom.getArgument(0) instanceof Variable) { + if (mVariables.contains(tVar = atom.getArgumentVariable(0))) { + maxCardToConcepts.put(tVar, AtomicNegationConcept.create((AtomicConcept) atom.getDLPredicate())); + iter.remove(); + } + } + } + + Map maxCardToProperty = new HashMap(); + + for (Iterator iter = eBodyAtoms.iterator(); iter.hasNext(); ) { + Atom atom = iter.next(); + if (atom.getArity() == 2 && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { + tVar1 = atom.getArgumentVariable(0); tVar2 = atom.getArgumentVariable(1); + if (mVariables.contains(tVar1)) { + if (groups.containsKey(tVar1)) + maxCardToProperty.put(tVar1, ((AtomicRole) atom.getDLPredicate()).getInverse()); + iter.remove(); + } else if (mVariables.contains(tVar2)) { + if (groups.containsKey(tVar2)) + maxCardToProperty.put(tVar2, atom.getDLPredicate()); + iter.remove(); + } + } + } + + int n; + Object r, A; + for (Variable var: groups.keySet()) { + if ((tVariables = groups.get(var)).isEmpty()) + continue; + n = tVariables.size() - 1; + tVariables.clear(); + r = maxCardToProperty.get(var); + if (r instanceof AtomicRole) { + if (isDataProperty(r)) { + if ((A = maxCardToConcepts.get(var)) != null) { + Utility.logError("Unknown data range: " + A); + } + + superClasses.add( + factory.getOWLDataMaxCardinality( + n, + factory.getOWLDataProperty(IRI.create(((AtomicRole) r).getIRI())))); + } + else { + OWLClassExpression clsExp = null; + if ((A = maxCardToConcepts.get(var)) != null) + if (A instanceof AtomicConcept) + clsExp = factory.getOWLClass(IRI.create(((AtomicConcept) A).getIRI())); + else if (A instanceof AtomicNegationConcept) + clsExp = factory.getOWLObjectComplementOf(factory.getOWLClass(IRI.create(((AtomicNegationConcept) A).getNegatedAtomicConcept().getIRI()))); + else + Utility.logError("Unknown to concept: " + A); + + if (A == null) + superClasses.add( + factory.getOWLObjectMaxCardinality( + n, + factory.getOWLObjectProperty(IRI.create(((AtomicRole) r).getIRI())) + )); + else + superClasses.add( + factory.getOWLObjectMaxCardinality( + n, + factory.getOWLObjectProperty(IRI.create(((AtomicRole) r).getIRI())), + clsExp)); + } + } + else if (r instanceof InverseRole) { + OWLClassExpression clsExp = null; + if ((A = maxCardToConcepts.get(var)) != null) { + if (A instanceof AtomicConcept) + clsExp = factory.getOWLClass(IRI.create(((AtomicConcept) A).getIRI())); + else if (A instanceof AtomicNegationConcept) + clsExp = factory.getOWLObjectComplementOf(factory.getOWLClass(IRI.create(((AtomicNegationConcept) A).getNegatedAtomicConcept().getIRI()))); + else + Utility.logError("Unknown to concept: " + A); + } + + if (A == null) + superClasses.add( + factory.getOWLObjectMaxCardinality( + n, + factory.getOWLObjectInverseOf(factory.getOWLObjectProperty(IRI.create(((InverseRole) r).getInverseOf().getIRI()))) + )); + else + superClasses.add( + factory.getOWLObjectMaxCardinality( + n, + factory.getOWLObjectInverseOf(factory.getOWLObjectProperty(IRI.create(((InverseRole) r).getInverseOf().getIRI()))), + clsExp)); + + } + else + Utility.logError("Unknown property: " + r); + } + + /* + * dealing with equalities of nominal + */ + Map nom2iri = new HashMap(); + for (Iterator iter = eBodyAtoms.iterator(); iter.hasNext(); ) { + Atom atom = iter.next(); + predicate = atom.getDLPredicate(); + if (predicate instanceof AtomicConcept && predicate.toString().startsWith("> equEdges = new HashMap>(); + Set terms = new HashSet(); + for (Atom atom: eHeadAtoms) { + predicate = atom.getDLPredicate(); + if (predicate instanceof Equality) { + first = atom.getArgument(0); + second = atom.getArgument(1); + + if (first instanceof Variable) { + if ((terms = equEdges.get(first)) == null) + equEdges.put((Variable) first, (terms = new HashSet())); + terms.add(second); + } + + if (second instanceof Variable) { + if ((terms = equEdges.get(second)) == null) + equEdges.put((Variable) second, (terms = new HashSet())); + terms.add(first); + } + } + } + + OWLObjectPropertyExpression objExp; + + Set individuals = new HashSet(); + if (equEdges.containsKey(X)) { + for (Term t: equEdges.get(X)) + if (t instanceof Variable) { + Variable var = (Variable) t; + individual = factory.getOWLNamedIndividual(IRI.create(nom2iri.get(var))); +// superClasses.add(factory.getOWLObjectOneOf(individual)); + individuals.add(individual); + } + else if (t instanceof Individual) + individuals.add(factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI()))); + } + + if (individuals.size() > 0) { + superClasses.add(factory.getOWLObjectOneOf(individuals)); + individuals.clear(); + } + + for (Atom atom: eBodyAtoms) { + predicate = atom.getDLPredicate(); + if (predicate instanceof AtomicRole) { + first = atom.getArgumentVariable(0); + second = atom.getArgumentVariable(1); + + objExp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) predicate).getIRI())); + if (eVariables.contains(first)) { + second = first; + objExp = factory.getOWLObjectInverseOf(objExp); + } + + for (Term t: equEdges.get(second)) { + if (t instanceof Variable) { + Variable var = (Variable) t; + individuals.add(factory.getOWLNamedIndividual(IRI.create(nom2iri.get(var)))); + } + else if (t instanceof Individual) { + individuals.add(factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI()))); + } + } + if (!individuals.isEmpty()) { + superClasses.add(factory.getOWLObjectAllValuesFrom(objExp, factory.getOWLObjectOneOf(individuals))); + individuals.clear(); + } + } + } + + } + + private boolean isDataProperty(Object r) { + if (!(r instanceof AtomicRole)) return false; + String iri = ((AtomicRole) r).getIRI(); + return dataProperties.contains(iri); + } + + private OWLObjectMaxCardinality getMaxCardinalityExpression( + AnnotatedEquality equ) { + OWLObjectPropertyExpression propExp = getObjectPropertyExpression(equ + .getOnRole()); + OWLClassExpression clsExp = getClassExpression(equ.getToConcept()); + return factory.getOWLObjectMaxCardinality(equ.getCaridnality(), + propExp, clsExp); + } + + private OWLObjectPropertyExpression getObjectPropertyExpression(Role role) { + if (role instanceof AtomicRole) + return factory.getOWLObjectProperty(IRI.create(((AtomicRole) role) + .getIRI())); + return factory.getOWLObjectProperty( + IRI.create(((InverseRole) role).getInverseOf().getIRI())) + .getInverseProperty(); + } + + private OWLDataProperty getDataPropertyExpression(Role role) { + return factory.getOWLDataProperty(IRI.create(((AtomicRole) role) + .getIRI())); + } + + private OWLClassExpression getClassExpression(LiteralConcept concept) { + if (concept instanceof AtomicConcept) + return factory.getOWLClass(IRI.create(((AtomicConcept) concept) + .getIRI())); + return factory.getOWLClass( + IRI.create(((AtomicNegationConcept) concept) + .getNegatedAtomicConcept().getIRI())) + .getComplementNNF(); + } + + private OWLDataRange getDataRange(LiteralDataRange dataRange) { + if (dataRange instanceof InternalDatatype) + return factory.getOWLDatatype(IRI + .create(((InternalDatatype) dataRange).getIRI())); + if (dataRange instanceof DatatypeRestriction) + return factory + .getOWLDatatype(IRI + .create(((DatatypeRestriction) dataRange) + .getDatatypeURI())); + if (dataRange instanceof ConstantEnumeration) { + ConstantEnumeration e = (ConstantEnumeration) dataRange; + OWLLiteral[] values = new OWLLiteral[e.getNumberOfConstants()]; + for (int i = 0; i < values.length; ++i) { + Constant c = e.getConstant(i); + values[i] = factory.getOWLLiteral(c.getDataValue().toString(), + factory.getOWLDatatype(IRI.create(c.getDatatypeURI()))); + } + return factory.getOWLDataOneOf(values); + } + Utility.logError(dataRange.toString(), "strange data type!!!!"); + return null; + } + + public void seperateEquality4Clause(Set eBodyAtoms, + Set eHeadAtoms, Set eVariables) { + Set variables = new HashSet(); + DLPredicate predicate; + for (Atom atom : headAtoms) { + predicate = atom.getDLPredicate(); + if (predicate instanceof Equality + || predicate instanceof AnnotatedEquality) { + variables.clear(); + atom.getVariables(variables); + for (Variable variable : variables) + eVariables.add(variable); + } + } + eVariables.remove(X); + + seperateEquality(bodyAtoms, eBodyAtoms, eVariables); + seperateEquality(headAtoms, eHeadAtoms, eVariables); + } + + public void seperateEquality(Set noEquality, Set inEquality, + Set eVariables) { + Set variables = new HashSet(); + for (Iterator iter = noEquality.iterator(); iter.hasNext();) { + Atom atom = iter.next(); + if (atom.getDLPredicate() instanceof Equality + || atom.getDLPredicate() instanceof AnnotatedEquality) { + iter.remove(); + inEquality.add(atom); + } else { + variables.clear(); + atom.getVariables(variables); + for (Variable variable : variables) + if (eVariables.contains(variable)) { + iter.remove(); + inEquality.add(atom); + break; + } + } + } + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder(); + boolean first = true; + for (OWLClassExpression exp : superClasses) + if (first) { + ret.append(exp.toString()); + first = false; + } else + ret.append(" v ").append(exp.toString()); + + first = true; + for (OWLClassExpression exp : subClasses) + if (first) { + ret.append(" :- ").append(exp.toString()); + first = false; + } else + ret.append(" ^ ").append(exp.toString()); + + return ret.toString(); + } +} diff --git a/src/uk/ac/ox/cs/pagoda/approx/Clausifier.java b/src/uk/ac/ox/cs/pagoda/approx/Clausifier.java new file mode 100644 index 0000000..ee23def --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/approx/Clausifier.java @@ -0,0 +1,37 @@ +package uk.ac.ox.cs.pagoda.approx; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLDataProperty; +import org.semanticweb.owlapi.model.OWLOntology; + +public class Clausifier { + + OWLDataFactory factory; + Set dataProperties = new HashSet(); + + private Clausifier(OWLOntology ontology) { + factory = ontology.getOWLOntologyManager().getOWLDataFactory(); + for (OWLDataProperty dataProperty: ontology.getDataPropertiesInSignature(true)) + dataProperties.add(dataProperty.toStringID()); + } + + public Clause clasuify(DLClause clause) { + return new Clause(this, clause); + } + + private static HashMap AllInstances = new HashMap(); + + public static Clausifier getInstance(OWLOntology onto) { + Clausifier c = AllInstances.get(onto); + if (c != null) return c; + c = new Clausifier(onto); + AllInstances.put(onto, c); + return c; + } + +} diff --git a/src/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java b/src/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java new file mode 100644 index 0000000..81b62f0 --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java @@ -0,0 +1,18 @@ +package uk.ac.ox.cs.pagoda.approx; + +import org.semanticweb.owlapi.model.OWLOntology; +import uk.ac.ox.cs.pagoda.constraints.BottomStrategy; + +public interface KnowledgeBase { + + void load(OWLOntology ontology, BottomStrategy botStrategy); + + public void transform(); + + public void save(); + + public String getOutputPath(); + + public String getDirectory(); + +} diff --git a/src/uk/ac/ox/cs/pagoda/approx/RLOntology.java b/src/uk/ac/ox/cs/pagoda/approx/RLOntology.java new file mode 100644 index 0000000..dba6a56 --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/approx/RLOntology.java @@ -0,0 +1,190 @@ +package uk.ac.ox.cs.pagoda.approx; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom; +import org.semanticweb.owlapi.model.OWLObjectHasSelf; +import org.semanticweb.owlapi.model.OWLObjectOneOf; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; + +import uk.ac.ox.cs.pagoda.owl.OWLHelper; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class RLOntology extends RLPlusOntology { + + @Override + public void transform() { + super.transform(); + + eliminateSelf(); + eliminateNominals(); + eliminateOWLThing(); + + save(); + if (aBox.getAxiomCount() != 0) + save(aBox); + } + + private void eliminateSelf() { + Collection axioms = new LinkedList(outputOntology.getAxioms()); + OWLClassExpression subExp, superExp, newSubExp, newSuperExp; + for (OWLAxiom axiom: axioms) + if (axiom instanceof OWLSubClassOfAxiom) { + subExp = ((OWLSubClassOfAxiom) axiom).getSubClass(); + superExp = ((OWLSubClassOfAxiom) axiom).getSuperClass(); + newSubExp = approximateSelf4Sub(subExp); + newSuperExp = approximateSelf4Super(superExp); + if (newSubExp != subExp || newSuperExp != superExp) + replaceAxiom4output(axiom, factory.getOWLSubClassOfAxiom(newSubExp, newSuperExp)); + } + } + + private void replaceAxiom4output(OWLAxiom oldAxiom, OWLAxiom newAxiom) { + manager.removeAxiom(outputOntology, oldAxiom); + manager.addAxiom(outputOntology, newAxiom); + correspondence.put(newAxiom, correspondence.remove(oldAxiom)); + } + + private boolean hasSelf(OWLClassExpression conjunction) { + for (OWLClassExpression conjunct: conjunction.asConjunctSet()) + if (conjunct instanceof OWLObjectHasSelf) + return true; + return false; + } + + private OWLClassExpression approximateSelf4Sub(OWLClassExpression exp) { + if (!hasSelf(exp)) return exp; + Set newConjuncts = new HashSet(); + for (OWLClassExpression conjunct: exp.asConjunctSet()) + if (conjunct instanceof OWLObjectHasSelf) + newConjuncts.add(factory.getOWLObjectSomeValuesFrom(((OWLObjectHasSelf) exp).getProperty(), factory.getOWLThing())); + else + newConjuncts.add(conjunct); + return OWLHelper.getSimplifiedConjunction(factory, newConjuncts); + } + + private OWLClassExpression approximateSelf4Super(OWLClassExpression exp) { + if (!hasSelf(exp)) return exp; + Set newConjuncts = new HashSet(); + for (OWLClassExpression conjunct: exp.asConjunctSet()) + if (conjunct instanceof OWLObjectHasSelf) { + OWLIndividual freshNominal = getNewIndividual(outputOntology, rlCounter++); + newConjuncts.add(factory.getOWLObjectOneOf(freshNominal)); + newConjuncts.add(factory.getOWLObjectHasValue(((OWLObjectHasSelf) exp).getProperty(), freshNominal)); + } + else + newConjuncts.add(conjunct); + + return OWLHelper.getSimplifiedConjunction(factory, newConjuncts); + } + + private void eliminateNominals() { + Collection axioms = new LinkedList(outputOntology.getAxioms()); + OWLClassExpression superExp, newSuperExp; + for (OWLAxiom axiom: axioms) + if (axiom instanceof OWLSubClassOfAxiom) { + superExp = ((OWLSubClassOfAxiom) axiom).getSuperClass(); + newSuperExp = approximateNominals(superExp); + if (newSuperExp != superExp) + replaceAxiom4output(axiom, factory.getOWLSubClassOfAxiom(((OWLSubClassOfAxiom) axiom).getSubClass(), newSuperExp)); + } + } + + private OWLClassExpression approximateNominals(OWLClassExpression exp) { + if (!hasIllegalNominals(exp)) return exp; + Set nominals; + Set newConjuncts = new HashSet(); + for (OWLClassExpression conjunct: exp.asConjunctSet()) { + if (conjunct instanceof OWLObjectOneOf) { + nominals = ((OWLObjectOneOf) conjunct).getIndividuals(); + newConjuncts.add(approximateNominal(nominals)); + } + else if (conjunct instanceof OWLObjectAllValuesFrom) { + OWLObjectAllValuesFrom allValuesFrom = ((OWLObjectAllValuesFrom) conjunct); + if (allValuesFrom.getFiller() instanceof OWLObjectOneOf) { + nominals = ((OWLObjectOneOf) allValuesFrom.getFiller()).getIndividuals(); + newConjuncts.add(factory.getOWLObjectAllValuesFrom(allValuesFrom.getProperty(), + approximateNominal(nominals))); + } + } + } + return OWLHelper.getSimplifiedConjunction(factory, newConjuncts); + } + + private OWLClassExpression approximateNominal(Set nominals) { + if (nominals.size() > 1) { + Utility.logError("Error: more than one nominal appearing in OWLObjectOneOf"); + return null; + } + OWLIndividual nominal = nominals.iterator().next(); + OWLObjectProperty freshProperty = getNewRole4Nominal(nominal); + addAxiom2output(factory.getOWLInverseFunctionalObjectPropertyAxiom(freshProperty), null); + manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(freshProperty, nominal, nominal)); + return factory.getOWLObjectHasValue(freshProperty, nominal); + } + + Map role4nominal = new HashMap(); + + private OWLObjectProperty getNewRole4Nominal(OWLIndividual nominal) { + OWLObjectProperty property; + if ((property = role4nominal.get(nominal)) == null) + role4nominal.put(nominal, property = getNewRole(outputOntology, rlCounter++)); + return property; + } + + private boolean hasIllegalNominals(OWLClassExpression exp) { + for (OWLClassExpression conjunct: exp.asConjunctSet()) { + if (conjunct instanceof OWLObjectOneOf) return true; + if (conjunct instanceof OWLObjectAllValuesFrom) { + OWLObjectAllValuesFrom allValuesFrom = ((OWLObjectAllValuesFrom) conjunct); + if (allValuesFrom.getFiller() instanceof OWLObjectOneOf) + return true; + } + } + return false; + } + + private void eliminateOWLThing() { + OWLClassExpression subExp; + boolean mark = false; + for (Clause clause: clauses) { + subExp = OWLHelper.getSimplifiedConjunction(factory, clause.getSubClasses()); + if (subExp.equals(factory.getOWLThing())) { + mark = true; + } + } + + if (mark) { + Utility.logDebug("Top appears in the left of an axiom."); + + OWLSubClassOfAxiom subClassAxiom; + OWLClass TOP = factory.getOWLClass(IRI.create(ontologyIRI + "#TOP")); + for (OWLAxiom axiom: new HashSet(outputOntology.getAxioms())) + if (axiom instanceof OWLSubClassOfAxiom && (subClassAxiom = (OWLSubClassOfAxiom) axiom).getSubClass().equals(factory.getOWLThing())) + replaceAxiom4output(axiom, factory.getOWLSubClassOfAxiom(TOP, subClassAxiom.getSuperClass())); + + for (OWLClass c: outputOntology.getClassesInSignature(true)) { + if (!c.equals(factory.getOWLThing())) + addAxiom2output(factory.getOWLSubClassOfAxiom(c, TOP), null); + else + addAxiom2output(factory.getOWLSubClassOfAxiom(TOP, c), null); + } + for (OWLObjectProperty p: outputOntology.getObjectPropertiesInSignature(true)) { + addAxiom2output(factory.getOWLObjectPropertyDomainAxiom(p, TOP), null); + addAxiom2output(factory.getOWLObjectPropertyRangeAxiom(p, TOP), null); + } + } + } + +} diff --git a/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java b/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java new file mode 100644 index 0000000..a43d9af --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java @@ -0,0 +1,608 @@ +package uk.ac.ox.cs.pagoda.approx; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import org.semanticweb.HermiT.Configuration; +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.HermiT.model.DLOntology; +import org.semanticweb.HermiT.structural.OWLClausification; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLDataFactory; +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.OWLDataSomeValuesFrom; +import org.semanticweb.owlapi.model.OWLDatatype; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom; +import org.semanticweb.owlapi.model.OWLObjectComplementOf; +import org.semanticweb.owlapi.model.OWLObjectHasValue; +import org.semanticweb.owlapi.model.OWLObjectMaxCardinality; +import org.semanticweb.owlapi.model.OWLObjectMinCardinality; +import org.semanticweb.owlapi.model.OWLObjectOneOf; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; +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.profiles.OWL2RLProfile; +import org.semanticweb.owlapi.profiles.OWLProfileReport; +import org.semanticweb.owlapi.profiles.OWLProfileViolation; + +import uk.ac.ox.cs.pagoda.constraints.NullaryBottom; +import uk.ac.ox.cs.pagoda.constraints.UnaryBottom; +import uk.ac.ox.cs.pagoda.owl.OWLHelper; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class RLPlusOntology implements KnowledgeBase { + + OWLOntologyManager manager; + OWLDataFactory factory; + String ontologyIRI; + String corrFileName = null; + String outputPath, aBoxPath; + + OWLOntology inputOntology = null; + OWLOntology tBox = null; + OWLOntology aBox = null; + OWLOntology restOntology = null; + OWLOntology outputOntology = null; //RL ontology + + DLOntology dlOntology = null; + int rlCounter = 0; + + LinkedList clauses; + Map correspondence; + + BottomStrategy botStrategy; + + @Override + public void load(OWLOntology o, uk.ac.ox.cs.pagoda.constraints.BottomStrategy bottomStrategy) { + if (bottomStrategy instanceof UnaryBottom) + botStrategy = BottomStrategy.UNARY; + else if (bottomStrategy instanceof NullaryBottom) + botStrategy = BottomStrategy.NULLARY; + else + botStrategy = BottomStrategy.TOREMOVE; + + if (corrFileName == null) + corrFileName = "rlplus.crr"; + manager = o.getOWLOntologyManager(); +// manager = OWLManager.createOWLOntologyManager(); + factory = manager.getOWLDataFactory(); + inputOntology = o; + + try { + String path = OWLHelper.getOntologyPath(inputOntology); + String name = path.substring(path.lastIndexOf(Utility.JAVA_FILE_SEPARATOR)); + String originalExtension = name.lastIndexOf(".") >= 0 ? name.substring(name.lastIndexOf(".")) : ""; + + if (inputOntology.getOntologyID().getOntologyIRI() == null) + ontologyIRI = "http://www.example.org/anonymous-ontology" + originalExtension; + else + ontologyIRI = inputOntology.getOntologyID().getOntologyIRI().toString(); + + String tOntoIRI = ontologyIRI; + if (!tOntoIRI.endsWith(originalExtension)) tOntoIRI += originalExtension; + + String rlOntologyIRI = originalExtension.isEmpty() ? tOntoIRI + "-RL.owl" : tOntoIRI.replaceFirst(originalExtension, "-RL.owl"); + String rlDocumentIRI = (outputPath = Utility.TempDirectory + "RL.owl"); + outputOntology = manager.createOntology(IRI.create(rlOntologyIRI)); + manager.setOntologyDocumentIRI(outputOntology, IRI.create(Utility.toFileIRI(rlDocumentIRI))); + + String tBoxOntologyIRI, aBoxOntologyIRI; + tBoxOntologyIRI = originalExtension.isEmpty() ? tOntoIRI + "-TBox.owl" : tOntoIRI.replaceFirst(originalExtension, "-TBox.owl"); + aBoxOntologyIRI = originalExtension.isEmpty() ? tOntoIRI + "-ABox.owl" : tOntoIRI.replaceFirst(originalExtension, "-ABox.owl"); + + String tBoxDocumentIRI = (Utility.TempDirectory + "TBox.owl"); + String aBoxDocumentIRI = (aBoxPath = Utility.TempDirectory + "ABox.owl"); + tBox = manager.createOntology(IRI.create(tBoxOntologyIRI)); + aBox = manager.createOntology(IRI.create(aBoxOntologyIRI)); + manager.setOntologyDocumentIRI(tBox, IRI.create(Utility.toFileIRI(tBoxDocumentIRI))); + manager.setOntologyDocumentIRI(aBox, IRI.create(Utility.toFileIRI(aBoxDocumentIRI))); + + FileOutputStream aBoxOut = new FileOutputStream(aBoxPath); + manager.saveOntology(aBox, aBoxOut); + aBoxOut.close(); + + restOntology = manager.createOntology(); + } + catch (OWLOntologyCreationException e) { + e.printStackTrace(); + } catch (OWLOntologyStorageException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public OWLOntology getTBox() { + return tBox; + } + + public String getABoxPath() { + return aBoxPath; + } + + private void add2SubCounter(OWLClassExpression exp) { + Integer count = subCounter.get(exp); + if (count == null) count = 0; + ++count; + subCounter.put(exp, count); + } + + public void simplify() { + if (simplifyABox()) { + save(aBox); +// save(tBox); + } + else + tBox = inputOntology; + } + + @Override + public void transform() { + simplify(); + filter(); + clausify(); + + subCounter = new HashMap(); + clauses = new LinkedList(); + Clausifier clausifier = Clausifier.getInstance(restOntology); + + for (DLClause c: dlOntology.getDLClauses()) { + Clause clause = new Clause(clausifier, c); + clauses.add(clause); + + /* + * count the expressions in the left + */ + for (OWLClassExpression exp: clause.getSubClasses()) { + if (exp instanceof OWLClass) + add2SubCounter(exp); + else if (exp instanceof OWLObjectSomeValuesFrom) { + OWLObjectSomeValuesFrom someValue = (OWLObjectSomeValuesFrom)exp; + add2SubCounter(factory.getOWLObjectSomeValuesFrom(someValue.getProperty(), factory.getOWLThing())); + add2SubCounter(someValue.getFiller()); + } + else if (exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard = (OWLObjectMinCardinality)exp; + add2SubCounter(factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing())); + add2SubCounter(minCard.getFiller()); + } + else + Utility.logError("strange class expression: " + exp); + + } + } + + correspondence = new HashMap(); + Set addedAxioms = new HashSet(); + OWLClassExpression subExp; + for (Clause clause: clauses) { + subExp = uk.ac.ox.cs.pagoda.owl.OWLHelper.getSimplifiedConjunction(factory, clause.getSubClasses()); + addedAxioms.clear(); + for (OWLClassExpression exp: getDisjunctionApprox0(clause.getSuperClasses())) { + addedAxioms.add(factory.getOWLSubClassOfAxiom(subExp, transform(exp, addedAxioms))); + for (OWLAxiom a: addedAxioms) + addAxiom2output(a, factory.getOWLSubClassOfAxiom(subExp, + OWLHelper.getSimplifiedDisjunction(factory, clause.getSuperClasses()))); + } + } + + subCounter.clear(); + } + + @Override + public void save() { + if (corrFileName != null) + save(correspondence, corrFileName); + save(outputOntology); + } + + private void save(Map map, String corrFileName) { + if (corrFileName == null) return ; + ObjectOutput output; + try { + output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(corrFileName))); + output.writeObject(map); + output.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected void save(OWLOntology onto) { + try { + onto.getOWLOntologyManager().saveOntology(onto); + } catch (OWLOntologyStorageException e) { + e.printStackTrace(); + } + } + + /* + * treat disjunction as conjunction + */ + private Set getDisjunctionApprox0(Set superClasses) { + return superClasses; + } + + /* + * choose one simple class disjunct + */ + @SuppressWarnings("unused") + private Set getDisjunctionApprox1(Set superClasses) { + if (superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + OWLClassExpression rep = null; + int min = Integer.MAX_VALUE, o; + for (OWLClassExpression exp: superClasses) + if (exp instanceof OWLClass && (o = getOccurrence(exp)) < min) { + min = o; + rep = exp; + } + + if (rep == null) rep = superClasses.iterator().next(); + + return Collections.singleton(rep); + } + + Random random = new Random(19900114); + /* + * randomly choose a class expression to represent this disjunction + */ + @SuppressWarnings("unused") + private Set getDisjunctionApprox2(Set superClasses) { + if (superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + int index = random.nextInt() % superClasses.size(); + if (index < 0) index += superClasses.size(); + + int i = 0; + for (OWLClassExpression exp: superClasses) + if (i++ == index) + return Collections.singleton(exp); + return null; + } + + private Map subCounter = null; + /* + * choose the one that appears least in the l.h.s. + */ + @SuppressWarnings("unused") + private Set getDisjunctionApprox3(Set superClasses) { + if (superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + OWLClassExpression rep = null, exp1; + int occurrence = Integer.MAX_VALUE, o; + for (OWLClassExpression exp: superClasses) { + o = 0; + exp1 = exp; + if (exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard = (OWLObjectMinCardinality)exp; + if (minCard.getCardinality() == 1) + exp1 = factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), minCard.getFiller()); + } + + if (!subCounter.containsKey(exp1) || (o = subCounter.get(exp1)) < occurrence) { + rep = exp; + occurrence = o; + } + } + + return Collections.singleton(rep); + } + + private int getOccurrence(OWLClassExpression exp) { + if (!subCounter.containsKey(exp)) + return 0; + return subCounter.get(exp); + } + + @SuppressWarnings("unused") + private Set getDisjunctionApprox4(Set superClasses) { + if (superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + OWLClassExpression rep = null; + int occurrence = Integer.MAX_VALUE, o; + for (OWLClassExpression exp: superClasses) { + o = 0; + if (exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard = (OWLObjectMinCardinality)exp; + if (minCard.getCardinality() == 1) { + o = getOccurrence((factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing()))); + o += getOccurrence(minCard.getFiller()); +// if (o < o1) o = o1; + } + } + else + o = getOccurrence(exp); + + if (o < occurrence || o == occurrence && !(rep instanceof OWLClass)) { + rep = exp; + occurrence = o; + } + } + + return Collections.singleton(rep); + } + + private boolean simplifyABox() { + boolean flag = false; + Map complex2atomic= new HashMap(); + + OWLDatatype anyURI = factory.getOWLDatatype(IRI.create(Namespace.XSD_NS + "anyURI")); + for (OWLOntology imported: inputOntology.getImportsClosure()) + for (OWLAxiom axiom: imported.getAxioms()) { + if (axiom instanceof OWLClassAssertionAxiom) { + flag = true; + OWLClassAssertionAxiom assertion = (OWLClassAssertionAxiom)axiom; + OWLClassExpression clsExp = assertion.getClassExpression(); + OWLClass cls; + if (clsExp instanceof OWLClass) { + if (((OWLClass) clsExp).toStringID().startsWith("owl:")) + manager.addAxiom(tBox, axiom); + else manager.addAxiom(aBox, axiom); + } + else { + if ((cls = complex2atomic.get(clsExp)) == null) { + complex2atomic.put(clsExp, cls = getNewConcept(tBox, rlCounter++)); + manager.addAxiom(tBox, factory.getOWLSubClassOfAxiom(cls, clsExp)); + } + manager.addAxiom(aBox, factory.getOWLClassAssertionAxiom(cls, assertion.getIndividual())); + } + } + else if (axiom instanceof OWLObjectPropertyAssertionAxiom || axiom instanceof OWLDataPropertyAssertionAxiom || axiom instanceof OWLAnnotationAssertionAxiom) { + if (axiom.containsEntityInSignature(anyURI)) continue; + flag = true; + manager.addAxiom(aBox, axiom); + } + else + manager.addAxiom(tBox, axiom); + } + + return flag; + } + + private void filter() { + OWL2RLProfile profile = new OWL2RLProfile(); + OWLProfileReport report = profile.checkOntology(tBox); + Set rlAxioms = tBox.getAxioms(); + OWLAxiom axiom; + + for (OWLProfileViolation violation: report.getViolations()) { + manager.addAxiom(restOntology, axiom = violation.getAxiom()); + rlAxioms.remove(axiom); + } + + for (Iterator iter = rlAxioms.iterator(); iter.hasNext(); ) + addAxiom2output(iter.next(), null); + } + + private void clausify() { + Configuration conf = new Configuration(); + OWLClausification clausifier = new OWLClausification(conf); + dlOntology = (DLOntology)clausifier.preprocessAndClausify(restOntology, null)[1]; + clausifier = null; + } + + protected void addAxiom2output(OWLAxiom axiom, OWLAxiom correspondingAxiom) { + manager.addAxiom(outputOntology, axiom); + if (correspondingAxiom != null) + correspondence.put(axiom, correspondingAxiom); + } + + private Map atomic2negation = new HashMap(); + + private OWLClassExpression transform(OWLClassExpression exp, Set addedAxioms) { + if (exp instanceof OWLClass) + return exp; + + if (exp instanceof OWLObjectHasValue) + return exp; + + if (exp instanceof OWLObjectSomeValuesFrom) { + OWLObjectSomeValuesFrom someValueExp = (OWLObjectSomeValuesFrom)exp; + + OWLClassExpression tExp = someValueExp.getFiller(); + if (tExp.equals(factory.getOWLThing())) + exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty()); + else + exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty(), someValueExp.getFiller()); + } + + if (exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minExp = (OWLObjectMinCardinality)exp; + OWLObjectPropertyExpression r; + + if (minExp.getFiller().equals(factory.getOWLThing())) { + r = minExp.getProperty(); + } + //TODO to be restored ... + //else if ((r = exists2role.get(someValueExp)) == null) { + // deal with r' \subseteq r & range(r') \subseteq C + else { + r = getNewRole(outputOntology, rlCounter); + addedAxioms.add(factory.getOWLSubObjectPropertyOfAxiom(r, minExp.getProperty())); + OWLClassExpression tExp = minExp.getFiller(); + if (!(tExp instanceof OWLObjectComplementOf)) { + if (tExp.equals(factory.getOWLThing())); + else + addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, tExp)); + } + else if (botStrategy != BottomStrategy.TOREMOVE) { + OWLClass cls = (OWLClass) ((OWLObjectComplementOf) tExp).getComplementNNF(); + OWLClass neg; + if ((neg = atomic2negation.get(cls)) == null) { + neg = getNewConcept(outputOntology, rlCounter); + addedAxioms.add(factory.getOWLDisjointClassesAxiom(neg, cls)); + atomic2negation.put(cls, neg); + } + addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, neg)); + } +// exists2role.put(someValueExp, (OWLObjectProperty) r); + } + + // deal with r'(x,c) + Set ret = new HashSet(); + int num = minExp.getCardinality(); + + Set cs = new HashSet(); + OWLNamedIndividual c; + for (int i = 0; i < num; ++i) { + c = getNewIndividual(outputOntology, rlCounter++); + ret.add(factory.getOWLObjectHasValue(r, c)); + cs.add(c); + } + + if (botStrategy != BottomStrategy.TOREMOVE && cs.size() > 1) { + addedAxioms.add(factory.getOWLDifferentIndividualsAxiom(cs)); + } + + return OWLHelper.getSimplifiedConjunction(factory, ret); + } + + if (exp instanceof OWLObjectMaxCardinality) { + OWLObjectMaxCardinality maxExp = (OWLObjectMaxCardinality)exp; + OWLClassExpression tExp = maxExp.getFiller(); + int card = maxExp.getCardinality() >= 1 ? 1 : 0; + if (!(tExp instanceof OWLObjectComplementOf)) + return factory.getOWLObjectMaxCardinality(card, maxExp.getProperty(), tExp); + else { + Utility.logDebug("oh, to be tested ... "); + OWLClassExpression tExp1 = factory.getOWLObjectAllValuesFrom(maxExp.getProperty(), tExp.getComplementNNF()); + if (card == 0) + return tExp1; + else { + OWLClassExpression tExp2 = factory.getOWLObjectMaxCardinality(1, maxExp.getProperty()); + return factory.getOWLObjectIntersectionOf(tExp1, tExp2); + } + } + } + + if (exp instanceof OWLObjectAllValuesFrom) + return exp; + + if (exp instanceof OWLObjectOneOf) + if (((OWLObjectOneOf) exp).getIndividuals().size() == 1) + return exp; + else + return null; + + if (exp instanceof OWLDataHasValue) + return exp; + + //TODO overapproximation - dealing with OWLDataMinCardinality + + if (exp instanceof OWLDataSomeValuesFrom) { + return exp; + } + + if (exp instanceof OWLDataMinCardinality) { + return exp; + } + + if (exp instanceof OWLDataMaxCardinality) { + return exp; + } + + + Set exps = exp.asConjunctSet(); + if (exps.size() == 1 && exps.iterator().next() == exp) { + Utility.logError(exp, "error in transform of Ontology~~~~"); + } + Set nexps = new HashSet(); + OWLClassExpression ne; + boolean changes = false; + for (OWLClassExpression e: exps) { + ne = transform(e, addedAxioms); + if (ne != e) changes = true; + nexps.add(ne); + } + if (changes) + return OWLHelper.getSimplifiedConjunction(factory, nexps); + else + return exp; + } + + protected OWLNamedIndividual getNewIndividual(OWLOntology onto, int number) { + OWLOntologyManager manager = onto.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLNamedIndividual newIndividual = factory.getOWLNamedIndividual(IRI.create(Namespace.PAGODA_ANONY + "NI" + number)); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newIndividual)); + return newIndividual; + } + + protected OWLObjectProperty getNewRole(OWLOntology onto, int number) { + OWLOntologyManager manager = onto.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLObjectProperty newProperty = factory.getOWLObjectProperty(IRI.create(Namespace.PAGODA_AUX + "NR" + number)); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newProperty)); + return newProperty; + } + + private OWLClass getNewConcept(OWLOntology onto, int number) { + OWLOntologyManager manager = onto.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLClass newClass = factory.getOWLClass(IRI.create(Namespace.PAGODA_AUX + "NC" + number)); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newClass)); + return newClass; + } + + public OWLOntologyManager getOWLOntologyManager() { + return inputOntology.getOWLOntologyManager(); + } + + public String getOntologyIRI() { + return ontologyIRI; + } + + public OWLOntology getOutputOntology() { + return outputOntology; + } + + @Override + public String getOutputPath() { + return outputPath; + } + + @Override + public String getDirectory() { + return outputPath.substring(0, outputPath.lastIndexOf(Utility.FILE_SEPARATOR)); + } + + public void setCorrespondenceFileLoc(String path) { + corrFileName = path; + } + + private static enum BottomStrategy { TOREMOVE, NULLARY, UNARY } +} + -- cgit v1.2.3