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

org.semanticweb.HermiT.blocking.AnywhereValidatedBlocking 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.blocking;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.semanticweb.HermiT.blocking.ValidatedSingleDirectBlockingChecker.ValidatedBlockingObject;
import org.semanticweb.HermiT.model.AtomicRole;
import org.semanticweb.HermiT.model.Concept;
import org.semanticweb.HermiT.model.DLClause;
import org.semanticweb.HermiT.model.DLOntology;
import org.semanticweb.HermiT.model.DataRange;
import org.semanticweb.HermiT.model.Variable;
import org.semanticweb.HermiT.monitor.TableauMonitor;
import org.semanticweb.HermiT.tableau.DLClauseEvaluator;
import org.semanticweb.HermiT.tableau.ExtensionManager;
import org.semanticweb.HermiT.tableau.Node;
import org.semanticweb.HermiT.tableau.NodeType;
import org.semanticweb.HermiT.tableau.Tableau;

public class AnywhereValidatedBlocking implements BlockingStrategy {
    protected final DirectBlockingChecker m_directBlockingChecker;
    protected final ValidatedBlockersCache m_currentBlockersCache;
    protected BlockingValidator m_permanentBlockingValidator;
    protected BlockingValidator m_additionalBlockingValidator;
    protected Tableau m_tableau;
    protected ExtensionManager m_extensionManager;
    protected Node m_firstChangedNode;
    protected Node m_lastValidatedUnchangedNode;
    protected boolean m_useSimpleCore;
    protected final boolean m_hasInverses;

