/*******************************************************************************
* This file is part of the Coporate Semantic Web Project.
*
* This work has been partially supported by the ``InnoProfile-Corporate Semantic Web" project funded by the German Federal
* Ministry of Education and Research (BMBF) and the BMBF Innovation Initiative for the New German Laender - Entrepreneurial Regions.
*
* http://www.corporate-semantic-web.de/
*
*
* Freie Universitaet Berlin
* Copyright (c) 2007-2013
*
*
* Institut fuer Informatik
* Working Group Coporate Semantic Web
* Koenigin-Luise-Strasse 24-26
* 14195 Berlin
*
* http://www.mi.fu-berlin.de/en/inf/groups/ag-csw/
*
*
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see <http://www.gnu.org/licenses/>
******************************************************************************/
package de.fuberlin.agcsw.svont.changedetection.smartcex.profiles;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.semanticweb.owlapi.apibinding.OWLManager;
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.OWLAxiom;
import org.semanticweb.owlapi.model.OWLAxiomVisitor;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLClassExpressionVisitor;
import org.semanticweb.owlapi.model.OWLDataAllValuesFrom;
import org.semanticweb.owlapi.model.OWLDataExactCardinality;
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.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.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyManager;
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;
import org.semanticweb.owlapi.profiles.OWLProfile;
import org.semanticweb.owlapi.profiles.OWLProfileReport;
import org.semanticweb.owlapi.profiles.OWLProfileViolation;
/**
* @author ralph
*
*/
public class CEXOWL2ELProfile implements OWLProfile, OWLAxiomVisitor {
private static final Logger log = Logger.getLogger(CEXOWL2ELProfile.class);
private final HashSet<OWLProfileViolation> violations = new HashSet<OWLProfileViolation>();
private OWLOntology ontology;
private OWLOntologyManager manager;
private OWLDataFactory factory;
/**
* @see org.semanticweb.owlapi.profiles.OWLProfile#checkOntology(org.semanticweb.owlapi.model.OWLOntology)
*/
@Override
public OWLProfileReport checkOntology(OWLOntology ontology) {
this.ontology = ontology;
manager = OWLManager.createOWLOntologyManager();
factory = manager.getOWLDataFactory();
for (OWLAxiom axiom : ontology.getAxioms()) {
axiom.accept(this);
}
return new OWLProfileReport(this, violations);
}
/**
* @see org.semanticweb.owlapi.profiles.OWLProfile#getName()
*/
@Override
public String getName() {
return "CEX algorithm compatible OWL 2 EL profile";
}
private void unusedAxiom(OWLAxiom axiom, boolean error) {
if (error) {
violations.add(new OWLProfileViolation(ontology, axiom));
}
}
private void unusedAxiom(OWLAxiom axiom) {
unusedAxiom(axiom, true);
}
public void visit(OWLSubClassOfAxiom axiom) {
OWLClassExpression sub = axiom.getSubClass();
// OWLClassExpression sup = axiom.getSuperClass();
if (!(sub.isOWLThing() || sub.isOWLNothing() || sub instanceof OWLClass)) {
// LOG.log(Level.SEVERE,
// "On the left side of a subAxiom is not a single class, skipping");
unusedAxiom(axiom);
}
}
private List<OWLClassExpression> getListOfConjunctions(OWLClassExpression in) throws UnusedClassExpressionException {
List<OWLClassExpression> list = new ArrayList<OWLClassExpression>();
new NormalizatorClassExpressionVisitor(in, list);
return list;
}
List<OWLObjectIntersectionOf> getConjunctionsFromLists(List<List<OWLClassExpression>> lists) {
List<OWLObjectIntersectionOf> conjs = new ArrayList<OWLObjectIntersectionOf>();
for (List<OWLClassExpression> list : lists) {
conjs.add(factory.getOWLObjectIntersectionOf(new HashSet<OWLClassExpression>(list)));
}
return conjs;
}
private List<List<OWLClassExpression>> getCartesianProduct(List<List<OWLClassExpression>> lists) {
List<List<OWLClassExpression>> out = new ArrayList<List<OWLClassExpression>>();
if (lists.size() == 0) {
return out;
}
if (lists.size() == 1) {
for (OWLClassExpression d : lists.get(0)) {
List<OWLClassExpression> l = new ArrayList<OWLClassExpression>();
l.add(d);
out.add(l);
}
return out;
}
List<OWLClassExpression> ll = lists.remove(lists.size() - 1);
List<List<OWLClassExpression>> fout = getCartesianProduct(lists);
for (List<OWLClassExpression> flist : fout) {
for (OWLClassExpression d : ll) {
List<OWLClassExpression> l = (List<OWLClassExpression>) ((ArrayList<OWLClassExpression>) flist).clone();
l.add(d);
out.add(l);
}
}
return out;
}
public void visit(OWLNegativeObjectPropertyAssertionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLAsymmetricObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLReflexiveObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDisjointClassesAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDataPropertyDomainAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLAnnotationAssertionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLObjectPropertyDomainAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLEquivalentObjectPropertiesAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLNegativeDataPropertyAssertionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDifferentIndividualsAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDisjointDataPropertiesAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDisjointObjectPropertiesAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLObjectPropertyRangeAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLObjectPropertyAssertionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLFunctionalObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLSubObjectPropertyOfAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDisjointUnionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDeclarationAxiom arg0) {
}
public void visit(OWLSymmetricObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDataPropertyRangeAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLFunctionalDataPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLEquivalentDataPropertiesAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLClassAssertionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLEquivalentClassesAxiom axiom) {
java.util.Set<OWLClassExpression> descrs = axiom.getClassExpressions();
OWLClass left = null;
OWLClassExpression right = null;
if (descrs.size() != 2) {
// LOG.log(Level.SEVERE, "Unsupported equAxiom - not 2 sides");
unusedAxiom(axiom);
return;
}
for (OWLClassExpression d : descrs) {
if ((d instanceof OWLClass) && (left == null)) {
left = (OWLClass) d;
} else {
right = d;
}
}
if (left == null) {
// LOG.log(Level.SEVERE,
// "Unsupported equAxiom - at least one side has to be class");
unusedAxiom(axiom);
return;
}
List<OWLClassExpression> list;
try {
list = getListOfConjunctions(right);
// TODO does it make sense to break down equivalence axiom like this ???
// Probably not:
if (list.size() != 1) {
// LOG.severe("Unsupported equAxiom - union of some things");
unusedAxiom(axiom);
}
} catch (UnusedClassExpressionException e) {
unusedAxiom(axiom);
}
}
public void visit(OWLDataPropertyAssertionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLTransitiveObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLIrreflexiveObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLSubDataPropertyOfAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLInverseFunctionalObjectPropertyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLSameIndividualAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLSubPropertyChainOfAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLInverseObjectPropertiesAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(SWRLRule arg0) {
unusedAxiom(arg0);
}
private class NormalizatorClassExpressionVisitor implements OWLClassExpressionVisitor {
private List<OWLClassExpression> list;
int errorCnt = 0;
public NormalizatorClassExpressionVisitor(OWLClassExpression in, List<OWLClassExpression> list) throws UnusedClassExpressionException {
this.list = list;
in.accept(this);
if (errorCnt != 0)
throw new UnusedClassExpressionException();
}
private void unusedClassExpression(OWLClassExpression descr) {
// LOG.warning("Ignored description: " + descr);
errorCnt++;
}
public void visit(OWLClass c) {
list.add(c);
}
public void visit(OWLObjectIntersectionOf inters) {
Set<OWLClassExpression> ops = inters.getOperands();
List<List<OWLClassExpression>> lists = new ArrayList<List<OWLClassExpression>>();
for (OWLClassExpression op : ops) {
try {
lists.add(getListOfConjunctions(op));
list.addAll(getConjunctionsFromLists(getCartesianProduct(lists)));
} catch (UnusedClassExpressionException e) {
errorCnt++;
}
}
}
public void visit(OWLObjectUnionOf union) {
Set<OWLClassExpression> ops = union.getOperands();
for (OWLClassExpression op : ops) {
/*
* ArrayList<OWLClassExpression> l = new
* ArrayList<OWLClassExpression>(); new
* NormalizatorClassExpressionVisitor(op, l); list.addAll(l);
*/
try {
list.addAll(getListOfConjunctions(op));
} catch (UnusedClassExpressionException e) {
errorCnt++;
}
}
}
public void visit(OWLObjectComplementOf arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectSomeValuesFrom restr) {
list.add(restr);
}
public void visit(OWLObjectAllValuesFrom arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectHasValue arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectMinCardinality arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectExactCardinality arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectMaxCardinality arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectHasSelf arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLObjectOneOf arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLDataSomeValuesFrom arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLDataAllValuesFrom arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLDataHasValue arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLDataMinCardinality arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLDataExactCardinality arg0) {
unusedClassExpression(arg0);
}
public void visit(OWLDataMaxCardinality arg0) {
unusedClassExpression(arg0);
}
}
public void visit(OWLHasKeyAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLDatatypeDefinitionAxiom arg0) {
unusedAxiom(arg0);
}
public void visit(OWLSubAnnotationPropertyOfAxiom arg0) {
unusedAxiom(arg0, false);
}
public void visit(OWLAnnotationPropertyDomainAxiom arg0) {
unusedAxiom(arg0, false);
}
public void visit(OWLAnnotationPropertyRangeAxiom arg0) {
unusedAxiom(arg0, false);
}
private class UnusedClassExpressionException extends Exception {
private static final long serialVersionUID = -944929993434077728L;
}
}