org.semanticweb.HermiT.Reasoner 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
an value representing releases of this packaged version. So, 1.3.7.1 is the
first release of the mavenized version of HermiT based on the 1.3.7 release
of HermiT.
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.
/* 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;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.semanticweb.HermiT.Configuration.BlockingStrategyType;
import org.semanticweb.HermiT.blocking.AncestorBlocking;
import org.semanticweb.HermiT.blocking.AnywhereBlocking;
import org.semanticweb.HermiT.blocking.AnywhereValidatedBlocking;
import org.semanticweb.HermiT.blocking.BlockingSignatureCache;
import org.semanticweb.HermiT.blocking.BlockingStrategy;
import org.semanticweb.HermiT.blocking.DirectBlockingChecker;
import org.semanticweb.HermiT.blocking.PairWiseDirectBlockingChecker;
import org.semanticweb.HermiT.blocking.SingleDirectBlockingChecker;
import org.semanticweb.HermiT.blocking.ValidatedPairwiseDirectBlockingChecker;
import org.semanticweb.HermiT.blocking.ValidatedSingleDirectBlockingChecker;
import org.semanticweb.HermiT.debugger.Debugger;
import org.semanticweb.HermiT.existentials.CreationOrderStrategy;
import org.semanticweb.HermiT.existentials.ExistentialExpansionStrategy;
import org.semanticweb.HermiT.existentials.IndividualReuseStrategy;
import org.semanticweb.HermiT.hierarchy.ClassificationProgressMonitor;
import org.semanticweb.HermiT.hierarchy.DeterministicClassification;
import org.semanticweb.HermiT.hierarchy.Hierarchy;
import org.semanticweb.HermiT.hierarchy.HierarchyDumperFSS;
import org.semanticweb.HermiT.hierarchy.HierarchyNode;
import org.semanticweb.HermiT.hierarchy.HierarchyPrinterFSS;
import org.semanticweb.HermiT.hierarchy.HierarchySearch;
import org.semanticweb.HermiT.hierarchy.InstanceManager;
import org.semanticweb.HermiT.hierarchy.QuasiOrderClassification;
import org.semanticweb.HermiT.hierarchy.QuasiOrderClassificationForRoles;
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.DLOntology;
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.InverseRole;
import org.semanticweb.HermiT.model.Role;
import org.semanticweb.HermiT.monitor.TableauMonitor;
import org.semanticweb.HermiT.monitor.TableauMonitorFork;
import org.semanticweb.HermiT.monitor.Timer;
import org.semanticweb.HermiT.monitor.TimerWithPause;
import org.semanticweb.HermiT.structural.BuiltInPropertyManager;
import org.semanticweb.HermiT.structural.OWLAxioms;
import org.semanticweb.HermiT.structural.OWLAxiomsExpressivity;
import org.semanticweb.HermiT.structural.OWLClausification;
import org.semanticweb.HermiT.structural.OWLNormalization;
import org.semanticweb.HermiT.structural.ObjectPropertyInclusionManager;
import org.semanticweb.HermiT.structural.ReducedABoxOnlyClausification;
import org.semanticweb.HermiT.tableau.InterruptFlag;
import org.semanticweb.HermiT.tableau.ReasoningTaskDescription;
import org.semanticweb.HermiT.tableau.Tableau;
import org.semanticweb.owlapi.model.AddAxiom;
import org.semanticweb.owlapi.model.AddOntologyAnnotation;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnonymousIndividual;
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.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLDatatype;
import org.semanticweb.owlapi.model.OWLDeclarationAxiom;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLException;
import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLIndividualAxiom;
import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectComplementOf;
import org.semanticweb.owlapi.model.OWLObjectHasSelf;
import org.semanticweb.owlapi.model.OWLObjectHasValue;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyChangeListener;
import org.semanticweb.owlapi.model.OWLOntologyFormat;
import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom;
import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom;
import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
import org.semanticweb.owlapi.model.RemoveAxiom;
import org.semanticweb.owlapi.model.RemoveOntologyAnnotation;
import org.semanticweb.owlapi.model.SWRLRule;
import org.semanticweb.owlapi.reasoner.BufferingMode;
import org.semanticweb.owlapi.reasoner.FreshEntitiesException;
import org.semanticweb.owlapi.reasoner.FreshEntityPolicy;
import org.semanticweb.owlapi.reasoner.InconsistentOntologyException;
import org.semanticweb.owlapi.reasoner.IndividualNodeSetPolicy;
import org.semanticweb.owlapi.reasoner.InferenceType;
import org.semanticweb.owlapi.reasoner.Node;
import org.semanticweb.owlapi.reasoner.NodeSet;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerConfiguration;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
import org.semanticweb.owlapi.reasoner.ReasonerInterruptedException;
import org.semanticweb.owlapi.reasoner.TimeOutException;
import org.semanticweb.owlapi.reasoner.impl.OWLClassNode;
import org.semanticweb.owlapi.reasoner.impl.OWLClassNodeSet;
import org.semanticweb.owlapi.reasoner.impl.OWLDataPropertyNode;
import org.semanticweb.owlapi.reasoner.impl.OWLDataPropertyNodeSet;
import org.semanticweb.owlapi.reasoner.impl.OWLNamedIndividualNode;
import org.semanticweb.owlapi.reasoner.impl.OWLNamedIndividualNodeSet;
import org.semanticweb.owlapi.reasoner.impl.OWLObjectPropertyNode;
import org.semanticweb.owlapi.reasoner.impl.OWLObjectPropertyNodeSet;
import org.semanticweb.owlapi.util.Version;
import org.semanticweb.owlapi.vocab.PrefixOWLOntologyFormat;
/**
* Answers queries about the logical implications of a particular knowledge base. A Reasoner is associated with a single knowledge base, which is "loaded" when the reasoner is constructed. By default a full classification of all atomic terms in the knowledge base is also performed at this time (which can take quite a while for large or complex ontologies), but this behavior can be disabled as a part of the Reasoner configuration. Internal details of the loading and reasoning algorithms can be configured in the Reasoner constructor and do not change over the lifetime of the Reasoner object---internal data structures and caches are optimized for a particular configuration. By default, HermiT will use the set of options which provide optimal performance.
*/
public class Reasoner implements OWLReasoner {
protected final OntologyChangeListener m_ontologyChangeListener;
protected final Configuration m_configuration;
protected final OWLOntology m_rootOntology;
protected final List m_pendingChanges;
protected final Collection m_descriptionGraphs;
protected final InterruptFlag m_interruptFlag;
protected ObjectPropertyInclusionManager m_objectPropertyInclusionManager;
protected DLOntology m_dlOntology;
protected Prefixes m_prefixes;
protected Tableau m_tableau;
protected Boolean m_isConsistent;
protected Hierarchy m_atomicConceptHierarchy;
protected Hierarchy m_objectRoleHierarchy;
protected Hierarchy m_dataRoleHierarchy;
protected Map>> m_directObjectRoleDomains;
protected Map>> m_directObjectRoleRanges;
protected Map>> m_directDataRoleDomains;
protected Map,Set>> m_directDisjointClasses;
protected InstanceManager m_instanceManager;
/**
* Creates a new reasoner object with standard parameters for blocking, expansion strategy etc. Then the given manager is used to find all required imports for the given ontology and the ontology with the imports is loaded into the reasoner and the data factory of the manager is used to create fresh concepts during the preprocessing phase if necessary.
*
* @param rootOntology
* - the ontology that should be loaded by the reasoner
*/
public Reasoner(OWLOntology rootOntology) {
this(new Configuration(),rootOntology,(Set)null);
}
/**
* Creates a new reasoner object with the parameters for blocking, expansion strategy etc as specified in the given configuration object. A default configuration can be obtained by just passing new Configuration(). Then the given manager is used to find all required imports for the given ontology and the ontology with the imports is loaded into the reasoner and the data factory of the manager is used to create fresh concepts during the preprocessing phase if necessary.
*
* @param configuration
* - a configuration in which parameters can be defined such as the blocking strategy to be used etc
* @param rootOntology
* - the ontology that should be loaded by the reasoner
*/
public Reasoner(Configuration configuration,OWLOntology rootOntology) {
this(configuration,rootOntology,(Set)null);
}
/**
* Creates a new reasoner object loaded with the given ontology and the given description graphs. When creating the reasoner, the given configuration determines the parameters for blocking, expansion strategy etc. A default configuration can be obtained by just passing new Configuration(). Then the given manager is used to find all required imports for the given ontology and the ontology with the imports and the description graphs are loaded into the reasoner. The data factory of the manager is used to create fresh concepts during the preprocessing phase if necessary.
*
* @param configuration
* - a configuration in which parameters can be defined such as the blocking strategy to be used etc
* @param rootOntology
* - the ontology that should be loaded by the reasoner
* @param descriptionGraphs
* - a set of description graphs
*/
public Reasoner(Configuration configuration,OWLOntology rootOntology,Collection descriptionGraphs) {
m_ontologyChangeListener=new OntologyChangeListener();
m_configuration=configuration;
m_rootOntology=rootOntology;
m_pendingChanges=new ArrayList();
m_rootOntology.getOWLOntologyManager().addOntologyChangeListener(m_ontologyChangeListener);
if (descriptionGraphs==null)
m_descriptionGraphs=Collections.emptySet();
else
m_descriptionGraphs=descriptionGraphs;
m_interruptFlag=new InterruptFlag(configuration.individualTaskTimeout);
m_directDisjointClasses=new HashMap,Set>>();
loadOntology();
}
// Life-cycle management methods
protected void loadOntology() {
clearState();
// Convert OWLOntology into DLOntology
OWLClausification clausifier=new OWLClausification(m_configuration);
Object[] result=clausifier.preprocessAndClausify(m_rootOntology,m_descriptionGraphs);
m_objectPropertyInclusionManager=(ObjectPropertyInclusionManager)result[0];
m_dlOntology=(DLOntology)result[1];
// Load the DLOntology
createPrefixes();
m_tableau=createTableau(m_interruptFlag,m_configuration,m_dlOntology,null,m_prefixes);
m_instanceManager=null;
}
protected void createPrefixes() {
m_prefixes=new Prefixes();
m_prefixes.declareSemanticWebPrefixes();
Set individualIRIs=new HashSet();
Set anonIndividualIRIs=new HashSet();
for (Individual individual : m_dlOntology.getAllIndividuals())
if (individual.isAnonymous())
addIRI(individual.getIRI(),anonIndividualIRIs);
else
addIRI(individual.getIRI(),individualIRIs);
m_prefixes.declareInternalPrefixes(individualIRIs,anonIndividualIRIs);
m_prefixes.declareDefaultPrefix(m_dlOntology.getOntologyIRI()+"#");
// declare prefixes as used in the ontology if possible
OWLOntologyFormat format=m_rootOntology.getOWLOntologyManager().getOntologyFormat(m_rootOntology);
if (format instanceof PrefixOWLOntologyFormat) {
PrefixOWLOntologyFormat prefixFormat=(PrefixOWLOntologyFormat)format;
for (String prefixName : prefixFormat.getPrefixName2PrefixMap().keySet()) {
String prefix=prefixFormat.getPrefixName2PrefixMap().get(prefixName);
if (m_prefixes.getPrefixName(prefix)==null)
try {
m_prefixes.declarePrefix(prefixName,prefix);
}
catch (IllegalArgumentException e) {
// ignore
}
}
}
}
protected void addIRI(String uri,Set prefixIRIs) {
if (!Prefixes.isInternalIRI(uri)) {
int lastHash=uri.lastIndexOf('#');
if (lastHash!=-1) {
String prefixIRI=uri.substring(0,lastHash+1);
prefixIRIs.add(prefixIRI);
}
}
}
protected void finalize() {
dispose();
}
public void dispose() {
m_rootOntology.getOWLOntologyManager().removeOntologyChangeListener(m_ontologyChangeListener);
clearState();
m_interruptFlag.dispose();
}
protected void clearState() {
m_pendingChanges.clear();
m_dlOntology=null;
m_prefixes=null;
m_tableau=null;
m_isConsistent=null;
m_atomicConceptHierarchy=null;
m_objectRoleHierarchy=null;
m_dataRoleHierarchy=null;
m_directObjectRoleDomains=new HashMap>>();
m_directObjectRoleRanges=new HashMap>>();
m_directDataRoleDomains=new HashMap>>();
m_directDisjointClasses=new HashMap,Set>>();
m_instanceManager=null;
}
public void interrupt() {
m_interruptFlag.interrupt();
}
public OWLDataFactory getDataFactory() {
return m_rootOntology.getOWLOntologyManager().getOWLDataFactory();
}
// Accessor methods of the OWL API
public String getReasonerName() {
return getClass().getPackage().getImplementationTitle();
}
public Version getReasonerVersion() {
String versionString=Reasoner.class.getPackage().getImplementationVersion();
String[] splitted;
int filled=0;
int version[]=new int[4];
if (versionString!=null) {
splitted=versionString.split("\\.");
while (filled changes) throws OWLException {
for (OWLOntologyChange change : changes)
if (!(change instanceof RemoveOntologyAnnotation || change instanceof AddOntologyAnnotation))
m_pendingChanges.add(change);
}
}
public BufferingMode getBufferingMode() {
return m_configuration.bufferChanges ? BufferingMode.BUFFERING : BufferingMode.NON_BUFFERING;
}
public Set getPendingAxiomAdditions() {
Set added=new HashSet();
for (OWLOntologyChange change : m_pendingChanges)
if (change instanceof AddAxiom)
added.add(change.getAxiom());
return added;
}
public Set getPendingAxiomRemovals() {
Set removed=new HashSet();
for (OWLOntologyChange change : m_pendingChanges)
if (change instanceof RemoveAxiom)
removed.add(change.getAxiom());
return removed;
}
public List getPendingChanges() {
return m_pendingChanges;
}
public void flush() {
if (!m_pendingChanges.isEmpty()) {
// check if we can only reload the ABox
if (canProcessPendingChangesIncrementally()) {
Set rootOntologyImportsClosure=m_rootOntology.getImportsClosure();
Set positiveFacts=m_dlOntology.getPositiveFacts();
Set negativeFacts=m_dlOntology.getNegativeFacts();
Set allIndividuals=new HashSet();
Set allAtomicConcepts=m_dlOntology.getAllAtomicConcepts();
Set allAtomicObjectRoles=m_dlOntology.getAllAtomicObjectRoles();
Set allAtomicDataRoles=m_dlOntology.getAllAtomicDataRoles();
ReducedABoxOnlyClausification aboxFactClausifier=new ReducedABoxOnlyClausification(m_configuration,getDataFactory(),allAtomicConcepts,allAtomicObjectRoles,allAtomicDataRoles);
for (OWLOntologyChange change : m_pendingChanges) {
if (rootOntologyImportsClosure.contains(change.getOntology())) {
OWLAxiom axiom=change.getAxiom();
if (axiom.isLogicalAxiom()) {
aboxFactClausifier.clausify((OWLIndividualAxiom)axiom);
if (change instanceof AddAxiom) {
positiveFacts.addAll(aboxFactClausifier.getPositiveFacts());
negativeFacts.addAll(aboxFactClausifier.getNegativeFacts());
}
else {
positiveFacts.removeAll(aboxFactClausifier.getPositiveFacts());
negativeFacts.removeAll(aboxFactClausifier.getNegativeFacts());
}
}
}
}
for (Atom atom : positiveFacts)
atom.getIndividuals(allIndividuals);
for (Atom atom : negativeFacts)
atom.getIndividuals(allIndividuals);
m_dlOntology=new DLOntology(m_dlOntology.getOntologyIRI(),m_dlOntology.getDLClauses(),positiveFacts,negativeFacts,allAtomicConcepts,allAtomicObjectRoles,m_dlOntology.getAllComplexObjectRoles(),allAtomicDataRoles,m_dlOntology.getAllUnknownDatatypeRestrictions(),m_dlOntology.getDefinedDatatypeIRIs(),allIndividuals,m_dlOntology.hasInverseRoles(),m_dlOntology.hasAtMostRestrictions(),m_dlOntology.hasNominals(),m_dlOntology.hasDatatypes());
m_tableau=new Tableau(m_interruptFlag,m_tableau.getTableauMonitor(),m_tableau.getExistentialsExpansionStrategy(),m_configuration.useDisjunctionLearning,m_dlOntology,null,m_configuration.parameters);
m_instanceManager=null;
m_isConsistent=null;
}
else
loadOntology();
m_pendingChanges.clear();
}
}
public boolean canProcessPendingChangesIncrementally() {
Set rootOntologyImportsClosure=m_rootOntology.getImportsClosure();
for (OWLOntologyChange change : m_pendingChanges) {
if (rootOntologyImportsClosure.contains(change.getOntology())) {
if (m_dlOntology.hasNominals() || !m_dlOntology.getAllDescriptionGraphs().isEmpty())
return false;
if (!change.isAxiomChange())
return false;
OWLAxiom axiom=change.getAxiom();
if (axiom.isLogicalAxiom()) {
if (axiom instanceof OWLClassAssertionAxiom) {
// we can handle everything that results in positive or negative facts
// (C a) with C a named class, HasSelf, HasValue, negated named class, negated HasSelf, negatedHasValue
// all used names must already exist in the loaded ontology
OWLClassAssertionAxiom classAssertion=(OWLClassAssertionAxiom)axiom;
OWLIndividual individual=classAssertion.getIndividual();
if (!isDefined(individual))
return false;
OWLClassExpression classExpression=classAssertion.getClassExpression();
if (classExpression instanceof OWLClass) {
if (!(isDefined((OWLClass)classExpression) || Prefixes.isInternalIRI(((OWLClass)classExpression).getIRI().toString())))
return false;
} else if (classExpression instanceof OWLObjectHasSelf) {
OWLObjectProperty namedOP=((OWLObjectHasSelf)classExpression).getProperty().getNamedProperty();
if (!(isDefined(namedOP) || Prefixes.isInternalIRI(namedOP.getIRI().toString())))
return false;
} else if (classExpression instanceof OWLObjectHasValue) {
OWLObjectHasValue hasValue=(OWLObjectHasValue)classExpression;
OWLObjectProperty namedOP=hasValue.getProperty().getNamedProperty();
OWLIndividual filler=hasValue.getValue();
if (!(isDefined(namedOP) || Prefixes.isInternalIRI(namedOP.getIRI().toString())) || !isDefined(filler))
return false;
} else if (classExpression instanceof OWLObjectComplementOf) {
OWLClassExpression negated=((OWLObjectComplementOf)classExpression).getOperand();
if (negated instanceof OWLClass) {
OWLClass cls=(OWLClass)negated;
if (!(isDefined(cls) || Prefixes.isInternalIRI(cls.getIRI().toString())))
return false;
} else if (negated instanceof OWLObjectHasSelf) {
OWLObjectHasSelf hasSelf=(OWLObjectHasSelf)negated;
OWLObjectProperty namedOP=hasSelf.getProperty().getNamedProperty();
if (!(isDefined(namedOP) || Prefixes.isInternalIRI(namedOP.getIRI().toString())))
return false;
} else if (negated instanceof OWLObjectHasValue) {
OWLObjectHasValue hasSelf=(OWLObjectHasValue)negated;
OWLObjectProperty namedOP=hasSelf.getProperty().getNamedProperty();
OWLIndividual filler=hasSelf.getValue();
if (!(isDefined(namedOP) || Prefixes.isInternalIRI(namedOP.getIRI().toString())) || !isDefined(filler))
return false;
} else {
return false;
}
} else
return false;
} else if (!(axiom instanceof OWLIndividualAxiom)) {
return false;
}
} else if (axiom instanceof OWLDeclarationAxiom) {
OWLEntity entity=((OWLDeclarationAxiom)axiom).getEntity();
if (entity.isOWLClass() && !(isDefined((OWLClass)entity) || Prefixes.isInternalIRI(((OWLClass)entity).getIRI().toString())))
return false;
else if (entity.isOWLObjectProperty() && !(isDefined((OWLObjectProperty)entity) || Prefixes.isInternalIRI(((OWLObjectProperty)entity).getIRI().toString())))
return false;
else if (entity.isOWLDataProperty() && !(isDefined((OWLDataProperty)entity) || Prefixes.isInternalIRI(((OWLDataProperty)entity).getIRI().toString())))
return false;
}
}
}
return true;
}
// General inferences
public boolean isDefined(OWLClass owlClass) {
AtomicConcept atomicConcept=AtomicConcept.create(owlClass.getIRI().toString());
return
m_dlOntology.containsAtomicConcept(atomicConcept) ||
AtomicConcept.THING.equals(atomicConcept) ||
AtomicConcept.NOTHING.equals(atomicConcept);
}
public boolean isDefined(OWLIndividual owlIndividual) {
Individual individual;
if (owlIndividual.isAnonymous())
individual=Individual.createAnonymous(owlIndividual.asOWLAnonymousIndividual().getID().toString());
else
individual=Individual.create(owlIndividual.asOWLNamedIndividual().getIRI().toString());
return m_dlOntology.containsIndividual(individual);
}
public boolean isDefined(OWLObjectProperty owlObjectProperty) {
AtomicRole atomicRole=AtomicRole.create(owlObjectProperty.getIRI().toString());
return
m_dlOntology.containsObjectRole(atomicRole) ||
AtomicRole.TOP_OBJECT_ROLE.equals(owlObjectProperty) ||
AtomicRole.BOTTOM_OBJECT_ROLE.equals(owlObjectProperty);
}
public boolean isDefined(OWLDataProperty owlDataProperty) {
AtomicRole atomicRole=AtomicRole.create(owlDataProperty.getIRI().toString());
return
m_dlOntology.containsDataRole(atomicRole) ||
AtomicRole.TOP_DATA_ROLE.equals(atomicRole) ||
AtomicRole.BOTTOM_DATA_ROLE.equals(atomicRole);
}
public Set getPrecomputableInferenceTypes() {
Set supportedInferenceTypes=new HashSet();
supportedInferenceTypes.add(InferenceType.CLASS_HIERARCHY);
supportedInferenceTypes.add(InferenceType.OBJECT_PROPERTY_HIERARCHY);
supportedInferenceTypes.add(InferenceType.DATA_PROPERTY_HIERARCHY);
supportedInferenceTypes.add(InferenceType.CLASS_ASSERTIONS);
supportedInferenceTypes.add(InferenceType.OBJECT_PROPERTY_ASSERTIONS);
// supportedInferenceTypes.add(InferenceType.DATA_PROPERTY_ASSERTIONS);
supportedInferenceTypes.add(InferenceType.SAME_INDIVIDUAL);
// supportedInferenceTypes.add(InferenceType.DISJOINT_CLASSES);
return supportedInferenceTypes;
}
public boolean isPrecomputed(InferenceType inferenceType) {
switch (inferenceType) {
case CLASS_HIERARCHY:
return m_atomicConceptHierarchy!=null;
case OBJECT_PROPERTY_HIERARCHY:
return m_objectRoleHierarchy!=null;
case DATA_PROPERTY_HIERARCHY:
return m_dataRoleHierarchy!=null;
case CLASS_ASSERTIONS:
return m_instanceManager!=null && m_instanceManager.realizationCompleted();
case OBJECT_PROPERTY_ASSERTIONS:
return m_instanceManager!=null && m_instanceManager.objectPropertyRealizationCompleted();
// case DATA_PROPERTY_ASSERTIONS:
// return m_dataRoleHierarchy!=null; // used to find sub-propeties
case SAME_INDIVIDUAL:
return m_instanceManager!=null && m_instanceManager.sameAsIndividualsComputed();
// case DIFFERENT_INDIVIDUALS:
// return false;
// case DISJOINT_CLASSES:
// return m_atomicConceptHierarchy!=null && m_directDisjointClasses.keySet().size()==m_atomicConceptHierarchy.getAllElements().size()-2;
default:
break;
}
return false;
}
public void precomputeInferences(InferenceType... inferenceTypes) throws ReasonerInterruptedException,TimeOutException,InconsistentOntologyException {
checkPreConditions();
boolean doAll=m_configuration.prepareReasonerInferences==null;
// doAll is only false when used via Protege, in that case the Protege preferences apply
Set requiredInferences=new HashSet(Arrays.asList(inferenceTypes));
if (requiredInferences.contains(InferenceType.CLASS_HIERARCHY))
if (doAll || m_configuration.prepareReasonerInferences.classClassificationRequired)
classifyClasses();
if (requiredInferences.contains(InferenceType.OBJECT_PROPERTY_HIERARCHY))
if (doAll || m_configuration.prepareReasonerInferences.objectPropertyClassificationRequired)
classifyObjectProperties();
if (requiredInferences.contains(InferenceType.DATA_PROPERTY_HIERARCHY))
if (doAll || m_configuration.prepareReasonerInferences.dataPropertyClassificationRequired)
classifyDataProperties();
if (requiredInferences.contains(InferenceType.CLASS_ASSERTIONS))
if (doAll || m_configuration.prepareReasonerInferences.realisationRequired) {
realise();
if (m_configuration.individualNodeSetPolicy==IndividualNodeSetPolicy.BY_SAME_AS || (m_configuration.prepareReasonerInferences!=null && m_configuration.prepareReasonerInferences.sameAs))
precomputeSameAsEquivalenceClasses();
}
if (requiredInferences.contains(InferenceType.OBJECT_PROPERTY_ASSERTIONS))
if (doAll || m_configuration.prepareReasonerInferences.objectPropertyRealisationRequired)
realiseObjectProperties();
// if (requiredInferences.contains(InferenceType.DATA_PROPERTY_ASSERTIONS))
// if (doAll || m_configuration.prepareReasonerInferences.dataPropertyRealisationRequired)
// classifyDataProperties(); // used to enriched stated instances
if (requiredInferences.contains(InferenceType.SAME_INDIVIDUAL))
if (doAll || m_configuration.prepareReasonerInferences.sameAs)
precomputeSameAsEquivalenceClasses();
// the tasks is not being supported by HermiT because it would be very slow
// we silently ignore the request as the documentation of the method recommends
// if (requiredInferences.contains(InferenceType.DIFFERENT_INDIVIDUALS))
// throw new UnsupportedOperationException("Error: HermiT cannot precompute different individuals. "+System.getProperty("line.separator")+"That is a very expensive task because all pairs of individuals have to be tested despite the fact that such a test will most likely fail. ");
// if (requiredInferences.contains(InferenceType.DISJOINT_CLASSES))
// precomputeDisjointClasses();
}
protected void initialisePropertiesInstanceManager() {
if (m_instanceManager==null || !m_instanceManager.arePropertiesInitialised()) {
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStarted("Initializing property instance data structures");
if (m_instanceManager==null)
m_instanceManager=new InstanceManager(m_interruptFlag,this,m_atomicConceptHierarchy,m_objectRoleHierarchy);
boolean isConsistent=true;
if (m_isConsistent!=null && !m_isConsistent)
m_instanceManager.setInconsistent();
else {
int noAxioms=m_dlOntology.getDLClauses().size();
int noComplexRoles=m_dlOntology.getAllComplexObjectRoles().size();
if (m_dlOntology.hasInverseRoles())
noComplexRoles=noComplexRoles/2;
int noIndividuals=m_dlOntology.getAllIndividuals().size();
int chunks=(((2*noComplexRoles*noIndividuals)/InstanceManager.thresholdForAdditionalAxioms))+1;
int stepsAdditionalAxioms=noComplexRoles*noIndividuals;
int stepsRewritingAdditionalAxioms=(5*noComplexRoles*noIndividuals)/chunks;
int stepsTableauExpansion=(stepsAdditionalAxioms/chunks)+noAxioms+noIndividuals;
int stepsInitialiseKnownPossible=noIndividuals+noComplexRoles*noIndividuals;
int steps=stepsAdditionalAxioms+(chunks*stepsRewritingAdditionalAxioms)+(chunks*stepsTableauExpansion)+stepsInitialiseKnownPossible;
int startIndividualIndex=0;
int completedSteps=0;
OWLAxiom[] additionalAxioms=m_instanceManager.getAxiomsForReadingOffCompexProperties(getDataFactory(),m_configuration.reasonerProgressMonitor,completedSteps,steps);
completedSteps+=stepsAdditionalAxioms/chunks;
boolean moreWork=true;
while (moreWork) {
Tableau tableau=getTableau(additionalAxioms);
completedSteps+=stepsRewritingAdditionalAxioms;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(completedSteps,steps);
isConsistent=tableau.isSatisfiable(true,true,null,null,null,null,m_instanceManager.getNodesForIndividuals(),new ReasoningTaskDescription(false,"Initial consistency check plus reading-off known and possible class and property instances (individual "+startIndividualIndex+" to "+m_instanceManager.getCurrentIndividualIndex()+")."));
completedSteps+=stepsTableauExpansion;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(completedSteps,steps);
if (!isConsistent) {
m_instanceManager.setInconsistent();
break;
}
else
completedSteps=m_instanceManager.initializeKnowAndPossiblePropertyInstances(tableau,m_configuration.reasonerProgressMonitor,startIndividualIndex,completedSteps,steps);
tableau.clearAdditionalDLOntology();
startIndividualIndex=m_instanceManager.getCurrentIndividualIndex();
additionalAxioms=m_instanceManager.getAxiomsForReadingOffCompexProperties(getDataFactory(),m_configuration.reasonerProgressMonitor,completedSteps,steps);
completedSteps+=stepsAdditionalAxioms/chunks;
moreWork=additionalAxioms.length>0;
}
if (m_isConsistent==null)
m_isConsistent=isConsistent;
}
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStopped();
}
}
protected void initialiseClassInstanceManager() {
if (m_instanceManager==null || !m_instanceManager.areClassesInitialised()) {
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStarted("Initializing class instance data structures");
if (m_instanceManager==null)
m_instanceManager=new InstanceManager(m_interruptFlag,this,m_atomicConceptHierarchy,m_objectRoleHierarchy);
boolean isConsistent=true;
if (m_isConsistent!=null && !m_isConsistent)
m_instanceManager.setInconsistent();
else {
int noAxioms=m_dlOntology.getDLClauses().size();
int noIndividuals=m_dlOntology.getAllIndividuals().size();
int stepsTableauExpansion=noAxioms+noIndividuals;
int stepsInitialiseKnownPossible=noIndividuals;
int steps=stepsTableauExpansion+stepsInitialiseKnownPossible;
int completedSteps=0;
Tableau tableau=getTableau();
isConsistent=tableau.isSatisfiable(true,true,null,null,null,null,m_instanceManager.getNodesForIndividuals(),new ReasoningTaskDescription(false,"Initial tableau for reading-off known and possible class instances."));
completedSteps+=stepsTableauExpansion;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(completedSteps,steps);
if (!isConsistent)
m_instanceManager.setInconsistent();
else
m_instanceManager.initializeKnowAndPossibleClassInstances(tableau,m_configuration.reasonerProgressMonitor,completedSteps,steps);
if (m_isConsistent==null)
m_isConsistent=isConsistent;
tableau.clearAdditionalDLOntology();
}
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStopped();
}
}
public boolean isConsistent() {
flushChangesIfRequired();
if (m_isConsistent==null)
m_isConsistent=getTableau().isSatisfiable(true,true,null,null,null,null,null,ReasoningTaskDescription.isABoxSatisfiable());
return m_isConsistent;
}
public boolean isEntailmentCheckingSupported(AxiomType> axiomType) {
return true;
}
public boolean isEntailed(OWLAxiom axiom) {
checkPreConditions(axiom);
if (!isConsistent())
return true;
EntailmentChecker checker=new EntailmentChecker(this,getDataFactory());
return checker.entails(axiom);
}
public boolean isEntailed(Set extends OWLAxiom> axioms) {
checkPreConditions(axioms.toArray(new OWLObject[0]));
if (!m_isConsistent)
return true;
EntailmentChecker checker=new EntailmentChecker(this,getDataFactory());
return checker.entails(axioms);
}
// Concept inferences
/**
* @deprecated As of release 1.3, replaced by {@link #precomputeInferences(InferenceType... inferenceTypes)} with inference type CLASS_HIERARCHY
*/
@Deprecated
public void classify() {
classifyClasses();
}
public void classifyClasses() {
checkPreConditions();
if (m_atomicConceptHierarchy==null) {
Set relevantAtomicConcepts=new HashSet();
relevantAtomicConcepts.add(AtomicConcept.THING);
relevantAtomicConcepts.add(AtomicConcept.NOTHING);
for (AtomicConcept atomicConcept : m_dlOntology.getAllAtomicConcepts())
if (!Prefixes.isInternalIRI(atomicConcept.getIRI()))
relevantAtomicConcepts.add(atomicConcept);
if (!m_isConsistent)
m_atomicConceptHierarchy=Hierarchy.emptyHierarchy(relevantAtomicConcepts,AtomicConcept.THING,AtomicConcept.NOTHING);
else {
try {
final int numRelevantConcepts=relevantAtomicConcepts.size();
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStarted("Building the class hierarchy...");
ClassificationProgressMonitor progressMonitor=new ClassificationProgressMonitor() {
protected int m_processedConcepts=0;
public void elementClassified(AtomicConcept element) {
m_processedConcepts++;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(m_processedConcepts,numRelevantConcepts);
}
};
m_atomicConceptHierarchy=classifyAtomicConcepts(getTableau(),progressMonitor,AtomicConcept.THING,AtomicConcept.NOTHING,relevantAtomicConcepts,m_configuration.forceQuasiOrderClassification);
if (m_instanceManager!=null)
m_instanceManager.setToClassifiedConceptHierarchy(m_atomicConceptHierarchy);
}
finally {
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStopped();
}
}
}
}
public Node getTopClassNode() {
classifyClasses();
return atomicConceptHierarchyNodeToNode(m_atomicConceptHierarchy.getTopNode());
}
public Node getBottomClassNode() {
classifyClasses();
return atomicConceptHierarchyNodeToNode(m_atomicConceptHierarchy.getBottomNode());
}
public boolean isSatisfiable(OWLClassExpression classExpression) {
checkPreConditions(classExpression);
if (!isConsistent())
return false;
if (classExpression instanceof OWLClass && m_atomicConceptHierarchy!=null) {
AtomicConcept concept=H((OWLClass)classExpression);
HierarchyNode node=m_atomicConceptHierarchy.getNodeForElement(concept);
return node!=m_atomicConceptHierarchy.getBottomNode();
}
else {
OWLDataFactory factory=getDataFactory();
OWLIndividual freshIndividual=factory.getOWLAnonymousIndividual("fresh-individual");
OWLClassAssertionAxiom assertClassExpression=factory.getOWLClassAssertionAxiom(classExpression,freshIndividual);
Tableau tableau=getTableau(assertClassExpression);
return tableau.isSatisfiable(true,null,null,null,null,null,ReasoningTaskDescription.isConceptSatisfiable(classExpression));
}
}
protected boolean isSubClassOf(OWLClassExpression subClassExpression,OWLClassExpression superClassExpression) {
checkPreConditions(subClassExpression,superClassExpression);
if (!isConsistent() || subClassExpression.isOWLNothing() || superClassExpression.isOWLThing())
return true;
if (subClassExpression instanceof OWLClass && superClassExpression instanceof OWLClass) {
AtomicConcept subconcept=H((OWLClass)subClassExpression);
AtomicConcept superconcept=H((OWLClass)superClassExpression);
if (m_atomicConceptHierarchy!=null && !containsFreshEntities(subClassExpression,superClassExpression)) {
HierarchyNode subconceptNode=m_atomicConceptHierarchy.getNodeForElement(subconcept);
return subconceptNode.isEquivalentElement(superconcept) || subconceptNode.isAncestorElement(superconcept);
}
else {
Tableau tableau=getTableau();
Individual freshIndividual=Individual.createAnonymous("fresh-individual");
Atom subconceptAssertion=Atom.create(subconcept,freshIndividual);
Atom superconceptAssertion=Atom.create(superconcept,freshIndividual);
return !tableau.isSatisfiable(true,Collections.singleton(subconceptAssertion),Collections.singleton(superconceptAssertion),null,null,null,ReasoningTaskDescription.isConceptSubsumedBy(subconcept,superconcept));
}
}
else {
OWLDataFactory factory=getDataFactory();
OWLIndividual freshIndividual=factory.getOWLAnonymousIndividual("fresh-individual");
OWLClassAssertionAxiom assertSubClassExpression=factory.getOWLClassAssertionAxiom(subClassExpression,freshIndividual);
OWLClassAssertionAxiom assertNotSuperClassExpression=factory.getOWLClassAssertionAxiom(superClassExpression.getObjectComplementOf(),freshIndividual);
Tableau tableau=getTableau(assertSubClassExpression,assertNotSuperClassExpression);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,ReasoningTaskDescription.isConceptSubsumedBy(subClassExpression,superClassExpression));
tableau.clearAdditionalDLOntology();
return !result;
}
}
public Node getEquivalentClasses(OWLClassExpression classExpression) {
HierarchyNode node=getHierarchyNode(classExpression);
return atomicConceptHierarchyNodeToNode(node);
}
public NodeSet getSuperClasses(OWLClassExpression classExpression,boolean direct) {
HierarchyNode node=getHierarchyNode(classExpression);
Set> result;
if (direct)
result=node.getParentNodes();
else {
result=new HashSet>(node.getAncestorNodes());
result.remove(node);
}
return atomicConceptHierarchyNodesToNodeSet(result);
}
public NodeSet getSubClasses(OWLClassExpression classExpression,boolean direct) {
HierarchyNode node=getHierarchyNode(classExpression);
Set> result;
if (direct)
result=node.getChildNodes();
else {
result=new HashSet>(node.getDescendantNodes());
result.remove(node);
}
return atomicConceptHierarchyNodesToNodeSet(result);
}
public Node getUnsatisfiableClasses() {
classifyClasses();
HierarchyNode node=m_atomicConceptHierarchy.getBottomNode();
return atomicConceptHierarchyNodeToNode(node);
}
public NodeSet getDisjointClasses(OWLClassExpression classExpression) {
checkPreConditions(classExpression);
classifyClasses();
if (classExpression.isOWLNothing() || !m_isConsistent) {
HierarchyNode node=m_atomicConceptHierarchy.getBottomNode();
return atomicConceptHierarchyNodesToNodeSet(node.getAncestorNodes());
}
else if (classExpression.isOWLThing()) {
HierarchyNode node=m_atomicConceptHierarchy.getBottomNode();
return atomicConceptHierarchyNodesToNodeSet(Collections.singleton(node));
}
else if (classExpression instanceof OWLClass) {
HierarchyNode node=getHierarchyNode(classExpression);
if (node==null || node==m_atomicConceptHierarchy.getTopNode()) {
// fresh concept
return new OWLClassNodeSet(getDataFactory().getOWLNothing());
}
else if (node==m_atomicConceptHierarchy.getBottomNode())
return atomicConceptHierarchyNodesToNodeSet(node.getAncestorNodes());
else {
Set> directDisjoints=getDisjointConceptNodes(node);
Set> result=new HashSet>();
for (HierarchyNode directDisjoint : directDisjoints) {
result.addAll(directDisjoint.getDescendantNodes());
}
return atomicConceptHierarchyNodesToNodeSet(result);
}
}
else {
Node equivalentToComplement=getEquivalentClasses(classExpression.getObjectComplementOf());
NodeSet subsDisjoint=getSubClasses(classExpression.getObjectComplementOf(),false);
Set> result=new HashSet>();
if (equivalentToComplement.getSize()>0)
result.add(equivalentToComplement);
result.addAll(subsDisjoint.getNodes());
return new OWLClassNodeSet(result);
}
}
protected Set> getDisjointConceptNodes(HierarchyNode node) {
if (m_directDisjointClasses.containsKey(node))
return m_directDisjointClasses.get(node);
else {
Set> result=new HashSet>();
OWLDataFactory factory=getDataFactory();
OWLClassExpression negated=factory.getOWLObjectComplementOf(factory.getOWLClass(IRI.create(node.getRepresentative().getIRI())));
HierarchyNode equivalentToComplement=getHierarchyNode(negated);
for (AtomicConcept equiv : equivalentToComplement.getEquivalentElements()) {
if (!Prefixes.isInternalIRI(equiv.getIRI())) {
HierarchyNode rootDisjoint=m_atomicConceptHierarchy.getNodeForElement(equiv);
result=Collections.singleton(rootDisjoint);
m_directDisjointClasses.put(node,result);
return result;
}
}
result=equivalentToComplement.getChildNodes();
m_directDisjointClasses.put(node,result);
return result;
}
}
public void precomputeDisjointClasses() {
checkPreConditions();
if (!m_isConsistent)
return;
if (m_atomicConceptHierarchy==null || m_directDisjointClasses.keySet().size()> nodes=new HashSet>(m_atomicConceptHierarchy.getAllNodes());
nodes.remove(m_atomicConceptHierarchy.getTopNode());
nodes.remove(m_atomicConceptHierarchy.getBottomNode());
nodes.removeAll(m_directDisjointClasses.keySet());
int steps=nodes.size();
int step=0;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStarted("Compute disjoint classes");
for (HierarchyNode node : nodes) {
getDisjointConceptNodes(node);
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(++step,steps);
}
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStopped();
}
}
protected HierarchyNode getHierarchyNode(OWLClassExpression classExpression) {
checkPreConditions(classExpression);
classifyClasses();
if (!isConsistent())
return m_atomicConceptHierarchy.getBottomNode();
else if (classExpression instanceof OWLClass) {
AtomicConcept atomicConcept=H((OWLClass)classExpression);
HierarchyNode node=m_atomicConceptHierarchy.getNodeForElement(atomicConcept);
if (node==null)
node=new HierarchyNode(atomicConcept,Collections.singleton(atomicConcept),Collections.singleton(m_atomicConceptHierarchy.getTopNode()),Collections.singleton(m_atomicConceptHierarchy.getBottomNode()));
return node;
}
else {
OWLDataFactory factory=getDataFactory();
OWLClass queryConcept=factory.getOWLClass(IRI.create("internal:query-concept"));
OWLAxiom classDefinitionAxiom=factory.getOWLEquivalentClassesAxiom(queryConcept,classExpression);
final Tableau tableau=getTableau(classDefinitionAxiom);
HierarchySearch.Relation hierarchyRelation=new HierarchySearch.Relation() {
public boolean doesSubsume(AtomicConcept parent,AtomicConcept child) {
Individual freshIndividual=Individual.createAnonymous("fresh-individual");
return !tableau.isSatisfiable(true,Collections.singleton(Atom.create(child,freshIndividual)),null,null,Collections.singleton(Atom.create(parent,freshIndividual)),null,ReasoningTaskDescription.isConceptSubsumedBy(child,parent));
}
};
HierarchyNode extendedHierarchy=HierarchySearch.findPosition(hierarchyRelation,AtomicConcept.create("internal:query-concept"),m_atomicConceptHierarchy.getTopNode(),m_atomicConceptHierarchy.getBottomNode());
tableau.clearAdditionalDLOntology();
return extendedHierarchy;
}
}
// Object property inferences
public void classifyObjectProperties() {
checkPreConditions();
if (m_objectRoleHierarchy==null) {
Set relevantObjectRoles=new HashSet();
for (AtomicRole atomicRole : m_dlOntology.getAllAtomicObjectRoles()) {
if (atomicRole!=AtomicRole.TOP_OBJECT_ROLE && atomicRole!=AtomicRole.BOTTOM_OBJECT_ROLE) {
relevantObjectRoles.add(atomicRole);
if (m_dlOntology.hasInverseRoles())
relevantObjectRoles.add(atomicRole.getInverse());
}
}
if (!m_isConsistent) {
relevantObjectRoles.add(AtomicRole.TOP_OBJECT_ROLE);
relevantObjectRoles.add(AtomicRole.BOTTOM_OBJECT_ROLE);
m_objectRoleHierarchy=Hierarchy.emptyHierarchy(relevantObjectRoles,AtomicRole.TOP_OBJECT_ROLE,AtomicRole.BOTTOM_OBJECT_ROLE);
}
else {
Map conceptsForRoles=new HashMap();
final Map rolesForConcepts=new HashMap();
// Create the additional axioms for classification
List additionalAxioms=new ArrayList();
OWLDataFactory factory=getDataFactory();
OWLClass freshConcept=factory.getOWLClass(IRI.create("internal:fresh-concept"));
for (Role objectRole : relevantObjectRoles) {
AtomicConcept conceptForRole;
OWLObjectPropertyExpression objectPropertyExpression;
if (objectRole instanceof AtomicRole) {
conceptForRole=AtomicConcept.create("internal:prop#"+((AtomicRole)objectRole).getIRI());
objectPropertyExpression=factory.getOWLObjectProperty(IRI.create(((AtomicRole)objectRole).getIRI()));
}
else {
conceptForRole=AtomicConcept.create("internal:prop#inv#"+((InverseRole)objectRole).getInverseOf().getIRI());
objectPropertyExpression=factory.getOWLObjectInverseOf(factory.getOWLObjectProperty(IRI.create(((InverseRole)objectRole).getInverseOf().getIRI())));
}
OWLAxiom axiom;
OWLClass classForRole=factory.getOWLClass(IRI.create(conceptForRole.getIRI()));
axiom=factory.getOWLEquivalentClassesAxiom(classForRole,factory.getOWLObjectSomeValuesFrom(objectPropertyExpression,freshConcept));
additionalAxioms.add(axiom);
conceptsForRoles.put(objectRole,conceptForRole);
rolesForConcepts.put(conceptForRole,objectRole);
}
// handle top & bottom case
conceptsForRoles.put(AtomicRole.TOP_OBJECT_ROLE,AtomicConcept.THING);
rolesForConcepts.put(AtomicConcept.THING,AtomicRole.TOP_OBJECT_ROLE);
conceptsForRoles.put(AtomicRole.BOTTOM_OBJECT_ROLE,AtomicConcept.NOTHING);
rolesForConcepts.put(AtomicConcept.NOTHING,AtomicRole.BOTTOM_OBJECT_ROLE);
OWLIndividual freshIndividual=factory.getOWLAnonymousIndividual();
OWLAxiom axiom=factory.getOWLClassAssertionAxiom(freshConcept,freshIndividual);
additionalAxioms.add(axiom);
OWLAxiom[] additionalAxiomsArray=new OWLAxiom[additionalAxioms.size()];
additionalAxioms.toArray(additionalAxiomsArray);
// Run the actual classification task
Tableau tableau=getTableau(additionalAxiomsArray);
try {
final int numberOfRoles=relevantObjectRoles.size();
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStarted("Classifying object properties...");
ClassificationProgressMonitor progressMonitor=new ClassificationProgressMonitor() {
protected int m_processedRoles=0;
public void elementClassified(AtomicConcept element) {
m_processedRoles++;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(m_processedRoles,numberOfRoles);
}
};
Hierarchy atomicConceptHierarchyForRoles=classifyAtomicConceptsForRoles(tableau,progressMonitor,conceptsForRoles.get(AtomicRole.TOP_OBJECT_ROLE),conceptsForRoles.get(AtomicRole.BOTTOM_OBJECT_ROLE),rolesForConcepts.keySet(),m_dlOntology.hasInverseRoles(),conceptsForRoles,rolesForConcepts,m_configuration.forceQuasiOrderClassification);
Hierarchy.Transformer transformer=new Hierarchy.Transformer() {
public Role transform(AtomicConcept atomicConcept) {
return rolesForConcepts.get(atomicConcept);
}
public Role determineRepresentative(AtomicConcept oldRepresentative,Set newEquivalentElements) {
return transform(oldRepresentative);
}
};
m_objectRoleHierarchy=atomicConceptHierarchyForRoles.transform(transformer,null);
if (m_instanceManager!=null)
m_instanceManager.setToClassifiedRoleHierarchy(m_objectRoleHierarchy);
}
finally {
tableau.clearAdditionalDLOntology();
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStopped();
}
}
}
}
public Node getTopObjectPropertyNode() {
classifyObjectProperties();
return objectPropertyHierarchyNodeToNode(m_objectRoleHierarchy.getTopNode());
}
public Node getBottomObjectPropertyNode() {
classifyObjectProperties();
return objectPropertyHierarchyNodeToNode(m_objectRoleHierarchy.getBottomNode());
}
protected boolean isSubObjectPropertyExpressionOf(OWLObjectPropertyExpression subObjectPropertyExpression,OWLObjectPropertyExpression superObjectPropertyExpression) {
checkPreConditions(subObjectPropertyExpression,superObjectPropertyExpression);
if (!m_isConsistent || subObjectPropertyExpression.getNamedProperty().isOWLBottomObjectProperty() || superObjectPropertyExpression.getNamedProperty().isOWLTopObjectProperty())
return true;
Role subrole=H(subObjectPropertyExpression);
Role superrole=H(superObjectPropertyExpression);
if (m_objectRoleHierarchy!=null && !containsFreshEntities(subObjectPropertyExpression,superObjectPropertyExpression)) {
HierarchyNode subroleNode=m_objectRoleHierarchy.getNodeForElement(subrole);
return subroleNode.isEquivalentElement(superrole) || subroleNode.isAncestorElement(superrole);
}
else {
OWLDataFactory factory=getDataFactory();
OWLClass pseudoNominal=factory.getOWLClass(IRI.create("internal:pseudo-nominal"));
OWLClassExpression allSuperNotPseudoNominal=factory.getOWLObjectAllValuesFrom(superObjectPropertyExpression,pseudoNominal.getObjectComplementOf());
OWLIndividual freshIndividualA=factory.getOWLAnonymousIndividual("fresh-individual-A");
OWLIndividual freshIndividualB=factory.getOWLAnonymousIndividual("fresh-individual-B");
OWLAxiom subObjectPropertyAssertion=factory.getOWLObjectPropertyAssertionAxiom(subObjectPropertyExpression,freshIndividualA,freshIndividualB);
OWLAxiom pseudoNominalAssertion=factory.getOWLClassAssertionAxiom(pseudoNominal,freshIndividualB);
OWLAxiom allSuperNotPseudoNominalAssertion=factory.getOWLClassAssertionAxiom(allSuperNotPseudoNominal,freshIndividualA);
Tableau tableau=getTableau(subObjectPropertyAssertion,pseudoNominalAssertion,allSuperNotPseudoNominalAssertion);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,ReasoningTaskDescription.isRoleSubsumedBy(subrole,superrole,true));
tableau.clearAdditionalDLOntology();
return !result;
}
}
protected boolean isSubObjectPropertyExpressionOf(List subPropertyChain,OWLObjectPropertyExpression superObjectPropertyExpression) {
OWLObject[] objects=new OWLObject[subPropertyChain.size()+1];
for (int i=0;i getSuperObjectProperties(OWLObjectPropertyExpression propertyExpression,boolean direct) {
HierarchyNode node=getHierarchyNode(propertyExpression);
Set> result=new HashSet>();
if (direct)
for (HierarchyNode n : node.getParentNodes())
result.add(n);
else {
result=node.getAncestorNodes();
result.remove(node);
}
return objectPropertyHierarchyNodesToNodeSet(result);
}
public NodeSet getSubObjectProperties(OWLObjectPropertyExpression propertyExpression,boolean direct) {
HierarchyNode node=getHierarchyNode(propertyExpression);
Set> result=new HashSet>();
if (direct)
for (HierarchyNode n : node.getChildNodes())
result.add(n);
else {
result=node.getDescendantNodes();
result.remove(node);
}
return objectPropertyHierarchyNodesToNodeSet(result);
}
public Node getEquivalentObjectProperties(OWLObjectPropertyExpression propertyExpression) {
return objectPropertyHierarchyNodeToNode(getHierarchyNode(propertyExpression));
}
public NodeSet getObjectPropertyDomains(OWLObjectPropertyExpression propertyExpression,boolean direct) {
checkPreConditions(propertyExpression);
classifyClasses();
if (!isConsistent())
return new OWLClassNodeSet(getBottomClassNode());
final Role role=H(propertyExpression);
Set> nodes=m_directObjectRoleDomains.get(role);
if (nodes==null) {
final Individual freshIndividualA=Individual.createAnonymous("fresh-individual-A");
final Individual freshIndividualB=Individual.createAnonymous("fresh-individual-B");
final Set roleAssertion=Collections.singleton(role.getRoleAssertion(freshIndividualA,freshIndividualB));
final Tableau tableau=getTableau();
HierarchySearch.SearchPredicate> searchPredicate=new HierarchySearch.SearchPredicate>() {
public Set> getSuccessorElements(HierarchyNode u) {
return u.getChildNodes();
}
public Set> getPredecessorElements(HierarchyNode u) {
return u.getParentNodes();
}
public boolean trueOf(HierarchyNode u) {
AtomicConcept potentialDomainConcept=u.getRepresentative();
return !tableau.isSatisfiable(false,roleAssertion,Collections.singleton(Atom.create(potentialDomainConcept,freshIndividualA)),null,null,null,ReasoningTaskDescription.isDomainOf(potentialDomainConcept,role));
}
};
nodes=HierarchySearch.search(searchPredicate,Collections.singleton(m_atomicConceptHierarchy.getTopNode()),null);
m_directObjectRoleDomains.put(role,nodes);
}
if (!direct)
nodes=HierarchyNode.getAncestorNodes(nodes);
return atomicConceptHierarchyNodesToNodeSet(nodes);
}
public NodeSet getObjectPropertyRanges(OWLObjectPropertyExpression propertyExpression,boolean direct) {
checkPreConditions(propertyExpression);
classifyClasses();
if (!isConsistent())
return new OWLClassNodeSet(getBottomClassNode());
final Role role=H(propertyExpression);
Set> nodes=m_directObjectRoleRanges.get(role);
if (nodes==null) {
final Individual freshIndividualA=Individual.createAnonymous("fresh-individual-A");
final Individual freshIndividualB=Individual.createAnonymous("fresh-individual-B");
final Set roleAssertion=Collections.singleton(role.getRoleAssertion(freshIndividualA,freshIndividualB));
final Tableau tableau=getTableau();
HierarchySearch.SearchPredicate> searchPredicate=new HierarchySearch.SearchPredicate>() {
public Set> getSuccessorElements(HierarchyNode u) {
return u.getChildNodes();
}
public Set> getPredecessorElements(HierarchyNode u) {
return u.getParentNodes();
}
public boolean trueOf(HierarchyNode u) {
AtomicConcept potentialRangeConcept=u.getRepresentative();
return !tableau.isSatisfiable(false,roleAssertion,Collections.singleton(Atom.create(potentialRangeConcept,freshIndividualB)),null,null,null,ReasoningTaskDescription.isRangeOf(potentialRangeConcept,role));
}
};
nodes=HierarchySearch.search(searchPredicate,Collections.singleton(m_atomicConceptHierarchy.getTopNode()),null);
m_directObjectRoleRanges.put(role,nodes);
}
if (!direct)
nodes=HierarchyNode.getAncestorNodes(nodes);
return atomicConceptHierarchyNodesToNodeSet(nodes);
}
public Node getInverseObjectProperties(OWLObjectPropertyExpression propertyExpression) {
return getEquivalentObjectProperties(propertyExpression.getSimplified().getInverseProperty());
}
public NodeSet getDisjointObjectProperties(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return new OWLObjectPropertyNodeSet();
classifyObjectProperties();
Set> result=new HashSet>();
if (propertyExpression.getNamedProperty().isOWLTopObjectProperty()) {
result.add(m_objectRoleHierarchy.getBottomNode());
return objectPropertyHierarchyNodesToNodeSet(result);
}
else if (propertyExpression.isOWLBottomObjectProperty()) {
HierarchyNode node=m_objectRoleHierarchy.getTopNode();
result.add(node);
result.addAll(node.getDescendantNodes());
return objectPropertyHierarchyNodesToNodeSet(result);
}
Role role=H(propertyExpression);
Individual freshIndividualA=Individual.createAnonymous("fresh-individual-A");
Individual freshIndividualB=Individual.createAnonymous("fresh-individual-B");
Atom roleAssertion=role.getRoleAssertion(freshIndividualA,freshIndividualB);
Tableau tableau=getTableau();
Set> nodesToTest=new HashSet>();
nodesToTest.addAll(m_objectRoleHierarchy.getTopNode().getChildNodes());
while (!nodesToTest.isEmpty()) {
HierarchyNode nodeToTest=nodesToTest.iterator().next();
nodesToTest.remove(nodeToTest);
Role roleToTest=nodeToTest.getRepresentative();
Atom roleToTestAssertion=roleToTest.getRoleAssertion(freshIndividualA,freshIndividualB);
Set perTestAtoms=new HashSet(2);
perTestAtoms.add(roleAssertion);
perTestAtoms.add(roleToTestAssertion);
if (!tableau.isSatisfiable(false,perTestAtoms,null,null,null,null,new ReasoningTaskDescription(true,"disjointness of {0} and {1}",role,roleToTest)))
// disjoint
result.addAll(nodeToTest.getDescendantNodes());
else
// maybe some children are disjoint
nodesToTest.addAll(nodeToTest.getChildNodes());
}
if (result.isEmpty())
result.add(m_objectRoleHierarchy.getBottomNode());
return objectPropertyHierarchyNodesToNodeSet(result);
}
protected boolean isDisjointObjectProperty(OWLObjectPropertyExpression propertyExpression1,OWLObjectPropertyExpression propertyExpression2) {
checkPreConditions(propertyExpression1,propertyExpression2);
if (!m_isConsistent)
return true;
Role role1=H(propertyExpression1);
Role role2=H(propertyExpression2);
Individual freshIndividualA=Individual.createAnonymous("fresh-individual-A");
Individual freshIndividualB=Individual.createAnonymous("fresh-individual-B");
Atom roleAssertion1=role1.getRoleAssertion(freshIndividualA,freshIndividualB);
Atom roleAssertion2=role2.getRoleAssertion(freshIndividualA,freshIndividualB);
Set perTestAtoms=new HashSet(2);
perTestAtoms.add(roleAssertion1);
perTestAtoms.add(roleAssertion2);
return !getTableau().isSatisfiable(false,perTestAtoms,null,null,null,null,new ReasoningTaskDescription(true,"disjointness of {0} and {1}",role1,role2));
}
protected boolean isFunctional(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return true;
Role role=H(propertyExpression);
Individual freshIndividual=Individual.createAnonymous("fresh-individual");
Individual freshIndividualA=Individual.createAnonymous("fresh-individual-A");
Individual freshIndividualB=Individual.createAnonymous("fresh-individual-B");
Set assertions=new HashSet();
assertions.add(role.getRoleAssertion(freshIndividual,freshIndividualA));
assertions.add(role.getRoleAssertion(freshIndividual,freshIndividualB));
assertions.add(Atom.create(Inequality.INSTANCE,freshIndividualA,freshIndividualB));
return !getTableau().isSatisfiable(false,assertions,null,null,null,null,new ReasoningTaskDescription(true,"functionality of {0}",role));
}
protected boolean isInverseFunctional(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return true;
Role role=H(propertyExpression);
Individual freshIndividual=Individual.createAnonymous("fresh-individual");
Individual freshIndividualA=Individual.createAnonymous("fresh-individual-A");
Individual freshIndividualB=Individual.createAnonymous("fresh-individual-B");
Set assertions=new HashSet();
assertions.add(role.getRoleAssertion(freshIndividualA,freshIndividual));
assertions.add(role.getRoleAssertion(freshIndividualB,freshIndividual));
assertions.add(Atom.create(Inequality.INSTANCE,freshIndividualA,freshIndividualB));
return !getTableau().isSatisfiable(false,assertions,null,null,null,null,new ReasoningTaskDescription(true,"inverse-functionality of {0}",role));
}
protected boolean isIrreflexive(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return true;
Role role=H(propertyExpression);
Individual freshIndividual=Individual.createAnonymous("fresh-individual");
return !getTableau().isSatisfiable(false,Collections.singleton(role.getRoleAssertion(freshIndividual,freshIndividual)),null,null,null,null,new ReasoningTaskDescription(true,"irreflexivity of {0}",role));
}
protected boolean isReflexive(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return true;
OWLDataFactory factory=getDataFactory();
OWLClass pseudoNominal=factory.getOWLClass(IRI.create("internal:pseudo-nominal"));
OWLClassExpression allNotPseudoNominal=factory.getOWLObjectAllValuesFrom(propertyExpression,pseudoNominal.getObjectComplementOf());
OWLIndividual freshIndividual=factory.getOWLAnonymousIndividual("fresh-individual");
OWLAxiom pseudoNominalAssertion=factory.getOWLClassAssertionAxiom(pseudoNominal,freshIndividual);
OWLAxiom allNotPseudoNominalAssertion=factory.getOWLClassAssertionAxiom(allNotPseudoNominal,freshIndividual);
Tableau tableau=getTableau(pseudoNominalAssertion,allNotPseudoNominalAssertion);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,new ReasoningTaskDescription(true,"symmetry of {0}",H(propertyExpression)));
tableau.clearAdditionalDLOntology();
return !result;
}
protected boolean isAsymmetric(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return true;
OWLDataFactory factory=getDataFactory();
OWLIndividual freshIndividualA=factory.getOWLAnonymousIndividual("fresh-individual-A");
OWLIndividual freshIndividualB=factory.getOWLAnonymousIndividual("fresh-individual-B");
OWLAxiom assertion1=factory.getOWLObjectPropertyAssertionAxiom(propertyExpression,freshIndividualA,freshIndividualB);
OWLAxiom assertion2=factory.getOWLObjectPropertyAssertionAxiom(propertyExpression.getInverseProperty(),freshIndividualA,freshIndividualB);
Tableau tableau=getTableau(assertion1,assertion2);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,new ReasoningTaskDescription(true,"asymmetry of {0}",H(propertyExpression)));
tableau.clearAdditionalDLOntology();
return !result;
}
protected boolean isSymmetric(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent || propertyExpression.getNamedProperty().isOWLTopObjectProperty())
return true;
OWLDataFactory factory=getDataFactory();
OWLClass pseudoNominal=factory.getOWLClass(IRI.create("internal:pseudo-nominal"));
OWLClassExpression allNotPseudoNominal=factory.getOWLObjectAllValuesFrom(propertyExpression,pseudoNominal.getObjectComplementOf());
OWLIndividual freshIndividualA=factory.getOWLAnonymousIndividual("fresh-individual-A");
OWLIndividual freshIndividualB=factory.getOWLAnonymousIndividual("fresh-individual-B");
OWLAxiom assertion1=factory.getOWLObjectPropertyAssertionAxiom(propertyExpression,freshIndividualA,freshIndividualB);
OWLAxiom assertion2=factory.getOWLClassAssertionAxiom(allNotPseudoNominal,freshIndividualB);
OWLAxiom assertion3=factory.getOWLClassAssertionAxiom(pseudoNominal,freshIndividualA);
Tableau tableau=getTableau(assertion1,assertion2,assertion3);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,new ReasoningTaskDescription(true,"symmetry of {0}",propertyExpression));
tableau.clearAdditionalDLOntology();
return !result;
}
protected boolean isTransitive(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (!m_isConsistent)
return true;
OWLDataFactory factory=getDataFactory();
OWLClass pseudoNominal=factory.getOWLClass(IRI.create("internal:pseudo-nominal"));
OWLClassExpression allNotPseudoNominal=factory.getOWLObjectAllValuesFrom(propertyExpression,pseudoNominal.getObjectComplementOf());
OWLIndividual freshIndividualA=factory.getOWLAnonymousIndividual("fresh-individual-A");
OWLIndividual freshIndividualB=factory.getOWLAnonymousIndividual("fresh-individual-B");
OWLIndividual freshIndividualC=factory.getOWLAnonymousIndividual("fresh-individual-C");
OWLAxiom assertion1=factory.getOWLObjectPropertyAssertionAxiom(propertyExpression,freshIndividualA,freshIndividualB);
OWLAxiom assertion2=factory.getOWLObjectPropertyAssertionAxiom(propertyExpression,freshIndividualB,freshIndividualC);
OWLAxiom assertion3=factory.getOWLClassAssertionAxiom(allNotPseudoNominal,freshIndividualA);
OWLAxiom assertion4=factory.getOWLClassAssertionAxiom(pseudoNominal,freshIndividualC);
Tableau tableau=getTableau(assertion1,assertion2,assertion3,assertion4);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,new ReasoningTaskDescription(true,"transitivity of {0}",H(propertyExpression)));
tableau.clearAdditionalDLOntology();
return !result;
}
protected HierarchyNode getHierarchyNode(OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
classifyObjectProperties();
if (!m_isConsistent)
return m_objectRoleHierarchy.getBottomNode();
else {
Role role=H(propertyExpression);
HierarchyNode node=m_objectRoleHierarchy.getNodeForElement(role);
if (node==null)
node=new HierarchyNode(role,Collections.singleton(role),Collections.singleton(m_objectRoleHierarchy.getTopNode()),Collections.singleton(m_objectRoleHierarchy.getBottomNode()));
return node;
}
}
// Data property inferences
public void classifyDataProperties() {
checkPreConditions();
if (m_dataRoleHierarchy==null) {
Set relevantDataRoles=new HashSet();
relevantDataRoles.add(AtomicRole.TOP_DATA_ROLE);
relevantDataRoles.add(AtomicRole.BOTTOM_DATA_ROLE);
relevantDataRoles.addAll(m_dlOntology.getAllAtomicDataRoles());
if (!m_isConsistent)
m_dataRoleHierarchy=Hierarchy.emptyHierarchy(relevantDataRoles,AtomicRole.TOP_DATA_ROLE,AtomicRole.BOTTOM_DATA_ROLE);
else {
if (m_dlOntology.hasDatatypes()) {
Map conceptsForRoles=new HashMap();
final Map rolesForConcepts=new HashMap();
// Create the additional axioms for classification
List additionalAxioms=new ArrayList();
OWLDataFactory factory=getDataFactory();
OWLDatatype unknownDatatypeA=factory.getOWLDatatype(IRI.create("internal:unknown-datatype#A"));
for (AtomicRole dataRole : relevantDataRoles) {
AtomicConcept conceptForRole;
if (AtomicRole.TOP_DATA_ROLE.equals(dataRole))
conceptForRole=AtomicConcept.THING;
else if (AtomicRole.BOTTOM_DATA_ROLE.equals(dataRole))
conceptForRole=AtomicConcept.NOTHING;
else {
conceptForRole=AtomicConcept.create("internal:prop#"+dataRole.getIRI());
OWLClass classForRole=factory.getOWLClass(IRI.create(conceptForRole.getIRI()));
OWLDataProperty dataProperty=factory.getOWLDataProperty(IRI.create(dataRole.getIRI()));
OWLAxiom axiom=factory.getOWLEquivalentClassesAxiom(classForRole,factory.getOWLDataSomeValuesFrom(dataProperty,unknownDatatypeA));
additionalAxioms.add(axiom);
}
conceptsForRoles.put(dataRole,conceptForRole);
rolesForConcepts.put(conceptForRole,dataRole);
}
OWLAxiom[] additionalAxiomsArray=new OWLAxiom[additionalAxioms.size()];
additionalAxioms.toArray(additionalAxiomsArray);
// Run the actual classification task
Tableau tableau=getTableau(additionalAxiomsArray);
try {
final int numberOfRoles=relevantDataRoles.size();
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStarted("Classifying data properties...");
ClassificationProgressMonitor progressMonitor=new ClassificationProgressMonitor() {
protected int m_processedRoles=0;
public void elementClassified(AtomicConcept element) {
m_processedRoles++;
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskProgressChanged(m_processedRoles,numberOfRoles);
}
};
Hierarchy atomicConceptHierarchyForRoles=classifyAtomicConcepts(tableau,progressMonitor,conceptsForRoles.get(AtomicRole.TOP_DATA_ROLE),conceptsForRoles.get(AtomicRole.BOTTOM_DATA_ROLE),rolesForConcepts.keySet(),m_configuration.forceQuasiOrderClassification);
Hierarchy.Transformer transformer=new Hierarchy.Transformer() {
public AtomicRole transform(AtomicConcept atomicConcept) {
return rolesForConcepts.get(atomicConcept);
}
public AtomicRole determineRepresentative(AtomicConcept oldRepresentative,Set newEquivalentElements) {
return transform(oldRepresentative);
}
};
m_dataRoleHierarchy=atomicConceptHierarchyForRoles.transform(transformer,null);
}
finally {
tableau.clearAdditionalDLOntology();
if (m_configuration.reasonerProgressMonitor!=null)
m_configuration.reasonerProgressMonitor.reasonerTaskStopped();
}
}
else
m_dataRoleHierarchy=Hierarchy.trivialHierarchy(AtomicRole.TOP_DATA_ROLE,AtomicRole.BOTTOM_DATA_ROLE);
}
}
}
public Node getTopDataPropertyNode() {
classifyDataProperties();
return dataPropertyHierarchyNodeToNode(m_dataRoleHierarchy.getTopNode());
}
public Node getBottomDataPropertyNode() {
classifyDataProperties();
return dataPropertyHierarchyNodeToNode(m_dataRoleHierarchy.getBottomNode());
}
protected boolean isSubDataPropertyOf(OWLDataProperty subDataProperty,OWLDataProperty superDataProperty) {
checkPreConditions(subDataProperty,superDataProperty);
if (!m_isConsistent || subDataProperty.isOWLBottomDataProperty() || superDataProperty.isOWLTopDataProperty())
return true;
AtomicRole subrole=H(subDataProperty);
AtomicRole superrole=H(superDataProperty);
if (m_dataRoleHierarchy!=null && !containsFreshEntities(subDataProperty,superDataProperty)) {
HierarchyNode subroleNode=m_dataRoleHierarchy.getNodeForElement(subrole);
return subroleNode.isEquivalentElement(superrole) || subroleNode.isAncestorElement(superrole);
}
else {
OWLDataFactory factory=getDataFactory();
OWLIndividual individual=factory.getOWLAnonymousIndividual("fresh-individual");
OWLLiteral freshConstant=factory.getOWLLiteral("internal:fresh-constant",factory.getOWLDatatype(IRI.create("internal:anonymous-constants")));
OWLDataProperty negatedSuperDataProperty=factory.getOWLDataProperty(IRI.create("internal:negated-superproperty"));
OWLAxiom subpropertyAssertion=factory.getOWLDataPropertyAssertionAxiom(subDataProperty,individual,freshConstant);
OWLAxiom negatedSuperpropertyAssertion=factory.getOWLDataPropertyAssertionAxiom(negatedSuperDataProperty,individual,freshConstant);
OWLAxiom superpropertyAxiomatization=factory.getOWLDisjointDataPropertiesAxiom(superDataProperty,negatedSuperDataProperty);
Tableau tableau=getTableau(subpropertyAssertion,negatedSuperpropertyAssertion,superpropertyAxiomatization);
boolean result=tableau.isSatisfiable(true,null,null,null,null,null,ReasoningTaskDescription.isRoleSubsumedBy(subrole,superrole,false));
tableau.clearAdditionalDLOntology();
return !result;
}
}
public NodeSet getSuperDataProperties(OWLDataProperty property,boolean direct) {
HierarchyNode node=getHierarchyNode(property);
Set> result;
if (direct)
result=node.getParentNodes();
else {
result=new HashSet>(node.getAncestorNodes());
result.remove(node);
}
return dataPropertyHierarchyNodesToNodeSet(result);
}
public NodeSet getSubDataProperties(OWLDataProperty property,boolean direct) {
HierarchyNode node=getHierarchyNode(property);
Set> result;
if (direct)
result=node.getChildNodes();
else {
result=new HashSet>(node.getDescendantNodes());
result.remove(node);
}
return dataPropertyHierarchyNodesToNodeSet(result);
}
public Node getEquivalentDataProperties(OWLDataProperty property) {
return dataPropertyHierarchyNodeToNode(getHierarchyNode(property));
}
public NodeSet getDataPropertyDomains(OWLDataProperty property,boolean direct) {
checkPreConditions(property);
classifyClasses();
if (!m_isConsistent)
return new OWLClassNodeSet(getBottomClassNode());
final AtomicRole atomicRole=H(property);
Set> nodes=m_directDataRoleDomains.get(atomicRole);
if (nodes==null) {
final Individual freshIndividual=Individual.createAnonymous("fresh-individual");
final Constant freshConstant=Constant.createAnonymous("fresh-constant");
final Set roleAssertion=Collections.singleton(atomicRole.getRoleAssertion(freshIndividual,freshConstant));
final Tableau tableau=getTableau();
HierarchySearch.SearchPredicate> searchPredicate=new HierarchySearch.SearchPredicate>() {
public Set> getSuccessorElements(HierarchyNode u) {
return u.getChildNodes();
}
public Set> getPredecessorElements(HierarchyNode u) {
return u.getParentNodes();
}
public boolean trueOf(HierarchyNode u) {
AtomicConcept potentialDomainConcept=u.getRepresentative();
return !tableau.isSatisfiable(false,roleAssertion,Collections.singleton(Atom.create(potentialDomainConcept,freshIndividual)),null,null,null,ReasoningTaskDescription.isDomainOf(potentialDomainConcept,atomicRole));
}
};
nodes=HierarchySearch.search(searchPredicate,Collections.singleton(m_atomicConceptHierarchy.getTopNode()),null);
m_directDataRoleDomains.put(atomicRole,nodes);
}
if (!direct)
nodes=HierarchyNode.getAncestorNodes(nodes);
return atomicConceptHierarchyNodesToNodeSet(nodes);
}
public NodeSet getDisjointDataProperties(OWLDataPropertyExpression propertyExpression) {
checkPreConditions(propertyExpression);
if (m_dlOntology.hasDatatypes()) {
classifyDataProperties();
if (!m_isConsistent)
return new OWLDataPropertyNodeSet();
Set> result=new HashSet>();
if (propertyExpression.isOWLTopDataProperty()) {
result.add(m_dataRoleHierarchy.getBottomNode());
return dataPropertyHierarchyNodesToNodeSet(result);
}
else if (propertyExpression.isOWLBottomDataProperty()) {
HierarchyNode node=m_dataRoleHierarchy.getTopNode();
result.add(node);
result.addAll(node.getDescendantNodes());
return dataPropertyHierarchyNodesToNodeSet(result);
}
AtomicRole atomicRole=H(propertyExpression.asOWLDataProperty());
Individual freshIndividual=Individual.create("fresh-individual");
Constant freshConstant=Constant.createAnonymous("fresh-constant");
Atom atomicRoleAssertion=atomicRole.getRoleAssertion(freshIndividual,freshConstant);
Tableau tableau=getTableau();
Set> nodesToTest=new HashSet>();
nodesToTest.addAll(m_dataRoleHierarchy.getTopNode().getChildNodes());
while (!nodesToTest.isEmpty()) {
HierarchyNode nodeToTest=nodesToTest.iterator().next();
nodesToTest.remove(nodeToTest);
AtomicRole atomicRoleToTest=nodeToTest.getRepresentative();
Atom atomicRoleToTestAssertion=atomicRoleToTest.getRoleAssertion(freshIndividual,freshConstant);
Set perTestAtoms=new HashSet(2);
perTestAtoms.add(atomicRoleAssertion);
perTestAtoms.add(atomicRoleToTestAssertion);
if (!tableau.isSatisfiable(false,perTestAtoms,null,null,null,null,new ReasoningTaskDescription(true,"disjointness of {0} and {1}",atomicRole,atomicRoleToTest)))
// disjoint
result.addAll(nodeToTest.getDescendantNodes());
else
// maybe some children are disjoint
nodesToTest.addAll(nodeToTest.getChildNodes());
}
if (result.isEmpty())
result.add(m_dataRoleHierarchy.getBottomNode());
return dataPropertyHierarchyNodesToNodeSet(result);
}
else {
OWLDataFactory factory=getDataFactory();
if (propertyExpression.isOWLTopDataProperty() && isConsistent())
return new OWLDataPropertyNodeSet(new OWLDataPropertyNode(factory.getOWLBottomDataProperty()));
else if (propertyExpression.isOWLBottomDataProperty() && isConsistent())
return new OWLDataPropertyNodeSet(new OWLDataPropertyNode(factory.getOWLTopDataProperty()));
else
return new OWLDataPropertyNodeSet();
}
}
protected boolean isFunctional(OWLDataProperty property) {
checkPreConditions(property);
if (!m_isConsistent)
return true;
AtomicRole atomicRole=H(property);
Individual freshIndividual=Individual.createAnonymous("fresh-individual");
Constant freshConstantA=Constant.createAnonymous("fresh-constant-A");
Constant freshConstantB=Constant.createAnonymous("fresh-constant-B");
Set assertions=new HashSet();
assertions.add(atomicRole.getRoleAssertion(freshIndividual,freshConstantA));
assertions.add(atomicRole.getRoleAssertion(freshIndividual,freshConstantB));
assertions.add(Atom.create(Inequality.INSTANCE,freshConstantA,freshConstantB));
return !getTableau().isSatisfiable(false,assertions,null,null,null,null,new ReasoningTaskDescription(true,"functionality of {0}",atomicRole));
}
protected HierarchyNode getHierarchyNode(OWLDataProperty property) {
checkPreConditions(property);
classifyDataProperties();
if (!m_isConsistent)
return m_dataRoleHierarchy.getBottomNode();
else {
AtomicRole atomicRole=H(property);
HierarchyNode node=m_dataRoleHierarchy.getNodeForElement(atomicRole);
if (node==null)
node=new HierarchyNode(atomicRole,Collections.singleton(atomicRole),Collections.singleton(m_dataRoleHierarchy.getTopNode()),Collections.singleton(m_dataRoleHierarchy.getBottomNode()));
return node;
}
}
// Individual inferences
protected void realise() {
checkPreConditions();
if (m_dlOntology.getAllIndividuals().size()>0) {
classifyClasses();
initialiseClassInstanceManager();
m_instanceManager.realize(m_configuration.reasonerProgressMonitor);
}
}
public void realiseObjectProperties() {
checkPreConditions();
if (m_dlOntology.getAllIndividuals().size()>0) {
classifyObjectProperties();
initialisePropertiesInstanceManager();
m_instanceManager.realizeObjectRoles(m_configuration.reasonerProgressMonitor);
}
}
public void precomputeSameAsEquivalenceClasses() {
checkPreConditions();
if (m_dlOntology.getAllIndividuals().size()>0) {
initialiseClassInstanceManager();
m_instanceManager.computeSameAsEquivalenceClasses(m_configuration.reasonerProgressMonitor);
}
}
public NodeSet getTypes(OWLNamedIndividual namedIndividual,boolean direct) {
checkPreConditions(namedIndividual);
Set> result;
if (!isDefined(namedIndividual)) {
classifyClasses();
result=new HashSet>();
result.add(m_atomicConceptHierarchy.getTopNode());
}
else {
if (direct)
classifyClasses();
initialiseClassInstanceManager();
if (direct)
m_instanceManager.setToClassifiedConceptHierarchy(m_atomicConceptHierarchy);
result=m_instanceManager.getTypes(H(namedIndividual),direct);
}
return atomicConceptHierarchyNodesToNodeSet(result);
}
public boolean hasType(OWLNamedIndividual namedIndividual,OWLClassExpression type,boolean direct) {
checkPreConditions(namedIndividual,type);
if (!m_isConsistent)
return true;
if (!isDefined(namedIndividual))
return getEquivalentClasses(type).contains(m_rootOntology.getOWLOntologyManager().getOWLDataFactory().getOWLThing());
else {
if (type instanceof OWLClass) {
if (direct)
classifyClasses();
initialiseClassInstanceManager();
if (direct)
m_instanceManager.setToClassifiedConceptHierarchy(m_atomicConceptHierarchy);
return m_instanceManager.hasType(H(namedIndividual),H((OWLClass)type),direct);
}
else {
OWLDataFactory factory=getDataFactory();
OWLAxiom negatedAssertionAxiom=factory.getOWLClassAssertionAxiom(type.getObjectComplementOf(),namedIndividual);
Tableau tableau=getTableau(negatedAssertionAxiom);
boolean result=tableau.isSatisfiable(true,true,null,null,null,null,null,ReasoningTaskDescription.isInstanceOf(namedIndividual,type));
tableau.clearAdditionalDLOntology();
return !result;
}
}
}
public NodeSet getInstances(OWLClassExpression classExpression,boolean direct) {
if (m_dlOntology.getAllIndividuals().size()>0) {
checkPreConditions(classExpression);
if (!m_isConsistent) {
Node node=new OWLNamedIndividualNode(getAllNamedIndividuals());
return new OWLNamedIndividualNodeSet(Collections.singleton(node));
}
if (direct || !(classExpression instanceof OWLClass))
classifyClasses();
initialiseClassInstanceManager();
Set result=new HashSet();
if (classExpression instanceof OWLClass)
result=m_instanceManager.getInstances(H((OWLClass)classExpression),direct);
else {
HierarchyNode hierarchyNode=getHierarchyNode(classExpression); //defines internal:query-concept as equivalent to the queried (complex) concepts and inserts internal:query-concept into the class hierarchy
result=m_instanceManager.getInstances(hierarchyNode,direct); // gets instances of classes that are direct subclasses of internal:query-concept
OWLDataFactory factory=getDataFactory();
OWLClass queryClass=factory.getOWLClass(IRI.create("internal:query-concept"));
OWLAxiom queryClassDefinition=factory.getOWLSubClassOfAxiom(queryClass,classExpression.getObjectComplementOf());
AtomicConcept queryConcept=AtomicConcept.create("internal:query-concept");
Set> visitedNodes=new HashSet>(hierarchyNode.getChildNodes());
List> toVisit=new ArrayList>(hierarchyNode.getParentNodes()); //look for (direct) sibling nodes
while (!toVisit.isEmpty()) {
HierarchyNode node=toVisit.remove(toVisit.size()-1);
if (visitedNodes.add(node)) {
Set realizationForNodeConcept=m_instanceManager.getInstances(node,true);
if (realizationForNodeConcept!=null) {
Tableau tableau=getTableau(queryClassDefinition);
for (Individual individual : realizationForNodeConcept)
if (isResultRelevantIndividual(individual))
if (!tableau.isSatisfiable(true,true,Collections.singleton(Atom.create(queryConcept,individual)),null,null,null,null,ReasoningTaskDescription.isInstanceOf(individual,classExpression)))
result.add(individual);
tableau.clearAdditionalDLOntology();
}
toVisit.addAll(node.getChildNodes());
}
}
}
return sortBySameAsIfNecessary(result);
}
else
return new OWLNamedIndividualNodeSet(new HashSet>());
}
public boolean isSameIndividual(OWLNamedIndividual namedIndividual1,OWLNamedIndividual namedIndividual2) {
checkPreConditions(namedIndividual1,namedIndividual2);
if (!m_isConsistent)
return true;
if (m_dlOntology.getAllIndividuals().size()==0)
return false;
else {
initialiseClassInstanceManager();
m_instanceManager.computeSameAsEquivalenceClasses(m_configuration.reasonerProgressMonitor);
return m_instanceManager.isSameIndividual(H(namedIndividual1),H(namedIndividual2));
}
}
public Node getSameIndividuals(OWLNamedIndividual namedIndividual) {
checkPreConditions(namedIndividual);
if (!m_isConsistent)
return new OWLNamedIndividualNode(getAllNamedIndividuals());
if (m_dlOntology.getAllIndividuals().size()==0 || !m_dlOntology.containsIndividual(H(namedIndividual)))
return new OWLNamedIndividualNode(namedIndividual);
else {
initialiseClassInstanceManager();
Set sameIndividuals=m_instanceManager.getSameAsIndividuals(H(namedIndividual));
OWLDataFactory factory=getDataFactory();
Set result=new HashSet();
for (Individual individual : sameIndividuals)
result.add(factory.getOWLNamedIndividual(IRI.create(individual.getIRI())));
return new OWLNamedIndividualNode(result);
}
}
public NodeSet getDifferentIndividuals(OWLNamedIndividual namedIndividual) {
checkPreConditions(namedIndividual);
if (!m_isConsistent) {
Node node=new OWLNamedIndividualNode(getAllNamedIndividuals());
return new OWLNamedIndividualNodeSet(Collections.singleton(node));
}
Individual individual=H(namedIndividual);
Tableau tableau=getTableau();
Set result=new HashSet();
for (Individual potentiallyDifferentIndividual : m_dlOntology.getAllIndividuals())
if (isResultRelevantIndividual(potentiallyDifferentIndividual) && !individual.equals(potentiallyDifferentIndividual))
if (!tableau.isSatisfiable(true,true,Collections.singleton(Atom.create(Equality.INSTANCE,individual,potentiallyDifferentIndividual)),null,null,null,null,new ReasoningTaskDescription(true,"is {0} different from {1}",individual,potentiallyDifferentIndividual)))
result.add(potentiallyDifferentIndividual);
return sortBySameAsIfNecessary(result);
}
public NodeSet getObjectPropertyValues(OWLNamedIndividual namedIndividual,OWLObjectPropertyExpression propertyExpression) {
checkPreConditions(namedIndividual,propertyExpression);
if (!m_isConsistent) {
Node node=new OWLNamedIndividualNode(getAllNamedIndividuals());
return new OWLNamedIndividualNodeSet(Collections.singleton(node));
}
AtomicRole role=H(propertyExpression.getNamedProperty());
if (!m_dlOntology.containsObjectRole(role))
return new OWLNamedIndividualNodeSet();
initialisePropertiesInstanceManager();
Individual individual=H(namedIndividual);
Set result;
if (propertyExpression.getSimplified().isAnonymous()) {
// inverse role
result=m_instanceManager.getObjectPropertySubjects(role,individual);
} else {
// named role
result=m_instanceManager.getObjectPropertyValues(role,individual);
}
return sortBySameAsIfNecessary(result);
}
public Map> getObjectPropertyInstances(OWLObjectProperty property) {
checkPreConditions(property);
Map> result=new HashMap>();
if (!m_isConsistent) {
Set all=getAllNamedIndividuals();
for (OWLNamedIndividual ind : all)
result.put(ind,all);
return result;
}
initialisePropertiesInstanceManager();
AtomicRole role=H(property);
Map> relations=m_instanceManager.getObjectPropertyInstances(role);
OWLDataFactory factory=getDataFactory();
for (Individual individual : relations.keySet()) {
Set successors=new HashSet();
result.put(factory.getOWLNamedIndividual(IRI.create(individual.getIRI())),successors);
for (Individual successorIndividual : relations.get(individual))
successors.add(factory.getOWLNamedIndividual(IRI.create(successorIndividual.getIRI())));
}
return result;
}
public boolean hasObjectPropertyRelationship(OWLNamedIndividual subject,OWLObjectPropertyExpression propertyExpression,OWLNamedIndividual object) {
checkPreConditions(subject,propertyExpression,object);
if (!m_isConsistent)
return true;
initialisePropertiesInstanceManager();
OWLObjectProperty property=propertyExpression.getNamedProperty();
if (propertyExpression.getSimplified().isAnonymous()) {
OWLNamedIndividual tmp=subject;
subject=object;
object=tmp;
}
AtomicRole role=H(property);
Individual subj=H(subject);
Individual obj=H(object);
return m_instanceManager.hasObjectRoleRelationship(role,subj,obj);
}
public Set getDataPropertyValues(OWLNamedIndividual namedIndividual,OWLDataProperty property) {
checkPreConditions(namedIndividual,property);
Set result=new HashSet();
if (m_dlOntology.hasDatatypes()) {
OWLDataFactory factory=getDataFactory();
Set relevantDataProperties=getSubDataProperties(property,false).getFlattened();
relevantDataProperties.add(property);
Set relevantIndividuals=getSameIndividuals(namedIndividual).getEntities();
for (OWLDataProperty dataProperty : relevantDataProperties) {
if (!dataProperty.isBottomEntity()) {
AtomicRole atomicRole=H(dataProperty);
Map> dataPropertyAssertions=m_dlOntology.getDataPropertyAssertions().get(atomicRole);
if (dataPropertyAssertions!=null) {
for (OWLNamedIndividual ind : relevantIndividuals) {
Individual individual=H(ind);
if (dataPropertyAssertions.containsKey(individual)) {
for (Constant constant : dataPropertyAssertions.get(individual)) {
String lexicalForm=constant.getLexicalForm();
String datatypeURI=constant.getDatatypeURI();
OWLLiteral literal;
if ((Prefixes.s_semanticWebPrefixes.get("rdf:")+"PlainLiteral").equals(datatypeURI)) {
int atPosition=lexicalForm.lastIndexOf('@');
literal=factory.getOWLLiteral(lexicalForm.substring(0,atPosition),lexicalForm.substring(atPosition+1));
}
else
literal=factory.getOWLLiteral(lexicalForm,factory.getOWLDatatype(IRI.create(datatypeURI)));
result.add(literal);
}
}
}
}
}
}
}
return result;
}
public boolean hasDataPropertyRelationship(OWLNamedIndividual subject,OWLDataProperty property,OWLLiteral object) {
checkPreConditions(subject,property);
if (!m_isConsistent)
return true;
OWLDataFactory factory=getDataFactory();
OWLAxiom notAssertion=factory.getOWLNegativeDataPropertyAssertionAxiom(property,subject,object);
Tableau tableau=getTableau(notAssertion);
boolean result=tableau.isSatisfiable(true,true,null,null,null,null,null,new ReasoningTaskDescription(true,"is {0} connected to {1} via {2}",H(subject),object,H(property)));
tableau.clearAdditionalDLOntology();
return !result;
}
protected Set> getDirectSuperConceptNodes(final Individual individual) {
HierarchySearch.SearchPredicate> predicate=new HierarchySearch.SearchPredicate>() {
public Set> getSuccessorElements(HierarchyNode