All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.semanticweb.owlapi.reasoner.structural.StructuralReasoner Maven / Gradle / Ivy

/*
 * This file is part of the OWL API.
 *
 * The contents of this file are subject to the LGPL License, Version 3.0.
 *
 * Copyright (C) 2011, The University of Manchester
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/.
 *
 *
 * Alternatively, the contents of this file may be used under the terms of the Apache License, Version 2.0
 * in which case, the provisions of the Apache License Version 2.0 are applicable instead of those above.
 *
 * Copyright 2011, University of Manchester
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.semanticweb.owlapi.reasoner.structural;

import java.util.ArrayList;
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 java.util.Stack;

import org.semanticweb.owlapi.model.AxiomType;
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.OWLDataPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom;
import org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObject;
import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLSameIndividualAxiom;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
import org.semanticweb.owlapi.reasoner.AxiomNotInProfileException;
import org.semanticweb.owlapi.reasoner.BufferingMode;
import org.semanticweb.owlapi.reasoner.ClassExpressionNotInProfileException;
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.NullReasonerProgressMonitor;
import org.semanticweb.owlapi.reasoner.OWLReasonerConfiguration;
import org.semanticweb.owlapi.reasoner.ReasonerInterruptedException;
import org.semanticweb.owlapi.reasoner.ReasonerProgressMonitor;
import org.semanticweb.owlapi.reasoner.TimeOutException;
import org.semanticweb.owlapi.reasoner.UnsupportedEntailmentTypeException;
import org.semanticweb.owlapi.reasoner.impl.DefaultNode;
import org.semanticweb.owlapi.reasoner.impl.DefaultNodeSet;
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.reasoner.impl.OWLReasonerBase;
import org.semanticweb.owlapi.util.CollectionFactory;
import org.semanticweb.owlapi.util.OWLObjectPropertyManager;
import org.semanticweb.owlapi.util.Version;

/**
 * Author: Matthew Horridge
* The University of Manchester
* Information Management Group
* Date: 04-Dec-2009 *

* This is a simple structural reasoner that essentially answers with told information. It is incomplete. */ public class StructuralReasoner extends OWLReasonerBase { private final ClassHierarchyInfo classHierarchyInfo = new ClassHierarchyInfo(); private final ObjectPropertyHierarchyInfo objectPropertyHierarchyInfo = new ObjectPropertyHierarchyInfo(); private final DataPropertyHierarchyInfo dataPropertyHierarchyInfo = new DataPropertyHierarchyInfo(); private static final Version version = new Version(1, 0, 0, 0); private boolean interrupted = false; protected final ReasonerProgressMonitor pm; private boolean prepared = false; /** * @param rootOntology the ontology * @param configuration the reasoner configuration * @param bufferingMode the buffering mode */ public StructuralReasoner(OWLOntology rootOntology, OWLReasonerConfiguration configuration, BufferingMode bufferingMode) { super(rootOntology, configuration, bufferingMode); pm = configuration.getProgressMonitor()==null?new NullReasonerProgressMonitor():configuration.getProgressMonitor(); prepareReasoner(); } /** * Gets the name of this reasoner. * @return A string that represents the name of this reasoner. */ public String getReasonerName() { return "Structural Reasoner"; } @Override public FreshEntityPolicy getFreshEntityPolicy() { return FreshEntityPolicy.ALLOW; } /** * Gets the IndividualNodeSetPolicy in use by this reasoner. The policy is set at reasoner creation time. * @return The policy. */ @Override public IndividualNodeSetPolicy getIndividualNodeSetPolicy() { return IndividualNodeSetPolicy.BY_NAME; } /** * Gets the version of this reasoner. * @return The version of this reasoner. Not null. */ public Version getReasonerVersion() { return version; } @Override protected void handleChanges(Set addAxioms, Set removeAxioms) { handleChanges(addAxioms, removeAxioms, classHierarchyInfo); handleChanges(addAxioms, removeAxioms, objectPropertyHierarchyInfo); handleChanges(addAxioms, removeAxioms, dataPropertyHierarchyInfo); } private void handleChanges(Set added, Set removed, HierarchyInfo hierarchyInfo) { Set sig = hierarchyInfo.getEntitiesInSignature(added); sig.addAll(hierarchyInfo.getEntitiesInSignature(removed)); hierarchyInfo.processChanges(sig, added, removed); } public void interrupt() { interrupted = true; } private void ensurePrepared() { if (!prepared) { prepareReasoner(); } } /** * @throws ReasonerInterruptedException on interruption * @throws TimeOutException on timeout */ public void prepareReasoner() throws ReasonerInterruptedException, TimeOutException { classHierarchyInfo.computeHierarchy(); objectPropertyHierarchyInfo.computeHierarchy(); dataPropertyHierarchyInfo.computeHierarchy(); prepared = true; } @SuppressWarnings("unused") public void precomputeInferences(InferenceType... inferenceTypes) throws ReasonerInterruptedException, TimeOutException, InconsistentOntologyException { prepareReasoner(); } @SuppressWarnings("unused") public boolean isPrecomputed(InferenceType inferenceType) { return true; } public Set getPrecomputableInferenceTypes() { return CollectionFactory.createSet(InferenceType.CLASS_HIERARCHY, InferenceType.OBJECT_PROPERTY_HIERARCHY, InferenceType.DATA_PROPERTY_HIERARCHY); } private void throwExceptionIfInterrupted() { if (interrupted) { interrupted = false; throw new ReasonerInterruptedException(); } } ////////////////////////////////////////////////////////////////////////////////////////////////////// public boolean isConsistent() throws ReasonerInterruptedException, TimeOutException { return true; } public boolean isSatisfiable(OWLClassExpression classExpression) throws ReasonerInterruptedException, TimeOutException, ClassExpressionNotInProfileException, FreshEntitiesException, InconsistentOntologyException { return !classExpression.isAnonymous() && !getEquivalentClasses(classExpression.asOWLClass()).contains(getDataFactory().getOWLNothing()); } public Node getUnsatisfiableClasses() throws ReasonerInterruptedException, TimeOutException { return OWLClassNode.getBottomNode(); } public boolean isEntailed(OWLAxiom axiom) throws ReasonerInterruptedException, UnsupportedEntailmentTypeException, TimeOutException, AxiomNotInProfileException, FreshEntitiesException, InconsistentOntologyException { return getRootOntology().containsAxiomIgnoreAnnotations(axiom, true); } public boolean isEntailed(Set axioms) throws ReasonerInterruptedException, UnsupportedEntailmentTypeException, TimeOutException, AxiomNotInProfileException, FreshEntitiesException, InconsistentOntologyException { for (OWLAxiom ax : axioms) { if (!getRootOntology().containsAxiomIgnoreAnnotations(ax, true)) { return false; } } return true; } public boolean isEntailmentCheckingSupported(AxiomType axiomType) { return false; } public Node getTopClassNode() { ensurePrepared(); return classHierarchyInfo.getEquivalents(getDataFactory().getOWLThing()); } public Node getBottomClassNode() { ensurePrepared(); return classHierarchyInfo.getEquivalents(getDataFactory().getOWLNothing()); } public NodeSet getSubClasses(OWLClassExpression ce, boolean direct) throws InconsistentOntologyException, ClassExpressionNotInProfileException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { OWLClassNodeSet ns = new OWLClassNodeSet(); if (!ce.isAnonymous()) { ensurePrepared(); return classHierarchyInfo.getNodeHierarchyChildren(ce.asOWLClass(), direct, ns); } return ns; } public NodeSet getSuperClasses(OWLClassExpression ce, boolean direct) throws InconsistentOntologyException, ClassExpressionNotInProfileException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { OWLClassNodeSet ns = new OWLClassNodeSet(); if (!ce.isAnonymous()) { ensurePrepared(); return classHierarchyInfo.getNodeHierarchyParents(ce.asOWLClass(), direct, ns); } return ns; } public Node getEquivalentClasses(OWLClassExpression ce) throws InconsistentOntologyException, ClassExpressionNotInProfileException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); if (!ce.isAnonymous()) { return classHierarchyInfo.getEquivalents(ce.asOWLClass()); } else { return new OWLClassNode(); } } public NodeSet getDisjointClasses(OWLClassExpression ce) { ensurePrepared(); OWLClassNodeSet nodeSet = new OWLClassNodeSet(); if (!ce.isAnonymous()) { for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLDisjointClassesAxiom ax : ontology.getDisjointClassesAxioms(ce.asOWLClass())) { for (OWLClassExpression op : ax.getClassExpressions()) { if (!op.isAnonymous()) { nodeSet.addNode(getEquivalentClasses(op)); } } } } } return nodeSet; } public Node getTopObjectPropertyNode() { ensurePrepared(); return objectPropertyHierarchyInfo.getEquivalents(getDataFactory().getOWLTopObjectProperty()); } public Node getBottomObjectPropertyNode() { ensurePrepared(); return objectPropertyHierarchyInfo.getEquivalents(getDataFactory().getOWLBottomObjectProperty()); } public NodeSet getSubObjectProperties(OWLObjectPropertyExpression pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { OWLObjectPropertyNodeSet ns = new OWLObjectPropertyNodeSet(); ensurePrepared(); return objectPropertyHierarchyInfo.getNodeHierarchyChildren(pe, direct, ns); } public NodeSet getSuperObjectProperties(OWLObjectPropertyExpression pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { OWLObjectPropertyNodeSet ns = new OWLObjectPropertyNodeSet(); ensurePrepared(); return objectPropertyHierarchyInfo.getNodeHierarchyParents(pe, direct, ns); } public Node getEquivalentObjectProperties(OWLObjectPropertyExpression pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { // OWLObjectPropertyNode nd = new OWLObjectPropertyNode(); ensurePrepared(); return objectPropertyHierarchyInfo.getEquivalents(pe); } public NodeSet getDisjointObjectProperties(OWLObjectPropertyExpression pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { return new OWLObjectPropertyNodeSet(); } public Node getInverseObjectProperties(OWLObjectPropertyExpression pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); OWLObjectPropertyExpression inv = pe.getInverseProperty().getSimplified(); return getEquivalentObjectProperties(inv); } public NodeSet getObjectPropertyDomains(OWLObjectPropertyExpression pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); DefaultNodeSet result = new OWLClassNodeSet(); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLObjectPropertyDomainAxiom axiom : ontology.getObjectPropertyDomainAxioms(pe)) { result.addNode(getEquivalentClasses(axiom.getDomain())); if (!direct) { result.addAllNodes(getSuperClasses(axiom.getDomain(), false).getNodes()); } } for (OWLObjectPropertyExpression invPe : getInverseObjectProperties(pe).getEntities()) { for (OWLObjectPropertyRangeAxiom axiom : ontology.getObjectPropertyRangeAxioms(invPe)) { result.addNode(getEquivalentClasses(axiom.getRange())); if (!direct) { result.addAllNodes(getSuperClasses(axiom.getRange(), false).getNodes()); } } } } return result; } public NodeSet getObjectPropertyRanges(OWLObjectPropertyExpression pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); DefaultNodeSet result = new OWLClassNodeSet(); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLObjectPropertyRangeAxiom axiom : ontology.getObjectPropertyRangeAxioms(pe)) { result.addNode(getEquivalentClasses(axiom.getRange())); if (!direct) { result.addAllNodes(getSuperClasses(axiom.getRange(), false).getNodes()); } } for (OWLObjectPropertyExpression invPe : getInverseObjectProperties(pe).getEntities()) { for (OWLObjectPropertyDomainAxiom axiom : ontology.getObjectPropertyDomainAxioms(invPe)) { result.addNode(getEquivalentClasses(axiom.getDomain())); if (!direct) { result.addAllNodes(getSuperClasses(axiom.getDomain(), false).getNodes()); } } } } return result; } public Node getTopDataPropertyNode() { ensurePrepared(); return dataPropertyHierarchyInfo.getEquivalents(getDataFactory().getOWLTopDataProperty()); } public Node getBottomDataPropertyNode() { ensurePrepared(); return dataPropertyHierarchyInfo.getEquivalents(getDataFactory().getOWLBottomDataProperty()); } public NodeSet getSubDataProperties(OWLDataProperty pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); OWLDataPropertyNodeSet ns = new OWLDataPropertyNodeSet(); return dataPropertyHierarchyInfo.getNodeHierarchyChildren(pe, direct, ns); } public NodeSet getSuperDataProperties(OWLDataProperty pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); OWLDataPropertyNodeSet ns = new OWLDataPropertyNodeSet(); return dataPropertyHierarchyInfo.getNodeHierarchyParents(pe, direct, ns); } public Node getEquivalentDataProperties(OWLDataProperty pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); return dataPropertyHierarchyInfo.getEquivalents(pe); } public NodeSet getDisjointDataProperties(OWLDataPropertyExpression pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); DefaultNodeSet result = new OWLDataPropertyNodeSet(); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLDisjointDataPropertiesAxiom axiom : ontology.getDisjointDataPropertiesAxioms(pe.asOWLDataProperty())) { for (OWLDataPropertyExpression dpe : axiom.getPropertiesMinus(pe)) { if (!dpe.isAnonymous()) { result.addNode(dataPropertyHierarchyInfo.getEquivalents(dpe.asOWLDataProperty())); result.addAllNodes(getSubDataProperties(dpe.asOWLDataProperty(), false).getNodes()); } } } } return result; } public NodeSet getDataPropertyDomains(OWLDataProperty pe, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); DefaultNodeSet result = new OWLClassNodeSet(); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLDataPropertyDomainAxiom axiom : ontology.getDataPropertyDomainAxioms(pe)) { result.addNode(getEquivalentClasses(axiom.getDomain())); if (!direct) { result.addAllNodes(getSuperClasses(axiom.getDomain(), false).getNodes()); } } } return result; } public NodeSet getTypes(OWLNamedIndividual ind, boolean direct) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); DefaultNodeSet result = new OWLClassNodeSet(); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLClassAssertionAxiom axiom : ontology.getClassAssertionAxioms(ind)) { OWLClassExpression ce = axiom.getClassExpression(); if (!ce.isAnonymous()) { result.addNode(classHierarchyInfo.getEquivalents(ce.asOWLClass())); if (!direct) { result.addAllNodes(getSuperClasses(ce, false).getNodes()); } } } } return result; } public NodeSet getInstances(OWLClassExpression ce, boolean direct) throws InconsistentOntologyException, ClassExpressionNotInProfileException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); DefaultNodeSet result = new OWLNamedIndividualNodeSet(); if (!ce.isAnonymous()) { OWLClass cls = ce.asOWLClass(); Set clses = new HashSet(); clses.add(cls); if (!direct) { clses.addAll(getSubClasses(cls, false).getFlattened()); } for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLClass curCls : clses) { for (OWLClassAssertionAxiom axiom : ontology.getClassAssertionAxioms(curCls)) { OWLIndividual individual = axiom.getIndividual(); if (!individual.isAnonymous()) { if (getIndividualNodeSetPolicy().equals(IndividualNodeSetPolicy.BY_SAME_AS)) { result.addNode(getSameIndividuals(individual.asOWLNamedIndividual())); } else { result.addNode(new OWLNamedIndividualNode(individual.asOWLNamedIndividual())); } } } } } } return result; } public NodeSet getObjectPropertyValues(OWLNamedIndividual ind, OWLObjectPropertyExpression pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); OWLNamedIndividualNodeSet result = new OWLNamedIndividualNodeSet(); Node inverses = getInverseObjectProperties(pe); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLObjectPropertyAssertionAxiom axiom : ontology.getObjectPropertyAssertionAxioms(ind)) { if (!axiom.getObject().isAnonymous()) { if (axiom.getProperty().getSimplified().equals(pe.getSimplified())) { if (getIndividualNodeSetPolicy().equals(IndividualNodeSetPolicy.BY_SAME_AS)) { result.addNode(getSameIndividuals(axiom.getObject().asOWLNamedIndividual())); } else { result.addNode(new OWLNamedIndividualNode(axiom.getObject().asOWLNamedIndividual())); } } } // Inverse of pe if (axiom.getObject().equals(ind) && !axiom.getSubject().isAnonymous()) { OWLObjectPropertyExpression invPe = axiom.getProperty().getInverseProperty().getSimplified(); if (!invPe.isAnonymous() && inverses.contains(invPe.asOWLObjectProperty())) { if (getIndividualNodeSetPolicy().equals(IndividualNodeSetPolicy.BY_SAME_AS)) { result.addNode(getSameIndividuals(axiom.getObject().asOWLNamedIndividual())); } else { result.addNode(new OWLNamedIndividualNode(axiom.getObject().asOWLNamedIndividual())); } } } } } // Could do other stuff like inspecting owl:hasValue restrictions return result; } /** * Gets the data property values for the specified individual and data property. * @param ind The individual that is the subject of the data property values * @param pe The data property whose values are to be retrieved for the specified individual * @return A set of OWLLiterals containing literals such that for each literal l in the * set, either there is an explicit data property assertion in the set of reasoner axioms * DataPropertyAssertion(pe, ind, l), or, there is an explicit * data property assertion in the set of reasoner axioms DataPropertyAssertion(S, ind, l) and * the set of reasoner axioms entails SubDataPropertyOf(S, pe). * @throws InconsistentOntologyException if the imports closure of the root ontology is inconsistent * @throws org.semanticweb.owlapi.reasoner.FreshEntitiesException * if the signature of the individual and property is not contained within the signature * of the imports closure of the root ontology and the undeclared entity policy of this reasoner is set to {@link org.semanticweb.owlapi.reasoner.FreshEntityPolicy#DISALLOW}. * @throws ReasonerInterruptedException if the reasoning process was interrupted for any particular reason (for example if * reasoning was cancelled by a client process) * @throws TimeOutException if the reasoner timed out during a basic reasoning operation. See {@link #getTimeOut()}. */ public Set getDataPropertyValues(OWLNamedIndividual ind, OWLDataProperty pe) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); Set literals = new HashSet(); Set superProperties = getSuperDataProperties(pe, false).getFlattened(); superProperties.addAll(getEquivalentDataProperties(pe).getEntities()); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLDataPropertyAssertionAxiom axiom : ontology.getDataPropertyAssertionAxioms(ind)) { if (superProperties.contains(axiom.getProperty().asOWLDataProperty())) { literals.add(axiom.getObject()); } } } return literals; } public Node getSameIndividuals(OWLNamedIndividual ind) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { ensurePrepared(); Set inds = new HashSet(); Set processed = new HashSet(); List stack = new ArrayList(); stack.add(ind); while (!stack.isEmpty()) { OWLNamedIndividual currentInd = stack.remove(0); for (OWLOntology ontology : getRootOntology().getImportsClosure()) { for (OWLSameIndividualAxiom axiom : ontology.getSameIndividualAxioms(currentInd)) { if (!processed.contains(axiom)) { processed.add(axiom); for (OWLIndividual i : axiom.getIndividuals()) { if (!i.isAnonymous()) { OWLNamedIndividual namedInd = i.asOWLNamedIndividual(); if (!inds.contains(namedInd)) { inds.add(namedInd); stack.add(namedInd); } } } } } } } return new OWLNamedIndividualNode(inds); } public NodeSet getDifferentIndividuals(OWLNamedIndividual ind) throws InconsistentOntologyException, FreshEntitiesException, ReasonerInterruptedException, TimeOutException { return new OWLNamedIndividualNodeSet(); } protected OWLDataFactory getDataFactory() { return getRootOntology().getOWLOntologyManager().getOWLDataFactory(); } /** * @param showBottomNode true if bottom node is to be showed */ public void dumpClassHierarchy(boolean showBottomNode) { dumpClassHierarchy(OWLClassNode.getTopNode(), 0, showBottomNode); } private void dumpClassHierarchy(Node cls, int level, boolean showBottomNode) { if (!showBottomNode && cls.isBottomNode()) { return; } printIndent(level); OWLClass representative = cls.getRepresentativeElement(); System.out.println(getEquivalentClasses(representative)); for (Node subCls : getSubClasses(representative, true)) { dumpClassHierarchy(subCls, level + 1, showBottomNode); } } /** * @param showBottomNode true if bottom node is to be showed */ public void dumpObjectPropertyHierarchy(boolean showBottomNode) { dumpObjectPropertyHierarchy(OWLObjectPropertyNode.getTopNode(), 0, showBottomNode); } private void dumpObjectPropertyHierarchy(Node cls, int level, boolean showBottomNode) { if (!showBottomNode && cls.isBottomNode()) { return; } printIndent(level); OWLObjectPropertyExpression representative = cls.getRepresentativeElement(); System.out.println(getEquivalentObjectProperties(representative)); for (Node subProp : getSubObjectProperties(representative, true)) { dumpObjectPropertyHierarchy(subProp, level + 1, showBottomNode); } } /** * @param showBottomNode true if bottom node is to be showed */ public void dumpDataPropertyHierarchy(boolean showBottomNode) { dumpDataPropertyHierarchy(OWLDataPropertyNode.getTopNode(), 0, showBottomNode); } private void dumpDataPropertyHierarchy(Node cls, int level, boolean showBottomNode) { if (!showBottomNode && cls.isBottomNode()) { return; } printIndent(level); OWLDataProperty representative = cls.getRepresentativeElement(); System.out.println(getEquivalentDataProperties(representative)); for (Node subProp : getSubDataProperties(representative, true)) { dumpDataPropertyHierarchy(subProp, level + 1, showBottomNode); } } private void printIndent(int level) { for (int i = 0; i < level; i++) { System.out.print(" "); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////// ////// HierarchyInfo ////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private abstract class HierarchyInfo { private RawHierarchyProvider rawParentChildProvider; /** * The entity that always appears in the top node in the hierarchy */ private T topEntity; /** * The entity that always appears as the bottom node in the hierarchy */ private T bottomEntity; private Set directChildrenOfTopNode = new HashSet(); private Set directParentsOfBottomNode = new HashSet(); private NodeCache nodeCache; private String name; private int classificationSize; public HierarchyInfo(String name, T topEntity, T bottomEntity, RawHierarchyProvider rawParentChildProvider) { this.topEntity = topEntity; this.bottomEntity = bottomEntity; this.nodeCache = new NodeCache(this); this.rawParentChildProvider = rawParentChildProvider; this.name = name; } public RawHierarchyProvider getRawParentChildProvider() { return rawParentChildProvider; } /** * Gets the set of relevant entities from the specified ontology * @param ont The ontology * @return A set of entities to be "classified" */ protected abstract Set getEntities(OWLOntology ont); /** * Creates a node for a given set of entities * @param cycle The set of entities * @return A node */ protected abstract DefaultNode createNode(Set cycle); protected abstract DefaultNode createNode(); /** * Gets the set of relevant entities in a particular axiom * @param ax The axiom * @return The set of relevant entities in the signature of the specified axiom */ protected abstract Set getEntitiesInSignature(OWLAxiom ax); private Set getEntitiesInSignature(Set axioms) { Set result = new HashSet(); for (OWLAxiom ax : axioms) { result.addAll(getEntitiesInSignature(ax)); } return result; } public void computeHierarchy() { pm.reasonerTaskStarted("Computing " + name + " hierarchy"); pm.reasonerTaskBusy(); nodeCache.clear(); Map> cache = new HashMap>(); Set entities = new HashSet(); for (OWLOntology ont : getRootOntology().getImportsClosure()) { entities.addAll(getEntities(ont)); } classificationSize = entities.size(); pm.reasonerTaskProgressChanged(0, classificationSize); updateForSignature(entities, cache); pm.reasonerTaskStopped(); } private void updateForSignature(Set signature, Map> cache) { HashSet> cyclesResult = new HashSet>(); Set processed = new HashSet(); nodeCache.clearTopNode(); nodeCache.clearBottomNode(); nodeCache.clearNodes(signature); directChildrenOfTopNode.removeAll(signature); Set equivTopOrChildrenOfTop = new HashSet(); Set equivBottomOrParentsOfBottom = new HashSet(); for (T entity : signature) { if (!processed.contains(entity)) { pm.reasonerTaskProgressChanged(processed.size(), signature.size()); tarjan(entity, 0, new Stack(), new HashMap(), new HashMap(), cyclesResult, processed, new HashSet(), cache, equivTopOrChildrenOfTop, equivBottomOrParentsOfBottom); throwExceptionIfInterrupted(); } } // Store new cycles for (Set cycle : cyclesResult) { nodeCache.addNode(cycle); } directChildrenOfTopNode.addAll(equivTopOrChildrenOfTop); directChildrenOfTopNode.removeAll(nodeCache.getTopNode().getEntities()); directParentsOfBottomNode.addAll(equivBottomOrParentsOfBottom); directParentsOfBottomNode.removeAll(nodeCache.getBottomNode().getEntities()); // Now check that each found cycle has a proper parent an child for (Set node : cyclesResult) { if (!node.contains(topEntity) && !node.contains(bottomEntity)) { boolean childOfTop = true; for (T element : node) { Collection parents = rawParentChildProvider.getParents(element); parents.removeAll(node); parents.removeAll(nodeCache.getTopNode().getEntities()); if (!parents.isEmpty()) { childOfTop = false; break; } } if (childOfTop) { directChildrenOfTopNode.addAll(node); } boolean parentOfBottom = true; for (T element : node) { Collection children = rawParentChildProvider.getChildren(element); children.removeAll(node); children.removeAll(nodeCache.getBottomNode().getEntities()); if (!children.isEmpty()) { parentOfBottom = false; break; } } if (parentOfBottom) { directParentsOfBottomNode.addAll(node); } } } } /** * Processes the specified signature that represents the signature of potential changes * @param signature The signature * @param added added axioms * @param removed removed axioms */ @SuppressWarnings("unused") public void processChanges(Set signature, Set added, Set removed) { updateForSignature(signature, null); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Applies the tarjan algorithm for a given entity. This computes the cycle that the entity is involved in (if * any). * @param entity The entity * @param index index * @param stack stack * @param indexMap index map * @param lowlinkMap low link map * @param result result * @param processed processed * @param stackEntities stack entities * @param cache A cache of children to parents - may be null if no caching is to take place. * @param childrenOfTop A set of entities that have a raw parent that is the top entity * @param parentsOfBottom A set of entities that have a raw parent that is the bottom entity */ public void tarjan(T entity, int index, Stack stack, Map indexMap, Map lowlinkMap, Set> result, Set processed, Set stackEntities, Map> cache, Set childrenOfTop, Set parentsOfBottom) { throwExceptionIfInterrupted(); if (processed.add(entity)) { Collection rawChildren = rawParentChildProvider.getChildren(entity); if (rawChildren.isEmpty() || rawChildren.contains(bottomEntity)) { parentsOfBottom.add(entity); } } pm.reasonerTaskProgressChanged(processed.size(), classificationSize); indexMap.put(entity, index); lowlinkMap.put(entity, index); index = index + 1; stack.push(entity); stackEntities.add(entity); // Get the raw parents - cache if necessary Collection rawParents = null; if (cache != null) { // We are therefore caching raw parents of children. rawParents = cache.get(entity); if (rawParents == null) { // Not in cache! rawParents = rawParentChildProvider.getParents(entity); // Note down if our entity is a if (rawParents.isEmpty() || rawParents.contains(topEntity)) { childrenOfTop.add(entity); } cache.put(entity, rawParents); } } else { rawParents = rawParentChildProvider.getParents(entity); // Note down if our entity is a if (rawParents.isEmpty() || rawParents.contains(topEntity)) { childrenOfTop.add(entity); } } for (T superEntity : rawParents) { if (!indexMap.containsKey(superEntity)) { tarjan(superEntity, index, stack, indexMap, lowlinkMap, result, processed, stackEntities, cache, childrenOfTop, parentsOfBottom); lowlinkMap.put(entity, Math.min(lowlinkMap.get(entity), lowlinkMap.get(superEntity))); } else if (stackEntities.contains(superEntity)) { lowlinkMap.put(entity, Math.min(lowlinkMap.get(entity), indexMap.get(superEntity))); } } if (lowlinkMap.get(entity).equals(indexMap.get(entity))) { Set scc = new HashSet(); while (true) { T clsPrime = stack.pop(); stackEntities.remove(clsPrime); scc.add(clsPrime); if (clsPrime.equals(entity)) { break; } } if (scc.size() > 1) { // We ADD a cycle result.add(scc); } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////// public NodeSet getNodeHierarchyChildren(T parent, boolean direct, DefaultNodeSet ns) { Node node = nodeCache.getNode(parent); if (node.isBottomNode()) { return ns; } Set directChildren = new HashSet(); for (T equiv : node) { directChildren.addAll(rawParentChildProvider.getChildren(equiv)); if(directParentsOfBottomNode.contains(equiv)) { ns.addNode(nodeCache.getBottomNode()); } } directChildren.removeAll(node.getEntities()); if (node.isTopNode()) { // Special treatment directChildren.addAll(directChildrenOfTopNode); } for (Node childNode : nodeCache.getNodes(directChildren)) { ns.addNode(childNode); } if (!direct) { for (T child : directChildren) { getNodeHierarchyChildren(child, direct, ns); } } return ns; } public NodeSet getNodeHierarchyParents(T child, boolean direct, DefaultNodeSet ns) { Node node = nodeCache.getNode(child); if (node.isTopNode()) { return ns; } Set directParents = new HashSet(); for (T equiv : node) { directParents.addAll(rawParentChildProvider.getParents(equiv)); if(directChildrenOfTopNode.contains(equiv)) { ns.addNode(nodeCache.getTopNode()); } } directParents.removeAll(node.getEntities()); if (node.isBottomNode()) { // Special treatment directParents.addAll(directParentsOfBottomNode); } for (Node parentNode : nodeCache.getNodes(directParents)) { ns.addNode(parentNode); } if (!direct) { for(T parent : directParents) { getNodeHierarchyParents(parent, direct, ns); } } return ns; } public Node getEquivalents(T element) { return nodeCache.getNode(element); } } private static class NodeCache { private HierarchyInfo hierarchyInfo; private Node topNode; private Node bottomNode; private Map> map = new HashMap>(); protected NodeCache(HierarchyInfo hierarchyInfo) { this.hierarchyInfo = hierarchyInfo; clearTopNode(); clearBottomNode(); } public void addNode(Node node) { for (T element : node.getEntities()) { map.put(element, node); if (element.isTopEntity()) { topNode = node; } else if (element.isBottomEntity()) { bottomNode = node; } } } public Set> getNodes(Set elements) { Set> result = new HashSet>(); for (T element : elements) { result.add(getNode(element)); } return result; } // public Set getTopEntities() { // return topNode.getEntities(); // } // // public Set getBottomEntities() { // return bottomNode.getEntities(); // } public Node getNode(T containing) { Node parentNode = map.get(containing); if (parentNode != null) { return parentNode; } else { return hierarchyInfo.createNode(Collections.singleton(containing)); } } public void addNode(Set elements) { addNode(hierarchyInfo.createNode(elements)); } public Node getTopNode() { return topNode; } public Node getBottomNode() { return bottomNode; } // public void setTopNode(Node topNode) { // this.topNode = topNode; // } // // public void setBottomNode(Node bottomNode) { // this.bottomNode = bottomNode; // } public void clearTopNode() { removeNode(hierarchyInfo.topEntity); topNode = hierarchyInfo.createNode(Collections.singleton(hierarchyInfo.topEntity)); addNode(topNode); } public void clearBottomNode() { removeNode(hierarchyInfo.bottomEntity); bottomNode = hierarchyInfo.createNode(Collections.singleton(hierarchyInfo.bottomEntity)); addNode(bottomNode); } public void clearNodes(Set containing) { for (T entity : containing) { removeNode(entity); } } public void clear() { map.clear(); clearTopNode(); clearBottomNode(); } public void removeNode(T containing) { Node node = map.remove(containing); if (node != null) { for (T object : node.getEntities()) { map.remove(object); } } } } private class ClassHierarchyInfo extends HierarchyInfo { public ClassHierarchyInfo() { super("class", getDataFactory().getOWLThing(), getDataFactory().getOWLNothing(), new RawClassHierarchyProvider()); } @Override protected Set getEntitiesInSignature(OWLAxiom ax) { return ax.getClassesInSignature(); } @Override protected DefaultNode createNode(Set cycle) { return new OWLClassNode(cycle); } @Override protected Set getEntities(OWLOntology ont) { return ont.getClassesInSignature(); } @Override protected DefaultNode createNode() { return new OWLClassNode(); } } private class ObjectPropertyHierarchyInfo extends HierarchyInfo { public ObjectPropertyHierarchyInfo() { super("object property", getDataFactory().getOWLTopObjectProperty(), getDataFactory().getOWLBottomObjectProperty(), new RawObjectPropertyHierarchyProvider()); } @Override protected Set getEntitiesInSignature(OWLAxiom ax) { Set result = new HashSet(); for (OWLObjectProperty property : ax.getObjectPropertiesInSignature()) { result.add(property); result.add(property.getInverseProperty()); } return result; } @Override protected Set getEntities(OWLOntology ont) { Set result = new HashSet(); for (OWLObjectPropertyExpression property : ont.getObjectPropertiesInSignature()) { result.add(property); result.add(property.getInverseProperty()); } return result; } @Override protected DefaultNode createNode(Set cycle) { return new OWLObjectPropertyNode(cycle); } @Override protected DefaultNode createNode() { return new OWLObjectPropertyNode(); } /** * Processes the specified signature that represents the signature of potential changes * @param signature The signature */ @Override public void processChanges(Set signature, Set added, Set removed) { boolean rebuild = false; for (OWLAxiom ax : added) { if(ax instanceof OWLObjectPropertyAxiom) { rebuild = true; break; } } if(!rebuild) { for(OWLAxiom ax : removed) { if(ax instanceof OWLObjectPropertyAxiom) { rebuild = true; break; } } } if(rebuild) { ((RawObjectPropertyHierarchyProvider) getRawParentChildProvider()).rebuild(); } super.processChanges(signature, added, removed); } } private class DataPropertyHierarchyInfo extends HierarchyInfo { public DataPropertyHierarchyInfo() { super("data property", getDataFactory().getOWLTopDataProperty(), getDataFactory().getOWLBottomDataProperty(), new RawDataPropertyHierarchyProvider()); } @Override protected Set getEntitiesInSignature(OWLAxiom ax) { return ax.getDataPropertiesInSignature(); } @Override protected Set getEntities(OWLOntology ont) { return ont.getDataPropertiesInSignature(); } @Override protected DefaultNode createNode(Set cycle) { return new OWLDataPropertyNode(cycle); } @Override protected DefaultNode createNode() { return new OWLDataPropertyNode(); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * An interface for objects who can provide the parents and children of some object. * @param */ private interface RawHierarchyProvider { /** * Gets the parents as asserted. These parents may also be children (resulting in equivalences). * @param child The child whose parents are to be retrieved * @return The raw asserted parents of the specified child. If the child does not have any parents * then the empty set can be returned. */ Collection getParents(T child); /** * Gets the children as asserted * @param parent The parent whose children are to be retrieved * @return The raw asserted children of the speicified parent */ Collection getChildren(T parent); } private class RawClassHierarchyProvider implements RawHierarchyProvider { public Collection getParents(OWLClass child) { Collection result = new HashSet(); for (OWLOntology ont : getRootOntology().getImportsClosure()) { for (OWLSubClassOfAxiom ax : ont.getSubClassAxiomsForSubClass(child)) { OWLClassExpression superCls = ax.getSuperClass(); if (!superCls.isAnonymous()) { result.add(superCls.asOWLClass()); } else if (superCls instanceof OWLObjectIntersectionOf) { OWLObjectIntersectionOf intersectionOf = (OWLObjectIntersectionOf) superCls; for (OWLClassExpression conjunct : intersectionOf.asConjunctSet()) { if (!conjunct.isAnonymous()) { result.add(conjunct.asOWLClass()); } } } } for (OWLEquivalentClassesAxiom ax : ont.getEquivalentClassesAxioms(child)) { for (OWLClassExpression ce : ax.getClassExpressionsMinus(child)) { if (!ce.isAnonymous()) { result.add(ce.asOWLClass()); } else if (ce instanceof OWLObjectIntersectionOf) { OWLObjectIntersectionOf intersectionOf = (OWLObjectIntersectionOf) ce; for (OWLClassExpression conjunct : intersectionOf.asConjunctSet()) { if (!conjunct.isAnonymous()) { result.add(conjunct.asOWLClass()); } } } } } } return result; } public Collection getChildren(OWLClass parent) { Collection result = new HashSet(); for (OWLOntology ont : getRootOntology().getImportsClosure()) { for (OWLAxiom ax : ont.getReferencingAxioms(parent)) { if (ax instanceof OWLSubClassOfAxiom) { OWLSubClassOfAxiom sca = (OWLSubClassOfAxiom) ax; if (!sca.getSubClass().isAnonymous()) { Set conjuncts = sca.getSuperClass().asConjunctSet(); if (conjuncts.contains(parent)) { result.add(sca.getSubClass().asOWLClass()); } } } else if (ax instanceof OWLEquivalentClassesAxiom) { OWLEquivalentClassesAxiom eca = (OWLEquivalentClassesAxiom) ax; for (OWLClassExpression ce : eca.getClassExpressions()) { if (ce.containsConjunct(parent)) { for (OWLClassExpression sub : eca.getClassExpressions()) { if (!sub.isAnonymous() && !sub.equals(ce)) { result.add(sub.asOWLClass()); } } } } } } } return result; } } private class RawObjectPropertyHierarchyProvider implements RawHierarchyProvider { private OWLObjectPropertyManager propertyManager; private Map> sub2Super; private Map> super2Sub; public RawObjectPropertyHierarchyProvider() { rebuild(); } public void rebuild() { propertyManager = new OWLObjectPropertyManager(getRootOntology().getOWLOntologyManager(), getRootOntology()); sub2Super = propertyManager.getPropertyHierarchy(); super2Sub = new HashMap>(); for(OWLObjectPropertyExpression sub : sub2Super.keySet()) { for(OWLObjectPropertyExpression superProp : sub2Super.get(sub)) { Set subs = super2Sub.get(superProp); if(subs == null) { subs = new HashSet(); super2Sub.put(superProp, subs); } subs.add(sub); } } } public Collection getParents(OWLObjectPropertyExpression child) { if(child.isBottomEntity()) { return Collections.emptySet(); } Set propertyExpressions = sub2Super.get(child); if(propertyExpressions == null) { return Collections.emptySet(); } else { return new HashSet(propertyExpressions); } } public Collection getChildren(OWLObjectPropertyExpression parent) { if(parent.isTopEntity()) { return Collections.emptySet(); } Set propertyExpressions = super2Sub.get(parent); if(propertyExpressions == null) { return Collections.emptySet(); } else { return new HashSet(propertyExpressions); } } } private class RawDataPropertyHierarchyProvider implements RawHierarchyProvider { public Collection getParents(OWLDataProperty child) { Set properties = new HashSet(); for (OWLDataPropertyExpression prop : child.getSuperProperties(getRootOntology().getImportsClosure())) { properties.add(prop.asOWLDataProperty()); } return properties; } public Collection getChildren(OWLDataProperty parent) { Set properties = new HashSet(); for (OWLDataPropertyExpression prop : parent.getSubProperties(getRootOntology().getImportsClosure())) { properties.add(prop.asOWLDataProperty()); } return properties; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy