/* 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 java.util.Collection; import java.util.HashMap; import java.util.Map; import org.semanticweb.HermiT.model.AnnotatedEquality; import org.semanticweb.HermiT.model.AtomicConcept; import org.semanticweb.HermiT.model.AtomicRole; import org.semanticweb.HermiT.model.Concept; import org.semanticweb.HermiT.model.DLPredicate; import org.semanticweb.HermiT.model.DataRange; import org.semanticweb.HermiT.model.DescriptionGraph; import org.semanticweb.HermiT.model.Equality; import org.semanticweb.HermiT.model.InternalDatatype; import org.semanticweb.HermiT.model.InverseRole; import org.semanticweb.HermiT.model.Role; import org.semanticweb.HermiT.monitor.TableauMonitor; public final class ExtensionManager implements Serializable { private static final long serialVersionUID=5900300914631070591L; protected final Tableau m_tableau; protected final TableauMonitor m_tableauMonitor; protected final DependencySetFactory m_dependencySetFactory; protected final Map<Integer,ExtensionTable> m_extensionTablesByArity; protected final ExtensionTable[] m_allExtensionTablesArray; protected final ExtensionTable m_binaryExtensionTable; protected final ExtensionTable m_ternaryExtensionTable; protected final Object[] m_binaryAuxiliaryTupleContains; protected final Object[] m_binaryAuxiliaryTupleAdd; protected final Object[] m_ternaryAuxiliaryTupleContains; protected final Object[] m_ternaryAuxiliaryTupleAdd; protected final Object[] m_fouraryAuxiliaryTupleContains; protected final Object[] m_fouraryAuxiliaryTupleAdd; protected PermanentDependencySet m_clashDependencySet; protected boolean m_addActive; public ExtensionManager(Tableau tableau) { m_tableau=tableau; m_tableauMonitor=m_tableau.m_tableauMonitor; m_dependencySetFactory=m_tableau.m_dependencySetFactory; m_extensionTablesByArity=new HashMap<Integer,ExtensionTable>(); m_binaryExtensionTable= new ExtensionTableWithTupleIndexes(m_tableau,2,!m_tableau.isDeterministic(), new TupleIndex[] { new TupleIndex(new int[] { 1,0 }), new TupleIndex(new int[] { 0,1 }) } ) { private static final long serialVersionUID=1462821385000191875L; public boolean isTupleActive(Object[] tuple) { return ((Node)tuple[1]).isActive(); } public boolean isTupleActive(int tupleIndex) { return ((Node)m_tupleTable.getTupleObject(tupleIndex,1)).isActive(); } }; m_extensionTablesByArity.put(new Integer(2),m_binaryExtensionTable); m_ternaryExtensionTable= new ExtensionTableWithTupleIndexes(m_tableau,3,!m_tableau.isDeterministic(), new TupleIndex[] { new TupleIndex(new int[] { 0,1,2 }), new TupleIndex(new int[] { 1,2,0 }), new TupleIndex(new int[] { 2,0,1 }) } ) { private static final long serialVersionUID=-731201626401421877L; public boolean isTupleActive(Object[] tuple) { return ((Node)tuple[1]).isActive() && ((Node)tuple[2]).isActive(); } public boolean isTupleActive(int tupleIndex) { return ((Node)m_tupleTable.getTupleObject(tupleIndex,1)).isActive() && ((Node)m_tupleTable.getTupleObject(tupleIndex,2)).isActive(); } }; m_extensionTablesByArity.put(new Integer(3),m_ternaryExtensionTable); for (DescriptionGraph descriptionGraph : m_tableau.m_permanentDLOntology.getAllDescriptionGraphs()) { Integer arityInteger=Integer.valueOf(descriptionGraph.getNumberOfVertices()+1); if (!m_extensionTablesByArity.containsKey(arityInteger)) m_extensionTablesByArity.put(arityInteger,new ExtensionTableWithFullIndex(m_tableau,descriptionGraph.getNumberOfVertices()+1,!m_tableau.isDeterministic())); } m_allExtensionTablesArray=new ExtensionTable[m_extensionTablesByArity.size()]; m_extensionTablesByArity.values().toArray(m_allExtensionTablesArray); m_binaryAuxiliaryTupleContains=new Object[2]; m_binaryAuxiliaryTupleAdd=new Object[2]; m_ternaryAuxiliaryTupleContains=new Object[3]; m_ternaryAuxiliaryTupleAdd=new Object[3]; m_fouraryAuxiliaryTupleContains=new Object[4]; m_fouraryAuxiliaryTupleAdd=new Object[4]; } public void clear() { for (int index=m_allExtensionTablesArray.length-1;index>=0;--index) m_allExtensionTablesArray[index].clear(); m_clashDependencySet=null; m_binaryAuxiliaryTupleContains[0]=null; m_binaryAuxiliaryTupleContains[1]=null; m_binaryAuxiliaryTupleAdd[0]=null; m_binaryAuxiliaryTupleAdd[1]=null; m_ternaryAuxiliaryTupleContains[0]=null; m_ternaryAuxiliaryTupleContains[1]=null; m_ternaryAuxiliaryTupleContains[2]=null; m_ternaryAuxiliaryTupleAdd[0]=null; m_ternaryAuxiliaryTupleAdd[1]=null; m_ternaryAuxiliaryTupleAdd[2]=null; m_fouraryAuxiliaryTupleContains[0]=null; m_fouraryAuxiliaryTupleContains[1]=null; m_fouraryAuxiliaryTupleContains[2]=null; m_fouraryAuxiliaryTupleContains[3]=null; m_fouraryAuxiliaryTupleAdd[0]=null; m_fouraryAuxiliaryTupleAdd[1]=null; m_fouraryAuxiliaryTupleAdd[2]=null; m_fouraryAuxiliaryTupleAdd[3]=null; } public void branchingPointPushed() { for (int index=m_allExtensionTablesArray.length-1;index>=0;--index) m_allExtensionTablesArray[index].branchingPointPushed(); } public void backtrack() { for (int index=m_allExtensionTablesArray.length-1;index>=0;--index) m_allExtensionTablesArray[index].backtrack(); } public ExtensionTable getBinaryExtensionTable() { return m_binaryExtensionTable; } public ExtensionTable getTernaryExtensionTable() { return m_ternaryExtensionTable; } public ExtensionTable getExtensionTable(int arity) { switch (arity) { case 2: return m_binaryExtensionTable; case 3: return m_ternaryExtensionTable; default: return m_extensionTablesByArity.get(arity); } } public Collection<ExtensionTable> getExtensionTables() { return m_extensionTablesByArity.values(); } public boolean propagateDeltaNew() { boolean hasChange=false; for (int index=0;index<m_allExtensionTablesArray.length;index++) if (m_allExtensionTablesArray[index].propagateDeltaNew()) hasChange=true; return hasChange; } public void clearClash() { if (m_clashDependencySet!=null) { m_dependencySetFactory.removeUsage(m_clashDependencySet); m_clashDependencySet=null; } } public void setClash(DependencySet clashDependencySet) { if (m_clashDependencySet!=null) m_dependencySetFactory.removeUsage(m_clashDependencySet); m_clashDependencySet=m_dependencySetFactory.getPermanent(clashDependencySet); if (m_clashDependencySet!=null) m_dependencySetFactory.addUsage(m_clashDependencySet); if (m_tableauMonitor!=null) m_tableauMonitor.clashDetected(); } public DependencySet getClashDependencySet() { return m_clashDependencySet; } public boolean containsClash() { return m_clashDependencySet!=null; } public boolean containsConceptAssertion(Concept concept,Node node) { if (node.getNodeType().isAbstract() && AtomicConcept.THING.equals(concept)) return true; else { m_binaryAuxiliaryTupleContains[0]=concept; m_binaryAuxiliaryTupleContains[1]=node; return m_binaryExtensionTable.containsTuple(m_binaryAuxiliaryTupleContains); } } public boolean containsDataRangeAssertion(DataRange range,Node node) { if (!node.getNodeType().isAbstract() && InternalDatatype.RDFS_LITERAL.equals(range)) return true; else { m_binaryAuxiliaryTupleContains[0]=range; m_binaryAuxiliaryTupleContains[1]=node; return m_binaryExtensionTable.containsTuple(m_binaryAuxiliaryTupleContains); } } public boolean containsRoleAssertion(Role role,Node nodeFrom,Node nodeTo) { if (role instanceof AtomicRole) { m_ternaryAuxiliaryTupleContains[0]=role; m_ternaryAuxiliaryTupleContains[1]=nodeFrom; m_ternaryAuxiliaryTupleContains[2]=nodeTo; } else { m_ternaryAuxiliaryTupleContains[0]=((InverseRole)role).getInverseOf(); m_ternaryAuxiliaryTupleContains[1]=nodeTo; m_ternaryAuxiliaryTupleContains[2]=nodeFrom; } return m_ternaryExtensionTable.containsTuple(m_ternaryAuxiliaryTupleContains); } public boolean containsAssertion(DLPredicate dlPredicate,Node node) { if (AtomicConcept.THING.equals(dlPredicate)) return true; else { m_binaryAuxiliaryTupleContains[0]=dlPredicate; m_binaryAuxiliaryTupleContains[1]=node; return m_binaryExtensionTable.containsTuple(m_binaryAuxiliaryTupleContains); } } public boolean containsAssertion(DLPredicate dlPredicate,Node node0,Node node1) { if (Equality.INSTANCE.equals(dlPredicate)) return node0==node1; else { m_ternaryAuxiliaryTupleContains[0]=dlPredicate; m_ternaryAuxiliaryTupleContains[1]=node0; m_ternaryAuxiliaryTupleContains[2]=node1; return m_ternaryExtensionTable.containsTuple(m_ternaryAuxiliaryTupleContains); } } public boolean containsAssertion(DLPredicate dlPredicate,Node node0,Node node1,Node node2) { m_fouraryAuxiliaryTupleContains[0]=dlPredicate; m_fouraryAuxiliaryTupleContains[1]=node0; m_fouraryAuxiliaryTupleContains[2]=node1; m_fouraryAuxiliaryTupleContains[3]=node2; return containsTuple(m_fouraryAuxiliaryTupleContains); } public boolean containsAnnotatedEquality(AnnotatedEquality annotatedEquality,Node node0,Node node1,Node node2) { return m_tableau.m_nominalIntroductionManager.canForgetAnnotation(annotatedEquality,node0,node1,node2) && node0==node1; } public boolean containsTuple(Object[] tuple) { if (tuple.length==0) return containsClash(); else if (AtomicConcept.THING.equals(tuple[0])) return true; else if (Equality.INSTANCE.equals(tuple[0])) return tuple[1]==tuple[2]; else if (tuple[0] instanceof AnnotatedEquality) return m_tableau.m_nominalIntroductionManager.canForgetAnnotation((AnnotatedEquality)tuple[0],(Node)tuple[1],(Node)tuple[2],(Node)tuple[3]) && tuple[1]==tuple[2]; else return getExtensionTable(tuple.length).containsTuple(tuple); } public DependencySet getConceptAssertionDependencySet(Concept concept,Node node) { if (AtomicConcept.THING.equals(concept)) return m_dependencySetFactory.emptySet(); else { m_binaryAuxiliaryTupleContains[0]=concept; m_binaryAuxiliaryTupleContains[1]=node; return m_binaryExtensionTable.getDependencySet(m_binaryAuxiliaryTupleContains); } } public DependencySet getDataRangeAssertionDependencySet(DataRange range,Node node) { if (InternalDatatype.RDFS_LITERAL.equals(range)) return m_dependencySetFactory.emptySet(); else { m_binaryAuxiliaryTupleContains[0]=range; m_binaryAuxiliaryTupleContains[1]=node; return m_binaryExtensionTable.getDependencySet(m_binaryAuxiliaryTupleContains); } } public DependencySet getRoleAssertionDependencySet(Role role,Node nodeFrom,Node nodeTo) { if (role instanceof AtomicRole) { m_ternaryAuxiliaryTupleContains[0]=role; m_ternaryAuxiliaryTupleContains[1]=nodeFrom; m_ternaryAuxiliaryTupleContains[2]=nodeTo; } else { m_ternaryAuxiliaryTupleContains[0]=((InverseRole)role).getInverseOf(); m_ternaryAuxiliaryTupleContains[1]=nodeTo; m_ternaryAuxiliaryTupleContains[2]=nodeFrom; } return m_ternaryExtensionTable.getDependencySet(m_ternaryAuxiliaryTupleContains); } public DependencySet getAssertionDependencySet(DLPredicate dlPredicate,Node node) { m_binaryAuxiliaryTupleContains[0]=dlPredicate; m_binaryAuxiliaryTupleContains[1]=node; return m_binaryExtensionTable.getDependencySet(m_binaryAuxiliaryTupleContains); } public DependencySet getAssertionDependencySet(DLPredicate dlPredicate,Node node0,Node node1) { if (Equality.INSTANCE.equals(dlPredicate)) return node0==node1 ? m_dependencySetFactory.emptySet() : null; else { m_ternaryAuxiliaryTupleContains[0]=dlPredicate; m_ternaryAuxiliaryTupleContains[1]=node0; m_ternaryAuxiliaryTupleContains[2]=node1; return m_ternaryExtensionTable.getDependencySet(m_ternaryAuxiliaryTupleContains); } } public DependencySet getAssertionDependencySet(DLPredicate dlPredicate,Node node0,Node node1,Node node2) { m_fouraryAuxiliaryTupleContains[0]=dlPredicate; m_fouraryAuxiliaryTupleContains[1]=node0; m_fouraryAuxiliaryTupleContains[2]=node1; m_fouraryAuxiliaryTupleContains[3]=node2; return getTupleDependencySet(m_fouraryAuxiliaryTupleContains); } public DependencySet getTupleDependencySet(Object[] tuple) { if (tuple.length==0) return m_clashDependencySet; else return getExtensionTable(tuple.length).getDependencySet(tuple); } public boolean isCore(Object[] tuple) { if (tuple.length==0) return true; else return getExtensionTable(tuple.length).isCore(tuple); } public boolean addConceptAssertion(Concept concept,Node node,DependencySet dependencySet,boolean isCore) { if (m_addActive) throw new IllegalStateException("ExtensionManager is not reentrant."); m_addActive=true; try { m_binaryAuxiliaryTupleAdd[0]=concept; m_binaryAuxiliaryTupleAdd[1]=node; return m_binaryExtensionTable.addTuple(m_binaryAuxiliaryTupleAdd,dependencySet,isCore); } finally { m_addActive=false; } } public boolean addDataRangeAssertion(DataRange dataRange,Node node,DependencySet dependencySet,boolean isCore) { if (m_addActive) throw new IllegalStateException("ExtensionManager is not reentrant."); m_addActive=true; try { m_binaryAuxiliaryTupleAdd[0]=dataRange; m_binaryAuxiliaryTupleAdd[1]=node; return m_binaryExtensionTable.addTuple(m_binaryAuxiliaryTupleAdd,dependencySet,isCore); } finally { m_addActive=false; } } public boolean addRoleAssertion(Role role,Node nodeFrom,Node nodeTo,DependencySet dependencySet,boolean isCore) { if (role instanceof AtomicRole) return addAssertion((AtomicRole)role,nodeFrom,nodeTo,dependencySet,isCore); else return addAssertion(((InverseRole)role).getInverseOf(),nodeTo,nodeFrom,dependencySet,isCore); } public boolean addAssertion(DLPredicate dlPredicate,Node node,DependencySet dependencySet,boolean isCore) { if (m_addActive) throw new IllegalStateException("ExtensionManager is not reentrant."); m_addActive=true; try { m_binaryAuxiliaryTupleAdd[0]=dlPredicate; m_binaryAuxiliaryTupleAdd[1]=node; return m_binaryExtensionTable.addTuple(m_binaryAuxiliaryTupleAdd,dependencySet,isCore); } finally { m_addActive=false; } } public boolean addAssertion(DLPredicate dlPredicate,Node node0,Node node1,DependencySet dependencySet,boolean isCore) { if (Equality.INSTANCE.equals(dlPredicate)) return m_tableau.m_mergingManager.mergeNodes(node0,node1,dependencySet); else { if (m_addActive) throw new IllegalStateException("ExtensionManager is not reentrant."); m_addActive=true; try { m_ternaryAuxiliaryTupleAdd[0]=dlPredicate; m_ternaryAuxiliaryTupleAdd[1]=node0; m_ternaryAuxiliaryTupleAdd[2]=node1; return m_ternaryExtensionTable.addTuple(m_ternaryAuxiliaryTupleAdd,dependencySet,isCore); } finally { m_addActive=false; } } } public boolean addAssertion(DLPredicate dlPredicate,Node node0,Node node1,Node node2,DependencySet dependencySet,boolean isCore) { if (m_addActive) throw new IllegalStateException("ExtensionManager is not reentrant."); m_fouraryAuxiliaryTupleAdd[0]=dlPredicate; m_fouraryAuxiliaryTupleAdd[1]=node0; m_fouraryAuxiliaryTupleAdd[2]=node1; m_fouraryAuxiliaryTupleAdd[3]=node2; return addTuple(m_fouraryAuxiliaryTupleAdd,dependencySet,isCore); } public boolean addAnnotatedEquality(AnnotatedEquality annotatedEquality,Node node0,Node node1,Node node2,DependencySet dependencySet) { return m_tableau.m_nominalIntroductionManager.addAnnotatedEquality(annotatedEquality,node0,node1,node2,dependencySet); } public boolean addTuple(Object[] tuple,DependencySet dependencySet,boolean isCore) { if (tuple.length==0) { boolean result=(m_clashDependencySet==null); setClash(dependencySet); return result; } else if (Equality.INSTANCE.equals(tuple[0])) return m_tableau.m_mergingManager.mergeNodes((Node)tuple[1],(Node)tuple[2],dependencySet); else if (tuple[0] instanceof AnnotatedEquality) return m_tableau.m_nominalIntroductionManager.addAnnotatedEquality((AnnotatedEquality)tuple[0],(Node)tuple[1],(Node)tuple[2],(Node)tuple[3],dependencySet); else { if (m_addActive) throw new IllegalStateException("ExtensionManager is not reentrant."); m_addActive=true; try { return getExtensionTable(tuple.length).addTuple(tuple,dependencySet,isCore); } finally { m_addActive=false; } } } }