org.semanticweb.HermiT.tableau.Tableau 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
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.
/* 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.tableau;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.semanticweb.HermiT.existentials.ExistentialExpansionStrategy;
import org.semanticweb.HermiT.model.Atom;
import org.semanticweb.HermiT.model.AtomicConcept;
import org.semanticweb.HermiT.model.AtomicRole;
import org.semanticweb.HermiT.model.Constant;
import org.semanticweb.HermiT.model.ConstantEnumeration;
import org.semanticweb.HermiT.model.DLClause;
import org.semanticweb.HermiT.model.DLOntology;
import org.semanticweb.HermiT.model.DLPredicate;
import org.semanticweb.HermiT.model.DescriptionGraph;
import org.semanticweb.HermiT.model.Equality;
import org.semanticweb.HermiT.model.ExistentialConcept;
import org.semanticweb.HermiT.model.Individual;
import org.semanticweb.HermiT.model.Inequality;
import org.semanticweb.HermiT.model.InternalDatatype;
import org.semanticweb.HermiT.model.LiteralConcept;
import org.semanticweb.HermiT.model.NegatedAtomicRole;
import org.semanticweb.HermiT.model.Term;
import org.semanticweb.HermiT.monitor.TableauMonitor;
import org.semanticweb.HermiT.tableau.Node.NodeState;
/**
* This class coordinates the main tableau expansion for a given DLOntology
* (a normalized and clausified ontology). It represents the state of a run
* on a set of clauses and coordinates the extension of the ABox and also the
* retraction of facts when backtracking. Before starting the expansion,
* the given clauses are (for better performance) preprocessed via the
* HyperresolutionManager into a compiled and executable form.
*/
public final class Tableau implements Serializable {
private static final long serialVersionUID=-28982363158925221L;
protected final InterruptFlag m_interruptFlag;
protected final Map m_parameters;
protected final TableauMonitor m_tableauMonitor;
protected final ExistentialExpansionStrategy m_existentialExpansionStrategy;
protected final DLOntology m_permanentDLOntology;
protected DLOntology m_additionalDLOntology;
protected final DependencySetFactory m_dependencySetFactory;
protected final ExtensionManager m_extensionManager;
protected final ClashManager m_clashManager;
protected final HyperresolutionManager m_permanentHyperresolutionManager;
protected HyperresolutionManager m_additionalHyperresolutionManager;
protected final MergingManager m_mergingManager;
protected final ExistentialExpansionManager m_existentialExpasionManager;
protected final NominalIntroductionManager m_nominalIntroductionManager;
protected final DescriptionGraphManager m_descriptionGraphManager;
protected final DatatypeManager m_datatypeManager;
protected final List> m_existentialConceptsBuffers;
protected final boolean m_useDisjunctionLearning;
protected final boolean m_hasDescriptionGraphs;
protected BranchingPoint[] m_branchingPoints;
protected int m_currentBranchingPoint;
protected int m_nonbacktrackableBranchingPoint;
protected boolean m_isCurrentModelDeterministic;
protected boolean m_needsThingExtension;
protected boolean m_needsNamedExtension;
protected boolean m_needsRDFSLiteralExtension;
protected boolean m_checkDatatypes;
protected boolean m_checkUnknownDatatypeRestrictions;
protected int m_allocatedNodes;
protected int m_numberOfNodesInTableau;
protected int m_numberOfMergedOrPrunedNodes;
protected int m_numberOfNodeCreations;
protected Node m_firstFreeNode;
protected Node m_firstTableauNode;
protected Node m_lastTableauNode;
protected Node m_lastMergedOrPrunedNode;
protected GroundDisjunction m_firstGroundDisjunction;
protected GroundDisjunction m_firstUnprocessedGroundDisjunction;
public Tableau(InterruptFlag interruptFlag,TableauMonitor tableauMonitor,ExistentialExpansionStrategy existentialsExpansionStrategy,boolean useDisjunctionLearning,DLOntology permanentDLOntology,DLOntology additionalDLOntology,Map parameters) {
if (additionalDLOntology!=null && !additionalDLOntology.getAllDescriptionGraphs().isEmpty())
throw new IllegalArgumentException("Additional ontology cannot contain description graphs.");
m_interruptFlag=interruptFlag;
m_interruptFlag.startTask();
try {
m_parameters=parameters;
m_tableauMonitor=tableauMonitor;
m_existentialExpansionStrategy=existentialsExpansionStrategy;
m_permanentDLOntology=permanentDLOntology;
m_additionalDLOntology=additionalDLOntology;
m_dependencySetFactory=new DependencySetFactory();
m_extensionManager=new ExtensionManager(this);
m_clashManager=new ClashManager(this);
m_permanentHyperresolutionManager=new HyperresolutionManager(this,m_permanentDLOntology.getDLClauses());
if (m_additionalDLOntology!=null)
m_additionalHyperresolutionManager=new HyperresolutionManager(this,m_additionalDLOntology.getDLClauses());
else
m_additionalHyperresolutionManager=null;
m_mergingManager=new MergingManager(this);
m_existentialExpasionManager=new ExistentialExpansionManager(this);
m_nominalIntroductionManager=new NominalIntroductionManager(this);
m_descriptionGraphManager=new DescriptionGraphManager(this);
m_datatypeManager=new DatatypeManager(this);
m_existentialExpansionStrategy.initialize(this);
m_existentialConceptsBuffers=new ArrayList>();
m_useDisjunctionLearning=useDisjunctionLearning;
m_hasDescriptionGraphs=!m_permanentDLOntology.getAllDescriptionGraphs().isEmpty();
m_branchingPoints=new BranchingPoint[2];
m_currentBranchingPoint=-1;
m_nonbacktrackableBranchingPoint=-1;
updateFlagsDependentOnAdditionalOntology();
if (m_tableauMonitor!=null)
m_tableauMonitor.setTableau(this);
}
finally {
m_interruptFlag.endTask();
}
}
public InterruptFlag getInterruptFlag() {
return m_interruptFlag;
}
public DLOntology getPermanentDLOntology() {
return m_permanentDLOntology;
}
public DLOntology getAdditionalDLOntology() {
return m_additionalDLOntology;
}
public Map getParameters() {
return m_parameters;
}
public TableauMonitor getTableauMonitor() {
return m_tableauMonitor;
}
public ExistentialExpansionStrategy getExistentialsExpansionStrategy() {
return m_existentialExpansionStrategy;
}
public boolean isDeterministic() {
return m_permanentDLOntology.isHorn() && (m_additionalDLOntology==null || m_additionalDLOntology.isHorn()) && m_existentialExpansionStrategy.isDeterministic();
}
public DependencySetFactory getDependencySetFactory() {
return m_dependencySetFactory;
}
public ExtensionManager getExtensionManager() {
return m_extensionManager;
}
public HyperresolutionManager getPermanentHyperresolutionManager() {
return m_permanentHyperresolutionManager;
}
public HyperresolutionManager getAdditionalHyperresolutionManager() {
return m_additionalHyperresolutionManager;
}
public MergingManager getMergingManager() {
return m_mergingManager;
}
public ExistentialExpansionManager getExistentialExpansionManager() {
return m_existentialExpasionManager;
}
public NominalIntroductionManager getNominalIntroductionManager() {
return m_nominalIntroductionManager;
}
public DescriptionGraphManager getDescriptionGraphManager() {
return m_descriptionGraphManager;
}
public void clear() {
m_allocatedNodes=0;
m_numberOfNodesInTableau=0;
m_numberOfMergedOrPrunedNodes=0;
m_numberOfNodeCreations=0;
m_firstFreeNode=null;
m_firstTableauNode=null;
m_lastTableauNode=null;
m_lastMergedOrPrunedNode=null;
m_firstGroundDisjunction=null;
m_firstUnprocessedGroundDisjunction=null;
m_branchingPoints=new BranchingPoint[2];
m_currentBranchingPoint=-1;
m_nonbacktrackableBranchingPoint=-1;
m_dependencySetFactory.clear();
m_extensionManager.clear();
m_clashManager.clear();
m_permanentHyperresolutionManager.clear();
if (m_additionalHyperresolutionManager!=null)
m_additionalHyperresolutionManager.clear();
m_mergingManager.clear();
m_existentialExpasionManager.clear();
m_nominalIntroductionManager.clear();
m_descriptionGraphManager.clear();
m_isCurrentModelDeterministic=true;
m_existentialExpansionStrategy.clear();
m_datatypeManager.clear();
m_existentialConceptsBuffers.clear();
if (m_tableauMonitor!=null)
m_tableauMonitor.tableauCleared();
}
public boolean supportsAdditionalDLOntology(DLOntology additionalDLOntology) {
boolean hasInverseRoles=(m_permanentDLOntology.hasInverseRoles() || (m_additionalDLOntology!=null && m_additionalDLOntology.hasInverseRoles()));
boolean hasNominals=(m_permanentDLOntology.hasNominals() || (m_additionalDLOntology!=null && m_additionalDLOntology.hasNominals()));
boolean isHorn=(m_permanentDLOntology.isHorn() || (m_additionalDLOntology!=null && m_additionalDLOntology.isHorn()));
boolean permanentHasBottomObjectProperty=m_permanentDLOntology.containsObjectRole(AtomicRole.BOTTOM_OBJECT_ROLE);
boolean hasBottomObjectProperty=(permanentHasBottomObjectProperty || (m_additionalDLOntology!=null && m_additionalDLOntology.containsObjectRole(AtomicRole.BOTTOM_OBJECT_ROLE)));
if (!additionalDLOntology.getAllDescriptionGraphs().isEmpty() || (additionalDLOntology.hasInverseRoles() && !hasInverseRoles) || (additionalDLOntology.hasNominals() && !hasNominals) || (!additionalDLOntology.isHorn() && isHorn) || (hasBottomObjectProperty && !permanentHasBottomObjectProperty))
return false;
for (DLClause dlClause : additionalDLOntology.getDLClauses())
if (dlClause.isAtomicRoleInclusion() || dlClause.isAtomicRoleInverseInclusion() || dlClause.isFunctionalityAxiom() || dlClause.isInverseFunctionalityAxiom())
return false;
return true;
}
public void setAdditionalDLOntology(DLOntology additionalDLOntology) {
if (!supportsAdditionalDLOntology(additionalDLOntology))
throw new IllegalArgumentException("Additional DL-ontology contains features that are incompatible with this tableau.");
m_additionalDLOntology=additionalDLOntology;
m_additionalHyperresolutionManager=new HyperresolutionManager(this,m_additionalDLOntology.getDLClauses());
m_existentialExpansionStrategy.additionalDLOntologySet(m_additionalDLOntology);
m_datatypeManager.additionalDLOntologySet(m_additionalDLOntology);
updateFlagsDependentOnAdditionalOntology();
}
public void clearAdditionalDLOntology() {
m_additionalDLOntology=null;
m_additionalHyperresolutionManager=null;
m_existentialExpansionStrategy.additionalDLOntologyCleared();
m_datatypeManager.additionalDLOntologyCleared();
updateFlagsDependentOnAdditionalOntology();
}
protected void updateFlagsDependentOnAdditionalOntology() {
m_needsThingExtension=m_permanentHyperresolutionManager.m_tupleConsumersByDeltaPredicate.containsKey(AtomicConcept.THING);
m_needsNamedExtension=m_permanentHyperresolutionManager.m_tupleConsumersByDeltaPredicate.containsKey(AtomicConcept.INTERNAL_NAMED);
m_needsRDFSLiteralExtension=m_permanentHyperresolutionManager.m_tupleConsumersByDeltaPredicate.containsKey(InternalDatatype.RDFS_LITERAL);
m_checkDatatypes=m_permanentDLOntology.hasDatatypes();
m_checkUnknownDatatypeRestrictions=m_permanentDLOntology.hasUnknownDatatypeRestrictions();
if (m_additionalHyperresolutionManager!=null) {
m_needsThingExtension|=m_additionalHyperresolutionManager.m_tupleConsumersByDeltaPredicate.containsKey(AtomicConcept.THING);
m_needsNamedExtension|=m_additionalHyperresolutionManager.m_tupleConsumersByDeltaPredicate.containsKey(AtomicConcept.INTERNAL_NAMED);
m_needsRDFSLiteralExtension|=m_additionalHyperresolutionManager.m_tupleConsumersByDeltaPredicate.containsKey(InternalDatatype.RDFS_LITERAL);
}
if (m_additionalDLOntology!=null) {
m_checkDatatypes|=m_additionalDLOntology.hasDatatypes();
m_checkUnknownDatatypeRestrictions|=m_additionalDLOntology.hasUnknownDatatypeRestrictions();
}
}
public boolean isSatisfiable(boolean loadAdditionalABox,Set perTestPositiveFactsNoDependency,Set perTestNegativeFactsNoDependency,Set perTestPositiveFactsDummyDependency,Set perTestNegativeFactsDummyDependency,Map nodesForIndividuals,ReasoningTaskDescription reasoningTaskDescription) {
boolean loadPermanentABox=m_permanentDLOntology.hasNominals() || (m_additionalDLOntology!=null && m_additionalDLOntology.hasNominals());
return isSatisfiable(loadPermanentABox,loadAdditionalABox,perTestPositiveFactsNoDependency,perTestNegativeFactsNoDependency,perTestPositiveFactsDummyDependency,perTestNegativeFactsDummyDependency,new HashMap(),nodesForIndividuals,reasoningTaskDescription);
}
public boolean isSatisfiable(boolean loadPermanentABox,boolean loadAdditionalABox,Set perTestPositiveFactsNoDependency,Set perTestNegativeFactsNoDependency,Set perTestPositiveFactsDummyDependency,Set perTestNegativeFactsDummyDependency,Map nodesForIndividuals,ReasoningTaskDescription reasoningTaskDescription) {
return isSatisfiable(loadPermanentABox,loadAdditionalABox,perTestPositiveFactsNoDependency,perTestNegativeFactsNoDependency,perTestPositiveFactsDummyDependency,perTestNegativeFactsDummyDependency,new HashMap(),nodesForIndividuals,reasoningTaskDescription);
}
public boolean isSatisfiable(boolean loadPermanentABox,boolean loadAdditionalABox,Set perTestPositiveFactsNoDependency,Set perTestNegativeFactsNoDependency,Set perTestPositiveFactsDummyDependency,Set perTestNegativeFactsDummyDependency,Map termsToNodes,Map nodesForIndividuals,ReasoningTaskDescription reasoningTaskDescription) {
if (m_tableauMonitor!=null)
m_tableauMonitor.isSatisfiableStarted(reasoningTaskDescription);
clear();
if (loadPermanentABox) {
for (Atom atom : m_permanentDLOntology.getPositiveFacts())
loadPositiveFact(termsToNodes,atom,m_dependencySetFactory.emptySet());
for (Atom atom : m_permanentDLOntology.getNegativeFacts())
loadNegativeFact(termsToNodes,atom,m_dependencySetFactory.emptySet());
}
if (loadAdditionalABox && m_additionalDLOntology!=null) {
for (Atom atom : m_additionalDLOntology.getPositiveFacts())
loadPositiveFact(termsToNodes,atom,m_dependencySetFactory.emptySet());
for (Atom atom : m_additionalDLOntology.getNegativeFacts())
loadNegativeFact(termsToNodes,atom,m_dependencySetFactory.emptySet());
}
if (perTestPositiveFactsNoDependency!=null && !perTestPositiveFactsNoDependency.isEmpty())
for (Atom atom : perTestPositiveFactsNoDependency)
loadPositiveFact(termsToNodes,atom,m_dependencySetFactory.emptySet());
if (perTestNegativeFactsNoDependency!=null && !perTestNegativeFactsNoDependency.isEmpty())
for (Atom atom : perTestNegativeFactsNoDependency)
loadNegativeFact(termsToNodes,atom,m_dependencySetFactory.emptySet());
if ((perTestPositiveFactsDummyDependency!=null && !perTestPositiveFactsDummyDependency.isEmpty()) || (perTestNegativeFactsDummyDependency!=null && !perTestNegativeFactsDummyDependency.isEmpty())) {
m_branchingPoints[0]=new BranchingPoint(this);
m_currentBranchingPoint++;
m_nonbacktrackableBranchingPoint=m_currentBranchingPoint;
DependencySet dependencySet=m_dependencySetFactory.addBranchingPoint(m_dependencySetFactory.emptySet(),m_currentBranchingPoint);
if (perTestPositiveFactsDummyDependency!=null && !perTestPositiveFactsDummyDependency.isEmpty())
for (Atom atom : perTestPositiveFactsDummyDependency)
loadPositiveFact(termsToNodes,atom,dependencySet);
if (perTestNegativeFactsDummyDependency!=null && !perTestNegativeFactsDummyDependency.isEmpty())
for (Atom atom : perTestNegativeFactsDummyDependency)
loadNegativeFact(termsToNodes,atom,dependencySet);
}
if (nodesForIndividuals!=null)
for (Map.Entry entry : nodesForIndividuals.entrySet()) {
if (termsToNodes.get(entry.getValue())==null) {
Atom topAssertion=Atom.create(AtomicConcept.THING, entry.getKey());
loadPositiveFact(termsToNodes,topAssertion,m_dependencySetFactory.emptySet());
}
entry.setValue(termsToNodes.get(entry.getKey()));
}
// Ensure that at least one individual exists.
if (m_firstTableauNode==null)
createNewNINode(m_dependencySetFactory.emptySet());
boolean result=runCalculus();
if (m_tableauMonitor!=null)
m_tableauMonitor.isSatisfiableFinished(reasoningTaskDescription,result);
return result;
}
protected void loadPositiveFact(Map termsToNodes,Atom atom,DependencySet dependencySet) {
DLPredicate dlPredicate=atom.getDLPredicate();
if (dlPredicate instanceof LiteralConcept)
m_extensionManager.addConceptAssertion((LiteralConcept)dlPredicate,getNodeForTerm(termsToNodes,atom.getArgument(0),dependencySet),dependencySet,true);
else if (dlPredicate instanceof AtomicRole || Equality.INSTANCE.equals(dlPredicate) || Inequality.INSTANCE.equals(dlPredicate))
m_extensionManager.addAssertion(dlPredicate,getNodeForTerm(termsToNodes,atom.getArgument(0),dependencySet),getNodeForTerm(termsToNodes,atom.getArgument(1),dependencySet),dependencySet,true);
else if (dlPredicate instanceof DescriptionGraph) {
DescriptionGraph descriptionGraph=(DescriptionGraph)dlPredicate;
Object[] tuple=new Object[descriptionGraph.getArity()+1];
tuple[0]=descriptionGraph;
for (int argumentIndex=0;argumentIndex termsToNodes,Atom atom,DependencySet dependencySet) {
DLPredicate dlPredicate=atom.getDLPredicate();
if (dlPredicate instanceof LiteralConcept)
m_extensionManager.addConceptAssertion(((LiteralConcept)dlPredicate).getNegation(),getNodeForTerm(termsToNodes,atom.getArgument(0),dependencySet),dependencySet,true);
else if (dlPredicate instanceof AtomicRole) {
Object[] ternaryTuple=m_extensionManager.m_ternaryAuxiliaryTupleAdd;
ternaryTuple[0]=NegatedAtomicRole.create((AtomicRole)dlPredicate);
ternaryTuple[1]=getNodeForTerm(termsToNodes,atom.getArgument(0),dependencySet);
ternaryTuple[2]=getNodeForTerm(termsToNodes,atom.getArgument(1),dependencySet);
m_extensionManager.addTuple(ternaryTuple,dependencySet,true);
}
else if (Equality.INSTANCE.equals(dlPredicate))
m_extensionManager.addAssertion(Inequality.INSTANCE,getNodeForTerm(termsToNodes,atom.getArgument(0),dependencySet),getNodeForTerm(termsToNodes,atom.getArgument(1),dependencySet),dependencySet,true);
else if (Inequality.INSTANCE.equals(dlPredicate))
m_extensionManager.addAssertion(Equality.INSTANCE,getNodeForTerm(termsToNodes,atom.getArgument(0),dependencySet),getNodeForTerm(termsToNodes,atom.getArgument(1),dependencySet),dependencySet,true);
else
throw new IllegalArgumentException("Unsupported type of negative ground atom.");
}
protected Node getNodeForTerm(Map termsToNodes,Term term,DependencySet dependencySet) {
Node node=termsToNodes.get(term);
if (node==null) {
if (term instanceof Individual) {
Individual individual=(Individual)term;
if (individual.isAnonymous())
node=createNewNINode(dependencySet);
else
node=createNewNamedNode(dependencySet);
}
else {
Constant constant=(Constant)term;
node=createNewRootConstantNode(dependencySet);
// Anonymous constant values are not assigned a particular value.
// See the hack in OWLClausification for an explanation.
if (!constant.isAnonymous())
m_extensionManager.addAssertion(ConstantEnumeration.create(new Constant[] { constant }),node,dependencySet,true);
}
termsToNodes.put(term,node);
}
return node.getCanonicalNode();
}
protected boolean runCalculus() {
m_interruptFlag.startTask();
try {
boolean existentialsAreExact=m_existentialExpansionStrategy.isExact();
if (m_tableauMonitor!=null)
m_tableauMonitor.saturateStarted();
boolean hasMoreWork=true;
while (hasMoreWork) {
if (m_tableauMonitor!=null)
m_tableauMonitor.iterationStarted();
hasMoreWork=doIteration();
if (m_tableauMonitor!=null)
m_tableauMonitor.iterationFinished();
if (!existentialsAreExact && !hasMoreWork && !m_extensionManager.containsClash()) {
// no more work to do, but since we use a blocking strategy that does not necessarily
// establish only valid blocks (existentialsAreExact == false), we tell the blocking
// strategy to go through the nodes and check whether all blocks are valid and if not,
// continue with the expansion
if (m_tableauMonitor!=null)
m_tableauMonitor.iterationStarted();
hasMoreWork=m_existentialExpansionStrategy.expandExistentials(true); // returns true if some blocks were invalid
if (m_tableauMonitor!=null)
m_tableauMonitor.iterationFinished();
}
}
if (m_tableauMonitor!=null)
m_tableauMonitor.saturateFinished(!m_extensionManager.containsClash());
if (!m_extensionManager.containsClash()) {
m_existentialExpansionStrategy.modelFound();
return true;
}
else
return false;
}
finally {
m_interruptFlag.endTask();
}
}
protected boolean doIteration() {
if (!m_extensionManager.containsClash()) {
m_nominalIntroductionManager.processAnnotatedEqualities();
boolean hasChange=false;
while (m_extensionManager.propagateDeltaNew() && !m_extensionManager.containsClash()) {
if (m_hasDescriptionGraphs && !m_extensionManager.containsClash())
m_descriptionGraphManager.checkGraphConstraints();
if (!m_extensionManager.containsClash())
m_permanentHyperresolutionManager.applyDLClauses();
if (m_additionalHyperresolutionManager!=null && !m_extensionManager.containsClash())
m_additionalHyperresolutionManager.applyDLClauses();
if (m_checkUnknownDatatypeRestrictions && !m_extensionManager.containsClash())
m_datatypeManager.applyUnknownDatatypeRestrictionSemantics();
if (m_checkDatatypes && !m_extensionManager.containsClash())
m_datatypeManager.checkDatatypeConstraints();
if (!m_extensionManager.containsClash())
m_nominalIntroductionManager.processAnnotatedEqualities();
hasChange=true;
}
if (hasChange)
return true;
}
if (!m_extensionManager.containsClash())
if (m_existentialExpansionStrategy.expandExistentials(false))
return true;
if (!m_extensionManager.containsClash()) {
while (m_firstUnprocessedGroundDisjunction!=null) {
GroundDisjunction groundDisjunction=m_firstUnprocessedGroundDisjunction;
if (m_tableauMonitor!=null)
m_tableauMonitor.processGroundDisjunctionStarted(groundDisjunction);
m_firstUnprocessedGroundDisjunction=groundDisjunction.m_previousGroundDisjunction;
if (!groundDisjunction.isPruned() && !groundDisjunction.isSatisfied(this)) {
int[] sortedDisjunctIndexes=groundDisjunction.getGroundDisjunctionHeader().getSortedDisjunctIndexes();
DependencySet dependencySet=groundDisjunction.getDependencySet();
if (groundDisjunction.getNumberOfDisjuncts()>1) {
BranchingPoint branchingPoint=new DisjunctionBranchingPoint(this,groundDisjunction,sortedDisjunctIndexes);
pushBranchingPoint(branchingPoint);
dependencySet=m_dependencySetFactory.addBranchingPoint(dependencySet,branchingPoint.getLevel());
}
if (m_tableauMonitor!=null)
m_tableauMonitor.disjunctProcessingStarted(groundDisjunction,sortedDisjunctIndexes[0]);
groundDisjunction.addDisjunctToTableau(this,sortedDisjunctIndexes[0],dependencySet);
if (m_tableauMonitor!=null) {
m_tableauMonitor.disjunctProcessingFinished(groundDisjunction,sortedDisjunctIndexes[0]);
m_tableauMonitor.processGroundDisjunctionFinished(groundDisjunction);
}
return true;
}
else {
if (m_tableauMonitor!=null)
m_tableauMonitor.groundDisjunctionSatisfied(groundDisjunction);
}
m_interruptFlag.checkInterrupt();
}
}
if (m_extensionManager.containsClash()) {
DependencySet clashDependencySet=m_extensionManager.getClashDependencySet();
int newCurrentBranchingPoint=clashDependencySet.getMaximumBranchingPoint();
if (newCurrentBranchingPoint<=m_nonbacktrackableBranchingPoint)
return false;
backtrackTo(newCurrentBranchingPoint);
BranchingPoint branchingPoint=getCurrentBranchingPoint();
if (m_tableauMonitor!=null)
m_tableauMonitor.startNextBranchingPointStarted(branchingPoint);
branchingPoint.startNextChoice(this,clashDependencySet);
if (m_tableauMonitor!=null)
m_tableauMonitor.startNextBranchingPointFinished(branchingPoint);
m_dependencySetFactory.removeUnusedSets();
return true;
}
return false;
}
public boolean isCurrentModelDeterministic() {
return m_isCurrentModelDeterministic;
}
public int getCurrentBranchingPointLevel() {
return m_currentBranchingPoint;
}
public BranchingPoint getCurrentBranchingPoint() {
return m_branchingPoints[m_currentBranchingPoint];
}
public void addGroundDisjunction(GroundDisjunction groundDisjunction) {
groundDisjunction.m_nextGroundDisjunction=m_firstGroundDisjunction;
groundDisjunction.m_previousGroundDisjunction=null;
if (m_firstGroundDisjunction!=null)
m_firstGroundDisjunction.m_previousGroundDisjunction=groundDisjunction;
m_firstGroundDisjunction=groundDisjunction;
if (m_firstUnprocessedGroundDisjunction==null)
m_firstUnprocessedGroundDisjunction=groundDisjunction;
if (m_tableauMonitor!=null)
m_tableauMonitor.groundDisjunctionDerived(groundDisjunction);
}
public GroundDisjunction getFirstUnprocessedGroundDisjunction() {
return m_firstUnprocessedGroundDisjunction;
}
/**
* Add a branching point in case we need to backtrack to this state.
*
* @param branchingPoint
*/
public void pushBranchingPoint(BranchingPoint branchingPoint) {
assert m_currentBranchingPoint+1==branchingPoint.m_level;
if (m_tableauMonitor!=null)
m_tableauMonitor.pushBranchingPointStarted(branchingPoint);
m_currentBranchingPoint++;
if (m_currentBranchingPoint>=m_branchingPoints.length) {
BranchingPoint[] newBranchingPoints=new BranchingPoint[m_currentBranchingPoint*3/2];
System.arraycopy(m_branchingPoints,0,newBranchingPoints,0,m_branchingPoints.length);
m_branchingPoints=newBranchingPoints;
}
m_branchingPoints[m_currentBranchingPoint]=branchingPoint;
m_extensionManager.branchingPointPushed();
m_existentialExpasionManager.branchingPointPushed();
m_existentialExpansionStrategy.branchingPointPushed();
m_nominalIntroductionManager.branchingPointPushed();
m_isCurrentModelDeterministic=false;
if (m_tableauMonitor!=null)
m_tableauMonitor.pushBranchingPointFinished(branchingPoint);
}
/**
* Backtrack to a certain branching point in the list of branching points that have been set during the run.
*
* @param newCurrentBrancingPoint
*/
protected void backtrackTo(int newCurrentBrancingPoint) {
BranchingPoint branchingPoint=m_branchingPoints[newCurrentBrancingPoint];
if (m_tableauMonitor!=null)
m_tableauMonitor.backtrackToStarted(branchingPoint);
// backtrack the list of branching points
for (int index=newCurrentBrancingPoint+1;index<=m_currentBranchingPoint;index++)
m_branchingPoints[index]=null;
m_currentBranchingPoint=newCurrentBrancingPoint;
// backtrack processed ground disjunctions
m_firstUnprocessedGroundDisjunction=branchingPoint.m_firstUnprocessedGroundDisjunction;
// backtrack added ground disjunctions
GroundDisjunction firstGroundDisjunctionShouldBe=branchingPoint.m_firstGroundDisjunction;
while (m_firstGroundDisjunction!=firstGroundDisjunctionShouldBe) {
m_firstGroundDisjunction.destroy(this);
m_firstGroundDisjunction=m_firstGroundDisjunction.m_nextGroundDisjunction;
}
if (m_firstGroundDisjunction!=null)
m_firstGroundDisjunction.m_previousGroundDisjunction=null;
// backtrack existentials
m_existentialExpansionStrategy.backtrack();
m_existentialExpasionManager.backtrack();
// backtrack nominal introduction
m_nominalIntroductionManager.backtrack();
// backtrack extensions
m_extensionManager.backtrack();
// backtrack node merges/prunes
Node lastMergedOrPrunedNodeShouldBe=branchingPoint.m_lastMergedOrPrunedNode;
while (m_lastMergedOrPrunedNode!=lastMergedOrPrunedNodeShouldBe)
backtrackLastMergedOrPrunedNode();
// backtrack node change list
Node lastTableauNodeShouldBe=branchingPoint.m_lastTableauNode;
while (lastTableauNodeShouldBe!=m_lastTableauNode)
destroyLastTableauNode();
// finish
m_extensionManager.clearClash();
if (m_tableauMonitor!=null)
m_tableauMonitor.backtrackToFinished(branchingPoint);
}
/**
* Create a new node that represents an individual named in the input ontology (thus, keys have to be applied to it)
*
* @param dependencySet
* the dependency set for the node
* @return the created node
*/
public Node createNewNamedNode(DependencySet dependencySet) {
return createNewNodeRaw(dependencySet,null,NodeType.NAMED_NODE,0);
}
/**
* Create a new node that represents a nominal, but one that is not named in the input ontology (thus, keys are not applicable)
*
* @param dependencySet
* the dependency set for the node
* @return the created node
*/
public Node createNewNINode(DependencySet dependencySet) {
return createNewNodeRaw(dependencySet,null,NodeType.NI_NODE,0);
}
/**
* Create a new tree node.
*
* @param dependencySet
* the dependency set for the node
* @param parent
* the parent of the node that is to be created
* @return the created node
*/
public Node createNewTreeNode(DependencySet dependencySet,Node parent) {
return createNewNodeRaw(dependencySet,parent,NodeType.TREE_NODE,parent.getTreeDepth()+1);
}
/**
* Create a new concrete node for datatypes.
*
* @param dependencySet
* the dependency set for the node
* @param parent
* the parent of the node that is to be created
* @return the created node
*/
public Node createNewConcreteNode(DependencySet dependencySet,Node parent) {
return createNewNodeRaw(dependencySet,parent,NodeType.CONCRETE_NODE,parent.getTreeDepth()+1);
}
/**
* Create a new root constant node for datatypes.
*
* @param dependencySet
* the dependency set for the node
* @return the created node
*/
public Node createNewRootConstantNode(DependencySet dependencySet) {
return createNewNodeRaw(dependencySet,null,NodeType.ROOT_CONSTANT_NODE,0);
}
/**
* Create a new node graph node for description graphs
*
* @param parent
* the parent of the node that is to be created (may be null)
* @param dependencySet
* the dependency set for the node
* @return the created node
*/
public Node createNewGraphNode(Node parent,DependencySet dependencySet) {
return createNewNodeRaw(dependencySet,parent,NodeType.GRAPH_NODE,parent==null ? 0 : parent.getTreeDepth());
}
protected Node createNewNodeRaw(DependencySet dependencySet,Node parent,NodeType nodeType,int treeDepth) {
Node node;
if (m_firstFreeNode==null) {
node=new Node(this);
m_allocatedNodes++;
}
else {
node=m_firstFreeNode;
m_firstFreeNode=m_firstFreeNode.m_nextTableauNode;
}
assert node.m_nodeID==-1;
assert node.m_nodeState==null;
node.initialize(++m_numberOfNodesInTableau,parent,nodeType,treeDepth);
m_existentialExpansionStrategy.nodeInitialized(node);
node.m_previousTableauNode=m_lastTableauNode;
if (m_lastTableauNode==null)
m_firstTableauNode=node;
else
m_lastTableauNode.m_nextTableauNode=node;
m_lastTableauNode=node;
m_existentialExpansionStrategy.nodeStatusChanged(node);
m_numberOfNodeCreations++;
if (m_tableauMonitor!=null)
m_tableauMonitor.nodeCreated(node);
if (nodeType.m_isAbstract) {
m_extensionManager.addConceptAssertion(AtomicConcept.THING,node,dependencySet,true);
if (nodeType==NodeType.NAMED_NODE && m_needsNamedExtension)
m_extensionManager.addConceptAssertion(AtomicConcept.INTERNAL_NAMED,node,dependencySet,true);
}
else
m_extensionManager.addDataRangeAssertion(InternalDatatype.RDFS_LITERAL,node,dependencySet,true);
return node;
}
/**
* Merges node into mergeInto. We assume that concepts and roles have already been copied from node to mergeInto. After the merge node has state NodeState.MERGED.
*
* @param node
* the node that is to be merged
* @param mergeInto
* the node we merge into
* @param dependencySet
*/
public void mergeNode(Node node,Node mergeInto,DependencySet dependencySet) {
assert node.m_nodeState==Node.NodeState.ACTIVE;
assert node.m_mergedInto==null;
assert node.m_mergedIntoDependencySet==null;
assert node.m_previousMergedOrPrunedNode==null;
node.m_mergedInto=mergeInto;
node.m_mergedIntoDependencySet=m_dependencySetFactory.getPermanent(dependencySet);
m_dependencySetFactory.addUsage(node.m_mergedIntoDependencySet);
node.m_nodeState=NodeState.MERGED;
node.m_previousMergedOrPrunedNode=m_lastMergedOrPrunedNode;
m_lastMergedOrPrunedNode=node;
m_numberOfMergedOrPrunedNodes++;
m_existentialExpansionStrategy.nodeStatusChanged(node);
m_existentialExpansionStrategy.nodesMerged(node,mergeInto);
}
public void pruneNode(Node node) {
assert node.m_nodeState==Node.NodeState.ACTIVE;
assert node.m_mergedInto==null;
assert node.m_mergedIntoDependencySet==null;
assert node.m_previousMergedOrPrunedNode==null;
node.m_nodeState=NodeState.PRUNED;
node.m_previousMergedOrPrunedNode=m_lastMergedOrPrunedNode;
m_lastMergedOrPrunedNode=node;
m_numberOfMergedOrPrunedNodes++;
m_existentialExpansionStrategy.nodeStatusChanged(node);
}
protected void backtrackLastMergedOrPrunedNode() {
Node node=m_lastMergedOrPrunedNode;
assert (node.m_nodeState==Node.NodeState.MERGED && node.m_mergedInto!=null && node.m_mergedInto!=null) || (node.m_nodeState==Node.NodeState.PRUNED && node.m_mergedInto==null && node.m_mergedInto==null);
Node savedMergedInfo=null;
if (node.m_nodeState==Node.NodeState.MERGED) {
m_dependencySetFactory.removeUsage(node.m_mergedIntoDependencySet);
savedMergedInfo=node.m_mergedInto;
node.m_mergedInto=null;
node.m_mergedIntoDependencySet=null;
}
node.m_nodeState=Node.NodeState.ACTIVE;
m_lastMergedOrPrunedNode=node.m_previousMergedOrPrunedNode;
node.m_previousMergedOrPrunedNode=null;
m_numberOfMergedOrPrunedNodes--;
m_existentialExpansionStrategy.nodeStatusChanged(node);
if (savedMergedInfo!=null)
m_existentialExpansionStrategy.nodesUnmerged(node,savedMergedInfo);
}
protected void destroyLastTableauNode() {
Node node=m_lastTableauNode;
assert node.m_nodeState==Node.NodeState.ACTIVE;
assert node.m_mergedInto==null;
assert node.m_mergedIntoDependencySet==null;
assert node.m_previousMergedOrPrunedNode==null;
m_existentialExpansionStrategy.nodeDestroyed(node);
if (node.m_previousTableauNode==null)
m_firstTableauNode=null;
else
node.m_previousTableauNode.m_nextTableauNode=null;
m_lastTableauNode=node.m_previousTableauNode;
node.destroy();
node.m_nextTableauNode=m_firstFreeNode;
m_firstFreeNode=node;
m_numberOfNodesInTableau--;
if (m_tableauMonitor!=null)
m_tableauMonitor.nodeDestroyed(node);
}
public int getNumberOfNodeCreations() {
return m_numberOfNodeCreations;
}
public Node getFirstTableauNode() {
return m_firstTableauNode;
}
public Node getLastTableauNode() {
return m_lastTableauNode;
}
public int getNumberOfAllocatedNodes() {
return m_allocatedNodes;
}
public int getNumberOfNodesInTableau() {
return m_numberOfNodesInTableau;
}
public int getNumberOfMergedOrPrunedNodes() {
return m_numberOfMergedOrPrunedNodes;
}
public Node getNode(int nodeID) {
Node node=m_firstTableauNode;
while (node!=null) {
if (node.getNodeID()==nodeID)
return node;
node=node.getNextTableauNode();
}
return null;
}
protected List getExistentialConceptsBuffer() {
if (m_existentialConceptsBuffers.isEmpty())
return new ArrayList();
else
return m_existentialConceptsBuffers.remove(m_existentialConceptsBuffers.size()-1);
}
public void putExistentialConceptsBuffer(List buffer) {
assert buffer.isEmpty();
m_existentialConceptsBuffers.add(buffer);
}
public void checkTableauList() {
Node node=m_firstTableauNode;
int numberOfNodesInTableau=0;
while (node!=null) {
if (node.m_previousTableauNode==null) {
if (m_firstTableauNode!=node)
throw new IllegalStateException("First tableau node is pointing wrongly.");
}
else {
if (node.m_previousTableauNode.m_nextTableauNode!=node)
throw new IllegalStateException("Previous tableau node is pointing wrongly.");
}
if (node.m_nextTableauNode==null) {
if (m_lastTableauNode!=node)
throw new IllegalStateException("Last tableau node is pointing wrongly.");
}
else {
if (node.m_nextTableauNode.m_previousTableauNode!=node)
throw new IllegalStateException("Next tableau node is pointing wrongly.");
}
numberOfNodesInTableau++;
node=node.m_nextTableauNode;
}
if (numberOfNodesInTableau!=m_numberOfNodesInTableau)
throw new IllegalStateException("Invalid number of nodes in the tableau.");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy