org.semanticweb.HermiT.structural.OWLClausification Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.semanticweb.hermit Show documentation
Show all versions of org.semanticweb.hermit Show documentation
HermiT is reasoner for ontologies written using the Web Ontology Language (OWL). Given an OWL file, HermiT can determine whether or not the ontology is consistent, identify subsumption relationships between classes, and much more.
This is the maven build of HermiT and is designed for people who wish to use HermiT from within the OWL API. It is now versioned in the main HermiT version repository, although not officially supported by the HermiT developers.
The version number of this package is a composite of the HermiT version and a value representing the OWLAPI release it is compatible with. Note that the group id for the upstream HermiT is com.hermit-reasoner, while this fork is released under net.sourceforge.owlapi.
This fork exists to allow HermiT users to use newer OWLAPI versions than the ones supported by the original HermiT codebase.
This package includes the Jautomata library (http://jautomata.sourceforge.net/), and builds with it directly. This library appears to be no longer under active development, and so a "fork" seems appropriate. No development is intended or anticipated on this code base.
The newest version!
/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory
This file is part of HermiT.
HermiT 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.
HermiT 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 HermiT. If not, see .
*/
package org.semanticweb.HermiT.structural;
import static org.semanticweb.owlapi.util.OWLAPIStreamUtils.asList;
import java.util.*;
import org.semanticweb.HermiT.Configuration;
import org.semanticweb.HermiT.Prefixes;
import org.semanticweb.HermiT.datatypes.DatatypeRegistry;
import org.semanticweb.HermiT.datatypes.UnsupportedDatatypeException;
import org.semanticweb.HermiT.model.AnnotatedEquality;
import org.semanticweb.HermiT.model.AtLeastConcept;
import org.semanticweb.HermiT.model.AtLeastDataRange;
import org.semanticweb.HermiT.model.Atom;
import org.semanticweb.HermiT.model.AtomicConcept;
import org.semanticweb.HermiT.model.AtomicRole;
import org.semanticweb.HermiT.model.Constant;
import org.semanticweb.HermiT.model.ConstantEnumeration;
import org.semanticweb.HermiT.model.DLClause;
import org.semanticweb.HermiT.model.DLOntology;
import org.semanticweb.HermiT.model.DLPredicate;
import org.semanticweb.HermiT.model.DatatypeRestriction;
import org.semanticweb.HermiT.model.DescriptionGraph;
import org.semanticweb.HermiT.model.Equality;
import org.semanticweb.HermiT.model.Individual;
import org.semanticweb.HermiT.model.Inequality;
import org.semanticweb.HermiT.model.InternalDatatype;
import org.semanticweb.HermiT.model.LiteralConcept;
import org.semanticweb.HermiT.model.LiteralDataRange;
import org.semanticweb.HermiT.model.NodeIDLessEqualThan;
import org.semanticweb.HermiT.model.NodeIDsAscendingOrEqual;
import org.semanticweb.HermiT.model.Role;
import org.semanticweb.HermiT.model.Term;
import org.semanticweb.HermiT.model.Variable;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.vocab.OWL2Datatype;
/**OWLClausification.*/
public class OWLClausification {
private static final String INVALID_NORMAL_FORM = "Internal error: invalid normal form.";
protected static final Variable X=Variable.create("X");
protected static final Variable Y=Variable.create("Y");
protected static final Variable Z=Variable.create("Z");
protected final Configuration m_configuration;
/**
* @param configuration configuration
*/
public OWLClausification(Configuration configuration) {
m_configuration=configuration;
}
/**
* @param rootOntology rootOntology
* @param descriptionGraphs descriptionGraphs
* @return clausifications
*/
public Object[] preprocessAndClausify(OWLOntology rootOntology,Collection descriptionGraphs) {
OWLDataFactory factory=rootOntology.getOWLOntologyManager().getOWLDataFactory();
Optional defaultDocumentIRI = rootOntology.getOntologyID().getDefaultDocumentIRI();
String ontologyIRI=defaultDocumentIRI.isPresent()?defaultDocumentIRI.get().toString(): "urn:hermit:kb" ;
OWLAxioms axioms=new OWLAxioms();
OWLNormalization normalization=new OWLNormalization(factory,axioms,0);
normalization.processOntology(rootOntology);
BuiltInPropertyManager builtInPropertyManager=new BuiltInPropertyManager(factory);
builtInPropertyManager.axiomatizeBuiltInPropertiesAsNeeded(axioms);
ObjectPropertyInclusionManager objectPropertyInclusionManager=new ObjectPropertyInclusionManager(axioms);
// now object property inclusion manager added all non-simple properties to axioms.m_complexObjectPropertyExpressions
// now that we know which roles are non-simple, we can decide which negative object property assertions have to be
// expressed as concept assertions so that transitivity rewriting applies properly.
objectPropertyInclusionManager.rewriteNegativeObjectPropertyAssertions(factory,axioms,normalization.m_definitions.size());
objectPropertyInclusionManager.rewriteAxioms(factory,axioms,0);
OWLAxiomsExpressivity axiomsExpressivity=new OWLAxiomsExpressivity(axioms);
DLOntology dlOntology=clausify(factory,ontologyIRI,axioms,axiomsExpressivity,descriptionGraphs!=null?descriptionGraphs:Collections.emptySet());
return new Object[] { objectPropertyInclusionManager,dlOntology };
}
/**
* @param factory factory
* @param ontologyIRI ontologyIRI
* @param axioms axioms
* @param axiomsExpressivity axiomsExpressivity
* @param descriptionGraphs descriptionGraphs
* @return dl ontology
*/
public DLOntology clausify(OWLDataFactory factory,String ontologyIRI,OWLAxioms axioms,OWLAxiomsExpressivity axiomsExpressivity,Collection descriptionGraphs) {
List dlClauses=new ArrayList<>();
Set allUnknownDatatypeRestrictions=new HashSet<>();
for (List inclusion : axioms.m_simpleObjectPropertyInclusions) {
Atom subRoleAtom=getRoleAtom(inclusion.get(0),X,Y);
Atom superRoleAtom=getRoleAtom(inclusion.get(1),X,Y);
DLClause dlClause=DLClause.create(new Atom[] { superRoleAtom },new Atom[] { subRoleAtom });
dlClauses.add(dlClause);
}
for (List inclusion : axioms.m_dataPropertyInclusions) {
Atom subProp=getRoleAtom(inclusion.get(0),X,Y);
Atom superProp=getRoleAtom(inclusion.get(1),X,Y);
DLClause dlClause=DLClause.create(new Atom[] { superProp },new Atom[] { subProp });
dlClauses.add(dlClause);
}
for (OWLObjectPropertyExpression objectPropertyExpression : axioms.m_asymmetricObjectProperties) {
Atom roleAtom=getRoleAtom(objectPropertyExpression,X,Y);
Atom inverseRoleAtom=getRoleAtom(objectPropertyExpression,Y,X);
DLClause dlClause=DLClause.create(new Atom[] {},new Atom[] { roleAtom,inverseRoleAtom });
dlClauses.add(dlClause);
}
for (OWLObjectPropertyExpression objectPropertyExpression : axioms.m_reflexiveObjectProperties) {
Atom roleAtom=getRoleAtom(objectPropertyExpression,X,X);
Atom bodyAtom=Atom.create(AtomicConcept.THING,X);
DLClause dlClause=DLClause.create(new Atom[] { roleAtom },new Atom[] { bodyAtom });
dlClauses.add(dlClause);
}
for (OWLObjectPropertyExpression objectPropertyExpression : axioms.m_irreflexiveObjectProperties) {
Atom roleAtom=getRoleAtom(objectPropertyExpression,X,X);
DLClause dlClause=DLClause.create(new Atom[] {},new Atom[] { roleAtom });
dlClauses.add(dlClause);
}
for (List properties : axioms.m_disjointObjectProperties)
for (int i=0;i properties : axioms.m_disjointDataProperties)
for (int i=0;i positiveFacts=new HashSet<>();
Set negativeFacts=new HashSet<>();
DataRangeConverter dataRangeConverter=new DataRangeConverter(m_configuration.warningMonitor,axioms.m_definedDatatypesIRIs,allUnknownDatatypeRestrictions,m_configuration.ignoreUnsupportedDatatypes);
NormalizedAxiomClausifier clausifier=new NormalizedAxiomClausifier(dataRangeConverter,positiveFacts);
for (List inclusion : axioms.m_conceptInclusions) {
for (OWLClassExpression description : inclusion)
description.accept(clausifier);
DLClause dlClause=clausifier.getDLClause();
dlClauses.add(dlClause.getSafeVersion(AtomicConcept.THING));
}
NormalizedDataRangeAxiomClausifier normalizedDataRangeAxiomClausifier=new NormalizedDataRangeAxiomClausifier(dataRangeConverter,factory, axioms.m_definedDatatypesIRIs);
for (List inclusion : axioms.m_dataRangeInclusions) {
for (OWLDataRange description : inclusion)
description.accept(normalizedDataRangeAxiomClausifier);
DLClause dlClause=normalizedDataRangeAxiomClausifier.getDLClause();
dlClauses.add(dlClause.getSafeVersion(InternalDatatype.RDFS_LITERAL));
}
for (OWLHasKeyAxiom hasKey : axioms.m_hasKeys)
dlClauses.add(clausifyKey(hasKey));
FactClausifier factClausifier=new FactClausifier(dataRangeConverter,positiveFacts,negativeFacts);
for (OWLIndividualAxiom fact : axioms.m_facts)
fact.accept(factClausifier);
for (DescriptionGraph descriptionGraph : descriptionGraphs)
descriptionGraph.produceStartDLClauses(dlClauses);
Set atomicConcepts=new HashSet<>();
Set atomicObjectRoles=new HashSet<>();
Set complexObjectRoles=new HashSet<>();
Set atomicDataRoles=new HashSet<>();
for (OWLClass owlClass : axioms.m_classes)
atomicConcepts.add(AtomicConcept.create(owlClass.getIRI().toString()));
Set individuals=new HashSet<>();
for (OWLNamedIndividual owlIndividual : axioms.m_namedIndividuals) {
Individual individual=Individual.create(owlIndividual.getIRI().toString());
individuals.add(individual);
// all named individuals are tagged with a concept, so that keys/rules are
// only applied to them
if (!axioms.m_hasKeys.isEmpty() || !axioms.m_rules.isEmpty())
positiveFacts.add(Atom.create(AtomicConcept.INTERNAL_NAMED,individual));
}
for (OWLObjectProperty objectProperty : axioms.m_objectProperties)
atomicObjectRoles.add(AtomicRole.create(objectProperty.getIRI().toString()));
for (OWLObjectPropertyExpression objectPropertyExpression : axioms.m_complexObjectPropertyExpressions)
complexObjectRoles.add(getRole(objectPropertyExpression));
for (OWLDataProperty dataProperty : axioms.m_dataProperties)
atomicDataRoles.add(AtomicRole.create(dataProperty.getIRI().toString()));
// Clausify SWRL rules
if (!axioms.m_rules.isEmpty())
new NormalizedRuleClausifier(axioms.m_objectPropertiesOccurringInOWLAxioms,descriptionGraphs,dataRangeConverter,dlClauses).processRules(axioms.m_rules);
//drop duplicates
dlClauses=new ArrayList<>(new LinkedHashSet<>(dlClauses));
// Create the DL ontology
return new DLOntology(ontologyIRI,dlClauses,positiveFacts,negativeFacts,atomicConcepts,atomicObjectRoles,complexObjectRoles,atomicDataRoles,allUnknownDatatypeRestrictions,axioms.m_definedDatatypesIRIs,individuals,axiomsExpressivity.m_hasInverseRoles,axiomsExpressivity.m_hasAtMostRestrictions,axiomsExpressivity.m_hasNominals,axiomsExpressivity.m_hasDatatypes);
}
protected DLClause clausifyKey(OWLHasKeyAxiom object) {
List headAtoms=new ArrayList<>();
List bodyAtoms=new ArrayList<>();
// we have two named individuals (corresponding to X1 and X2) that
// might have to be equated
Variable X2=Variable.create("X2");
Variable X1=Variable.create("X1");
headAtoms.add(Atom.create(Equality.INSTANCE,X1,X2));
// keys only work on datatypes and named individuals
bodyAtoms.add(Atom.create(AtomicConcept.INTERNAL_NAMED,X1));
bodyAtoms.add(Atom.create(AtomicConcept.INTERNAL_NAMED,X2));
// the concept expression of a hasKey statement is either a concept
// name or a negated concept name after normalization
OWLClassExpression description=object.getClassExpression();
if (description instanceof OWLClass) {
OWLClass owlClass=(OWLClass)description;
if (!owlClass.isOWLThing()) {
bodyAtoms.add(Atom.create(AtomicConcept.create(owlClass.getIRI().toString()),X1));
bodyAtoms.add(Atom.create(AtomicConcept.create(owlClass.getIRI().toString()),X2));
}
}
else if (description instanceof OWLObjectComplementOf) {
OWLClassExpression internal=((OWLObjectComplementOf)description).getOperand();
if (internal instanceof OWLClass) {
OWLClass owlClass=(OWLClass)internal;
headAtoms.add(Atom.create(AtomicConcept.create(owlClass.getIRI().toString()),X1));
headAtoms.add(Atom.create(AtomicConcept.create(owlClass.getIRI().toString()),X2));
}
else
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
else
throw new IllegalStateException(INVALID_NORMAL_FORM);
int yIndex=1;
// object properties always go to the body
for (OWLObjectPropertyExpression p : asList(object.objectPropertyExpressions())) {
Variable y;
y=Variable.create("Y"+yIndex);
yIndex++;
bodyAtoms.add(getRoleAtom(p,X1,y));
bodyAtoms.add(getRoleAtom(p,X2,y));
// also the key criteria are named in case of object properties
bodyAtoms.add(Atom.create(AtomicConcept.INTERNAL_NAMED,y));
}
// data properties go to the body, but with different variables
// the head gets an atom asserting inequality between that data values
for (OWLDataPropertyExpression d : asList(object.dataPropertyExpressions())) {
Variable y;
y=Variable.create("Y"+yIndex);
yIndex++;
bodyAtoms.add(getRoleAtom(d,X1,y));
Variable y2;
y2=Variable.create("Y"+yIndex);
yIndex++;
bodyAtoms.add(getRoleAtom(d,X2,y2));
headAtoms.add(Atom.create(Inequality.INSTANCE,y,y2));
}
Atom[] hAtoms=new Atom[headAtoms.size()];
headAtoms.toArray(hAtoms);
Atom[] bAtoms=new Atom[bodyAtoms.size()];
bodyAtoms.toArray(bAtoms);
return DLClause.create(hAtoms,bAtoms);
}
private static boolean contains(OWLAxioms axioms, OWLDataProperty p) {
for(List e: axioms.m_dataPropertyInclusions) {
for(OWLDataPropertyExpression candidate:e) {
if(candidate.equals(p)) {
return true;
}
}
}
return false;
}
protected static LiteralConcept getLiteralConcept(OWLClassExpression description) {
if (description instanceof OWLClass) {
return AtomicConcept.create(((OWLClass)description).getIRI().toString());
}
else if (description instanceof OWLObjectComplementOf) {
OWLClassExpression internal=((OWLObjectComplementOf)description).getOperand();
if (!(internal instanceof OWLClass))
throw new IllegalStateException(INVALID_NORMAL_FORM);
return AtomicConcept.create(((OWLClass)internal).getIRI().toString()).getNegation();
}
else
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
protected static Role getRole(OWLObjectPropertyExpression objectPropertyExpression) {
if (objectPropertyExpression instanceof OWLObjectProperty)
return AtomicRole.create(((OWLObjectProperty)objectPropertyExpression).getIRI().toString());
else if (objectPropertyExpression instanceof OWLObjectInverseOf) {
OWLObjectPropertyExpression internal=((OWLObjectInverseOf)objectPropertyExpression).getInverse();
if (!(internal instanceof OWLObjectProperty))
throw new IllegalStateException(INVALID_NORMAL_FORM);
return AtomicRole.create(((OWLObjectProperty)internal).getIRI().toString()).getInverse();
}
else
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
protected static AtomicRole getAtomicRole(OWLDataPropertyExpression dataPropertyExpression) {
return AtomicRole.create(((OWLDataProperty)dataPropertyExpression).getIRI().toString());
}
protected static Atom getRoleAtom(OWLObjectPropertyExpression objectProperty,Term first,Term second) {
if (!objectProperty.isAnonymous()) {
AtomicRole role=AtomicRole.create(objectProperty.asOWLObjectProperty().getIRI().toString());
return Atom.create(role,first,second);
}
else if (objectProperty.isAnonymous()) {
OWLObjectProperty internalObjectProperty=objectProperty.getNamedProperty();
AtomicRole role=AtomicRole.create(internalObjectProperty.getIRI().toString());
return Atom.create(role,second,first);
}
else
throw new IllegalStateException("Internal error: unsupported type of object property!");
}
protected static Atom getRoleAtom(OWLDataPropertyExpression dataProperty,Term first,Term second) {
if (dataProperty instanceof OWLDataProperty) {
AtomicRole property=AtomicRole.create(((OWLDataProperty)dataProperty).getIRI().toString());
return Atom.create(property,first,second);
}
else
throw new IllegalStateException("Internal error: unsupported type of data property!");
}
protected static Individual getIndividual(OWLIndividual individual) {
if (individual.isAnonymous())
return Individual.createAnonymous(individual.asOWLAnonymousIndividual().getID().toString());
else
return Individual.create(individual.asOWLNamedIndividual().getIRI().toString());
}
protected static class NormalizedAxiomClausifier implements OWLClassExpressionVisitor {
protected final DataRangeConverter m_dataRangeConverter;
protected final List m_headAtoms;
protected final List m_bodyAtoms;
protected final Set m_positiveFacts;
protected int m_yIndex;
protected int m_zIndex;
public NormalizedAxiomClausifier(DataRangeConverter dataRangeConverter,Set positiveFacts) {
m_dataRangeConverter=dataRangeConverter;
m_headAtoms=new ArrayList<>();
m_bodyAtoms=new ArrayList<>();
m_positiveFacts=positiveFacts;
}
protected DLClause getDLClause() {
Atom[] headAtoms=new Atom[m_headAtoms.size()];
m_headAtoms.toArray(headAtoms);
Atom[] bodyAtoms=new Atom[m_bodyAtoms.size()];
m_bodyAtoms.toArray(bodyAtoms);
DLClause dlClause=DLClause.create(headAtoms,bodyAtoms);
m_headAtoms.clear();
m_bodyAtoms.clear();
m_yIndex=0;
m_zIndex=0;
return dlClause;
}
protected void ensureYNotZero() {
if (m_yIndex==0)
m_yIndex++;
}
protected Variable nextY() {
Variable result;
if (m_yIndex==0)
result=Y;
else
result=Variable.create("Y"+m_yIndex);
m_yIndex++;
return result;
}
protected Variable nextZ() {
Variable result;
if (m_zIndex==0)
result=Z;
else
result=Variable.create("Z"+m_zIndex);
m_zIndex++;
return result;
}
protected AtomicConcept getConceptForNominal(OWLIndividual individual) {
AtomicConcept result;
if (individual.isAnonymous()) {
result=AtomicConcept.create("internal:anon#"+individual.asOWLAnonymousIndividual().getID().toString());
}
else {
result=AtomicConcept.create("internal:nom#"+individual.asOWLNamedIndividual().getIRI().toString());
}
m_positiveFacts.add(Atom.create(result,getIndividual(individual)));
return result;
}
// Various types of descriptions
@Override
public void visit(OWLClass object) {
m_headAtoms.add(Atom.create(AtomicConcept.create(object.getIRI().toString()),X));
}
@Override
public void visit(OWLObjectIntersectionOf object) {
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
@Override
public void visit(OWLObjectUnionOf object) {
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
@Override
public void visit(OWLObjectComplementOf object) {
OWLClassExpression description=object.getOperand();
if (description instanceof OWLObjectHasSelf) {
OWLObjectPropertyExpression objectProperty=((OWLObjectHasSelf)description).getProperty();
Atom roleAtom=getRoleAtom(objectProperty,X,X);
m_bodyAtoms.add(roleAtom);
}
else if (description instanceof OWLObjectOneOf && ((OWLObjectOneOf)description).individuals().count()==1) {
OWLIndividual individual=((OWLObjectOneOf)description).individuals().iterator().next();
m_bodyAtoms.add(Atom.create(getConceptForNominal(individual),X));
}
else if (!(description instanceof OWLClass))
throw new IllegalStateException(INVALID_NORMAL_FORM);
else
m_bodyAtoms.add(Atom.create(AtomicConcept.create(((OWLClass)description).getIRI().toString()),X));
}
@Override
public void visit(OWLObjectOneOf object) {
object.individuals().forEach(i-> {
Variable z=nextZ();
AtomicConcept conceptForNominal=getConceptForNominal(i);
m_headAtoms.add(Atom.create(Equality.INSTANCE,X,z));
m_bodyAtoms.add(Atom.create(conceptForNominal,z));
});
}
@Override
public void visit(OWLObjectSomeValuesFrom object) {
OWLClassExpression filler=object.getFiller();
if (filler instanceof OWLObjectOneOf) {
((OWLObjectOneOf)filler).individuals().forEach(i-> {
Variable z=nextZ();
m_bodyAtoms.add(Atom.create(getConceptForNominal(i),z));
m_headAtoms.add(getRoleAtom(object.getProperty(),X,z));
});
}
else {
LiteralConcept toConcept=getLiteralConcept(filler);
Role onRole=getRole(object.getProperty());
AtLeastConcept atLeastConcept=AtLeastConcept.create(1,onRole,toConcept);
if (!atLeastConcept.isAlwaysFalse())
m_headAtoms.add(Atom.create(atLeastConcept,X));
}
}
@Override
public void visit(OWLObjectAllValuesFrom object) {
Variable y=nextY();
m_bodyAtoms.add(getRoleAtom(object.getProperty(),X,y));
OWLClassExpression filler=object.getFiller();
if (filler instanceof OWLClass) {
AtomicConcept atomicConcept=AtomicConcept.create(((OWLClass)filler).getIRI().toString());
if (!atomicConcept.isAlwaysFalse())
m_headAtoms.add(Atom.create(atomicConcept,y));
}
else if (filler instanceof OWLObjectOneOf) {
((OWLObjectOneOf)filler).individuals().forEach(i-> {
Variable zInd=nextZ();
m_bodyAtoms.add(Atom.create(getConceptForNominal(i),zInd));
m_headAtoms.add(Atom.create(Equality.INSTANCE,y,zInd));
});
}
else if (filler instanceof OWLObjectComplementOf) {
OWLClassExpression operand=((OWLObjectComplementOf)filler).getOperand();
if (operand instanceof OWLClass) {
AtomicConcept internalAtomicConcept=AtomicConcept.create(((OWLClass)operand).getIRI().toString());
if (!internalAtomicConcept.isAlwaysTrue())
m_bodyAtoms.add(Atom.create(internalAtomicConcept,y));
}
else if (operand instanceof OWLObjectOneOf && ((OWLObjectOneOf)operand).individuals().count()==1) {
OWLIndividual individual=((OWLObjectOneOf)operand).individuals().iterator().next();
m_bodyAtoms.add(Atom.create(getConceptForNominal(individual),y));
}
else
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
else
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
@Override
public void visit(OWLObjectHasValue object) {
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
@Override
public void visit(OWLObjectHasSelf object) {
OWLObjectPropertyExpression objectProperty=object.getProperty();
Atom roleAtom=getRoleAtom(objectProperty,X,X);
m_headAtoms.add(roleAtom);
}
@Override
public void visit(OWLObjectMinCardinality object) {
LiteralConcept toConcept=getLiteralConcept(object.getFiller());
Role onRole=getRole(object.getProperty());
AtLeastConcept atLeastConcept=AtLeastConcept.create(object.getCardinality(),onRole,toConcept);
if (!atLeastConcept.isAlwaysFalse())
m_headAtoms.add(Atom.create(atLeastConcept,X));
}
@Override
public void visit(OWLObjectMaxCardinality object) {
int cardinality=object.getCardinality();
OWLObjectPropertyExpression onObjectProperty=object.getProperty();
OWLClassExpression filler=object.getFiller();
ensureYNotZero();
boolean isPositive;
AtomicConcept atomicConcept;
if (filler instanceof OWLClass) {
isPositive=true;
atomicConcept=AtomicConcept.create(((OWLClass)filler).getIRI().toString());
if (atomicConcept.isAlwaysTrue())
atomicConcept=null;
}
else if (filler instanceof OWLObjectComplementOf) {
OWLClassExpression internal=((OWLObjectComplementOf)filler).getOperand();
if (!(internal instanceof OWLClass))
throw new IllegalStateException("Internal error: Invalid ontology normal form.");
isPositive=false;
atomicConcept=AtomicConcept.create(((OWLClass)internal).getIRI().toString());
if (atomicConcept.isAlwaysFalse())
atomicConcept=null;
}
else
throw new IllegalStateException("Internal error: Invalid ontology normal form.");
Role onRole=getRole(onObjectProperty);
LiteralConcept toConcept=getLiteralConcept(filler);
AnnotatedEquality annotatedEquality=AnnotatedEquality.create(cardinality,onRole,toConcept);
Variable[] yVars=new Variable[cardinality+1];
for (int i=0;i2) {
for (int i=0;i m_definedDatatypeIRIs;
protected final List m_headAtoms;
protected final List m_bodyAtoms;
protected final OWLDataFactory m_factory;
protected int m_yIndex;
public NormalizedDataRangeAxiomClausifier(DataRangeConverter dataRangeConverter,OWLDataFactory factory,Set definedDatatypeIRIs) {
m_dataRangeConverter=dataRangeConverter;
m_definedDatatypeIRIs=definedDatatypeIRIs;
m_headAtoms=new ArrayList<>();
m_bodyAtoms=new ArrayList<>();
m_factory=factory;
}
protected DLClause getDLClause() {
Atom[] headAtoms=new Atom[m_headAtoms.size()];
m_headAtoms.toArray(headAtoms);
Atom[] bodyAtoms=new Atom[m_bodyAtoms.size()];
m_bodyAtoms.toArray(bodyAtoms);
DLClause dlClause=DLClause.create(headAtoms,bodyAtoms);
m_headAtoms.clear();
m_bodyAtoms.clear();
m_yIndex=0;
return dlClause;
}
protected void ensureYNotZero() {
if (m_yIndex==0)
m_yIndex++;
}
protected Variable nextY() {
Variable result;
if (m_yIndex==0)
result=Y;
else
result=Variable.create("Y"+m_yIndex);
m_yIndex++;
return result;
}
// Various types of descriptions
@Override
public void visit(OWLDatatype dt) {
LiteralDataRange literalRange=m_dataRangeConverter.convertDataRange(dt);
m_headAtoms.add(Atom.create((DLPredicate)literalRange,X));
}
@Override
public void visit(OWLDataIntersectionOf dr) {
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
@Override
public void visit(OWLDataUnionOf dr) {
throw new IllegalStateException(INVALID_NORMAL_FORM);
}
private static String datatypeIRI(OWLDataRange r) {
if(r.isOWLDatatype()) {
return r.asOWLDatatype().getIRI().toString();
}
return null;
}
@Override
public void visit(OWLDataComplementOf dr) {
String iri=datatypeIRI(dr.getDataRange());
if (iri!=null && (Prefixes.isInternalIRI(iri) || m_definedDatatypeIRIs.contains(iri))) {
m_bodyAtoms.add(Atom.create(InternalDatatype.create(iri),X));
}
else {
LiteralDataRange literalRange=m_dataRangeConverter.convertDataRange(dr);
if (literalRange.isNegatedInternalDatatype()) {
InternalDatatype negatedDatatype=(InternalDatatype)literalRange.getNegation();
if (!negatedDatatype.isAlwaysTrue())
m_bodyAtoms.add(Atom.create(negatedDatatype,X));
}
else {
if (!literalRange.isAlwaysFalse())
m_headAtoms.add(Atom.create((DLPredicate)literalRange,X));
}
}
}
@Override
public void visit(OWLDataOneOf object) {
LiteralDataRange literalRange=m_dataRangeConverter.convertDataRange(object);
m_headAtoms.add(Atom.create((DLPredicate)literalRange,X));
}
@Override
public void visit(OWLFacetRestriction node) {
throw new IllegalStateException("Internal error: Invalid normal form. ");
}
@Override
public void visit(OWLDatatypeRestriction node) {
LiteralDataRange literalRange=m_dataRangeConverter.convertDataRange(node);
m_headAtoms.add(Atom.create((DLPredicate)literalRange,X));
}
@Override
public void visit(OWLLiteral node) {
throw new IllegalStateException("Internal error: Invalid normal form. ");
}
}
protected static class DataRangeConverter implements OWLDataVisitorEx