org.semanticweb.HermiT.hierarchy.InstanceManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.semanticweb.hermit Show documentation
Show all versions of org.semanticweb.hermit Show documentation
HermiT is reasoner for ontologies written using the Web Ontology Language (OWL). Given an OWL file, HermiT can determine whether or not the ontology is consistent, identify subsumption relationships between classes, and much more.
This is the maven build of HermiT and is designed for people who wish to use HermiT from within the OWL API. It is now versioned in the main HermiT version repository, although not officially supported by the HermiT developers.
The version number of this package is a composite of the HermiT version and a value representing the OWLAPI release it is compatible with. Note that the group id for the upstream HermiT is com.hermit-reasoner, while this fork is released under net.sourceforge.owlapi.
This fork exists to allow HermiT users to use newer OWLAPI versions than the ones supported by the original HermiT codebase.
This package includes the Jautomata library (http://jautomata.sourceforge.net/), and builds with it directly. This library appears to be no longer under active development, and so a "fork" seems appropriate. No development is intended or anticipated on this code base.
The newest version!
/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory
This file is part of HermiT.
HermiT is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
HermiT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with HermiT. If not, see .
*/
package org.semanticweb.HermiT.hierarchy;
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.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import org.semanticweb.HermiT.Prefixes;
import org.semanticweb.HermiT.Reasoner;
import org.semanticweb.HermiT.graph.Graph;
import org.semanticweb.HermiT.hierarchy.DeterministicClassification.GraphNode;
import org.semanticweb.HermiT.hierarchy.RoleElementManager.RoleElement;
import org.semanticweb.HermiT.model.Atom;
import org.semanticweb.HermiT.model.AtomicConcept;
import org.semanticweb.HermiT.model.AtomicRole;
import org.semanticweb.HermiT.model.DLClause;
import org.semanticweb.HermiT.model.DLOntology;
import org.semanticweb.HermiT.model.DLPredicate;
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.tableau.ExtensionManager;
import org.semanticweb.HermiT.tableau.ExtensionTable;
import org.semanticweb.HermiT.tableau.InterruptFlag;
import org.semanticweb.HermiT.tableau.Node;
import org.semanticweb.HermiT.tableau.NodeType;
import org.semanticweb.HermiT.tableau.ReasoningTaskDescription;
import org.semanticweb.HermiT.tableau.Tableau;
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.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.reasoner.ReasonerProgressMonitor;
/**InstanceManager.*/
public class InstanceManager {
/**threshold*/
public static final int thresholdForAdditionalAxioms=10000;
protected final InterruptFlag m_interruptFlag;
protected final Reasoner m_reasoner;
protected final TableauMonitor m_tableauMonitor;
protected final Individual[] m_individuals;
protected final HashSet m_complexRoles;
protected final Map m_conceptToElement;
protected final AtomicConcept m_topConcept;
protected final AtomicConcept m_bottomConcept;
protected Hierarchy m_currentConceptHierarchy;
protected final RoleElementManager m_roleElementManager;
protected final RoleElement m_topRoleElement;
protected final RoleElement m_bottomRoleElement;
protected Hierarchy m_currentRoleHierarchy;
protected final boolean m_usesInverseRoles;
protected final Map m_nodesForIndividuals;
protected final Map m_individualsForNodes;
protected final Map> m_canonicalNodeToDetMergedNodes;
protected final Map> m_canonicalNodeToNonDetMergedNodes;
protected boolean m_isInconsistent;
protected boolean m_realizationCompleted;
protected boolean m_roleRealizationCompleted;
protected boolean m_usesClassifiedConceptHierarchy;
protected boolean m_classesInitialised;
protected boolean m_propertiesInitialised;
protected boolean m_readingOffFoundPossibleConceptInstance;
protected boolean m_readingOffFoundPossiblePropertyInstance;
protected final Map> m_individualToEquivalenceClass;
protected Map,Set>> m_individualToPossibleEquivalenceClass;
protected final ExtensionTable.Retrieval m_binaryRetrieval0Bound;
protected final ExtensionTable.Retrieval m_binaryRetrieval1Bound;
protected final ExtensionTable.Retrieval m_ternaryRetrieval1Bound;
protected int m_currentIndividualIndex=0;
/**
* @param interruptFlag interruptFlag
* @param reasoner reasoner
* @param atomicConceptHierarchy atomicConceptHierarchy
* @param objectRoleHierarchy objectRoleHierarchy
*/
public InstanceManager(InterruptFlag interruptFlag,Reasoner reasoner,Hierarchy atomicConceptHierarchy,Hierarchy objectRoleHierarchy) {
m_interruptFlag=interruptFlag;
m_interruptFlag.startTask();
try {
m_reasoner=reasoner;
m_tableauMonitor=m_reasoner.getTableau().getTableauMonitor();
DLOntology dlo=m_reasoner.getDLOntology();
m_individuals=new ArrayList<>(dlo.getAllIndividuals()).toArray(new Individual[0]);
m_complexRoles=new HashSet<>();
m_individualToEquivalenceClass=new HashMap<>();
m_nodesForIndividuals=new HashMap<>();
for (Individual individual : m_individuals) {
m_nodesForIndividuals.put(individual,null);
Set equivalentIndividuals=new HashSet<>();
equivalentIndividuals.add(individual);
m_individualToEquivalenceClass.put(individual, equivalentIndividuals);
m_interruptFlag.checkInterrupt();
}
m_individualsForNodes=new HashMap<>();
m_canonicalNodeToDetMergedNodes=new HashMap<>();
m_canonicalNodeToNonDetMergedNodes=new HashMap<>();
m_individualToPossibleEquivalenceClass=null;
m_topConcept=AtomicConcept.THING;
m_bottomConcept=AtomicConcept.NOTHING;
m_conceptToElement=new HashMap<>();
m_conceptToElement.put(m_topConcept, new AtomicConceptElement(null, null));
Graph knownConceptSubsumptions=null;
Set atomicConcepts=null;
if (atomicConceptHierarchy!=null)
setToClassifiedConceptHierarchy(atomicConceptHierarchy);
else {
knownConceptSubsumptions=new Graph<>();
atomicConcepts=new HashSet<>();
atomicConcepts.add(m_topConcept);
atomicConcepts.add(m_bottomConcept);
for (AtomicConcept atomicConcept : dlo.getAllAtomicConcepts()) {
if (!Prefixes.isInternalIRI(atomicConcept.getIRI())) {
atomicConcepts.add(atomicConcept);
addKnownConceptSubsumption(knownConceptSubsumptions,atomicConcept,atomicConcept);
addKnownConceptSubsumption(knownConceptSubsumptions,atomicConcept,m_topConcept);
addKnownConceptSubsumption(knownConceptSubsumptions,m_bottomConcept,atomicConcept);
}
m_interruptFlag.checkInterrupt();
}
addKnownConceptSubsumption(knownConceptSubsumptions,m_bottomConcept,m_bottomConcept);
}
m_roleElementManager=new RoleElementManager();
Graph knownRoleSubsumptions=null;
m_topRoleElement=m_roleElementManager.getRoleElement(AtomicRole.TOP_OBJECT_ROLE);
m_bottomRoleElement=m_roleElementManager.getRoleElement(AtomicRole.BOTTOM_OBJECT_ROLE);
m_usesInverseRoles=dlo.hasInverseRoles();
Set roles=null;
Set complexRoles=dlo.getAllComplexObjectRoles();
if (objectRoleHierarchy!=null) {
setToClassifiedRoleHierarchy(objectRoleHierarchy);
for (Role role : complexRoles)
if (role instanceof AtomicRole && role!=AtomicRole.TOP_OBJECT_ROLE && role!=AtomicRole.BOTTOM_OBJECT_ROLE)
m_complexRoles.add((AtomicRole)role);
}
else {
knownRoleSubsumptions=new Graph<>();
roles=new HashSet<>();
roles.add(AtomicRole.TOP_OBJECT_ROLE);
roles.add(AtomicRole.BOTTOM_OBJECT_ROLE);
roles.addAll(dlo.getAllAtomicObjectRoles());
for (Role role : roles) {
addKnownRoleSubsumption(knownRoleSubsumptions,role,role);
addKnownRoleSubsumption(knownRoleSubsumptions,role,AtomicRole.TOP_OBJECT_ROLE);
addKnownRoleSubsumption(knownRoleSubsumptions,AtomicRole.BOTTOM_OBJECT_ROLE,role);
if (complexRoles.contains(role) && role instanceof AtomicRole && role!=AtomicRole.TOP_OBJECT_ROLE && role!=AtomicRole.BOTTOM_OBJECT_ROLE)
m_complexRoles.add((AtomicRole)role);
m_interruptFlag.checkInterrupt();
}
addKnownRoleSubsumption(knownRoleSubsumptions,AtomicRole.BOTTOM_OBJECT_ROLE,AtomicRole.BOTTOM_OBJECT_ROLE);
}
if (atomicConceptHierarchy==null || objectRoleHierarchy==null) {
updateKnownSubsumptionsUsingToldSubsumers(dlo.getDLClauses(),knownConceptSubsumptions,atomicConcepts,knownRoleSubsumptions,roles);
}
if (atomicConceptHierarchy==null)
m_currentConceptHierarchy=buildTransitivelyReducedConceptHierarchy(knownConceptSubsumptions);
if (objectRoleHierarchy==null)
m_currentRoleHierarchy=buildTransitivelyReducedRoleHierarchy(knownRoleSubsumptions);
ExtensionManager extensionManager=m_reasoner.getTableau().getExtensionManager();
m_binaryRetrieval0Bound=extensionManager.getBinaryExtensionTable().createRetrieval(new boolean[] { true, false }, ExtensionTable.View.TOTAL);
m_binaryRetrieval1Bound=extensionManager.getBinaryExtensionTable().createRetrieval(new boolean[] { false, true }, ExtensionTable.View.TOTAL);
m_ternaryRetrieval1Bound=extensionManager.getTernaryExtensionTable().createRetrieval(new boolean[] { false,true,false }, ExtensionTable.View.TOTAL);
}
finally {
m_interruptFlag.endTask();
}
}
protected void addKnownConceptSubsumption(Graph knownSubsumptions,AtomicConcept subConcept,AtomicConcept superConcept) {
knownSubsumptions.addEdge(subConcept,superConcept);
}
protected void addKnownRoleSubsumption(Graph knownSubsumptions,Role subRole,Role superRole) {
knownSubsumptions.addEdge(subRole,superRole);
if (m_usesInverseRoles)
knownSubsumptions.addEdge(subRole.getInverse(),superRole.getInverse());
}
protected void updateKnownSubsumptionsUsingToldSubsumers(Collection dlClauses, Graph knownConceptSubsumptions,Set concepts,Graph knownRoleSubsumptions,Set roles) {
boolean requiresConceptSubsumers=knownConceptSubsumptions!=null;
boolean requiresRoleSubsumers=knownRoleSubsumptions!=null;
if (requiresConceptSubsumers || requiresRoleSubsumers) {
for (DLClause dlClause : dlClauses) {
if (dlClause.getHeadLength()==1 && dlClause.getBodyLength()==1) {
DLPredicate headPredicate=dlClause.getHeadAtom(0).getDLPredicate();
DLPredicate bodyPredicate=dlClause.getBodyAtom(0).getDLPredicate();
if (requiresConceptSubsumers && headPredicate instanceof AtomicConcept && bodyPredicate instanceof AtomicConcept) {
AtomicConcept headConcept=(AtomicConcept)headPredicate;
AtomicConcept bodyConcept=(AtomicConcept)bodyPredicate;
if (concepts.contains(headConcept) && concepts.contains(bodyConcept))
addKnownConceptSubsumption(knownConceptSubsumptions,bodyConcept,headConcept);
}
else if (requiresRoleSubsumers && headPredicate instanceof AtomicRole && bodyPredicate instanceof AtomicRole) {
AtomicRole headRole=(AtomicRole)headPredicate;
AtomicRole bodyRole=(AtomicRole)bodyPredicate;
if (roles.contains(headRole) && roles.contains(bodyRole)) {
if (dlClause.getBodyAtom(0).getArgument(0)!=dlClause.getHeadAtom(0).getArgument(0))
// r -> s^- and r^- -> s
addKnownRoleSubsumption(knownRoleSubsumptions,InverseRole.create(bodyRole),headRole);
else
// r-> s and r^- -> s^-
addKnownRoleSubsumption(knownRoleSubsumptions,bodyRole,headRole);
}
}
}
m_interruptFlag.checkInterrupt();
}
}
}
protected Hierarchy buildTransitivelyReducedConceptHierarchy(Graph knownSubsumptions) {
final Map> allSubsumers=new HashMap<>();
for (AtomicConcept element : knownSubsumptions.getElements())
allSubsumers.put(element,new GraphNode<>(element,knownSubsumptions.getSuccessors(element)));
m_interruptFlag.checkInterrupt();
return DeterministicClassification.buildHierarchy(m_topConcept,m_bottomConcept,allSubsumers);
}
/**
* @param atomicConceptHierarchy atomicConceptHierarchy
*/
public void setToClassifiedConceptHierarchy(Hierarchy atomicConceptHierarchy) {
if (atomicConceptHierarchy!=m_currentConceptHierarchy) {
m_currentConceptHierarchy=atomicConceptHierarchy;
if (m_classesInitialised && m_individuals.length>0) {
for (HierarchyNode node : m_currentConceptHierarchy.getAllNodesSet()) {
if (node.m_representative!=m_bottomConcept) {
AtomicConcept representativeConcept=node.getRepresentative();
Set known=new HashSet<>();
Set possible=null;
for (AtomicConcept concept : node.getEquivalentElements()) {
if (m_conceptToElement.containsKey(concept)) {
AtomicConceptElement element=m_conceptToElement.get(concept);
known.addAll(element.m_knownInstances);
if (possible==null)
possible=new HashSet<>(element.m_possibleInstances);
else
possible.retainAll(element.m_possibleInstances);
m_conceptToElement.remove(concept);
}
}
if (possible!=null)
possible.removeAll(known);
if (!known.isEmpty()||possible!=null||representativeConcept==m_topConcept)
m_conceptToElement.put(representativeConcept, new AtomicConceptElement(known, possible));
}
}
// clean up known and possibles
Queue> toProcess=new LinkedList<>();
toProcess.addAll(m_currentConceptHierarchy.m_bottomNode.m_parentNodes);
while (!toProcess.isEmpty()) {
HierarchyNode current=toProcess.remove();
AtomicConcept currentConcept=current.getRepresentative();
AtomicConceptElement currentElement=m_conceptToElement.get(currentConcept);
if (currentElement!=null) {
Set> ancestors=current.getAncestorNodes();
ancestors.remove(current);
for (HierarchyNode ancestor : ancestors) {
AtomicConcept ancestorConcept=ancestor.getRepresentative();
AtomicConceptElement ancestorElement=m_conceptToElement.get(ancestorConcept);
if (ancestorElement!=null) {
ancestorElement.m_knownInstances.removeAll(currentElement.m_knownInstances);
ancestorElement.m_possibleInstances.removeAll(currentElement.m_knownInstances);
ancestorElement.m_possibleInstances.removeAll(currentElement.m_possibleInstances);
}
}
for (HierarchyNode parent : current.getParentNodes())
if (!toProcess.contains(parent))
toProcess.add(parent);
}
m_interruptFlag.checkInterrupt();
}
}
m_usesClassifiedConceptHierarchy=true;
}
}
protected Hierarchy buildTransitivelyReducedRoleHierarchy(Graph knownSubsumptions) {
final Map> allSubsumers=new HashMap<>();
for (Role role : knownSubsumptions.getElements())
allSubsumers.put(role,new GraphNode<>(role,knownSubsumptions.getSuccessors(role)));
m_interruptFlag.checkInterrupt();
return transformRoleHierarchy(DeterministicClassification.buildHierarchy(AtomicRole.TOP_OBJECT_ROLE,AtomicRole.BOTTOM_OBJECT_ROLE,allSubsumers));
}
/**
* Removes the inverses from the given hierarchy and then converts Role hierarchy nodes to RoleElement hierarchy nodes, which can store
* known and possible instances.
* @param roleHierarchy roleHierarchy
* @return a hierarchy containing role element nodes and no inverses
*/
protected Hierarchy transformRoleHierarchy(final Hierarchy roleHierarchy) {
Hierarchy newHierarchy=removeInverses(roleHierarchy);
Hierarchy.Transformer transformer=new Hierarchy.Transformer() {
@Override
public RoleElement transform(Role role) {
m_interruptFlag.checkInterrupt();
if (!(role instanceof AtomicRole))
throw new IllegalArgumentException("Internal error: The instance manager should only use atomic roles, but here we got a hierarchy element for an inverse role:" + role);
return m_roleElementManager.getRoleElement((AtomicRole)role);
}
@Override
public RoleElement determineRepresentative(Role oldRepresentative,Set newEquivalentElements) {
RoleElement representative=transform(oldRepresentative);
for (RoleElement newEquiv : newEquivalentElements) {
if (!newEquiv.equals(representative)) {
newEquiv.m_knownRelations.forEach((individual, set)->representative.m_knownRelations.computeIfAbsent(individual, x->new HashSet<>()).addAll(set));
newEquiv.m_possibleRelations.forEach((individual, set)->Optional.ofNullable(representative.m_possibleRelations.get(individual)).ifPresent(s->s.retainAll(set)));
newEquiv.m_knownRelations.clear();
newEquiv.m_possibleRelations.clear();
}
}
m_interruptFlag.checkInterrupt();
return representative;
}
};
return newHierarchy.transform(transformer,null);
}
protected Hierarchy removeInverses(Hierarchy hierarchy) {
final Map> allSubsumers=new HashMap<>();
Set toProcess=new HashSet<>();
Set visited=new HashSet<>();
toProcess.add(m_bottomRoleElement.m_role);
while (!toProcess.isEmpty()) {
AtomicRole current=toProcess.iterator().next();
visited.add(current);
HierarchyNode currentNode=hierarchy.getNodeForElement(current);
Set atomicRepresentatives=new HashSet<>();
findNextHierarchyNodeWithAtomic(atomicRepresentatives, currentNode);
allSubsumers.put(current,new GraphNode<>(current,atomicRepresentatives));
toProcess.addAll(atomicRepresentatives);
toProcess.removeAll(visited);
m_interruptFlag.checkInterrupt();
}
Hierarchy newHierarchy=DeterministicClassification.buildHierarchy(m_topRoleElement.m_role,m_bottomRoleElement.m_role,allSubsumers);
for (AtomicRole element : newHierarchy.m_nodesByElements.keySet()) {
HierarchyNode oldNode=hierarchy.getNodeForElement(element);
HierarchyNode newNode=newHierarchy.getNodeForElement(element);
for (Role equivalent : oldNode.m_equivalentElements) {
if (equivalent instanceof AtomicRole)
newNode.m_equivalentElements.add((AtomicRole)equivalent);
}
m_interruptFlag.checkInterrupt();
}
return newHierarchy;
}
/**
* @param roleHierarchy roleHierarchy
*/
public void setToClassifiedRoleHierarchy(final Hierarchy roleHierarchy) {
m_currentRoleHierarchy=transformRoleHierarchy(roleHierarchy);
// clean up known and possibles
if (m_propertiesInitialised && m_individuals.length>0) {
Queue> toProcess=new LinkedList<>();
toProcess.add(m_currentRoleHierarchy.m_bottomNode);
while (!toProcess.isEmpty()) {
HierarchyNode current=toProcess.remove();
RoleElement currentRepresentative=current.getRepresentative();
Set> ancestors=current.getAncestorNodes();
ancestors.remove(current);
for (HierarchyNode ancestor : ancestors) {
RoleElement ancestorRepresentative=ancestor.m_representative;
Map> ancestorKnowRelations=ancestorRepresentative.m_knownRelations;
Map> ancestorPossibleRelations=ancestorRepresentative.m_possibleRelations;
currentRepresentative.m_knownRelations.forEach((individual, set)->{
Set successors=ancestorKnowRelations.get(individual);
if (successors!=null) {
successors.removeAll(set);
if (successors.isEmpty())
ancestorKnowRelations.remove(individual);
}
successors=ancestorPossibleRelations.get(individual);
if (successors!=null) {
successors.removeAll(set);
if (successors.isEmpty())
ancestorPossibleRelations.remove(individual);
}
});
currentRepresentative.m_possibleRelations.forEach((individual, set)->{
Set successors=ancestorPossibleRelations.get(individual);
if (successors!=null) {
successors.removeAll(set);
if (successors.isEmpty())
ancestorPossibleRelations.remove(individual);
}
});
}
for (HierarchyNode parent : current.getParentNodes())
if (!toProcess.contains(parent))
toProcess.add(parent);
m_interruptFlag.checkInterrupt();
}
}
}
protected void findNextHierarchyNodeWithAtomic(Set atomicRepresentatives, HierarchyNode current) {
for (HierarchyNode successor : current.getParentNodes()) {
Set suitable=new HashSet<>();
for (Role role : successor.getEquivalentElements()) {
if (role instanceof AtomicRole)
suitable.add((AtomicRole)role);
}
if (!suitable.isEmpty())
atomicRepresentatives.add(suitable.iterator().next());
else if (successor!=current)
findNextHierarchyNodeWithAtomic(atomicRepresentatives, successor);
}
}
/**
* @param factory factory
* @param monitor monitor
* @param _completedSteps completedSteps
* @param steps steps
* @return axioms
*/
public OWLAxiom[] getAxiomsForReadingOffCompexProperties(OWLDataFactory factory, ReasonerProgressMonitor monitor, int _completedSteps, int steps) {
if (!m_complexRoles.isEmpty()) {
int noAdditionalAxioms=0;
List additionalAxioms=new ArrayList<>();
m_interruptFlag.startTask();
int completedSteps=_completedSteps;
try {
for (;m_currentIndividualIndex=m_individuals.length-1) {
// we are done now with everything
if (!m_readingOffFoundPossiblePropertyInstance)
m_roleRealizationCompleted=true;
m_propertiesInitialised=true;
}
m_individualsForNodes.clear();
} finally {
m_interruptFlag.endTask();
}
}
return completedSteps;
}
protected int readOffPropertyInstancesByIndividual(ReasonerProgressMonitor monitor, int _completedSteps, int steps, int startIndividualIndex) {
int completedSteps=_completedSteps;
// first round we go over all individuals
int endIndex=(startIndividualIndex==0) ? m_individuals.length : m_currentIndividualIndex;
for (int index=startIndividualIndex;index merged=m_canonicalNodeToDetMergedNodes.get(canonicalNode);
if (merged==null) {
merged=new HashSet<>();
m_canonicalNodeToDetMergedNodes.put(canonicalNode,merged);
}
merged.add(node);
} else {
// nondeterministically merged
Set merged=m_canonicalNodeToNonDetMergedNodes.get(canonicalNode);
if (merged==null) {
merged=new HashSet<>();
m_canonicalNodeToNonDetMergedNodes.put(canonicalNode,merged);
}
merged.add(node);
}
}
m_interruptFlag.checkInterrupt();
}
}
protected void initializeSameAs() {
m_individualToPossibleEquivalenceClass=new HashMap<>();
for (Node node : m_individualsForNodes.keySet()) {
Node mergedInto=node.getMergedInto();
if (mergedInto!=null) {
Individual individual1=m_individualsForNodes.get(node);
Individual individual2=m_individualsForNodes.get(mergedInto);
Set individual1Equivalences=m_individualToEquivalenceClass.get(individual1);
Set individual2Equivalences=m_individualToEquivalenceClass.get(individual2);
if (node.getMergedIntoDependencySet().isEmpty()) {
individual1Equivalences.addAll(individual2Equivalences);
m_individualToEquivalenceClass.put(individual2, individual1Equivalences);
}
else {
Set> possibleEquivalenceClasses=m_individualToPossibleEquivalenceClass.get(individual1Equivalences);
if (possibleEquivalenceClasses==null) {
possibleEquivalenceClasses=new HashSet<>();
m_individualToPossibleEquivalenceClass.put(individual1Equivalences,possibleEquivalenceClasses);
}
possibleEquivalenceClasses.add(individual2Equivalences);
}
}
m_interruptFlag.checkInterrupt();
}
}
protected boolean readOffTypes(Individual ind, Node nodeForIndividual) {
boolean hasBeenAdded=false;
m_binaryRetrieval1Bound.getBindingsBuffer()[1]=nodeForIndividual.getCanonicalNode();
m_binaryRetrieval1Bound.open();
Object[] tupleBuffer=m_binaryRetrieval1Bound.getTupleBuffer();
while (!m_binaryRetrieval1Bound.afterLast()) {
Object predicate=tupleBuffer[0];
if (predicate instanceof AtomicConcept) {
AtomicConcept atomicConcept=(AtomicConcept)predicate;
if (!atomicConcept.equals(m_topConcept) && !Prefixes.isInternalIRI(atomicConcept.getIRI())) {
HierarchyNode node=m_currentConceptHierarchy.getNodeForElement(atomicConcept);
AtomicConcept representative=node.getRepresentative();
AtomicConceptElement element=m_conceptToElement.get(representative);
if (element==null) {
element=new AtomicConceptElement(null, null);
m_conceptToElement.put(representative, element);
}
hasBeenAdded=true;
if (m_binaryRetrieval1Bound.getDependencySet().isEmpty())
addKnownConceptInstance(node, element, ind);
else {
addPossibleConceptInstance(node, element, ind);
m_readingOffFoundPossibleConceptInstance=true;
}
}
}
m_interruptFlag.checkInterrupt();
m_binaryRetrieval1Bound.next();
}
return hasBeenAdded;
}
protected void readOffPropertyInstances(Node nodeForIndividual) {
// nodeForIndividual is always a canonical node
m_ternaryRetrieval1Bound.getBindingsBuffer()[1]=nodeForIndividual;
m_ternaryRetrieval1Bound.open();
Object[] tupleBuffer=m_ternaryRetrieval1Bound.getTupleBuffer();
while (!m_ternaryRetrieval1Bound.afterLast()) {
Object roleObject=tupleBuffer[0];
Node successorNode=((Node)tupleBuffer[2]);
if (roleObject instanceof AtomicRole && !successorNode.isMerged() && successorNode.getNodeType()==NodeType.NAMED_NODE && m_individualsForNodes.containsKey(successorNode) && successorNode.isActive()) {
AtomicRole atomicrole=(AtomicRole)roleObject;
if (!atomicrole.equals(AtomicRole.TOP_OBJECT_ROLE) && m_roleElementManager.m_roleToElement.containsKey(atomicrole)) {
// the latter condition ensures that we do not accidentally try and read of something for data properties
RoleElement representative=m_currentRoleHierarchy.getNodeForElement(m_roleElementManager.getRoleElement(atomicrole)).getRepresentative();
// determine equivalent and possibly equivalent named nodes for the node
Set equivalentToNode=m_canonicalNodeToDetMergedNodes.get(nodeForIndividual);
if (equivalentToNode==null)
equivalentToNode=new HashSet<>();
equivalentToNode.add(nodeForIndividual);
Set possiblyEquivalentToNode=m_canonicalNodeToNonDetMergedNodes.get(nodeForIndividual);
if (possiblyEquivalentToNode==null)
possiblyEquivalentToNode=new HashSet<>();
// determine equivalent and possibly equivalent named nodes for the successor node
Set equivalentToSuccessor=m_canonicalNodeToDetMergedNodes.get(successorNode);
if (equivalentToSuccessor==null)
equivalentToSuccessor=new HashSet<>();
equivalentToSuccessor.add(successorNode);
Set possiblyEquivalentToSuccessor=m_canonicalNodeToNonDetMergedNodes.get(successorNode);
if (possiblyEquivalentToSuccessor==null)
possiblyEquivalentToSuccessor=new HashSet<>();
for (Node sourceNode : equivalentToNode) {
Individual sourceIndividual=m_individualsForNodes.get(sourceNode);
for (Node targetNode : equivalentToSuccessor) {
Individual targetIndividual=m_individualsForNodes.get(targetNode);
if (m_ternaryRetrieval1Bound.getDependencySet().isEmpty()) {
addKnownRoleInstance(representative, sourceIndividual, targetIndividual);
} else {
m_readingOffFoundPossiblePropertyInstance=true;
addPossibleRoleInstance(representative, sourceIndividual, targetIndividual);
}
}
for (Node targetNode : possiblyEquivalentToSuccessor) {
Individual targetIndividual=m_individualsForNodes.get(targetNode);
m_readingOffFoundPossiblePropertyInstance=true;
addPossibleRoleInstance(representative, sourceIndividual, targetIndividual);
}
}
for (Node sourceNode : new ArrayList<>(possiblyEquivalentToNode)) {
Individual sourceIndividual=m_individualsForNodes.get(sourceNode);
possiblyEquivalentToSuccessor.addAll(equivalentToSuccessor);
for (Node targetNode : possiblyEquivalentToSuccessor) {
Individual targetIndividual=m_individualsForNodes.get(targetNode);
m_readingOffFoundPossiblePropertyInstance=true;
addPossibleRoleInstance(representative, sourceIndividual, targetIndividual);
}
}
}
}
m_interruptFlag.checkInterrupt();
m_ternaryRetrieval1Bound.next();
}
}
protected int readOffComplexRoleSuccessors(Individual ind, ReasonerProgressMonitor monitor, int _completedSteps, int steps) {
int completedSteps=_completedSteps;
String indIRI=ind.getIRI();
AtomicConcept conceptForRole;
for (AtomicRole atomicRole : m_complexRoles) {
conceptForRole=AtomicConcept.create("internal:individual-concept#"+atomicRole.getIRI()+"#"+indIRI);
m_binaryRetrieval0Bound.getBindingsBuffer()[0]=conceptForRole;
m_binaryRetrieval0Bound.open();
Object[] tupleBuffer=m_binaryRetrieval0Bound.getTupleBuffer();
while (!m_binaryRetrieval0Bound.afterLast()) {
Node node=(Node)tupleBuffer[1];
if (node.isActive() && node.getNodeType()==NodeType.NAMED_NODE && m_individualsForNodes.containsKey(node)) {
RoleElement representative=m_currentRoleHierarchy.getNodeForElement(m_roleElementManager.getRoleElement(atomicRole)).getRepresentative();
//Individual successor=m_individualsForNodes.get(node.getCanonicalNode());
// determine equivalent and possibly equivalent named nodes for the successor node
Set equivalentToSuccessor=m_canonicalNodeToDetMergedNodes.get(node);
if (equivalentToSuccessor==null)
equivalentToSuccessor=new HashSet<>();
equivalentToSuccessor.add(node);
Set possiblyEquivalentToSuccessor=m_canonicalNodeToNonDetMergedNodes.get(node);
if (possiblyEquivalentToSuccessor==null)
possiblyEquivalentToSuccessor=new HashSet<>();
for (Node targetNode : equivalentToSuccessor) {
Individual targetIndividual=m_individualsForNodes.get(targetNode);
if (m_binaryRetrieval0Bound.getDependencySet().isEmpty()) {
addKnownRoleInstance(representative, ind, targetIndividual);
} else {
m_readingOffFoundPossiblePropertyInstance=true;
addPossibleRoleInstance(representative, ind, targetIndividual);
}
}
for (Node targetNode : possiblyEquivalentToSuccessor) {
Individual targetIndividual=m_individualsForNodes.get(targetNode);
m_readingOffFoundPossiblePropertyInstance=true;
addPossibleRoleInstance(representative, ind, targetIndividual);
}
}
m_interruptFlag.checkInterrupt();
m_binaryRetrieval0Bound.next();
}
completedSteps++;
if (monitor!=null)
monitor.reasonerTaskProgressChanged(completedSteps,steps);
}
return completedSteps;
}
protected void addKnownConceptInstance(HierarchyNode currentNode, AtomicConceptElement element, Individual instance) {
Set> nodes=currentNode.getDescendantNodes();
for (HierarchyNode node : nodes) {
AtomicConceptElement descendantElement=m_conceptToElement.get(node.getRepresentative());
if (descendantElement!=null && descendantElement.m_knownInstances.contains(instance))
return;
m_interruptFlag.checkInterrupt();
}
element.m_knownInstances.add(instance);
nodes=currentNode.getAncestorNodes();
nodes.remove(currentNode);
for (HierarchyNode node : nodes) {
AtomicConceptElement ancestorElement=m_conceptToElement.get(node.getRepresentative());
if (ancestorElement!=null) {
ancestorElement.m_knownInstances.remove(instance);
ancestorElement.m_possibleInstances.remove(instance);
}
}
}
protected void addPossibleConceptInstance(HierarchyNode currentNode, AtomicConceptElement element, Individual instance) {
Set> nodes=currentNode.getDescendantNodes();
for (HierarchyNode node : nodes) {
AtomicConceptElement descendantElement=m_conceptToElement.get(node.getRepresentative());
if (descendantElement!=null && (descendantElement.m_knownInstances.contains(instance) || descendantElement.m_possibleInstances.contains(instance)))
return;
m_interruptFlag.checkInterrupt();
}
element.m_possibleInstances.add(instance);
nodes=currentNode.getAncestorNodes();
nodes.remove(currentNode);
for (HierarchyNode node : nodes) {
AtomicConceptElement ancestorElement=m_conceptToElement.get(node.getRepresentative());
if (ancestorElement!=null) {
ancestorElement.m_possibleInstances.remove(instance);
if (ancestorElement.m_possibleInstances.isEmpty() && ancestorElement.m_knownInstances.isEmpty() && node.getRepresentative()!=m_topConcept)
m_conceptToElement.remove(node.getRepresentative());
}
m_interruptFlag.checkInterrupt();
}
}
protected void addKnownRoleInstance(RoleElement element, Individual individual1, Individual individual2) {
if (!element.equals(m_topRoleElement)) {
HierarchyNode currentNode=m_currentRoleHierarchy.getNodeForElement(element);
Set> nodes=currentNode.getDescendantNodes();
for (HierarchyNode node : nodes) {
for (RoleElement descendantElement : node.getEquivalentElements()) {
if (descendantElement.isKnown(individual1,individual2))
return;
}
m_interruptFlag.checkInterrupt();
}
element.addKnown(individual1, individual2);
nodes=currentNode.getAncestorNodes();
nodes.remove(currentNode);
for (HierarchyNode node : nodes) {
node.getRepresentative().removeKnown(individual1, individual2);
m_interruptFlag.checkInterrupt();
}
}
}
protected void addPossibleRoleInstance(RoleElement element, Individual individual1, Individual individual2) {
if (!element.equals(m_topRoleElement)) {
HierarchyNode currentNode=m_currentRoleHierarchy.getNodeForElement(element);
Set> nodes=currentNode.getDescendantNodes();
for (HierarchyNode node : nodes) {
for (RoleElement descendantElement : node.getEquivalentElements()) {
if (descendantElement.isPossible(individual1, individual2))
return;
}
m_interruptFlag.checkInterrupt();
}
element.addPossible(individual1, individual2);
nodes=currentNode.getAncestorNodes();
nodes.remove(currentNode);
for (HierarchyNode node : nodes) {
for (RoleElement ancestorElement : node.getEquivalentElements()) {
if (ancestorElement.isPossible(individual1,individual2))
ancestorElement.removePossible(individual1, individual2);
}
m_interruptFlag.checkInterrupt();
}
}
}
/**
* Set inconsistent.
*/
public void setInconsistent() {
m_isInconsistent=true;
m_realizationCompleted=true;
m_roleRealizationCompleted=true;
m_usesClassifiedConceptHierarchy=true;
m_currentConceptHierarchy=null;
m_currentRoleHierarchy=null;
}
/**
* @param monitor monitor
*/
public void realize(ReasonerProgressMonitor monitor) {
assert m_usesClassifiedConceptHierarchy;
if (m_readingOffFoundPossibleConceptInstance && !m_realizationCompleted) {
if (monitor!=null)
monitor.reasonerTaskStarted("Computing instances for all classes");
int numHierarchyNodes=m_currentConceptHierarchy.m_nodesByElements.values().size();
int currentHierarchyNode=0;
Queue> toProcess=new LinkedList<>();
Set> visited=new HashSet<>();
toProcess.addAll(m_currentConceptHierarchy.m_bottomNode.m_parentNodes);
while (!toProcess.isEmpty()) {
if (monitor!=null)
monitor.reasonerTaskProgressChanged(currentHierarchyNode,numHierarchyNodes);
HierarchyNode current=toProcess.remove();
visited.add(current);
currentHierarchyNode++;
AtomicConcept atomicConcept=current.getRepresentative();
AtomicConceptElement atomicConceptElement=m_conceptToElement.get(atomicConcept);
if (atomicConceptElement!=null) {
Set> parents=current.getParentNodes();
for (HierarchyNode parent : parents) {
if (!visited.contains(parent) && !toProcess.contains(parent))
toProcess.add(parent);
}
if (atomicConceptElement.hasPossibles()) {
Set nonInstances=new HashSet<>();
for (Individual individual : atomicConceptElement.getPossibleInstances()) {
if (isInstance(individual, atomicConcept))
atomicConceptElement.m_knownInstances.add(individual);
else
nonInstances.add(individual);
}
atomicConceptElement.m_possibleInstances.clear();
for (HierarchyNode parent : parents) {
AtomicConcept parentRepresentative=parent.getRepresentative();
AtomicConceptElement parentElement=m_conceptToElement.get(parentRepresentative);
if (parentElement==null) {
parentElement=new AtomicConceptElement(null, nonInstances);
m_conceptToElement.put(parentRepresentative, parentElement);
}
else if (parentRepresentative.equals(m_topConcept))
m_conceptToElement.get(m_topConcept).m_knownInstances.addAll(nonInstances);
else
parentElement.addPossibles(nonInstances);
}
}
}
m_interruptFlag.checkInterrupt();
}
if (monitor!=null)
monitor.reasonerTaskStopped();
}
m_realizationCompleted=true;
}
/**
* @param monitor monitor
*/
public void realizeObjectRoles(ReasonerProgressMonitor monitor) {
if (m_readingOffFoundPossiblePropertyInstance && !m_roleRealizationCompleted) {
if (monitor!=null)
monitor.reasonerTaskStarted("Computing instances for all object properties...");
int numHierarchyNodes=m_currentRoleHierarchy.m_nodesByElements.values().size();
int currentHierarchyNode=0;
Queue> toProcess=new LinkedList<>();
Set> visited=new HashSet<>();
toProcess.add(m_currentRoleHierarchy.m_bottomNode);
while (!toProcess.isEmpty()) {
if (monitor!=null)
monitor.reasonerTaskProgressChanged(currentHierarchyNode,numHierarchyNodes);
HierarchyNode current=toProcess.remove();
visited.add(current);
currentHierarchyNode++;
RoleElement roleElement=current.getRepresentative();
Role role=roleElement.getRole();
Set> parents=current.getParentNodes();
for (HierarchyNode parent : parents)
if (!toProcess.contains(parent) && !visited.contains(parent))
toProcess.add(parent);
if (roleElement.hasPossibles()) {
roleElement.m_possibleRelations.forEach((individual, set)->{
Set nonInstances=new HashSet<>();
for (Individual successor : set) {
if (isRoleInstance(role, individual, successor))
roleElement.addKnown(individual, successor);
else {
nonInstances.add(individual);
}
}
for (HierarchyNode parent : parents) {
RoleElement parentRepresentative=parent.getRepresentative();
if (!parentRepresentative.equals(m_topRoleElement))
parentRepresentative.addPossibles(individual, nonInstances);
}
});
roleElement.m_possibleRelations.clear();
}
m_interruptFlag.checkInterrupt();
}
if (monitor!=null)
monitor.reasonerTaskStopped();
}
m_roleRealizationCompleted=true;
}
/**
* @param individual individual
* @param direct direct
* @return types
*/
public Set> getTypes(Individual individual,boolean direct) {
if (m_isInconsistent)
return Collections.singleton(m_currentConceptHierarchy.m_bottomNode);
Set> result=new HashSet<>();
assert !direct || m_usesClassifiedConceptHierarchy;
Queue> toProcess=new LinkedList<>();
Set> visited=new HashSet<>();
toProcess.add(m_currentConceptHierarchy.m_bottomNode);
while (!toProcess.isEmpty()) {
HierarchyNode current=toProcess.remove();
boolean ancestor=true;
while (ancestor && current!=null) {
ancestor=false;
for (HierarchyNode node : result) {
if (current.isDescendantElement(node.m_representative)) {
ancestor=true;
visited.add(current);
if (!toProcess.isEmpty())
current=toProcess.remove();
else
current=null;
break;
}
}
}
if (current!=null) {
Set> parents=current.getParentNodes();
AtomicConcept atomicConcept=current.getRepresentative();
AtomicConceptElement atomicConceptElement=m_conceptToElement.get(atomicConcept);
if (atomicConceptElement!=null && atomicConceptElement.isPossible(individual)) {
if (isInstance(individual, atomicConcept)) {
atomicConceptElement.setToKnown(individual);
}
else {
for (HierarchyNode parent : parents) {
AtomicConcept parentRepresentative=parent.getRepresentative();
AtomicConceptElement parentElement=m_conceptToElement.get(parentRepresentative);
if (parentElement==null) {
parentElement=new AtomicConceptElement(null, null);
m_conceptToElement.put(parentRepresentative,parentElement);
}
parentElement.addPossible(individual);
}
}
}
if (atomicConceptElement!=null && atomicConceptElement.isKnown(individual)) {
if (direct)
result.add(current);
else
result.addAll(current.getAncestorNodes());
}
else {
for (HierarchyNode parent : parents)
if (!toProcess.contains(parent) && !visited.contains(parent))
toProcess.add(parent);
}
}
}
return result;
}
/**
* @param individual individual
* @param atomicConcept atomicConcept
* @param direct direct
* @return true if has type
*/
public boolean hasType(Individual individual,AtomicConcept atomicConcept,boolean direct) {
HierarchyNode node=m_currentConceptHierarchy.getNodeForElement(atomicConcept);
if (node==null)
return false;
return hasType(individual, node, direct);
}
/**
* @param individual individual
* @param node node
* @param direct direct
* @return true if has type
*/
public boolean hasType(Individual individual,HierarchyNode node,boolean direct) {
assert !direct || m_usesClassifiedConceptHierarchy;
AtomicConcept representative=node.getRepresentative();
if (representative==m_bottomConcept)
return false;
AtomicConceptElement element=m_conceptToElement.get(representative);
if ((element!=null && element.isKnown(individual)) || (!direct && node==m_currentConceptHierarchy.m_topNode))
return true;
if (element!=null && element.isPossible(individual)) {
if (isInstance(individual, representative)) {
element.setToKnown(individual);
return true;
}
else {
element.m_possibleInstances.remove(individual);
if (element.m_knownInstances.isEmpty() && element.m_possibleInstances.isEmpty() && representative!=m_topConcept)
m_conceptToElement.remove(representative);
for (HierarchyNode parent : node.getParentNodes()) {
AtomicConcept parentConcept=parent.getRepresentative();
AtomicConceptElement parentElement=m_conceptToElement.get(parentConcept);
if (parentElement==null) {
parentElement=new AtomicConceptElement(null, null);
m_conceptToElement.put(parentConcept, parentElement);
}
parentElement.addPossible(individual);
}
}
}
else if (!direct)
for (HierarchyNode child : node.getChildNodes())
if (hasType(individual, child, false))
return true;
return false;
}
/**
* @param atomicConcept atomicConcept
* @param direct direct
* @return instances
*/
public Set getInstances(AtomicConcept atomicConcept, boolean direct) {
Set result=new HashSet<>();
HierarchyNode node=m_currentConceptHierarchy.getNodeForElement(atomicConcept);
if (node==null) return result; // unknown concept
getInstancesForNode(node,result,direct);
return result;
}
/**
* @param node node
* @param direct direct
* @return instances
*/
public Set getInstances(HierarchyNode node,boolean direct) {
Set result=new HashSet<>();
HierarchyNode nodeFromCurrentHierarchy=m_currentConceptHierarchy.getNodeForElement(node.m_representative);
if (nodeFromCurrentHierarchy==null) {
// complex concept instances
if (!direct) {
for (HierarchyNode child : node.getChildNodes()) {
getInstancesForNode(child, result, direct);
}
}
}
else
getInstancesForNode(nodeFromCurrentHierarchy, result, direct);
return result;
}
protected void getInstancesForNode(HierarchyNode node,Set result,boolean direct) {
assert !direct || m_usesClassifiedConceptHierarchy;
AtomicConcept representative=node.getRepresentative();
if (!direct && representative.equals(m_topConcept)) {
for (Individual individual : m_individuals)
if (isResultRelevantIndividual(individual))
result.add(individual);
return;
}
AtomicConceptElement representativeElement=m_conceptToElement.get(representative);
if (representativeElement!=null) {
Set possibleInstances=representativeElement.getPossibleInstances();
if (!possibleInstances.isEmpty()) {
for (Individual possibleInstance : new HashSet<>(possibleInstances)) {
if (isInstance(possibleInstance, representative))
representativeElement.setToKnown(possibleInstance);
else {
representativeElement.m_possibleInstances.remove(possibleInstance);
if (representativeElement.m_knownInstances.isEmpty() && representativeElement.m_possibleInstances.isEmpty() && representative!=m_topConcept)
m_conceptToElement.remove(representative);
for (HierarchyNode parent : node.getParentNodes()) {
AtomicConcept parentConcept=parent.getRepresentative();
AtomicConceptElement parentElement=m_conceptToElement.get(parentConcept);
if (parentElement==null) {
parentElement=new AtomicConceptElement(null, null);
m_conceptToElement.put(parentConcept, parentElement);
}
parentElement.addPossible(possibleInstance);
}
}
}
}
for (Individual individual : representativeElement.getKnownInstances()) {
if (isResultRelevantIndividual(individual)) {
boolean isDirect=true;
if (direct) {
for (HierarchyNode child : node.getChildNodes()) {
if (hasType(individual, child, false)) {
isDirect=false;
break;
}
}
}
if (!direct || isDirect)
result.add(individual);
}
}
}
if (!direct)
for (HierarchyNode child : node.getChildNodes())
if (child!=m_currentConceptHierarchy.m_bottomNode)
getInstancesForNode(child, result, false);
}
/**
* @param role role
* @param individual1 individual1
* @param individual2 individual2
* @return true if has object role
*/
public boolean hasObjectRoleRelationship(AtomicRole role, Individual individual1, Individual individual2) {
RoleElement element=m_roleElementManager.getRoleElement(role);
HierarchyNode currentNode=m_currentRoleHierarchy.getNodeForElement(element);
if (currentNode==null)
return false;
return hasObjectRoleRelationship(currentNode, individual1, individual2);
}
/**
* @param node node
* @param individual1 individual1
* @param individual2 individual2
* @return true if has object role
*/
public boolean hasObjectRoleRelationship(HierarchyNode node,Individual individual1,Individual individual2) {
RoleElement representativeElement=node.getRepresentative();
if (representativeElement.isKnown(individual1, individual2) || representativeElement.equals(m_topRoleElement))
return true;
List individuals=Arrays.asList(m_individuals);
boolean containsUnknown=!individuals.contains(individual1) || !individuals.contains(individual2);
if (representativeElement.isPossible(individual1,individual2) || containsUnknown) {
if (isRoleInstance(representativeElement.getRole(),individual1,individual2)) {
if (!containsUnknown)
representativeElement.setToKnown(individual1,individual2);
return true;
}
else
for (HierarchyNode parent : node.getParentNodes())
parent.getRepresentative().addPossible(individual1,individual2);
}
else
for (HierarchyNode child : node.getChildNodes())
if (hasObjectRoleRelationship(child,individual1,individual2))
return true;
return false;
}
/**
* @param role role
* @return object property instances
*/
public Map> getObjectPropertyInstances(AtomicRole role) {
Map> result=new HashMap<>();
HierarchyNode node=m_currentRoleHierarchy.getNodeForElement(m_roleElementManager.getRoleElement(role));
if (node==null)
return result;
getObjectPropertyInstances(node,result);
return result;
}
protected void getObjectPropertyInstances(HierarchyNode node,Map> result) {
RoleElement representativeElement=node.getRepresentative();
if (representativeElement.equals(m_topRoleElement) || m_isInconsistent) {
Set allResultRelevantIndividuals=new HashSet<>();
for (Individual individual : m_individuals)
if (isResultRelevantIndividual(individual)) {
allResultRelevantIndividuals.add(individual);
result.put(individual, allResultRelevantIndividuals);
}
return;
}
Map> possibleInstances=representativeElement.getPossibleRelations();
for (Individual possibleInstance : new ArrayList<>(possibleInstances.keySet())) {
for (Individual possibleSuccessor : new ArrayList<>(possibleInstances.get(possibleInstance))) {
if (isRoleInstance(representativeElement.getRole(),possibleInstance,possibleSuccessor))
representativeElement.setToKnown(possibleInstance,possibleSuccessor);
else
for (HierarchyNode parent : node.getParentNodes())
parent.getRepresentative().addPossible(possibleInstance,possibleSuccessor);
}
}
Map> knownInstances=representativeElement.getKnownRelations();
knownInstances.forEach((instance1, set)->{
if (isResultRelevantIndividual(instance1)) {
Set successors=result.get(instance1);
boolean isNew=false;
if (successors==null) {
successors=new HashSet<>();
isNew=true;
}
for (Individual instance2 : set) {
if (isResultRelevantIndividual(instance2)) {
successors.add(instance2);
}
}
if (isNew && !successors.isEmpty())
result.put(instance1, successors);
}
});
for (HierarchyNode child : node.getChildNodes())
getObjectPropertyInstances(child, result);
}
/**
* @param role role
* @param individual individual
* @return object property values
*/
public Set getObjectPropertyValues(AtomicRole role,Individual individual) {
Set result=new HashSet<>();
HierarchyNode node=m_currentRoleHierarchy.getNodeForElement(m_roleElementManager.getRoleElement(role));
getObjectPropertyValues(node,individual, result);
return result;
}
/**
* @param role role
* @param individual individual
* @return object property subjects
*/
public Set getObjectPropertySubjects(AtomicRole role,Individual individual) {
Set result=new HashSet<>();
HierarchyNode node=m_currentRoleHierarchy.getNodeForElement(m_roleElementManager.getRoleElement(role));
getObjectPropertySubjects(node, individual, result);
return result;
}
protected void getObjectPropertySubjects(HierarchyNode node, Individual object, Set result) {
RoleElement representativeElement=node.getRepresentative();
if (representativeElement.equals(m_topRoleElement) || m_isInconsistent) {
for (Individual ind : m_individuals)
if (isResultRelevantIndividual(ind))
result.add(ind);
return;
}
Map> relevantRelations=representativeElement.getKnownRelations();
for (Individual subject : new ArrayList<>(relevantRelations.keySet())) {
if (isResultRelevantIndividual(subject) && relevantRelations.get(subject).contains(object))
result.add(subject);
}
relevantRelations=representativeElement.getPossibleRelations();
for (Individual possibleSubject : new ArrayList<>(relevantRelations.keySet())) {
if (isResultRelevantIndividual(possibleSubject) && relevantRelations.get(possibleSubject).contains(object) && isRoleInstance(representativeElement.getRole(),possibleSubject,object)) {
representativeElement.setToKnown(possibleSubject,object);
result.add(possibleSubject);
}
else
for (HierarchyNode parent : node.getParentNodes())
parent.getRepresentative().addPossible(possibleSubject,object);
}
for (HierarchyNode child : node.getChildNodes())
getObjectPropertySubjects(child, object, result);
}
protected void getObjectPropertyValues(HierarchyNode node, Individual subject, Set result) {
RoleElement representativeElement=node.getRepresentative();
if (representativeElement.equals(m_topRoleElement) || m_isInconsistent) {
for (Individual ind : m_individuals)
if (isResultRelevantIndividual(ind))
result.add(ind);
return;
}
Set possibleSuccessors=representativeElement.getPossibleRelations().get(subject);
if (possibleSuccessors!=null) {
for (Individual possibleSuccessor : new HashSet<>(possibleSuccessors)) {
if (isRoleInstance(representativeElement.getRole(),subject,possibleSuccessor))
representativeElement.setToKnown(subject,possibleSuccessor);
else
for (HierarchyNode parent : node.getParentNodes())
parent.getRepresentative().addPossible(subject,possibleSuccessor);
}
}
Set knownSuccessors=representativeElement.getKnownRelations().get(subject);
if (knownSuccessors!=null) {
for (Individual successor : knownSuccessors)
if (isResultRelevantIndividual(successor))
result.add(successor);
}
for (HierarchyNode child : node.getChildNodes())
getObjectPropertyValues(child, subject, result);
}
/**
* @param individual individual
* @return same individuals
*/
public Set getSameAsIndividuals(Individual individual) {
Set equivalenceClass=m_individualToEquivalenceClass.get(individual);
Set> possiblySameEquivalenceClasses=m_individualToPossibleEquivalenceClass.get(equivalenceClass);
if (possiblySameEquivalenceClasses!=null) {
while (!possiblySameEquivalenceClasses.isEmpty()) {
Set possiblyEquivalentClass=possiblySameEquivalenceClasses.iterator().next();
possiblySameEquivalenceClasses.remove(possiblyEquivalentClass);
if (possiblySameEquivalenceClasses.isEmpty())
m_individualToPossibleEquivalenceClass.remove(equivalenceClass);
Individual possiblyEquivalentIndividual=possiblyEquivalentClass.iterator().next();
if (isSameIndividual(equivalenceClass.iterator().next(), possiblyEquivalentIndividual)) {
equivalenceClass.addAll(possiblyEquivalentClass);
equivalenceClass.addAll(m_individualToEquivalenceClass.get(possiblyEquivalentIndividual));
for (Individual nowKnownEquivalent : possiblyEquivalentClass)
m_individualToEquivalenceClass.put(nowKnownEquivalent, equivalenceClass);
}
else {
Set> possiblyEquivalentToNowKnownInequivalent=m_individualToPossibleEquivalenceClass.get(possiblyEquivalentClass);
if (possiblyEquivalentToNowKnownInequivalent!=null && possiblyEquivalentToNowKnownInequivalent.contains(equivalenceClass)) {
possiblyEquivalentToNowKnownInequivalent.remove(equivalenceClass);
if (possiblyEquivalentToNowKnownInequivalent.isEmpty())
m_individualToPossibleEquivalenceClass.remove(possiblyEquivalentClass);
}
}
}
}
for (Set otherEquivalenceClass : new ArrayList<>(m_individualToPossibleEquivalenceClass.keySet())) {
if (otherEquivalenceClass!=equivalenceClass && m_individualToPossibleEquivalenceClass.get(otherEquivalenceClass).contains(equivalenceClass)) {
if (isSameIndividual(equivalenceClass.iterator().next(), otherEquivalenceClass.iterator().next())) {
m_individualToPossibleEquivalenceClass.get(otherEquivalenceClass).remove(equivalenceClass);
if (m_individualToPossibleEquivalenceClass.get(otherEquivalenceClass).isEmpty())
m_individualToPossibleEquivalenceClass.remove(otherEquivalenceClass);
for (Individual nowKnownEquivalent : otherEquivalenceClass)
m_individualToEquivalenceClass.put(nowKnownEquivalent, equivalenceClass);
equivalenceClass.addAll(otherEquivalenceClass);
}
}
}
return equivalenceClass;
}
/**
* @param individual1 individual1
* @param individual2 individual2
* @return true if same
*/
public boolean isSameIndividual(Individual individual1, Individual individual2) {
return (!m_reasoner.getTableau().isSatisfiable(true,false,Collections.singleton(Atom.create(Inequality.INSTANCE,individual1,individual2)),null,null,null,null,new ReasoningTaskDescription(true,"is {0} same as {1}",individual1,individual2)));
}
/**
* @param progressMonitor progressMonitor
*/
public void computeSameAsEquivalenceClasses(ReasonerProgressMonitor progressMonitor) {
if (!m_individualToPossibleEquivalenceClass.isEmpty()) {
int steps=m_individualToPossibleEquivalenceClass.size();
if (steps>0 && progressMonitor!=null)
progressMonitor.reasonerTaskStarted("Precompute same individuals");
while (!m_individualToPossibleEquivalenceClass.isEmpty()) {
Set equivalenceClass=m_individualToPossibleEquivalenceClass.keySet().iterator().next();
getSameAsIndividuals(equivalenceClass.iterator().next());
if (progressMonitor!=null)
progressMonitor.reasonerTaskProgressChanged(steps-m_individualToPossibleEquivalenceClass.size(), steps);
}
if (progressMonitor!=null)
progressMonitor.reasonerTaskStopped();
}
}
protected boolean isInstance(Individual individual,AtomicConcept atomicConcept) {
boolean result = !m_reasoner.getTableau().isSatisfiable(true,false,null,Collections.singleton(Atom.create(atomicConcept,individual)),null,null,null,ReasoningTaskDescription.isInstanceOf(atomicConcept,individual));
if (m_tableauMonitor!=null) {
if (result)
m_tableauMonitor.possibleInstanceIsInstance();
else
m_tableauMonitor.possibleInstanceIsNotInstance();
}
return result;
}
protected boolean isRoleInstance(Role role, Individual _individual1, Individual _individual2) {
OWLDataFactory factory=m_reasoner.getDataFactory();
Individual individual1=_individual1;
Individual individual2=_individual2;
AtomicRole atomicRole;
if (role instanceof InverseRole) {
Individual tmp=individual1;
individual1=individual2;
individual2=tmp;
atomicRole=((InverseRole)role).getInverseOf();
}
else
atomicRole=(AtomicRole)role;
OWLObjectProperty property=factory.getOWLObjectProperty(IRI.create(atomicRole.getIRI()));
OWLNamedIndividual namedIndividual1=factory.getOWLNamedIndividual(IRI.create(individual1.getIRI()));
OWLNamedIndividual namedIndividual2=factory.getOWLNamedIndividual(IRI.create(individual2.getIRI()));
OWLClass pseudoNominal=factory.getOWLClass(IRI.create("internal:pseudo-nominal"));
OWLClassExpression allNotPseudoNominal=factory.getOWLObjectAllValuesFrom(property,pseudoNominal.getObjectComplementOf());
OWLAxiom allNotPseudoNominalAssertion=factory.getOWLClassAssertionAxiom(allNotPseudoNominal,namedIndividual1);
OWLAxiom pseudoNominalAssertion=factory.getOWLClassAssertionAxiom(pseudoNominal,namedIndividual2);
Tableau tableau=m_reasoner.getTableau(allNotPseudoNominalAssertion,pseudoNominalAssertion);
boolean result=!tableau.isSatisfiable(true,true,null,null,null,null,null,new ReasoningTaskDescription(true,"is {0} connected to {1} via {2}",individual1,individual2,atomicRole));
if (m_tableauMonitor!=null) {
if (result)
m_tableauMonitor.possibleInstanceIsInstance();
else
m_tableauMonitor.possibleInstanceIsNotInstance();
}
return result;
}
protected static boolean isResultRelevantIndividual(Individual individual) {
return !individual.isAnonymous() && !Prefixes.isInternalIRI(individual.getIRI());
}
/**
* @return true if realisation completed
*/
public boolean realizationCompleted() {
return m_realizationCompleted;
}
/**
* @return true if object property realisation complete
*/
public boolean objectPropertyRealizationCompleted() {
return m_roleRealizationCompleted;
}
/**
* @return true if sameas computed
*/
public boolean sameAsIndividualsComputed() {
return m_individualToPossibleEquivalenceClass.isEmpty();
}
/**
* @return true if classes initialised
*/
public boolean areClassesInitialised() {
return m_classesInitialised;
}
/**
* @return true if proeprties initialised
*/
public boolean arePropertiesInitialised() {
return m_propertiesInitialised;
}
/**
* @return current inex
*/
public int getCurrentIndividualIndex() {
return m_currentIndividualIndex;
}
/**
* @return nodes for individuals
*/
public Map getNodesForIndividuals() {
return m_nodesForIndividuals;
}
}