/* 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 <http://www.gnu.org/licenses/>. */ package org.semanticweb.HermiT.blocking; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.semanticweb.HermiT.model.AtomicConcept; import org.semanticweb.HermiT.model.AtomicRole; import org.semanticweb.HermiT.model.Concept; import org.semanticweb.HermiT.model.DataRange; import org.semanticweb.HermiT.tableau.ExtensionTable; import org.semanticweb.HermiT.tableau.Node; import org.semanticweb.HermiT.tableau.NodeType; import org.semanticweb.HermiT.tableau.Tableau; public class SingleDirectBlockingChecker implements DirectBlockingChecker,Serializable { private static final long serialVersionUID=9093753046859877016L; protected final SetFactory<AtomicConcept> m_atomicConceptsSetFactory; protected final List<AtomicConcept> m_atomicConceptsBuffer; protected Tableau m_tableau; protected ExtensionTable.Retrieval m_binaryTableSearch1Bound; public SingleDirectBlockingChecker() { m_atomicConceptsSetFactory=new SetFactory<AtomicConcept>(); m_atomicConceptsBuffer=new ArrayList<AtomicConcept>(); } public void initialize(Tableau tableau) { m_tableau=tableau; m_binaryTableSearch1Bound=tableau.getExtensionManager().getBinaryExtensionTable().createRetrieval(new boolean[] { false,true },ExtensionTable.View.TOTAL); } public void clear() { m_atomicConceptsSetFactory.clearNonpermanent(); m_binaryTableSearch1Bound.clear(); } public boolean isBlockedBy(Node blocker,Node blocked) { return !blocker.isBlocked() && blocker.getNodeType()==NodeType.TREE_NODE && blocked.getNodeType()==NodeType.TREE_NODE && ((SingleBlockingObject)blocker.getBlockingObject()).getAtomicConceptsLabel()==((SingleBlockingObject)blocked.getBlockingObject()).getAtomicConceptsLabel(); } public int blockingHashCode(Node node) { return ((SingleBlockingObject)node.getBlockingObject()).m_atomicConceptsLabelHashCode; } public boolean canBeBlocker(Node node) { return node.getNodeType()==NodeType.TREE_NODE; } public boolean canBeBlocked(Node node) { return node.getNodeType()==NodeType.TREE_NODE; } public boolean hasBlockingInfoChanged(Node node) { return ((SingleBlockingObject)node.getBlockingObject()).m_hasChanged; } public void clearBlockingInfoChanged(Node node) { ((SingleBlockingObject)node.getBlockingObject()).m_hasChanged=false; } public void nodeInitialized(Node node) { if (node.getBlockingObject()==null) node.setBlockingObject(new SingleBlockingObject(node)); ((SingleBlockingObject)node.getBlockingObject()).initialize(); } public void nodeDestroyed(Node node) { ((SingleBlockingObject)node.getBlockingObject()).destroy(); } public Node assertionAdded(Concept concept,Node node,boolean isCore) { if (concept instanceof AtomicConcept) { ((SingleBlockingObject)node.getBlockingObject()).addAtomicConcept((AtomicConcept)concept); return node; } else return null; } public Node assertionRemoved(Concept concept,Node node,boolean isCore) { if (concept instanceof AtomicConcept) { ((SingleBlockingObject)node.getBlockingObject()).removeAtomicConcept((AtomicConcept)concept); return node; } else return null; } public Node assertionAdded(DataRange range,Node node,boolean isCore) { return null; } public Node assertionRemoved(DataRange range,Node node,boolean isCore) { return null; } public Node assertionAdded(AtomicRole atomicRole,Node nodeFrom,Node nodeTo,boolean isCore) { return null; } public Node assertionRemoved(AtomicRole atomicRole,Node nodeFrom,Node nodeTo,boolean isCore) { return null; } public Node nodesMerged(Node mergeFrom,Node mergeInto) { return null; } public Node nodesUnmerged(Node mergeFrom,Node mergeInto) { return null; } public BlockingSignature getBlockingSignatureFor(Node node) { return new SingleBlockingSignature(this,node); } protected Set<AtomicConcept> fetchAtomicConceptsLabel(Node node) { m_atomicConceptsBuffer.clear(); m_binaryTableSearch1Bound.getBindingsBuffer()[1]=node; m_binaryTableSearch1Bound.open(); Object[] tupleBuffer=m_binaryTableSearch1Bound.getTupleBuffer(); while (!m_binaryTableSearch1Bound.afterLast()) { Object concept=tupleBuffer[0]; if (concept instanceof AtomicConcept) m_atomicConceptsBuffer.add((AtomicConcept)concept); m_binaryTableSearch1Bound.next(); } Set<AtomicConcept> result=m_atomicConceptsSetFactory.getSet(m_atomicConceptsBuffer); m_atomicConceptsBuffer.clear(); return result; } public boolean hasChangedSinceValidation(Node node) { return false; } public void setHasChangedSinceValidation(Node node,boolean hasChanged) { // do nothing } protected final class SingleBlockingObject implements Serializable { private static final long serialVersionUID=-5439737072100509531L; protected final Node m_node; protected boolean m_hasChanged; protected Set<AtomicConcept> m_atomicConceptsLabel; protected int m_atomicConceptsLabelHashCode; public SingleBlockingObject(Node node) { m_node=node; } public void initialize() { m_atomicConceptsLabel=null; m_atomicConceptsLabelHashCode=0; m_hasChanged=true; } public void destroy() { if (m_atomicConceptsLabel!=null) { m_atomicConceptsSetFactory.removeReference(m_atomicConceptsLabel); m_atomicConceptsLabel=null; } } public Set<AtomicConcept> getAtomicConceptsLabel() { if (m_atomicConceptsLabel==null) { m_atomicConceptsLabel=SingleDirectBlockingChecker.this.fetchAtomicConceptsLabel(m_node); m_atomicConceptsSetFactory.addReference(m_atomicConceptsLabel); } return m_atomicConceptsLabel; } public void addAtomicConcept(AtomicConcept atomicConcept) { if (m_atomicConceptsLabel!=null) { // invalidate, recompute real label later if necessary m_atomicConceptsSetFactory.removeReference(m_atomicConceptsLabel); m_atomicConceptsLabel=null; } m_atomicConceptsLabelHashCode+=atomicConcept.hashCode(); m_hasChanged=true; } public void removeAtomicConcept(AtomicConcept atomicConcept) { if (m_atomicConceptsLabel!=null) { // invalidate, recompute real label later if necessary m_atomicConceptsSetFactory.removeReference(m_atomicConceptsLabel); m_atomicConceptsLabel=null; } m_atomicConceptsLabelHashCode-=atomicConcept.hashCode(); m_hasChanged=true; } } protected static class SingleBlockingSignature extends BlockingSignature implements Serializable { private static final long serialVersionUID=-7349489846772132258L; protected final Set<AtomicConcept> m_atomicConceptsLabel; public SingleBlockingSignature(SingleDirectBlockingChecker checker,Node node) { m_atomicConceptsLabel=((SingleBlockingObject)node.getBlockingObject()).getAtomicConceptsLabel(); checker.m_atomicConceptsSetFactory.makePermanent(m_atomicConceptsLabel); } public boolean blocksNode(Node node) { return ((SingleBlockingObject)node.getBlockingObject()).getAtomicConceptsLabel()==m_atomicConceptsLabel; } public int hashCode() { return m_atomicConceptsLabel.hashCode(); } public boolean equals(Object that) { if (this==that) return true; if (!(that instanceof SingleBlockingSignature)) return false; return m_atomicConceptsLabel==((SingleBlockingSignature)that).m_atomicConceptsLabel; } } }