/* 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 org.semanticweb.HermiT.Prefixes;
import org.semanticweb.HermiT.model.AtLeastConcept;
import org.semanticweb.HermiT.model.AtomicNegationConcept;
import org.semanticweb.HermiT.model.DLPredicate;
public final class GroundDisjunctionHeader {
protected final DLPredicate[] m_dlPredicates;
protected final int[] m_disjunctStart;
protected final int m_hashCode;
protected final DisjunctIndexWithBacktrackings[] m_disjunctIndexesWithBacktrackings;
protected final int m_firstAtLeastPositiveIndex;
protected final int m_firstAtLeastNegativeIndex;
protected GroundDisjunctionHeader m_nextEntry;
protected GroundDisjunctionHeader(DLPredicate[] dlPredicates,int hashCode,GroundDisjunctionHeader nextEntry) {
m_dlPredicates=dlPredicates;
m_disjunctStart=new int[m_dlPredicates.length];
int argumentsSize=0;
for (int disjunctIndex=0;disjunctIndex<m_dlPredicates.length;disjunctIndex++) {
m_disjunctStart[disjunctIndex]=argumentsSize;
argumentsSize+=m_dlPredicates[disjunctIndex].getArity();
}
m_hashCode=hashCode;
m_nextEntry=nextEntry;
m_disjunctIndexesWithBacktrackings=new DisjunctIndexWithBacktrackings[dlPredicates.length];
// The disjuncts are arranged in a particular order that seems to work well in practice
// Thus we initialize m_disjunctIndexesWithBacktrackings in the following order:
// First, we have the disjuncts that are at least concepts but over a negated atomic concept
// Next, we have the atomic concept disjuncts
// Finally, we have the at least concepts that are not over a negated atomic concept
// Later on we will ensure that disjunction learning (if enabled) does not move the disjuncts
// out of their partition.
int numberOfAtLeastPositiveDisjuncts=0;
int numberOfAtLeastNegativeDisjuncts=0;
for (int index=0;index<dlPredicates.length;index++)
if (m_dlPredicates[index] instanceof AtLeastConcept) {
AtLeastConcept atLeast=(AtLeastConcept)m_dlPredicates[index];
if (atLeast.getToConcept() instanceof AtomicNegationConcept)
numberOfAtLeastNegativeDisjuncts++;
else
numberOfAtLeastPositiveDisjuncts++;
}
m_firstAtLeastNegativeIndex=m_disjunctIndexesWithBacktrackings.length-numberOfAtLeastPositiveDisjuncts-numberOfAtLeastNegativeDisjuncts;
m_firstAtLeastPositiveIndex=m_disjunctIndexesWithBacktrackings.length-numberOfAtLeastPositiveDisjuncts;
int nextAtomicDisjunct=0;
int nextAtLeastNegativeDisjunct=m_firstAtLeastNegativeIndex;
int nextAtLeastPositiveDisjunct=m_firstAtLeastPositiveIndex;
for (int index=0;index<dlPredicates.length;index++)
if (m_dlPredicates[index] instanceof AtLeastConcept) {
AtLeastConcept atLeast=(AtLeastConcept)m_dlPredicates[index];
if (atLeast.getToConcept() instanceof AtomicNegationConcept)
m_disjunctIndexesWithBacktrackings[nextAtLeastNegativeDisjunct++]=new DisjunctIndexWithBacktrackings(index);
else
m_disjunctIndexesWithBacktrackings[nextAtLeastPositiveDisjunct++]=new DisjunctIndexWithBacktrackings(index);
}
else
m_disjunctIndexesWithBacktrackings[nextAtomicDisjunct++]=new DisjunctIndexWithBacktrackings(index);
}
protected boolean isEqual(DLPredicate[] dlPredicates) {
if (m_dlPredicates.length!=dlPredicates.length)
return false;
for (int index=m_dlPredicates.length-1;index>=0;--index)
if (!m_dlPredicates[index].equals(dlPredicates[index]))
return false;
return true;
}
public int[] getSortedDisjunctIndexes() {
int[] sortedDisjunctIndexes=new int[m_disjunctIndexesWithBacktrackings.length];
for (int index=m_disjunctIndexesWithBacktrackings.length-1;index>=0;--index)
sortedDisjunctIndexes[index]=m_disjunctIndexesWithBacktrackings[index].m_disjunctIndex;
return sortedDisjunctIndexes;
}
public void increaseNumberOfBacktrackings(int disjunctIndex) {
for (int index=0;index<m_disjunctIndexesWithBacktrackings.length;index++) {
DisjunctIndexWithBacktrackings disjunctIndexWithBacktrackings=m_disjunctIndexesWithBacktrackings[index];
if (disjunctIndexWithBacktrackings.m_disjunctIndex==disjunctIndex) {
disjunctIndexWithBacktrackings.m_numberOfBacktrackings++;
// find the partition end, swapping of disjuncts stops when the number of backtrackings for the
// current disjunct is lower than the one for the next disjunct or when the partition end is reached
int partitionEnd;
if (index<m_firstAtLeastNegativeIndex) partitionEnd=m_firstAtLeastNegativeIndex;
else if (index>=m_firstAtLeastNegativeIndex && index<m_firstAtLeastPositiveIndex) partitionEnd=m_firstAtLeastPositiveIndex;
else partitionEnd=m_disjunctIndexesWithBacktrackings.length;
int currentIndex=index;
int nextIndex=currentIndex+1;
while (nextIndex<partitionEnd && disjunctIndexWithBacktrackings.m_numberOfBacktrackings>m_disjunctIndexesWithBacktrackings[nextIndex].m_numberOfBacktrackings) {
m_disjunctIndexesWithBacktrackings[currentIndex]=m_disjunctIndexesWithBacktrackings[nextIndex];
m_disjunctIndexesWithBacktrackings[nextIndex]=disjunctIndexWithBacktrackings;
currentIndex=nextIndex;
nextIndex++;
}
break;
}
}
}
public String toString(Prefixes prefixes) {
StringBuffer buffer=new StringBuffer();
for (int disjunctIndex=0;disjunctIndex<m_dlPredicates.length;disjunctIndex++) {
if (disjunctIndex>0)
buffer.append(" \\/ ");
buffer.append(m_dlPredicates[disjunctIndex].toString(prefixes));
buffer.append(" (");
for (DisjunctIndexWithBacktrackings disjunctIndexWithBacktrackings : m_disjunctIndexesWithBacktrackings) {
if (disjunctIndexWithBacktrackings.m_disjunctIndex==disjunctIndex) {
buffer.append(disjunctIndexWithBacktrackings.m_numberOfBacktrackings);
break;
}
}
buffer.append(")");
}
return buffer.toString();
}
public String toString() {
return toString(Prefixes.STANDARD_PREFIXES);
}
protected static class DisjunctIndexWithBacktrackings {
protected final int m_disjunctIndex;
protected int m_numberOfBacktrackings;
public DisjunctIndexWithBacktrackings(int index) {
m_disjunctIndex=index;
}
}
}