package uk.ac.manchester.cs.jfact;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
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.OWLAxiomVisitorEx;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom;
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.OWLIndividual;
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.OWLObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
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.reasoner.UnsupportedEntailmentTypeException;
import uk.ac.manchester.cs.jfact.kernel.ReasoningKernel;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.ConceptExpression;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.ObjectRoleExpression;
/** entailment checker */
public class EntailmentChecker implements OWLAxiomVisitorEx<Boolean>,
Serializable {
private static final long serialVersionUID = 11000L;
private final ReasoningKernel kernel;
private final TranslationMachinery tr;
private final OWLDataFactory df;
/**
* @param k
* k
* @param df
* df
* @param tr
* tr
*/
public EntailmentChecker(ReasoningKernel k, OWLDataFactory df,
TranslationMachinery tr) {
kernel = k;
this.tr = tr;
this.df = df;
}
@Override
public Boolean visit(OWLSubClassOfAxiom axiom) {
if (axiom.getSuperClass().equals(df.getOWLThing())
|| axiom.getSubClass().equals(df.getOWLNothing())) {
return Boolean.TRUE;
}
ConceptExpression sub = tr.pointer(axiom.getSubClass());
if (!kernel.isSatisfiable(sub)) {
return true;
}
ConceptExpression sup = tr.pointer(axiom.getSuperClass());
return kernel.isSubsumedBy(sub, sup);
}
@Override
public Boolean visit(OWLNegativeObjectPropertyAssertionAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLAsymmetricObjectPropertyAxiom axiom) {
return kernel.isAsymmetric(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLReflexiveObjectPropertyAxiom axiom) {
return kernel.isReflexive(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLDisjointClassesAxiom axiom) {
Set<OWLClassExpression> classExpressions = axiom.getClassExpressions();
if (classExpressions.size() == 2) {
Iterator<OWLClassExpression> it = classExpressions.iterator();
return kernel.isDisjoint(tr.pointer(it.next()),
tr.pointer(it.next()));
} else {
for (OWLAxiom ax : axiom.asOWLSubClassOfAxioms()) {
if (!ax.accept(this)) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
}
@Override
public Boolean visit(OWLDataPropertyDomainAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLObjectPropertyDomainAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLEquivalentObjectPropertiesAxiom axiom) {
for (OWLAxiom ax : axiom.asSubObjectPropertyOfAxioms()) {
if (!ax.accept(this)) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
@Override
public Boolean visit(OWLNegativeDataPropertyAssertionAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLDifferentIndividualsAxiom axiom) {
for (OWLSubClassOfAxiom ax : axiom.asOWLSubClassOfAxioms()) {
if (!ax.accept(this)) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
// TODO: this check is incomplete
@Override
public Boolean visit(OWLDisjointDataPropertiesAxiom axiom) {
List<OWLDataPropertyExpression> l = new ArrayList<OWLDataPropertyExpression>(
axiom.getProperties());
for (int i = 0; i < l.size() - 1; i++) {
for (int j = i + 1; j < l.size(); j++) {
if (!kernel.isDisjointRoles(tr.pointer(l.get(i)),
tr.pointer(l.get(i)))) {
return Boolean.FALSE;
}
}
}
return Boolean.TRUE;
}
@Override
public Boolean visit(OWLDisjointObjectPropertiesAxiom axiom) {
List<OWLObjectPropertyExpression> l = new ArrayList<OWLObjectPropertyExpression>(
axiom.getProperties());
for (int i = 0; i < l.size() - 1; i++) {
for (int j = i + 1; j < l.size(); j++) {
if (!kernel.isDisjointRoles(tr.pointer(l.get(i)),
tr.pointer(l.get(i)))) {
return Boolean.FALSE;
}
}
}
return Boolean.TRUE;
}
@Override
public Boolean visit(OWLObjectPropertyRangeAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLObjectPropertyAssertionAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLFunctionalObjectPropertyAxiom axiom) {
return kernel.isFunctional(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLSubObjectPropertyOfAxiom axiom) {
return kernel.isSubRoles(tr.pointer(axiom.getSubProperty()),
tr.pointer(axiom.getSuperProperty()));
}
@Override
public Boolean visit(OWLDisjointUnionAxiom axiom) {
return axiom.getOWLEquivalentClassesAxiom().accept(this)
&& axiom.getOWLDisjointClassesAxiom().accept(this);
}
@Override
public Boolean visit(OWLDeclarationAxiom axiom) {
return Boolean.FALSE;
}
@Override
public Boolean visit(OWLAnnotationAssertionAxiom axiom) {
return Boolean.FALSE;
}
@Override
public Boolean visit(OWLSymmetricObjectPropertyAxiom axiom) {
return kernel.isSymmetric(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLDataPropertyRangeAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLFunctionalDataPropertyAxiom axiom) {
return kernel.isFunctional(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLEquivalentDataPropertiesAxiom axiom) {
for (OWLAxiom ax : axiom.asSubDataPropertyOfAxioms()) {
if (!ax.accept(this)) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
@Override
public Boolean visit(OWLClassAssertionAxiom axiom) {
return kernel.isInstance(tr.pointer(axiom.getIndividual()),
tr.pointer(axiom.getClassExpression()));
}
@Override
public Boolean visit(OWLEquivalentClassesAxiom axiom) {
Set<OWLClassExpression> classExpressionSet = axiom
.getClassExpressions();
if (classExpressionSet.size() == 2) {
Iterator<OWLClassExpression> it = classExpressionSet.iterator();
return kernel.isEquivalent(tr.pointer(it.next()),
tr.pointer(it.next()));
} else {
for (OWLAxiom ax : axiom.asOWLSubClassOfAxioms()) {
if (!ax.accept(this)) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
}
@Override
public Boolean visit(OWLDataPropertyAssertionAxiom axiom) {
return axiom.asOWLSubClassOfAxiom().accept(this);
}
@Override
public Boolean visit(OWLTransitiveObjectPropertyAxiom axiom) {
return kernel.isTransitive(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLIrreflexiveObjectPropertyAxiom axiom) {
return kernel.isIrreflexive(tr.pointer(axiom.getProperty()));
}
// TODO: this is incomplete
@Override
public Boolean visit(OWLSubDataPropertyOfAxiom axiom) {
return kernel.isSubRoles(tr.pointer(axiom.getSubProperty()),
tr.pointer(axiom.getSuperProperty()));
}
@Override
public Boolean visit(OWLInverseFunctionalObjectPropertyAxiom axiom) {
return kernel.isInverseFunctional(tr.pointer(axiom.getProperty()));
}
@Override
public Boolean visit(OWLSameIndividualAxiom axiom) {
for (OWLSameIndividualAxiom ax : axiom.asPairwiseAxioms()) {
Iterator<OWLIndividual> it = ax.getIndividuals().iterator();
OWLIndividual indA = it.next();
OWLIndividual indB = it.next();
if (!kernel.isSameIndividuals(tr.pointer(indA), tr.pointer(indB))) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
@Override
public Boolean visit(OWLSubPropertyChainOfAxiom axiom) {
List<ObjectRoleExpression> l = new ArrayList<ObjectRoleExpression>();
for (OWLObjectPropertyExpression p : axiom.getPropertyChain()) {
l.add(tr.pointer(p));
}
return kernel.isSubChain(tr.pointer(axiom.getSuperProperty()), l);
}
@Override
public Boolean visit(OWLInverseObjectPropertiesAxiom axiom) {
for (OWLAxiom ax : axiom.asSubObjectPropertyOfAxioms()) {
if (!ax.accept(this)) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
}
@Override
public Boolean visit(OWLHasKeyAxiom axiom) {
// FIXME!! unsupported by FaCT++ ATM
// return null;
throw new UnsupportedEntailmentTypeException(axiom);
}
@Override
public Boolean visit(OWLDatatypeDefinitionAxiom axiom) {
// FIXME!! unsupported by FaCT++ ATM
// return null;
throw new UnsupportedEntailmentTypeException(axiom);
}
@Override
public Boolean visit(SWRLRule rule) {
// FIXME!! unsupported by FaCT++ ATM
// return null;
throw new UnsupportedEntailmentTypeException(rule);
}
@Override
public Boolean visit(OWLSubAnnotationPropertyOfAxiom axiom) {
return Boolean.FALSE;
}
@Override
public Boolean visit(OWLAnnotationPropertyDomainAxiom axiom) {
return Boolean.FALSE;
}
@Override
public Boolean visit(OWLAnnotationPropertyRangeAxiom axiom) {
return Boolean.FALSE;
}
}