    public AnywhereValidatedBlocking(DirectBlockingChecker directBlockingChecker,boolean hasInverses,boolean useSimpleCore) {
        m_directBlockingChecker=directBlockingChecker;
        m_currentBlockersCache=new ValidatedBlockersCache(m_directBlockingChecker);
        m_hasInverses=hasInverses;
        m_useSimpleCore=useSimpleCore;
    }
    public void initialize(Tableau tableau) {
        m_tableau=tableau;
        m_directBlockingChecker.initialize(tableau);
        m_extensionManager=m_tableau.getExtensionManager();
        m_permanentBlockingValidator=new BlockingValidator(m_tableau,m_tableau.getPermanentDLOntology().getDLClauses());
        updateAdditionalBlockingValidator();
    }
    public void additionalDLOntologySet(DLOntology additionalDLOntology) {
        updateAdditionalBlockingValidator();
    }
    public void additionalDLOntologyCleared() {
        updateAdditionalBlockingValidator();
    }
    protected void updateAdditionalBlockingValidator() {
        if (m_tableau.getAdditionalHyperresolutionManager()==null)
            m_additionalBlockingValidator=null;
        else
            m_additionalBlockingValidator=new BlockingValidator(m_tableau,m_tableau.getAdditionalDLOntology().getDLClauses());
    }
    public void clear() {
        m_currentBlockersCache.clear();
        m_firstChangedNode=null;
        m_directBlockingChecker.clear();
        m_lastValidatedUnchangedNode=null;
        m_permanentBlockingValidator.clear();
        if (m_additionalBlockingValidator!=null)
            m_additionalBlockingValidator.clear();
    }
    public void computeBlocking(boolean finalChance) {
        if (finalChance) {
            validateBlocks();
        }
        else {
            computePreBlocking();
        }
    }
    public void computePreBlocking() {
        if (m_firstChangedNode!=null) {
            Node node=m_firstChangedNode;
            while (node!=null) {
                m_currentBlockersCache.removeNode(node);
                node=node.getNextTableauNode();
            }
            node=m_firstChangedNode;
            while (node!=null) {
                if (node.isActive() && (m_directBlockingChecker.canBeBlocked(node) || m_directBlockingChecker.canBeBlocker(node))) {
                    if (m_directBlockingChecker.hasBlockingInfoChanged(node) || !node.isDirectlyBlocked() || node.getBlocker().getNodeID()>=m_firstChangedNode.getNodeID()) {
                        Node parent=node.getParent();
                        if (parent==null)
                            node.setBlocked(null,false);
                        else if (parent.isBlocked())
                            node.setBlocked(parent,false);
                        else {
                            Node blocker=null;
                            if (m_lastValidatedUnchangedNode==null)
                                blocker=m_currentBlockersCache.getBlocker(node);
                            else {
                                // after a validation has been done, only re-block if something has been modified
                                Node previousBlocker=node.getBlocker();
                                boolean nodeModified=m_directBlockingChecker.hasChangedSinceValidation(node);
                                for (Node possibleBlocker : m_currentBlockersCache.getPossibleBlockers(node)) {
                                    if (nodeModified || m_directBlockingChecker.hasChangedSinceValidation(possibleBlocker) || previousBlocker==possibleBlocker) {
                                        blocker=possibleBlocker;
                                        break;
                                    }
                                }
                            }
                            node.setBlocked(blocker,blocker!=null);
                        }
                    }
                    if (!node.isBlocked() && m_directBlockingChecker.canBeBlocker(node))
                        m_currentBlockersCache.addNode(node);
                }
                m_directBlockingChecker.clearBlockingInfoChanged(node);
                node=node.getNextTableauNode();
            }
            m_firstChangedNode=null;
        }
    }
    public void validateBlocks() {
        // statistics for debugging:
        boolean debuggingMode=false;
        int checkedBlocks=0;
        int invalidBlocks=0;

        TableauMonitor monitor=m_tableau.getTableauMonitor();
        if (monitor!=null)
            monitor.blockingValidationStarted();

        Node node;
        node=m_lastValidatedUnchangedNode==null ? m_tableau.getFirstTableauNode() : m_lastValidatedUnchangedNode;
        Node firstValidatedNode=node;
        while (node!=null) {
            m_currentBlockersCache.removeNode(node);
            node=node.getNextTableauNode();
        }
        node=firstValidatedNode;
        if (debuggingMode)
            System.out.print("Model size: "+(m_tableau.getNumberOfNodesInTableau()-m_tableau.getNumberOfMergedOrPrunedNodes())+" Current ID:");
        Node firstInvalidlyBlockedNode=null;
        while (node!=null) {
            if (node.isActive()) {
                if (node.isBlocked()) { // && node.hasUnprocessedExistentials()
                    checkedBlocks++;
                    // check whether the block is a correct one
                    if ((node.isDirectlyBlocked() && (m_directBlockingChecker.hasChangedSinceValidation(node) || m_directBlockingChecker.hasChangedSinceValidation(node.getParent()) || m_directBlockingChecker.hasChangedSinceValidation(node.getBlocker()))) || !node.getParent().isBlocked()) {
                        Node validBlocker=null;
                        Node currentBlocker=node.getBlocker();
                        if (node.isDirectlyBlocked() && currentBlocker!=null) {
                            // try the old blocker fist
                            if (isBlockValid(node))
                                validBlocker=currentBlocker;
                        }
                        if (validBlocker==null) {
                            for (Node possibleBlocker : m_currentBlockersCache.getPossibleBlockers(node)) {
                                if (possibleBlocker!=currentBlocker) {
                                    node.setBlocked(possibleBlocker,true);
                                    m_permanentBlockingValidator.blockerChanged(node); // invalidate cache
                                    if (m_additionalBlockingValidator!=null)
                                        m_additionalBlockingValidator.blockerChanged(node);
                                    if (isBlockValid(node)) {
                                        validBlocker=possibleBlocker;
                                        break;
                                    }
                                }
                            }
                        }
                        if (validBlocker==null && node.hasUnprocessedExistentials()) {
                            invalidBlocks++;
                            if (firstInvalidlyBlockedNode==null)
                                firstInvalidlyBlockedNode=node;
                        }
                        node.setBlocked(validBlocker,validBlocker!=null);
                    }
                }
                m_lastValidatedUnchangedNode=node;
                if (!node.isBlocked() && m_directBlockingChecker.canBeBlocker(node))
                    m_currentBlockersCache.addNode(node);
            }
            node=node.getNextTableauNode();
        }

        node=firstValidatedNode;
        while (node!=null) {
            if (node.isActive()) {
                m_directBlockingChecker.setHasChangedSinceValidation(node,false);
                ValidatedBlockingObject blockingObject=(ValidatedBlockingObject)node.getBlockingObject();
                blockingObject.setBlockViolatesParentConstraints(false);
                blockingObject.setHasAlreadyBeenChecked(false);
            }
            node=node.getNextTableauNode();
        }
        // if set to some node, then computePreblocking will be asked to check from that node onwards in case of invalid blocks
        m_firstChangedNode=firstInvalidlyBlockedNode;
        if (monitor!=null)
            monitor.blockingValidationFinished(invalidBlocks);

        if (debuggingMode) {
            System.out.println("");
            System.out.println("Checked "+checkedBlocks+" blocked nodes of which "+invalidBlocks+" were invalid.");
        }
    }
    protected boolean isBlockValid(Node node) {
        if (m_permanentBlockingValidator.isBlockValid(node)) {
            if (m_additionalBlockingValidator!=null)
                return m_additionalBlockingValidator.isBlockValid(node);
            else
                return true;
        }
        else
            return false;
    }
    public boolean isPermanentAssertion(Concept concept,Node node) {
        return true;
    }
    public boolean isPermanentAssertion(DataRange range,Node node) {
        return true;
    }
    protected void validationInfoChanged(Node node) {
        if (node!=null) {
            if (m_lastValidatedUnchangedNode!=null && node.getNodeID()=node.getNodeID())
            m_firstChangedNode=null;
        if (m_lastValidatedUnchangedNode!=null && node.getNodeID() {
        public final String m_violatedConstraint;
        public final Integer m_numberOfViolations;
        public ViolationStatistic(String violatedConstraint,Integer numberOfViolations) {
            m_violatedConstraint=violatedConstraint;
            m_numberOfViolations=numberOfViolations;
        }
        public int compareTo(ViolationStatistic that) {
            if (this==that)
                return 0;
            if (that==null)
                throw new NullPointerException("Comparing to a null object is illegal. ");
            if (this.m_numberOfViolations==that.m_numberOfViolations)
                return m_violatedConstraint.compareTo(that.m_violatedConstraint);
            else
                return that.m_numberOfViolations-this.m_numberOfViolations;
        }
        public String toString() {
            return m_numberOfViolations+": "+m_violatedConstraint.replaceAll("http://www.co-ode.org/ontologies/galen#","");
        }
    }
    public boolean isExact() {
        return false;
    }
    public void dlClauseBodyCompiled(List workers,DLClause dlClause,List variables,Object[] valuesBuffer,boolean[] coreVariables) {
        if (m_useSimpleCore) {
            for (int i=0;i1) {
                for (int i=0;i1) {
                    workers.add(new ComputeCoreVariables(dlClause,variables,valuesBuffer,coreVariables));
                }
            }
        }
    }

    protected static final class ComputeCoreVariables implements DLClauseEvaluator.Worker,Serializable {
        private static final long serialVersionUID=899293772370136783L;

        protected final DLClause m_dlClause;
        protected final List m_variables;
        protected final Object[] m_valuesBuffer;
        protected final boolean[] m_coreVariables;

        public ComputeCoreVariables(DLClause dlClause,List variables,Object[] valuesBuffer,boolean[] coreVariables) {
            m_dlClause=dlClause;
            m_variables=variables;
            m_valuesBuffer=valuesBuffer;
            m_coreVariables=coreVariables;
        }
        public void clear() {
        }
        public int execute(int programCounter) {
            Node potentialNonCore=null;
            // find the root of the subtree induced by the mapped nodes that node cannot be core
            for (int variableIndex=m_coreVariables.length-1;variableIndex>=0;--variableIndex) {
                Node node=(Node)m_valuesBuffer[variableIndex];
                if (node.getNodeType()==NodeType.TREE_NODE && (potentialNonCore==null || node.getTreeDepth()=0;--variableIndex) {
                    Node node=(Node)m_valuesBuffer[variableIndex];
                    if (!node.isRootNode() && potentialNonCore!=node && potentialNonCore.getTreeDepth()();
                        entry.m_hashCode=0;
                        m_emptyEntries=entry;
                        m_numberOfElements--;
                    }
                    else {
                        if (entry.m_nodes.contains(node)) {
                            for (int i=entry.m_nodes.size()-1;i>=entry.m_nodes.indexOf(node);i--) {
                                entry.m_nodes.get(i).setBlockingCargo(null);
                            }
                            entry.m_nodes.subList(entry.m_nodes.indexOf(node),entry.m_nodes.size()).clear();
                        }
                        else {
                            throw new IllegalStateException("Internal error: entry not in cache!");
                        }
                    }
                    return true;
                }
                lastEntry=entry;
                entry=entry.m_nextEntry;
            }
            throw new IllegalStateException("Internal error: entry not in cache!");
        }
        return false;
    }
    public void addNode(Node node) {
        int hashCode=m_directBlockingChecker.blockingHashCode(node);
        int bucketIndex=getIndexFor(hashCode,m_buckets.length);
        CacheEntry entry=m_buckets[bucketIndex];
        while (entry!=null) {
            if (hashCode==entry.m_hashCode && m_directBlockingChecker.isBlockedBy(entry.m_nodes.get(0),node)) {
                if (!entry.m_nodes.contains(node)) {
                    entry.add(node);
                    node.setBlockingCargo(entry);
                    return;
                }
                else {
                    throw new IllegalStateException("Internal error: node already in the cache!");
                }
            }
            entry=entry.m_nextEntry;
        }
        if (m_emptyEntries==null)
            entry=new CacheEntry();
        else {
            entry=m_emptyEntries;
            m_emptyEntries=m_emptyEntries.m_nextEntry;
        }
        entry.initialize(node,hashCode,m_buckets[bucketIndex]);
        m_buckets[bucketIndex]=entry;
        // When a node is added to the cache, we record with the node the entry.
        // This is used to remove nodes from the cache. Note that changes to a node
        // can affect its label. Therefore, we CANNOT remove a node by taking its present
        // blocking hash-code, as this can be different from the hash-code used at the
        // time the node has been added to the cache.
        node.setBlockingCargo(entry);
        m_numberOfElements++;
        if (m_numberOfElements>=m_threshold)
            resize(m_buckets.length*2);
    }
    protected void resize(int newCapacity) {
        CacheEntry[] newBuckets=new CacheEntry[newCapacity];
        for (int i=0;i getPossibleBlockers(Node node) {
        if (m_directBlockingChecker.canBeBlocked(node)) {
            int hashCode=m_directBlockingChecker.blockingHashCode(node);
            int bucketIndex=getIndexFor(hashCode,m_buckets.length);
            CacheEntry entry=m_buckets[bucketIndex];
            while (entry!=null) {
                if (hashCode==entry.m_hashCode && m_directBlockingChecker.isBlockedBy(entry.m_nodes.get(0),node)) {
                    assert !entry.m_nodes.contains(node); // we try to block a node that is in the cache
                    return entry.m_nodes;
                }
                entry=entry.m_nextEntry;
            }
        }
        return new ArrayList();
    }
    protected static int getIndexFor(int hashCode,int tableLength) {
        hashCode+=~(hashCode<<9);
        hashCode^=(hashCode>>>14);
        hashCode+=(hashCode<<4);
        hashCode^=(hashCode>>>10);
        return hashCode&(tableLength-1);
    }
    public String toString() {
        String buckets="";
        for (int i=0;i m_nodes;
        protected int m_hashCode;
        protected CacheEntry m_nextEntry;

        public void initialize(Node node,int hashCode,CacheEntry nextEntry) {
            m_nodes=new ArrayList();
            add(node);
            m_hashCode=hashCode;
            m_nextEntry=nextEntry;
        }
        public boolean add(Node node) {
            for (Node n : m_nodes) {
                assert n.getNodeID()<=node.getNodeID();
            }
            return m_nodes.add(node);
        }
        public String toString() {
            String nodes="HashCode: "+m_hashCode+" Nodes: ";
            for (Node n : m_nodes) {
                nodes+=n.getNodeID()+" ";
            }
            return nodes;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy