package uk.ac.manchester.cs.jfact;
/* This file is part of the JFact DL reasoner
Copyright 2011-2013 by Ignazio Palmisano, Dmitry Tsarkov, University of Manchester
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLDataRange;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
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.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.ReasonerInterruptedException;
import org.semanticweb.owlapi.reasoner.ReasonerProgressMonitor;
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.OWLObjectPropertyNodeSet;
import org.semanticweb.owlapi.reasoner.knowledgeexploration.OWLKnowledgeExplorerReasoner;
import org.semanticweb.owlapi.util.Version;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
import uk.ac.manchester.cs.jfact.datatypes.DatatypeFactory;
import uk.ac.manchester.cs.jfact.helpers.LogAdapter;
import uk.ac.manchester.cs.jfact.kernel.DlCompletionTree;
import uk.ac.manchester.cs.jfact.kernel.ExpressionManager;
import uk.ac.manchester.cs.jfact.kernel.Individual;
import uk.ac.manchester.cs.jfact.kernel.NamedEntry;
import uk.ac.manchester.cs.jfact.kernel.Ontology;
import uk.ac.manchester.cs.jfact.kernel.ReasonerFreshEntityException;
import uk.ac.manchester.cs.jfact.kernel.ReasoningKernel;
import uk.ac.manchester.cs.jfact.kernel.actors.ClassPolicy;
import uk.ac.manchester.cs.jfact.kernel.actors.DataPropertyPolicy;
import uk.ac.manchester.cs.jfact.kernel.actors.IndividualPolicy;
import uk.ac.manchester.cs.jfact.kernel.actors.ObjectPropertyPolicy;
import uk.ac.manchester.cs.jfact.kernel.actors.TaxonomyActor;
import uk.ac.manchester.cs.jfact.kernel.dl.IndividualName;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.AxiomInterface;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.ConceptExpression;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.DataRoleExpression;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.Expression;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.IndividualExpression;
import uk.ac.manchester.cs.jfact.kernel.dl.interfaces.ObjectRoleExpression;
import uk.ac.manchester.cs.jfact.kernel.options.JFactReasonerConfiguration;
import uk.ac.manchester.cs.jfact.split.ModuleType;
import uk.ac.manchester.cs.jfact.split.TOntologyAtom;
import conformance.Original;
/**
* Synchronization policy: all methods for OWLReasoner are synchronized, except
* the methods which do not touch the kernel or only affect threadsafe data
* structures. inner private classes are not synchronized since methods from
* those classes cannot be invoked from outsize synchronized methods.
*/
public class JFactReasoner implements OWLReasoner, OWLOntologyChangeListener,
OWLKnowledgeExplorerReasoner, Serializable {
private static final long serialVersionUID = 10000L;
protected final AtomicBoolean interrupted = new AtomicBoolean(false);
private ReasoningKernel kernel;
private final ExpressionManager em;
private static final EnumSet<InferenceType> supportedInferenceTypes = EnumSet
.of(InferenceType.CLASS_ASSERTIONS, InferenceType.CLASS_HIERARCHY,
InferenceType.DATA_PROPERTY_HIERARCHY,
InferenceType.OBJECT_PROPERTY_HIERARCHY,
InferenceType.SAME_INDIVIDUAL);
private final OWLOntology root;
private final BufferingMode bufferingMode;
private final List<OWLOntologyChange> rawChanges = new ArrayList<OWLOntologyChange>();
private final Set<OWLAxiom> reasonerAxioms = new LinkedHashSet<OWLAxiom>();
@Original
private final JFactReasonerConfiguration configuration;
private final OWLDataFactory df;
protected TranslationMachinery tr;
// holds the consistency status: true for consistent, false for
// inconsistent, null for not verified (or changes received)
private Boolean consistencyVerified = null;
private final Set<OWLEntity> knownEntities = new HashSet<OWLEntity>();
private final DatatypeFactory datatypeFactory;
/**
* @param o
* o
* @param c
* c
* @param b
* b
*/
public JFactReasoner(OWLOntology o, OWLReasonerConfiguration c,
BufferingMode b) {
this(
o,
c instanceof JFactReasonerConfiguration ? (JFactReasonerConfiguration) c
: new JFactReasonerConfiguration(c), b);
}
/**
* @param rootOntology
* rootOntology
* @param axioms
* axioms to actually use
* @param config
* config
* @param bufferingMode
* bufferingMode
*/
public JFactReasoner(OWLOntology rootOntology, Collection<OWLAxiom> axioms,
JFactReasonerConfiguration config, BufferingMode bufferingMode) {
configuration = config;
root = rootOntology;
df = root.getOWLOntologyManager().getOWLDataFactory();
datatypeFactory = DatatypeFactory.getInstance();
kernel = new ReasoningKernel(configuration, datatypeFactory);
em = kernel.getExpressionManager();
this.bufferingMode = bufferingMode;
knownEntities.add(df.getOWLThing());
knownEntities.add(df.getOWLNothing());
for (OWLOntology o : root.getImportsClosure()) {
knownEntities.addAll(o.getSignature());
}
kernel.setTopBottomRoleNames(
OWLRDFVocabulary.OWL_TOP_OBJECT_PROPERTY.getIRI(),
OWLRDFVocabulary.OWL_BOTTOM_OBJECT_PROPERTY.getIRI(),
OWLRDFVocabulary.OWL_TOP_DATA_PROPERTY.getIRI(),
OWLRDFVocabulary.OWL_BOTTOM_DATA_PROPERTY.getIRI());
kernel.setInterruptedSwitch(interrupted);
kernel.clearKB();
configuration.getProgressMonitor().reasonerTaskStarted(
ReasonerProgressMonitor.LOADING);
configuration.getProgressMonitor().reasonerTaskBusy();
tr = new TranslationMachinery(kernel, df, datatypeFactory);
reasonerAxioms.addAll(axioms);
tr.loadAxioms(reasonerAxioms);
configuration.getProgressMonitor().reasonerTaskStopped();
}
/**
* @param ont
* ontology
* @return all axioms in the ontology and its import closure
*/
public static List<OWLAxiom> importsIncluded(OWLOntology ont) {
List<OWLAxiom> axioms = new ArrayList<OWLAxiom>();
for (OWLOntology o : ont.getImportsClosure()) {
for (OWLAxiom ax : o.getLogicalAxioms()) {
axioms.add(ax);
}
for (OWLAxiom ax : o.getAxioms(AxiomType.DECLARATION)) {
axioms.add(ax);
}
}
return axioms;
}
/**
* @param rootOntology
* rootOntology
* @param config
* config
* @param bufferingMode
* bufferingMode
*/
public JFactReasoner(OWLOntology rootOntology,
JFactReasonerConfiguration config, BufferingMode bufferingMode) {
this(rootOntology, importsIncluded(rootOntology), config, bufferingMode);
}
/**
* @return the configuration for this reasoner
*/
public JFactReasonerConfiguration getConfiguration() {
return configuration;
}
/** @return ontology */
public Ontology getOntology() {
return kernel.getOntology();
}
@Override
public synchronized Node<OWLClass> getEquivalentClasses(
OWLClassExpression ce) {
Collection<ConceptExpression> pointers = Collections.emptyList();
if (!isFreshName(ce)) {
checkConsistency();
pointers = kernel.getEquivalentConcepts(tr.pointer(ce),
classActor()).getSynonyms();
}
return tr.getClassExpressionTranslator().node(pointers);
}
private boolean isFreshName(OWLClassExpression ce) {
if (ce.isAnonymous()) {
return false;
}
return !knownEntities.contains(ce.asOWLClass());
}
@Override
public void ontologiesChanged(List<? extends OWLOntologyChange> changes) {
rawChanges.addAll(changes);
// We auto-flush the changes if the reasoner is non-buffering
if (bufferingMode.equals(BufferingMode.NON_BUFFERING)) {
flush();
}
}
@Override
public BufferingMode getBufferingMode() {
return bufferingMode;
}
@Override
public long getTimeOut() {
return configuration.getTimeOut();
}
@Override
public OWLOntology getRootOntology() {
return root;
}
@Override
public synchronized List<OWLOntologyChange> getPendingChanges() {
return new ArrayList<OWLOntologyChange>(rawChanges);
}
@Override
public synchronized Set<OWLAxiom> getPendingAxiomAdditions() {
if (!rawChanges.isEmpty()) {
Set<OWLAxiom> added = new HashSet<OWLAxiom>();
computeDiff(added, new HashSet<OWLAxiom>());
return added;
}
return Collections.emptySet();
}
@Override
public synchronized Set<OWLAxiom> getPendingAxiomRemovals() {
if (!rawChanges.isEmpty()) {
Set<OWLAxiom> removed = new HashSet<OWLAxiom>();
computeDiff(new HashSet<OWLAxiom>(), removed);
return removed;
}
return Collections.emptySet();
}
@Override
public synchronized void flush() {
// Process the changes
if (!rawChanges.isEmpty()) {
Set<OWLAxiom> added = new HashSet<OWLAxiom>();
Set<OWLAxiom> removed = new HashSet<OWLAxiom>();
computeDiff(added, removed);
rawChanges.clear();
if (!added.isEmpty() || !removed.isEmpty()) {
reasonerAxioms.removeAll(removed);
reasonerAxioms.addAll(added);
knownEntities.clear();
for (OWLAxiom ax : reasonerAxioms) {
knownEntities.addAll(ax.getSignature());
}
// set the consistency status to not verified
consistencyVerified = null;
handleChanges(added, removed);
}
}
}
/**
* Computes a diff of what axioms have been added and what axioms have been
* removed from the list of pending changes. Note that even if the list of
* pending changes is non-empty then there may be no changes for the
* reasoner to deal with.
*
* @param added
* The logical axioms that have been added to the imports closure of
* the reasoner root ontology
* @param removed
* The logical axioms that have been removed from the imports closure
* of the reasoner root ontology
*/
private synchronized void computeDiff(Set<OWLAxiom> added,
Set<OWLAxiom> removed) {
for (OWLOntologyChange change : rawChanges) {
OWLAxiom ax = change.getAxiom();
if (change.isAddAxiom()) {
if (!reasonerAxioms.contains(ax)
&& !reasonerAxioms.contains(ax
.getAxiomWithoutAnnotations())) {
added.add(ax);
}
} else if (change.isRemoveAxiom()) {
if (reasonerAxioms.contains(ax)
|| reasonerAxioms.contains(ax
.getAxiomWithoutAnnotations())) {
removed.add(change.getAxiom());
}
}
}
added.removeAll(removed);
}
@Override
public FreshEntityPolicy getFreshEntityPolicy() {
return configuration.getFreshEntityPolicy();
}
@Override
public IndividualNodeSetPolicy getIndividualNodeSetPolicy() {
return configuration.getIndividualNodeSetPolicy();
}
/**
* Asks the reasoner implementation to handle axiom additions and removals
* from the imports closure of the root ontology. The changes will not
* include annotation axiom additions and removals.
*
* @param addAxioms
* The axioms to be added to the reasoner.
* @param removeAxioms
* The axioms to be removed from the reasoner
*/
private synchronized void handleChanges(Set<OWLAxiom> addAxioms,
Set<OWLAxiom> removeAxioms) {
tr.loadAxioms(addAxioms);
for (OWLAxiom ax_r : removeAxioms) {
tr.retractAxiom(ax_r);
}
}
@Override
public String getReasonerName() {
return "JFact";
}
@Override
public Version getReasonerVersion() {
return new Version(1, 2, 1, 0);
}
@Override
public void interrupt() {
interrupted.set(true);
}
// precompute inferences
@Override
public synchronized void precomputeInferences(
InferenceType... inferenceTypes) {
for (InferenceType it : inferenceTypes) {
if (supportedInferenceTypes.contains(it)) {
if (!kernel.isKBRealised()) {
kernel.realiseKB();
}
return;
}
}
}
@Override
public boolean isPrecomputed(InferenceType inferenceType) {
if (supportedInferenceTypes.contains(inferenceType)) {
return kernel.isKBRealised();
}
return true;
}
@Override
public Set<InferenceType> getPrecomputableInferenceTypes() {
return supportedInferenceTypes;
}
// consistency
@Override
public synchronized boolean isConsistent() {
if (consistencyVerified == null) {
try {
consistencyVerified = kernel.isKBConsistent();
} catch (InconsistentOntologyException e) {
consistencyVerified = Boolean.FALSE;
}
}
return consistencyVerified;
}
private void checkConsistency() {
if (interrupted.get()) {
throw new ReasonerInterruptedException();
}
if (!isConsistent()) {
throw new InconsistentOntologyException();
}
}
@Override
public synchronized boolean
isSatisfiable(OWLClassExpression classExpression) {
checkConsistency();
return kernel.isSatisfiable(tr.pointer(classExpression));
}
@Override
public Node<OWLClass> getUnsatisfiableClasses() {
return getBottomClassNode();
}
// entailments
@Override
public synchronized boolean isEntailed(OWLAxiom axiom) {
checkConsistency();
if (root.containsAxiomIgnoreAnnotations(axiom, true)) {
return true;
}
try {
return axiom.accept(tr.getEntailmentChecker());
} catch (ReasonerFreshEntityException e) {
IRI iri = e.getIri();
if (getFreshEntityPolicy() == FreshEntityPolicy.DISALLOW) {
for (OWLEntity o : axiom.getSignature()) {
if (o.getIRI().equals(iri)) {
throw new FreshEntitiesException(o, e);
}
}
throw new FreshEntitiesException(axiom.getSignature(), e);
}
System.out
.println("JFactReasoner.isEntailed() WARNING: fresh entity exception in the reasoner for entity: "
+ iri + "; defaulting to axiom not entailed");
return false;
}
}
@Override
public synchronized boolean isEntailed(Set<? extends OWLAxiom> axioms) {
for (OWLAxiom ax : axioms) {
if (!this.isEntailed(ax)) {
return false;
}
}
return true;
}
@Override
public boolean isEntailmentCheckingSupported(AxiomType<?> axiomType) {
if (axiomType.equals(AxiomType.SWRL_RULE)) {
return false;
}
return true;
}
// tracing
/**
* @param axiom
* axiom
* @return tracing set (set of axioms that were participate in achieving
* result) for a given entailment. Return empty set if the axiom is
* not entailed.
*/
public synchronized Set<OWLAxiom> getTrace(OWLAxiom axiom) {
kernel.needTracing();
if (this.isEntailed(axiom)) {
return tr.translateTAxiomSet(kernel.getTrace());
}
return Collections.emptySet();
}
// classes
@Override
public Node<OWLClass> getTopClassNode() {
return getEquivalentClasses(df.getOWLThing());
}
@Override
public Node<OWLClass> getBottomClassNode() {
return getEquivalentClasses(df.getOWLNothing());
}
@Override
public synchronized NodeSet<OWLClass> getSubClasses(OWLClassExpression ce,
boolean direct) {
if (isFreshName(ce)) {
if (configuration.getFreshEntityPolicy() == FreshEntityPolicy.DISALLOW) {
throw new FreshEntitiesException(ce.getSignature());
}
return new OWLClassNodeSet(getBottomClassNode());
}
checkConsistency();
List<Collection<ConceptExpression>> pointers = kernel.getConcepts(
tr.pointer(ce), direct, classActor(), false).getElements();
if (pointers.isEmpty() || pointers.get(0).isEmpty()) {
// XXX trick: empty sets imply the ony subclasses are the equivalent
// to bottom.
// should happen in the reasoner proper, but something stops that
pointers.add(kernel.getEquivalentConcepts(
tr.pointer(df.getOWLNothing()), classActor()).getSynonyms());
}
return tr.getClassExpressionTranslator().nodeSet(pointers);
}
@Override
public synchronized NodeSet<OWLClass> getSuperClasses(
OWLClassExpression ce, boolean direct) {
if (isFreshName(ce)) {
return new OWLClassNodeSet(getTopClassNode());
}
checkConsistency();
return tr.getClassExpressionTranslator().nodeSet(
askSuperClasses(tr.pointer(ce), direct));
}
@Override
public synchronized NodeSet<OWLClass> getDisjointClasses(
OWLClassExpression ce) {
ConceptExpression p = tr.pointer(ce);
return tr.getClassExpressionTranslator().nodeSet(
kernel.getDisjointConcepts(p, classActor()).getElements());
}
// object properties
@Override
public Node<OWLObjectPropertyExpression> getTopObjectPropertyNode() {
return getEquivalentObjectProperties(df.getOWLTopObjectProperty());
}
@Override
public Node<OWLObjectPropertyExpression> getBottomObjectPropertyNode() {
return getEquivalentObjectProperties(df.getOWLBottomObjectProperty());
}
@Override
public synchronized NodeSet<OWLObjectPropertyExpression>
getSubObjectProperties(OWLObjectPropertyExpression pe,
boolean direct) {
checkConsistency();
return tr.getObjectPropertyTranslator().nodeSet(
kernel.getRoles(tr.pointer(pe), direct, objectActor(), false)
.getElements());
}
@Override
public synchronized NodeSet<OWLObjectPropertyExpression>
getSuperObjectProperties(OWLObjectPropertyExpression pe,
boolean direct) {
checkConsistency();
List<Collection<ObjectRoleExpression>> elements = kernel.getRoles(
tr.pointer(pe), direct, objectActor(), true).getElements();
// XXX trick
if (elements.isEmpty() || elements.get(0).isEmpty()) {
elements.add(kernel.getEquivalentRoles(
tr.pointer(df.getOWLTopObjectProperty()), objectActor())
.getSynonyms());
}
return tr.getObjectPropertyTranslator().nodeSet(elements);
}
@Override
public synchronized Node<OWLObjectPropertyExpression>
getEquivalentObjectProperties(OWLObjectPropertyExpression pe) {
checkConsistency();
return tr.getObjectPropertyTranslator().node(
kernel.getEquivalentRoles(tr.pointer(pe), objectActor())
.getSynonyms());
}
@Override
public synchronized NodeSet<OWLObjectPropertyExpression>
getDisjointObjectProperties(OWLObjectPropertyExpression pe) {
checkConsistency();
// TODO: incomplete
return new OWLObjectPropertyNodeSet(getBottomObjectPropertyNode());
}
@Override
public Node<OWLObjectPropertyExpression> getInverseObjectProperties(
OWLObjectPropertyExpression pe) {
return getEquivalentObjectProperties(pe.getInverseProperty());
}
@Override
public synchronized NodeSet<OWLClass> getObjectPropertyDomains(
OWLObjectPropertyExpression pe, boolean direct) {
checkConsistency();
return tr.getClassExpressionTranslator().nodeSet(
kernel.getORoleDomain(tr.pointer(pe), direct, classActor())
.getElements());
}
@Override
public NodeSet<OWLClass> getObjectPropertyRanges(
OWLObjectPropertyExpression pe, boolean direct) {
return getObjectPropertyDomains(pe.getInverseProperty(), direct);
}
// data properties
@Override
public Node<OWLDataProperty> getTopDataPropertyNode() {
return new OWLDataPropertyNode(df.getOWLTopDataProperty());
}
@Override
public Node<OWLDataProperty> getBottomDataPropertyNode() {
OWLDataPropertyNode toReturn = new OWLDataPropertyNode();
toReturn.add(df.getOWLBottomDataProperty());
return toReturn;
// XXX both this and the previous method look like hacks
// return getEquivalentDataProperties(df.getOWLBottomDataProperty());
}
@Override
public synchronized NodeSet<OWLDataProperty> getSubDataProperties(
OWLDataProperty pe, boolean direct) {
checkConsistency();
return tr.getDataPropertyTranslator().nodeSet(
kernel.getRoles(tr.pointer(pe), direct, dataActor(), false)
.getElements());
}
@Override
public synchronized NodeSet<OWLDataProperty> getSuperDataProperties(
OWLDataProperty pe, boolean direct) {
checkConsistency();
List<Collection<DataRoleExpression>> elements = kernel.getRoles(
tr.pointer(pe), direct, dataActor(), true).getElements();
// XXX trick
if (elements.isEmpty() || elements.get(0).isEmpty()) {
elements.add(kernel.getEquivalentRoles(
tr.pointer(df.getOWLTopDataProperty()), dataActor())
.getSynonyms());
}
return tr.getDataPropertyTranslator().nodeSet(elements);
}
@Override
public synchronized Node<OWLDataProperty> getEquivalentDataProperties(
OWLDataProperty pe) {
checkConsistency();
DataRoleExpression p = tr.pointer(pe);
Collection<DataRoleExpression> dataPropertySynonyms = kernel
.getEquivalentRoles(p, dataActor()).getSynonyms();
return tr.getDataPropertyTranslator().node(dataPropertySynonyms);
}
@Override
public synchronized NodeSet<OWLDataProperty> getDisjointDataProperties(
OWLDataPropertyExpression pe) {
checkConsistency();
// TODO: incomplete
return new OWLDataPropertyNodeSet(getBottomDataPropertyNode());
}
@Override
public NodeSet<OWLClass> getDataPropertyDomains(OWLDataProperty pe,
boolean direct) {
return tr.getClassExpressionTranslator().nodeSet(
kernel.getDRoleDomain(tr.pointer(pe), direct, classActor())
.getElements());
}
// individuals
@Override
public synchronized NodeSet<OWLClass> getTypes(OWLNamedIndividual ind,
boolean direct) {
checkConsistency();
Collection<Collection<ConceptExpression>> classElements = kernel
.getTypes(tr.pointer(ind), direct, classActor()).getElements();
return tr.getClassExpressionTranslator().nodeSet(classElements);
}
/** @return class actor */
private TaxonomyActor<ConceptExpression> classActor() {
return new TaxonomyActor<ConceptExpression>(em, new ClassPolicy());
}
/** @return object property actor */
private TaxonomyActor<ObjectRoleExpression> objectActor() {
return new TaxonomyActor<ObjectRoleExpression>(em,
new ObjectPropertyPolicy());
}
/** @return data property actor */
private TaxonomyActor<DataRoleExpression> dataActor() {
return new TaxonomyActor<DataRoleExpression>(em,
new DataPropertyPolicy());
}
/**
* @param t
* type
* @param <T>
* type
* @return individual property actor
*/
private <T extends Expression> TaxonomyActor<T> individualActor(
@SuppressWarnings("unused") Class<T> t) {
return new TaxonomyActor<T>(em, new IndividualPolicy(true));
}
@Override
public synchronized NodeSet<OWLNamedIndividual> getInstances(
OWLClassExpression ce, boolean direct) {
checkConsistency();
TaxonomyActor<IndividualExpression> actor = kernel.getInstances(
tr.pointer(ce), individualActor(IndividualExpression.class),
direct);
return tr.translateNodeSet(actor.getElements().iterator().next());
}
@Override
public synchronized NodeSet<OWLNamedIndividual> getObjectPropertyValues(
OWLNamedIndividual ind, OWLObjectPropertyExpression pe) {
checkConsistency();
List<Individual> fillers = kernel.getRoleFillers(tr.pointer(ind),
tr.pointer(pe));
List<IndividualExpression> acc = new ArrayList<IndividualExpression>();
for (NamedEntry p : fillers) {
acc.add(em.individual(p.getName()));
}
return tr.translateNodeSet(acc);
}
@Override
public synchronized Set<OWLLiteral> getDataPropertyValues(
OWLNamedIndividual ind, OWLDataProperty pe) {
checkConsistency();
// for(DataRoleExpression e:
// askDataProperties(translationMachinery.toIndividualPointer(ind))) {
//
// }
// return kernel.getDRM().
// return translationMachinery
// .translateIndividualPointersToNodeSet(askRelatedIndividuals(
// translationMachinery.toIndividualPointer(ind),
// translationMachinery.pointer(pe)));
// TODO:
return Collections.emptySet();
}
@Override
public synchronized Node<OWLNamedIndividual> getSameIndividuals(
OWLNamedIndividual ind) {
checkConsistency();
return tr.getIndividualTranslator().node(
kernel.getSameAs(tr.pointer(ind),
individualActor(IndividualName.class)).getSynonyms());
}
@Override
public NodeSet<OWLNamedIndividual> getDifferentIndividuals(
OWLNamedIndividual ind) {
OWLClassExpression ce = df.getOWLObjectOneOf(ind)
.getObjectComplementOf();
return getInstances(ce, false);
}
@Override
public synchronized void dispose() {
root.getOWLOntologyManager().removeOntologyChangeListener(this);
tr = null;
kernel = null;
}
/**
* @param pw
* pw
* @param includeBottomNode
* includeBottomNode
*/
public void dumpClassHierarchy(LogAdapter pw, boolean includeBottomNode) {
dumpSubClasses(getTopClassNode(), pw, 0, includeBottomNode);
}
private void dumpSubClasses(Node<OWLClass> node, LogAdapter pw, int depth,
boolean includeBottomNode) {
if (includeBottomNode || !node.isBottomNode()) {
for (int i = 0; i < depth; i++) {
pw.print(" ");
}
pw.print(node);
pw.println();
for (Node<OWLClass> sub : getSubClasses(
node.getRepresentativeElement(), true)) {
dumpSubClasses(sub, pw, depth + 1, includeBottomNode);
}
}
}
private Collection<Collection<ConceptExpression>> askSuperClasses(
ConceptExpression arg, boolean direct) {
return kernel.getConcepts(arg, direct, classActor(), true)
.getElements();
}
/**
* @param time
* time
*/
public synchronized void writeReasoningResult(long time) {
kernel.writeReasoningResult(time);
}
// owl knowledge exploration
private class RootNodeImpl implements RootNode, Serializable {
private static final long serialVersionUID = 11000L;
private final DlCompletionTree pointer;
public RootNodeImpl(DlCompletionTree p) {
pointer = p;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getNode() {
return (T) pointer;
}
}
@Override
public RootNode getRoot(OWLClassExpression expression) {
return new RootNodeImpl(kernel.buildCompletionTree(tr
.pointer(expression)));
}
@Override
public Node<? extends OWLObjectPropertyExpression> getObjectNeighbours(
RootNode object, boolean deterministicOnly) {
return tr.getObjectPropertyTranslator().node(
kernel.getObjectRoles((DlCompletionTree) object.getNode(),
deterministicOnly, false));
}
@Override
public Node<OWLDataProperty> getDataNeighbours(RootNode object,
boolean deterministicOnly) {
return tr.getDataPropertyTranslator().node(
kernel.getDataRoles((DlCompletionTree) object.getNode(),
deterministicOnly));
}
@Override
public Collection<RootNode> getObjectNeighbours(RootNode n,
OWLObjectProperty property) {
List<RootNode> toReturn = new ArrayList<RootNode>();
for (DlCompletionTree t : kernel.getNeighbours(
(DlCompletionTree) n.getNode(), tr.pointer(property))) {
toReturn.add(new RootNodeImpl(t));
}
return toReturn;
}
@Override
public Collection<RootNode> getDataNeighbours(RootNode n,
OWLDataProperty property) {
List<RootNode> toReturn = new ArrayList<RootNode>();
for (DlCompletionTree t : kernel.getNeighbours(
(DlCompletionTree) n.getNode(), tr.pointer(property))) {
toReturn.add(new RootNodeImpl(t));
}
return toReturn;
}
@Override
public Node<? extends OWLClassExpression> getObjectLabel(RootNode object,
boolean deterministicOnly) {
Node<OWLClass> nodeFromPointers = tr
.getClassExpressionTranslator()
.node(kernel.getObjectLabel(
(DlCompletionTree) object.getNode(), deterministicOnly));
return nodeFromPointers;
}
@Override
public Node<? extends OWLDataRange> getDataLabel(RootNode object,
boolean deterministicOnly) {
return tr.getDataRangeTranslator().node(
kernel.getDataLabel((DlCompletionTree) object.getNode(),
deterministicOnly));
}
@Override
public RootNode getBlocker(RootNode object) {
return new RootNodeImpl(kernel.getBlocker((DlCompletionTree) object
.getNode()));
}
/**
* @param useSemantics
* useSemantics
* @param type
* type
* @return number of atoms
*/
public int
getAtomicDecompositionSize(boolean useSemantics, ModuleType type) {
return kernel.getAtomicDecompositionSize(useSemantics, type);
}
/** @return set of tautologies */
public Set<OWLAxiom> getTautologies() {
return axiomsToSet(kernel.getTautologies());
}
/**
* @param index
* index
* @return set of axioms that corresponds to the atom with the id INDEX
*/
public Set<OWLAxiom> getAtomAxioms(int index) {
return axiomsToSet(kernel.getAtomAxioms(index));
}
private static Set<OWLAxiom> axiomsToSet(Collection<AxiomInterface> index) {
Set<OWLAxiom> toReturn = new HashSet<OWLAxiom>();
for (AxiomInterface ax : index) {
OWLAxiom owlAxiom = ax.getOWLAxiom();
if (owlAxiom != null) {
toReturn.add(owlAxiom);
}
}
return toReturn;
}
/**
* @param index
* index
* @return set of axioms that corresponds to the module of the atom with the
* id INDEX
*/
public Set<OWLAxiom> getAtomModule(int index) {
return axiomsToSet(kernel.getAtomModule(index));
}
/** @return number of locality checks performed for Ad creation */
public long getLocCheckNumber() {
return kernel.getLocCheckNumber();
}
/**
* @param index
* index
* @return set of atoms on which atom with index INDEX depends
*/
public Set<TOntologyAtom> getAtomDependents(int index) {
return kernel.getAtomDependents(index);
}
/**
* @param signature
* signature
* @param useSemantic
* useSemantic
* @param moduletype
* moduletype
* @return set of axioms in the module
*/
public Set<OWLAxiom> getModule(Set<OWLEntity> signature,
boolean useSemantic, ModuleType moduletype) {
List<Expression> list = tr.translateExpressions(signature);
List<AxiomInterface> axioms = kernel.getModule(list, useSemantic,
moduletype);
return axiomsToSet(axioms);
}
/**
* @param signature
* signature
* @param useSemantic
* useSemantic
* @param moduletype
* moduletype
* @return set of non local axioms
*/
public Set<OWLAxiom> getNonLocal(Set<OWLEntity> signature,
boolean useSemantic, ModuleType moduletype) {
List<Expression> list = tr.translateExpressions(signature);
Set<AxiomInterface> axioms = kernel.getNonLocal(list, useSemantic,
moduletype);
return axiomsToSet(axioms);
}
/**
* get all individuals from the set individuals that has r-successor and
* s-successor and those are related via OP: r op s.
*
* @param individuals
* set of individuals to choose from
* @param r
* first operand of the comparison
* @param s
* second operand of the comparison
* @param op
* comparison operation: 0 means "equal", 1 means "different", 2
* means "lesser", 3 means "lesser than or equal", 4 means
* "greater than", 5 means "greater than or equal"
* @return data related individuals
*/
public synchronized Node<OWLNamedIndividual> getDataRelatedIndividuals(
Set<OWLIndividual> individuals, OWLDataProperty r,
OWLDataProperty s, int op) {
checkConsistency();
// load all the individuals as parameters
return tr.getIndividualTranslator().node(
kernel.getDataRelatedIndividuals(tr.pointer(r), tr.pointer(s),
op, tr.translate(individuals)));
}
}