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

org.semanticweb.HermiT.hierarchy.InstanceManager Maven / Gradle / Ivy

Go to download

HermiT is reasoner for ontologies written using the Web Ontology Language (OWL). Given an OWL file, HermiT can determine whether or not the ontology is consistent, identify subsumption relationships between classes, and much more. This is the maven build of HermiT and is designed for people who wish to use HermiT from within the OWL API. It is now versioned in the main HermiT version repository, although not officially supported by the HermiT developers. The version number of this package is a composite of the HermiT version and an value representing releases of this packaged version. So, 1.3.7.1 is the first release of the mavenized version of HermiT based on the 1.3.7 release of HermiT. This package includes the Jautomata library (http://jautomata.sourceforge.net/), and builds with it directly. This library appears to be no longer under active development, and so a "fork" seems appropriate. No development is intended or anticipated on this code base.

There is a newer version: 1.3.8.4
Show 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.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
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;

public class InstanceManager {
    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_usesClassifiedObjectRoleHierarchy;
    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_binaryRetrieval01Bound;
    protected final ExtensionTable.Retrieval m_ternaryRetrieval1Bound;
    protected final ExtensionTable.Retrieval m_ternaryRetrieval0Bound;
    protected final ExtensionTable.Retrieval m_ternaryRetrieval012Bound;
    protected int m_currentIndividualIndex=0;

    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_binaryRetrieval01Bound=extensionManager.getBinaryExtensionTable().createRetrieval(new boolean[] { true, true }, ExtensionTable.View.TOTAL);
            m_ternaryRetrieval1Bound=extensionManager.getTernaryExtensionTable().createRetrieval(new boolean[] { false,true,false }, ExtensionTable.View.TOTAL);
            m_ternaryRetrieval0Bound=extensionManager.getTernaryExtensionTable().createRetrieval(new boolean[] { true,false,false }, ExtensionTable.View.TOTAL);
            m_ternaryRetrieval012Bound=extensionManager.getTernaryExtensionTable().createRetrieval(new boolean[] { true,true,true }, 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(Set 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);
    }
    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
     * @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() {
            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);
            }
            public RoleElement determineRepresentative(Role oldRepresentative,Set newEquivalentElements) {
                RoleElement representative=transform(oldRepresentative);
                for (RoleElement newEquiv : newEquivalentElements) {
                    if (!newEquiv.equals(representative)) {
                        for (Individual individual : newEquiv.m_knownRelations.keySet()) {
                            Set successors=representative.m_knownRelations.get(individual);
                            if (successors==null) {
                                successors=new HashSet();
                                representative.m_knownRelations.put(individual, successors);
                            }
                            successors.addAll(newEquiv.m_knownRelations.get(individual));
                        }
                        for (Individual individual : newEquiv.m_possibleRelations.keySet()) {
                            Set successors=representative.m_possibleRelations.get(individual);
                            if (successors!=null) {
                                successors.retainAll(newEquiv.m_possibleRelations.get(individual));
                            }
                        }
                        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;
    }
    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;
                    for (Individual individual : currentRepresentative.m_knownRelations.keySet()) {
                        Set successors=ancestorKnowRelations.get(individual);
                        if (successors!=null) {
                            successors.removeAll(currentRepresentative.m_knownRelations.get(individual));
                            if (successors.isEmpty())
                                ancestorKnowRelations.remove(individual);
                        }
                        successors=ancestorPossibleRelations.get(individual);
                        if (successors!=null) {
                            successors.removeAll(currentRepresentative.m_knownRelations.get(individual));
                            if (successors.isEmpty())
                                ancestorPossibleRelations.remove(individual);
                        }
                    }
                    for (Individual individual : currentRepresentative.m_possibleRelations.keySet()) {
                        Set successors=ancestorPossibleRelations.get(individual);
                        if (successors!=null) {
                            successors.removeAll(currentRepresentative.m_possibleRelations.get(individual));
                            if (successors.isEmpty())
                                ancestorPossibleRelations.remove(individual);
                        }
                    }
                }
                for (HierarchyNode parent : current.getParentNodes())
                    if (!toProcess.contains(parent))
                        toProcess.add(parent);
                m_interruptFlag.checkInterrupt();
            }
        }
        m_usesClassifiedObjectRoleHierarchy=true;
    }
    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);
        }
    }
    public OWLAxiom[] getAxiomsForReadingOffCompexProperties(OWLDataFactory factory, ReasonerProgressMonitor monitor, int completedSteps, int steps) {
        if (m_complexRoles.size()>0) {
            int noAdditionalAxioms=0;
            List additionalAxioms=new ArrayList();
            m_interruptFlag.startTask();
            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(Tableau tableau,Map individualsForNodes, ReasonerProgressMonitor monitor, int completedSteps, int steps, int startIndividualIndex) {
        // 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, Set>>();
        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 : 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, Node nodeForIndividual, ReasonerProgressMonitor monitor, int completedSteps, int steps) {
        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();
            }
        }
    }
    public void setInconsistent() {
        m_isInconsistent=true;
        m_realizationCompleted=true;
        m_roleRealizationCompleted=true;
        m_usesClassifiedConceptHierarchy=true;
        m_usesClassifiedObjectRoleHierarchy=true;
        m_currentConceptHierarchy=null;
        m_currentRoleHierarchy=null;
    }
    public void realize(ReasonerProgressMonitor monitor) {
        assert m_usesClassifiedConceptHierarchy==true;
        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;
    }
    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()) {
                    for (Individual individual : roleElement.m_possibleRelations.keySet()) {
                        Set nonInstances=new HashSet();
                        for (Individual successor : roleElement.m_possibleRelations.get(individual)) {
                            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;
    }
    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>();
        toProcess.add(m_currentConceptHierarchy.m_bottomNode);
        while (!toProcess.isEmpty()) {
            HierarchyNode current=toProcess.remove();
            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))
                        toProcess.add(parent);
            }
        }
        return result;
    }
    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);
    }
    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;
    }
    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;
    }
    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);
    }

    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);
    }
    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;
    }
    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 HashSet(possibleInstances.keySet())) {
            for (Individual possibleSuccessor : new HashSet(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();
        for (Individual instance1 : knownInstances.keySet()) {
            if (isResultRelevantIndividual(instance1)) {
                Set successors=result.get(instance1);
                boolean isNew=false;
                if (successors==null) {
                    successors=new HashSet();
                    isNew=true;
                }
                for (Individual instance2 : knownInstances.get(instance1)) {
                    if (isResultRelevantIndividual(instance2)) {
                        successors.add(instance2);
                    }
                }
                if (isNew && !successors.isEmpty())
                    result.put(instance1, successors);
            }
        }
        for (HierarchyNode child : node.getChildNodes())
            getObjectPropertyInstances(child, result);
    }
    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;
    }
    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 HashSet(relevantRelations.keySet())) {
            if (isResultRelevantIndividual(subject) && relevantRelations.get(subject).contains(object))
                result.add(subject);
        }
        relevantRelations=representativeElement.getPossibleRelations();
        for (Individual possibleSubject : new HashSet(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);
    }
    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 HashSet>(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;
    }
    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)));
    }
    public void computeSameAsEquivalenceClasses(ReasonerProgressMonitor progressMonitor) {
        if (!m_individualToPossibleEquivalenceClass.isEmpty()) {
            int steps=m_individualToPossibleEquivalenceClass.keySet().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.keySet().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();
        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());
    }
    public boolean realizationCompleted() {
        return m_realizationCompleted;
    }
    public boolean objectPropertyRealizationCompleted() {
        return m_roleRealizationCompleted;
    }
    public boolean sameAsIndividualsComputed() {
        return m_individualToPossibleEquivalenceClass.isEmpty();
    }
    public boolean areClassesInitialised() {
        return m_classesInitialised;
    }
    public boolean arePropertiesInitialised() {
        return m_propertiesInitialised;
    }
    public int getCurrentIndividualIndex() {
        return m_currentIndividualIndex;
    }
    public Map getNodesForIndividuals() {
        return m_nodesForIndividuals;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy