/* 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.tableau; import java.io.Serializable; import org.semanticweb.HermiT.model.AtomicConcept; import org.semanticweb.HermiT.model.AtomicRole; import org.semanticweb.HermiT.model.Concept; import org.semanticweb.HermiT.model.InternalDatatype; /** * This extension table is for use with Description Graphs and it supports tuple * tables with arity greater than three, but are, as a result, less efficient. * @see ExtensionTableWithTupleIndexes */ public class ExtensionTableWithFullIndex extends ExtensionTable { private static final long serialVersionUID=2856811178050960058L; protected final TupleTableFullIndex m_tupleTableFullIndex; protected final Object[] m_auxiliaryTuple; public ExtensionTableWithFullIndex(Tableau tableau,int tupleArity,boolean needsDependencySets) { super(tableau,tupleArity,needsDependencySets); m_tupleTableFullIndex=new TupleTableFullIndex(m_tupleTable,m_tupleArity); m_auxiliaryTuple=new Object[m_tupleArity]; } public int sizeInMemory() { return m_tupleTable.sizeInMemory()+m_tupleTableFullIndex.sizeInMemory(); } public boolean addTuple(Object[] tuple,DependencySet dependencySet,boolean isCore) { if (m_tableauMonitor!=null) m_tableauMonitor.addFactStarted(tuple,isCore); if (isTupleActive(tuple) && (m_tableau.m_needsThingExtension || !AtomicConcept.THING.equals(tuple[0])) && (m_tableau.m_needsRDFSLiteralExtension || !InternalDatatype.RDFS_LITERAL.equals(tuple[0]))) { int firstFreeTupleIndex=m_tupleTable.getFirstFreeTupleIndex(); int addTupleIndex=m_tupleTableFullIndex.addTuple(tuple,firstFreeTupleIndex); if (addTupleIndex==firstFreeTupleIndex) { m_tupleTable.addTuple(tuple); m_dependencySetManager.setDependencySet(addTupleIndex,dependencySet); m_coreManager.setCore(addTupleIndex,isCore); m_afterDeltaNewTupleIndex=m_tupleTable.getFirstFreeTupleIndex(); if (m_tableauMonitor!=null) m_tableauMonitor.addFactFinished(tuple,isCore,true); postAdd(tuple,dependencySet,addTupleIndex,isCore); return true; } if (isCore && !m_coreManager.isCore(addTupleIndex)) { m_coreManager.addCore(addTupleIndex); Object dlPredicateObject=tuple[0]; if (dlPredicateObject instanceof Concept) m_tableau.m_existentialExpansionStrategy.assertionCoreSet((Concept)dlPredicateObject,(Node)tuple[1]); else if (dlPredicateObject instanceof AtomicRole) m_tableau.m_existentialExpansionStrategy.assertionCoreSet((AtomicRole)dlPredicateObject,(Node)tuple[1],(Node)tuple[2]); } } if (m_tableauMonitor!=null) m_tableauMonitor.addFactFinished(tuple,isCore,false); return false; } public boolean containsTuple(Object[] tuple) { int tupleIndex=m_tupleTableFullIndex.getTupleIndex(tuple); return tupleIndex!=-1 && isTupleActive(tupleIndex); } public DependencySet getDependencySet(Object[] tuple) { int tupleIndex=m_tupleTableFullIndex.getTupleIndex(tuple); if (tupleIndex==-1) return null; else return m_dependencySetManager.getDependencySet(tupleIndex); } public boolean isCore(Object[] tuple) { int tupleIndex=m_tupleTableFullIndex.getTupleIndex(tuple); if (tupleIndex==-1) return false; else return m_coreManager.isCore(tupleIndex); } public Retrieval createRetrieval(int[] bindingPositions,Object[] bindingsBuffer,Object[] tupleBuffer,boolean ownsBuffers,View extensionView) { int numberOfBindings=0; for (int index=m_tupleArity-1;index>=0;--index) if (bindingPositions[index]!=-1) numberOfBindings++; if (numberOfBindings==m_tupleArity) return new IndexedRetrieval(bindingPositions,bindingsBuffer,tupleBuffer,ownsBuffers,extensionView); else return new UnindexedRetrieval(bindingPositions,bindingsBuffer,tupleBuffer,ownsBuffers,extensionView); } protected void removeTuple(int tupleIndex) { m_tupleTableFullIndex.removeTuple(tupleIndex); m_tupleTable.retrieveTuple(m_auxiliaryTuple,tupleIndex); postRemove(m_auxiliaryTuple,tupleIndex); } public void clear() { super.clear(); m_tupleTableFullIndex.clear(); } protected class IndexedRetrieval implements Retrieval,Serializable { private static final long serialVersionUID=5984560476970027366L; protected final int[] m_bindingPositions; protected final Object[] m_bindingsBuffer; protected final Object[] m_tupleBuffer; protected final boolean m_ownsBuffers; protected final ExtensionTable.View m_extensionView; protected int m_currentTupleIndex; public IndexedRetrieval(int[] bindingPositions,Object[] bindingsBuffer,Object[] tupleBuffer,boolean ownsBuffers,View extensionView) { m_bindingPositions=bindingPositions; m_bindingsBuffer=bindingsBuffer; m_tupleBuffer=tupleBuffer; m_ownsBuffers=ownsBuffers; m_extensionView=extensionView; } public ExtensionTable getExtensionTable() { return ExtensionTableWithFullIndex.this; } public ExtensionTable.View getExtensionView() { return m_extensionView; } public void clear() { if (m_ownsBuffers) { for (int index=m_bindingsBuffer.length-1;index>=0;--index) m_bindingsBuffer[index]=null; for (int index=m_tupleBuffer.length-1;index>=0;--index) m_tupleBuffer[index]=null; } } public int[] getBindingPositions() { return m_bindingPositions; } public Object[] getBindingsBuffer() { return m_bindingsBuffer; } public Object[] getTupleBuffer() { return m_tupleBuffer; } public DependencySet getDependencySet() { if (m_currentTupleIndex==-1) return null; else return m_dependencySetManager.getDependencySet(m_currentTupleIndex); } public boolean isCore() { if (m_currentTupleIndex==-1) return false; else return m_coreManager.isCore(m_currentTupleIndex); } public void open() { m_currentTupleIndex=m_tupleTableFullIndex.getTupleIndex(m_bindingsBuffer,m_bindingPositions); switch (m_extensionView) { case EXTENSION_THIS: if (!(0<=m_currentTupleIndex && m_currentTupleIndex<m_afterExtensionThisTupleIndex)) m_currentTupleIndex=-1; break; case EXTENSION_OLD: if (!(0<=m_currentTupleIndex && m_currentTupleIndex<m_afterExtensionOldTupleIndex)) m_currentTupleIndex=-1; break; case DELTA_OLD: if (!(m_afterExtensionOldTupleIndex<=m_currentTupleIndex && m_currentTupleIndex<m_afterExtensionThisTupleIndex)) m_currentTupleIndex=-1; break; case TOTAL: if (!(0<=m_currentTupleIndex && m_currentTupleIndex<m_afterDeltaNewTupleIndex)) m_currentTupleIndex=-1; break; } if (m_currentTupleIndex!=-1) { m_tupleTable.retrieveTuple(m_tupleBuffer,m_currentTupleIndex); if (!isTupleActive(m_tupleBuffer)) m_currentTupleIndex=-1; } } public boolean afterLast() { return m_currentTupleIndex==-1; } public int getCurrentTupleIndex() { return m_currentTupleIndex; } public void next() { m_currentTupleIndex++; } } }