Package org.semanticweb.HermiT.tableau

Source Code of org.semanticweb.HermiT.tableau.DLClauseEvaluator$NextRetrieval

/* 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.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
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.DLClause;
import org.semanticweb.HermiT.model.DLPredicate;
import org.semanticweb.HermiT.model.NodeIDLessEqualThan;
import org.semanticweb.HermiT.model.NodeIDsAscendingOrEqual;
import org.semanticweb.HermiT.model.Variable;
import org.semanticweb.HermiT.monitor.TableauMonitor;

public class DLClauseEvaluator implements Serializable {
    private static final long serialVersionUID=4639844159658590456L;
    protected static final String CRLF=System.getProperty("line.separator");

    protected final InterruptFlag m_interruptFlag;
    protected final ExtensionManager m_extensionManager;
    protected final ExtensionTable.Retrieval[] m_retrievals;
    protected final Worker[] m_workers;
    protected final DLClause m_bodyDLClause;
    protected final List<DLClause> m_headDLClauses;

    public DLClauseEvaluator(Tableau tableau,DLClause bodyDLClause,List<DLClause> headDLClauses,ExtensionTable.Retrieval firstAtomRetrieval,BufferSupply bufferSupply,ValuesBufferManager valuesBufferManager,GroundDisjunctionHeaderManager groundDisjunctionHeaderManager,Map<Integer,UnionDependencySet> unionDependencySetsBySize) {
        m_interruptFlag=tableau.m_interruptFlag;
        m_extensionManager=tableau.m_extensionManager;
        DLClauseCompiler compiler=new DLClauseCompiler(bufferSupply,valuesBufferManager,groundDisjunctionHeaderManager,unionDependencySetsBySize,this,m_extensionManager,tableau.getExistentialsExpansionStrategy(),bodyDLClause,headDLClauses,firstAtomRetrieval);
        m_retrievals=new ExtensionTable.Retrieval[compiler.m_retrievals.size()];
        compiler.m_retrievals.toArray(m_retrievals);
        m_workers=new Worker[compiler.m_workers.size()];
        compiler.m_workers.toArray(m_workers);
        m_bodyDLClause=bodyDLClause;
        m_headDLClauses=headDLClauses;
    }
    public int getBodyLength() {
        return m_bodyDLClause.getBodyLength();
    }
    public Atom getBodyAtom(int atomIndex) {
        return m_bodyDLClause.getBodyAtom(atomIndex);
    }
    public int getNumberOfDLClauses() {
        return m_headDLClauses.size();
    }
    public DLClause getDLClause(int dlClauseIndex) {
        return m_headDLClauses.get(dlClauseIndex);
    }
    public int getHeadLength(int dlClauseIndex) {
        return m_headDLClauses.get(dlClauseIndex).getHeadLength();
    }
    public Atom getHeadAtom(int dlClauseIndex,int atomIndex) {
        return m_headDLClauses.get(dlClauseIndex).getHeadAtom(atomIndex);
    }
    public Object[] getTupleMatchedToBody(int atomIndex) {
        return m_retrievals[atomIndex].getTupleBuffer();
    }
    public void evaluate() {
        int programCounter=0;
        while (programCounter<m_workers.length && !m_extensionManager.containsClash()) {
            m_interruptFlag.checkInterrupt();
            programCounter=m_workers[programCounter].execute(programCounter);
        }
    }
    public String toString() {
        StringBuffer buffer=new StringBuffer();
        int maximalPCLength=String.valueOf(m_workers.length-1).length();
        for (int programCounter=0;programCounter<m_workers.length;programCounter++) {
            String programCounterString=String.valueOf(programCounter);
            for (int count=maximalPCLength-programCounterString.length();count>0;--count)
                buffer.append(' ');
            buffer.append(programCounterString);
            buffer.append(": ");
            buffer.append(m_workers[programCounter].toString());
            buffer.append(CRLF);
        }
        return buffer.toString();
    }

    public static class BufferSupply {
        protected final List<Object[]> m_allBuffers;
        protected final Map<Integer,List<Object[]>> m_availableBuffersByArity;

        public BufferSupply() {
            m_allBuffers=new ArrayList<Object[]>();
            m_availableBuffersByArity=new HashMap<Integer,List<Object[]>>();
        }
        public void reuseBuffers() {
            m_availableBuffersByArity.clear();
            for (Object[] buffer : m_allBuffers) {
                Integer arityInteger=Integer.valueOf(buffer.length);
                List<Object[]> buffers=m_availableBuffersByArity.get(arityInteger);
                if (buffers==null) {
                    buffers=new ArrayList<Object[]>();
                    m_availableBuffersByArity.put(arityInteger,buffers);
                }
                buffers.add(buffer);
            }
        }
        public Object[] getBuffer(int arity) {
            Object[] buffer;
            Integer arityInteger=Integer.valueOf(arity);
            List<Object[]> buffers=m_availableBuffersByArity.get(arityInteger);
            if (buffers==null || buffers.isEmpty()) {
                buffer=new Object[arity];
                m_allBuffers.add(buffer);
            }
            else
                buffer=buffers.remove(buffers.size()-1);
            return buffer;
        }
        public Object[][] getAllBuffers() {
            Object[][] result=new Object[m_allBuffers.size()][];
            m_allBuffers.toArray(result);
            return result;
        }
    }

    public static class ValuesBufferManager {
        public final Object[] m_valuesBuffer;
        public final Map<DLPredicate,Integer> m_bodyDLPredicatesToIndexes;
        public final int m_maxNumberOfVariables;

        public ValuesBufferManager(Set<DLClause> dlClauses) {
            Set<DLPredicate> bodyDLPredicates=new HashSet<DLPredicate>();
            Set<Variable> variables=new HashSet<Variable>();
            int maxNumberOfVariables=0;
            for (DLClause dlClause : dlClauses) {
                variables.clear();
                for (int bodyIndex=dlClause.getBodyLength()-1;bodyIndex>=0;--bodyIndex) {
                    Atom atom=dlClause.getBodyAtom(bodyIndex);
                    bodyDLPredicates.add(atom.getDLPredicate());
                    for (int argumentIndex=0;argumentIndex<atom.getArity();argumentIndex++) {
                        Variable variable=atom.getArgumentVariable(argumentIndex);
                        if (variable!=null)
                            variables.add(variable);
                    }
                }
                if (variables.size()>maxNumberOfVariables)
                    maxNumberOfVariables=variables.size();
            }
            m_valuesBuffer=new Object[maxNumberOfVariables+bodyDLPredicates.size()];
            m_bodyDLPredicatesToIndexes=new HashMap<DLPredicate,Integer>();
            int predicateIndex=maxNumberOfVariables;
            for (DLPredicate bodyDLPredicate : bodyDLPredicates) {
                m_bodyDLPredicatesToIndexes.put(bodyDLPredicate,Integer.valueOf(predicateIndex));
                m_valuesBuffer[predicateIndex]=bodyDLPredicate;
                predicateIndex++;
            }
            m_maxNumberOfVariables=maxNumberOfVariables;
        }
    }

    public static class GroundDisjunctionHeaderManager {
        protected GroundDisjunctionHeader[] m_buckets;
        protected int m_numberOfElements;
        protected int m_threshold;

        public GroundDisjunctionHeaderManager() {
            m_buckets=new GroundDisjunctionHeader[1024];
            m_threshold=(int)(m_buckets.length*0.75);
            m_numberOfElements=0;
        }
        public GroundDisjunctionHeader get(DLPredicate[] dlPredicates) {
            int hashCode=0;
            for (int disjunctIndex=0;disjunctIndex<dlPredicates.length;disjunctIndex++)
                hashCode=hashCode*7+dlPredicates[disjunctIndex].hashCode();
            int bucketIndex=getIndexFor(hashCode,m_buckets.length);
            GroundDisjunctionHeader entry=m_buckets[bucketIndex];
            while (entry!=null) {
                if (hashCode==entry.m_hashCode && entry.isEqual(dlPredicates))
                    return entry;
                entry=entry.m_nextEntry;
            }
            entry=new GroundDisjunctionHeader(dlPredicates,hashCode,entry);
            m_buckets[bucketIndex]=entry;
            m_numberOfElements++;
            if (m_numberOfElements>=m_threshold)
                resize(m_buckets.length*2);
            return entry;
        }
        protected void resize(int newCapacity) {
            GroundDisjunctionHeader[] newBuckets=new GroundDisjunctionHeader[newCapacity];
            for (int i=0;i<m_buckets.length;i++) {
                GroundDisjunctionHeader entry=m_buckets[i];
                while (entry!=null) {
                    GroundDisjunctionHeader nextEntry=entry.m_nextEntry;
                    int newIndex=getIndexFor(entry.hashCode(),newCapacity);
                    entry.m_nextEntry=newBuckets[newIndex];
                    newBuckets[newIndex]=entry;
                    entry=nextEntry;
                }
            }
            m_buckets=newBuckets;
            m_threshold=(int)(newCapacity*0.75);
        }
        protected static int getIndexFor(int hashCode,int tableLength) {
            hashCode+=~(hashCode << 9);
            hashCode^=(hashCode >>> 14);
            hashCode+=(hashCode << 4);
            hashCode^=(hashCode >>> 10);
            return hashCode & (tableLength-1);
        }
    }

    public static interface Worker {
        int execute(int programCounter);
    }

    protected static interface BranchingWorker extends Worker {
        int getBranchingAddress();
        void setBranchingAddress(int branchingAddress);
    }

    protected static final class CopyValues implements Worker,Serializable {
        private static final long serialVersionUID=-4323769483485648756L;

        protected final Object[] m_fromBuffer;
        protected final int m_fromIndex;
        protected final Object[] m_toBuffer;
        protected final int m_toIndex;

        public CopyValues(Object[] fromBuffer,int fromIndex,Object[] toBuffer,int toIndex) {
            m_fromBuffer=fromBuffer;
            m_fromIndex=fromIndex;
            m_toBuffer=toBuffer;
            m_toIndex=toIndex;
        }
        public int execute(int programCounter) {
            m_toBuffer[m_toIndex]=m_fromBuffer[m_fromIndex];
            return programCounter+1;
        }
        public String toString() {
            return "Copy "+m_fromIndex+" --> "+m_toIndex;
        }
    }

    protected static final class CopyDependencySet implements Worker,Serializable {
        private static final long serialVersionUID=705172386083123813L;

        protected final ExtensionTable.Retrieval m_retrieval;
        protected final DependencySet[] m_targetDependencySets;
        protected final int m_targetIndex;

        public CopyDependencySet(ExtensionTable.Retrieval retrieval,DependencySet[] targetDependencySets,int targetIndex) {
            m_retrieval=retrieval;
            m_targetDependencySets=targetDependencySets;
            m_targetIndex=targetIndex;
        }
        public int execute(int programCounter) {
            m_targetDependencySets[m_targetIndex]=m_retrieval.getDependencySet();
            return programCounter+1;
        }
        public String toString() {
            return "Copy dependency set to "+m_targetIndex;
        }
    }

    protected static final class BranchIfNotEqual implements BranchingWorker,Serializable {
        private static final long serialVersionUID=-1880147431680856293L;

        protected int m_notEqualProgramCounter;
        protected final Object[] m_buffer;
        protected final int m_index1;
        protected final int m_index2;

        public BranchIfNotEqual(int notEqualProgramCounter,Object[] buffer,int index1,int index2) {
            m_notEqualProgramCounter=notEqualProgramCounter;
            m_buffer=buffer;
            m_index1=index1;
            m_index2=index2;
        }
        public int execute(int programCounter) {
            if (m_buffer[m_index1].equals(m_buffer[m_index2]))
                return programCounter+1;
            else
                return m_notEqualProgramCounter;
        }
        public int getBranchingAddress() {
            return m_notEqualProgramCounter;
        }
        public void setBranchingAddress(int branchingAddress) {
            m_notEqualProgramCounter=branchingAddress;
        }
        public String toString() {
            return "Branch to "+m_notEqualProgramCounter+" if "+m_index1+" != "+m_index2;
        }
    }

    protected static final class BranchIfNotNodeIDLessEqualThan implements BranchingWorker,Serializable {
        private static final long serialVersionUID=2484359261424674914L;

        protected int m_notLessProgramCounter;
        protected final Object[] m_buffer;
        protected final int m_index1;
        protected final int m_index2;

        public BranchIfNotNodeIDLessEqualThan(int notLessProgramCounter,Object[] buffer,int index1,int index2) {
            m_notLessProgramCounter=notLessProgramCounter;
            m_buffer=buffer;
            m_index1=index1;
            m_index2=index2;
        }
        public int execute(int programCounter) {
            if (((Node)m_buffer[m_index1]).getNodeID()<=((Node)m_buffer[m_index2]).getNodeID())
                return programCounter+1;
            else
                return m_notLessProgramCounter;
        }
        public int getBranchingAddress() {
            return m_notLessProgramCounter;
        }
        public void setBranchingAddress(int branchingAddress) {
            m_notLessProgramCounter=branchingAddress;
        }
        public String toString() {
            return "Branch to "+m_notLessProgramCounter+" if "+m_index1+".ID > "+m_index2+".ID";
        }
    }

    protected static final class BranchIfNotNodeIDsAscendingOrEqual implements BranchingWorker,Serializable {
        private static final long serialVersionUID=8053779312249250349L;

        protected int m_branchProgramCounter;
        protected final Object[] m_buffer;
        protected final int[] m_nodeIndexes;

        public BranchIfNotNodeIDsAscendingOrEqual(int branchProgramCounter,Object[] buffer,int[] nodeIndexes) {
            m_branchProgramCounter=branchProgramCounter;
            m_buffer=buffer;
            m_nodeIndexes=nodeIndexes;
        }
        public int execute(int programCounter) {
            boolean strictlyAscending=true;
            boolean allEqual=true;
            int lastNodeID=((Node)m_buffer[m_nodeIndexes[0]]).getNodeID();
            for (int index=1;index<m_nodeIndexes.length;index++) {
                int nodeID=((Node)m_buffer[m_nodeIndexes[index]]).getNodeID();
                if (lastNodeID>=nodeID)
                    strictlyAscending=false;
                if (nodeID!=lastNodeID)
                    allEqual=false;
                lastNodeID=nodeID;
            }
            if ((!strictlyAscending && allEqual) || (strictlyAscending && !allEqual))
                return programCounter+1;
            else
                return m_branchProgramCounter;
        }
        public int getBranchingAddress() {
            return m_branchProgramCounter;
        }
        public void setBranchingAddress(int branchingAddress) {
            m_branchProgramCounter=branchingAddress;
        }
        public String toString() {
            return "Branch to "+m_branchProgramCounter+" if node IDs are not ascending or equal";
        }
    }

    protected static final class OpenRetrieval implements Worker,Serializable {
        private static final long serialVersionUID=8246610603084803950L;

        protected final ExtensionTable.Retrieval m_retrieval;

        public OpenRetrieval(ExtensionTable.Retrieval retrieval) {
            m_retrieval=retrieval;
        }
        public int execute(int programCounter) {
            m_retrieval.open();
            return programCounter+1;
        }
        public String toString() {
            return "Open "+m_retrieval.getBindingsBuffer()[m_retrieval.getBindingPositions()[0]];
        }
    }

    protected static final class NextRetrieval implements Worker,Serializable {
        private static final long serialVersionUID=-2787897558147109082L;

        protected final ExtensionTable.Retrieval m_retrieval;

        public NextRetrieval(ExtensionTable.Retrieval retrieval) {
            m_retrieval=retrieval;
        }
        public int execute(int programCounter) {
            m_retrieval.next();
            return programCounter+1;
        }
        public String toString() {
            return "Next "+m_retrieval.getBindingsBuffer()[m_retrieval.getBindingPositions()[0]];
        }
    }

    protected static final class HasMoreRetrieval implements BranchingWorker,Serializable {
        private static final long serialVersionUID=-2415094151423166585L;

        protected int m_eofProgramCounter;
        protected final ExtensionTable.Retrieval m_retrieval;

        public HasMoreRetrieval(int eofProgramCounter,ExtensionTable.Retrieval retrieval) {
            m_eofProgramCounter=eofProgramCounter;
            m_retrieval=retrieval;
        }
        public int execute(int programCounter) {
            if (m_retrieval.afterLast())
                return m_eofProgramCounter;
            else
                return programCounter+1;
        }
        public int getBranchingAddress() {
            return m_eofProgramCounter;
        }
        public void setBranchingAddress(int branchingAddress) {
            m_eofProgramCounter=branchingAddress;
        }
        public String toString() {
            return "Branch to "+m_eofProgramCounter+" if "+m_retrieval.getBindingsBuffer()[m_retrieval.getBindingPositions()[0]]+" is empty";
        }
    }

    protected static final class JumpTo implements BranchingWorker,Serializable {
        private static final long serialVersionUID=-6957866973028474739L;

        protected int m_jumpTo;

        public JumpTo(int jumpTo) {
            m_jumpTo=jumpTo;
        }
        public int execute(int programCounter) {
            return m_jumpTo;
        }
        public int getBranchingAddress() {
            return m_jumpTo;
        }
        public void setBranchingAddress(int branchingAddress) {
            m_jumpTo=branchingAddress;
        }
        public String toString() {
            return "Jump to "+m_jumpTo;
        }
    }

    protected static final class CallMatchStartedOnMonitor implements Worker,Serializable {
        private static final long serialVersionUID=8736659573939242252L;

        protected final TableauMonitor m_tableauMonitor;
        protected final DLClauseEvaluator m_dlClauseEvaluator;
        protected final int m_dlClauseIndex;

        public CallMatchStartedOnMonitor(TableauMonitor tableauMonitor,DLClauseEvaluator dlClauseEvaluator,int dlClauseIndex) {
            m_tableauMonitor=tableauMonitor;
            m_dlClauseEvaluator=dlClauseEvaluator;
            m_dlClauseIndex=dlClauseIndex;
        }
        public int execute(int programCounter) {
            m_tableauMonitor.dlClauseMatchedStarted(m_dlClauseEvaluator,m_dlClauseIndex);
            return programCounter+1;
        }
        public String toString() {
            return "Monitor -> Match started";
        }
    }

    protected static final class CallMatchFinishedOnMonitor implements Worker,Serializable {
        private static final long serialVersionUID=1046400921858176361L;

        protected final TableauMonitor m_tableauMonitor;
        protected final DLClauseEvaluator m_dlClauseEvaluator;
        protected final int m_dlClauseIndex;

        public CallMatchFinishedOnMonitor(TableauMonitor tableauMonitor,DLClauseEvaluator dlClauseEvaluator,int dlClauseIndex) {
            m_tableauMonitor=tableauMonitor;
            m_dlClauseEvaluator=dlClauseEvaluator;
            m_dlClauseIndex=dlClauseIndex;
        }
        public int execute(int programCounter) {
            m_tableauMonitor.dlClauseMatchedFinished(m_dlClauseEvaluator,m_dlClauseIndex);
            return programCounter+1;
        }
        public String toString() {
            return "Monitor -> Match finished";
        }
    }

    protected static final class SetClash implements Worker,Serializable {
        private static final long serialVersionUID=-4981087765064918953L;

        protected final ExtensionManager m_extensionManager;
        protected final DependencySet m_dependencySet;

        public SetClash(ExtensionManager extensionManager,DependencySet dependencySet) {
            m_extensionManager=extensionManager;
            m_dependencySet=dependencySet;
        }
        public int execute(int programCounter) {
            m_extensionManager.setClash(m_dependencySet);
            return programCounter+1;
        }
        public String toString() {
            return "Set clash";
        }
    }

    protected static final class DeriveUnaryFact implements Worker,Serializable {
        private static final long serialVersionUID=7883620022252842010L;

        protected final ExtensionManager m_extensionManager;
        protected final Object[] m_valuesBuffer;
        protected final boolean[] m_coreVariables;
        protected final DependencySet m_dependencySet;
        protected final DLPredicate m_dlPredicate;
        protected final int m_argumentIndex;

        public DeriveUnaryFact(ExtensionManager extensionManager,Object[] valuesBuffer,boolean[] coreVariables,DependencySet dependencySet,DLPredicate dlPredicate,int argumentIndex) {
            m_extensionManager=extensionManager;
            m_valuesBuffer=valuesBuffer;
            m_coreVariables=coreVariables;
            m_dependencySet=dependencySet;
            m_argumentIndex=argumentIndex;
            m_dlPredicate=dlPredicate;
        }
        public int execute(int programCounter) {
            Node argument=(Node)m_valuesBuffer[m_argumentIndex];
            boolean isCore=m_coreVariables[m_argumentIndex];
            m_extensionManager.addAssertion(m_dlPredicate,argument,m_dependencySet,isCore);
            return programCounter+1;
        }
        public String toString() {
            return "Derive unary fact";
        }
    }

    protected static final class DeriveBinaryFact implements Worker,Serializable {
        private static final long serialVersionUID=1823363493615682288L;

        protected final ExtensionManager m_extensionManager;
        protected final Object[] m_valuesBuffer;
        protected final DependencySet m_dependencySet;
        protected final DLPredicate m_dlPredicate;
        protected final int m_argumentIndex1;
        protected final int m_argumentIndex2;

        public DeriveBinaryFact(ExtensionManager extensionManager,Object[] valuesBuffer,DependencySet dependencySet,DLPredicate dlPredicate,int argumentIndex1,int argumentIndex2) {
            m_extensionManager=extensionManager;
            m_valuesBuffer=valuesBuffer;
            m_dependencySet=dependencySet;
            m_dlPredicate=dlPredicate;
            m_argumentIndex1=argumentIndex1;
            m_argumentIndex2=argumentIndex2;
        }
        public int execute(int programCounter) {
            Node argument1=(Node)m_valuesBuffer[m_argumentIndex1];
            Node argument2=(Node)m_valuesBuffer[m_argumentIndex2];
            m_extensionManager.addAssertion(m_dlPredicate,argument1,argument2,m_dependencySet,true);
            return programCounter+1;
        }
        public String toString() {
            return "Derive binary fact";
        }
    }

    protected static final class DeriveTernaryFact implements Worker,Serializable {
        private static final long serialVersionUID=1823363493615682288L;

        protected final ExtensionManager m_extensionManager;
        protected final Object[] m_valuesBuffer;
        protected final DependencySet m_dependencySet;
        protected final DLPredicate m_dlPredicate;
        protected final int m_argumentIndex1;
        protected final int m_argumentIndex2;
        protected final int m_argumentIndex3;

        public DeriveTernaryFact(ExtensionManager extensionManager,Object[] valuesBuffer,DependencySet dependencySet,DLPredicate dlPredicate,int argumentIndex1,int argumentIndex2,int argumentIndex3) {
            m_extensionManager=extensionManager;
            m_valuesBuffer=valuesBuffer;
            m_dependencySet=dependencySet;
            m_dlPredicate=dlPredicate;
            m_argumentIndex1=argumentIndex1;
            m_argumentIndex2=argumentIndex2;
            m_argumentIndex3=argumentIndex3;
        }
        public int execute(int programCounter) {
            Node argument1=(Node)m_valuesBuffer[m_argumentIndex1];
            Node argument2=(Node)m_valuesBuffer[m_argumentIndex2];
            Node argument3=(Node)m_valuesBuffer[m_argumentIndex3];
            m_extensionManager.addAssertion(m_dlPredicate,argument1,argument2,argument3,m_dependencySet,true);
            return programCounter+1;
        }
        public String toString() {
            return "Derive ternary fact";
        }
    }

    protected static final class DeriveDisjunction implements Worker,Serializable {
        private static final long serialVersionUID=-3546622575743138887L;

        protected final Tableau m_tableau;
        protected final Object[] m_valuesBuffer;
        protected final boolean[] m_coreVariables;
        protected final DependencySet m_dependencySet;
        protected final GroundDisjunctionHeader m_groundDisjunctionHeader;
        protected final int[] m_copyIsCore;
        protected final int[] m_copyValuesToArguments;

        public DeriveDisjunction(Object[] valuesBuffer,boolean[] coreVariables,DependencySet dependencySet,Tableau tableau,GroundDisjunctionHeader groundDisjunctionHeader,int[] copyIsCore,int[] copyValuesToArguments) {
            m_valuesBuffer=valuesBuffer;
            m_coreVariables=coreVariables;
            m_dependencySet=dependencySet;
            m_tableau=tableau;
            m_groundDisjunctionHeader=groundDisjunctionHeader;
            m_copyIsCore=copyIsCore;
            m_copyValuesToArguments=copyValuesToArguments;
        }
        public void clear() {
        }
        public int execute(int programCounter) {
            Node[] arguments=new Node[m_copyValuesToArguments.length];
            for (int argumentIndex=m_copyValuesToArguments.length-1;argumentIndex>=0;--argumentIndex)
                arguments[argumentIndex]=(Node)m_valuesBuffer[m_copyValuesToArguments[argumentIndex]];
            boolean[] isCore=new boolean[m_copyIsCore.length];
            for (int copyIndex=m_copyIsCore.length-1;copyIndex>=0;--copyIndex) {
                int copyFrom=m_copyIsCore[copyIndex];
                if (copyFrom==-1)
                    isCore[copyIndex]=true;
                else
                    isCore[copyIndex]=m_coreVariables[copyFrom];
            }
            GroundDisjunction groundDisjunction=new GroundDisjunction(m_tableau,m_groundDisjunctionHeader,arguments,isCore,m_tableau.m_dependencySetFactory.getPermanent(m_dependencySet));
            if (!groundDisjunction.isSatisfied(m_tableau))
                m_tableau.addGroundDisjunction(groundDisjunction);
            return programCounter+1;
        }
        public String toString() {
            return "Derive disjunction";
        }
    }

    protected static final class DLClauseCompiler {
        protected final DLClauseEvaluator m_dlClauseEvalautor;
        protected final BufferSupply m_bufferSupply;
        protected final ValuesBufferManager m_valuesBufferManager;
        protected final GroundDisjunctionHeaderManager m_groundDisjunctionHeaderManager;
        protected final ExtensionManager m_extensionManager;
        protected final ExistentialExpansionStrategy m_existentialExpansionStrategy;
        protected final DLClause m_bodyDLClause;
        protected final List<DLClause> m_headDLClauses;
        protected final List<Variable> m_variables;
        protected final Set<Variable> m_boundSoFar;
        protected final boolean[] m_coreVariables;
        protected final UnionDependencySet m_unionDependencySet;
        protected final List<ExtensionTable.Retrieval> m_retrievals;
        protected final List<Worker> m_workers;
        protected final List<Integer> m_labels;

        public DLClauseCompiler(BufferSupply bufferSupply,ValuesBufferManager valuesBufferManager,GroundDisjunctionHeaderManager groundDisjunctionHeaderManager,Map<Integer,UnionDependencySet> unionDependencySetsBySize,DLClauseEvaluator dlClauseEvalautor,ExtensionManager extensionManager,ExistentialExpansionStrategy existentialExpansionStrategy,DLClause bodyDLClause,List<DLClause> headDLClauses,ExtensionTable.Retrieval firstAtomRetrieval) {
            m_bufferSupply=bufferSupply;
            m_valuesBufferManager=valuesBufferManager;
            m_groundDisjunctionHeaderManager=groundDisjunctionHeaderManager;
            m_dlClauseEvalautor=dlClauseEvalautor;
            m_extensionManager=extensionManager;
            m_existentialExpansionStrategy=existentialExpansionStrategy;
            m_bodyDLClause=bodyDLClause;
            m_headDLClauses=headDLClauses;
            m_variables=new ArrayList<Variable>();
            int numberOfRealAtoms=0;
            for (int bodyIndex=0;bodyIndex<getBodyLength();bodyIndex++) {
                Atom atom=getBodyAtom(bodyIndex);
                for (int argumentIndex=0;argumentIndex<atom.getArity();argumentIndex++) {
                    Variable variable=atom.getArgumentVariable(argumentIndex);
                    if (variable!=null && !m_variables.contains(variable) && occursInBodyAtomsAfter(variable,bodyIndex+1))
                        m_variables.add(variable);
                }
                if (!atom.getDLPredicate().equals(NodeIDLessEqualThan.INSTANCE) && !(atom.getDLPredicate() instanceof NodeIDsAscendingOrEqual))
                    numberOfRealAtoms++;
            }
            for (int dlClauseIndex=0;dlClauseIndex<getNumberOfHeads();dlClauseIndex++) {
                for (int headIndex=0;headIndex<getHeadLength(dlClauseIndex);headIndex++) {
                    Atom atom=getHeadAtom(dlClauseIndex,headIndex);
                    for (int argumentIndex=0;argumentIndex<atom.getArity();argumentIndex++) {
                        Variable variable=atom.getArgumentVariable(argumentIndex);
                        if (variable!=null && !m_variables.contains(variable))
                            m_variables.add(variable);
                    }
                }
            }
            m_boundSoFar=new HashSet<Variable>();
            m_coreVariables=new boolean[m_variables.size()];
            Integer numberOfRealAtomsInteger=Integer.valueOf(numberOfRealAtoms);
            UnionDependencySet unionDependencySet=unionDependencySetsBySize.get(numberOfRealAtomsInteger);
            if (unionDependencySet==null) {
                unionDependencySet=new UnionDependencySet(numberOfRealAtoms);
                unionDependencySetsBySize.put(numberOfRealAtomsInteger,unionDependencySet);
            }
            m_unionDependencySet=unionDependencySet;
            m_retrievals=new ArrayList<ExtensionTable.Retrieval>();
            m_workers=new ArrayList<Worker>();
            m_labels=new ArrayList<Integer>();
            m_labels.add(null);
            m_retrievals.add(firstAtomRetrieval);
            int afterRule=addLabel();
            compileCheckUnboundVariableMatches(getBodyAtom(0),firstAtomRetrieval,afterRule);
            compileGenerateBindings(firstAtomRetrieval,getBodyAtom(0));
            m_workers.add(new CopyDependencySet(firstAtomRetrieval,m_unionDependencySet.m_dependencySets,0));
            compileBodyAtom(1,afterRule);
            setLabelProgramCounter(afterRule);
            for (Worker worker : m_workers)
                if (worker instanceof BranchingWorker) {
                    BranchingWorker branchingWorker=(BranchingWorker)worker;
                    int branchingAddress=branchingWorker.getBranchingAddress();
                    if (branchingAddress<0) {
                        int resolvedAddress=m_labels.get(-branchingAddress);
                        branchingWorker.setBranchingAddress(resolvedAddress);
                    }
                }
        }
        protected int getNumberOfHeads() {
            return m_headDLClauses.size();
        }
        protected int getBodyLength() {
            return m_bodyDLClause.getBodyLength();
        }
        protected Atom getBodyAtom(int atomIndex) {
            return m_bodyDLClause.getBodyAtom(atomIndex);
        }
        protected int getHeadLength(int dlClauseIndex) {
            return m_headDLClauses.get(dlClauseIndex).getHeadLength();
        }
        protected Atom getHeadAtom(int dlClauseIndex,int atomIndex) {
            return m_headDLClauses.get(dlClauseIndex).getHeadAtom(atomIndex);
        }
        protected boolean occursInBodyAtomsAfter(Variable variable,int startIndex) {
            for (int argumentIndex=startIndex;argumentIndex<getBodyLength();argumentIndex++)
                if (getBodyAtom(argumentIndex).containsVariable(variable))
                    return true;
            return false;
        }
        protected void compileBodyAtom(int bodyAtomIndex,int lastAtomNextElement) {
            if (bodyAtomIndex==getBodyLength()) {
                m_existentialExpansionStrategy.dlClauseBodyCompiled(m_workers,m_bodyDLClause,m_variables,m_valuesBufferManager.m_valuesBuffer,m_coreVariables);
                compileHeads();
            }
            else if (getBodyAtom(bodyAtomIndex).getDLPredicate().equals(NodeIDLessEqualThan.INSTANCE)) {
                Atom atom=getBodyAtom(bodyAtomIndex);
                int variable1Index=m_variables.indexOf(atom.getArgumentVariable(0));
                int variable2Index=m_variables.indexOf(atom.getArgumentVariable(1));
                assert variable1Index!=-1;
                assert variable2Index!=-1;
                m_workers.add(new BranchIfNotNodeIDLessEqualThan(lastAtomNextElement,m_valuesBufferManager.m_valuesBuffer,variable1Index,variable2Index));
                compileBodyAtom(bodyAtomIndex+1,lastAtomNextElement);
            }
            else if (getBodyAtom(bodyAtomIndex).getDLPredicate() instanceof NodeIDsAscendingOrEqual) {
                Atom atom=getBodyAtom(bodyAtomIndex);
                int[] nodeIndexes=new int[atom.getArity()];
                for (int index=0;index<atom.getArity();index++) {
                    nodeIndexes[index]=m_variables.indexOf(atom.getArgumentVariable(index));
                    assert nodeIndexes[index]!=-1;
                }
                m_workers.add(new BranchIfNotNodeIDsAscendingOrEqual(lastAtomNextElement,m_valuesBufferManager.m_valuesBuffer,nodeIndexes));
                compileBodyAtom(bodyAtomIndex+1,lastAtomNextElement);
            }
            else {
                // Each atom is compiled into the following structure:
                //
                //              retrieval.open()
                // loopStart:   if (!retrieval.hasMore) goto afterLoop
                //              if (!retrieval.unboundVariableMatches) goto nextElement
                //              generate bindings - copy bindings from the retrieval to the values buffer
                //              copy the dependency set from the retrieval into the union dependency set
                //                  < the code for the next atom >
                // nextElement: retrieval.next
                //              goto loopStart
                // afterLoop:
                //
                // NodeIDLessEqualThan and NodeIDsAscendingOrEqual atoms are compiled such that they
                // immediately jump to the next element of the previous regular atom.

                int afterLoop=addLabel();
                int nextElement=addLabel();
                Atom atom=getBodyAtom(bodyAtomIndex);
                int[] bindingPositions=new int[atom.getArity()+1];
                bindingPositions[0]=m_valuesBufferManager.m_bodyDLPredicatesToIndexes.get(atom.getDLPredicate()).intValue();
                for (int argumentIndex=0;argumentIndex<atom.getArity();argumentIndex++) {
                    Variable variable=atom.getArgumentVariable(argumentIndex);
                    if (variable!=null && m_boundSoFar.contains(variable))
                        bindingPositions[argumentIndex+1]=m_variables.indexOf(variable);
                    else
                        bindingPositions[argumentIndex+1]=-1;
                }
                ExtensionTable.Retrieval retrieval=m_extensionManager.getExtensionTable(atom.getArity()+1).createRetrieval(bindingPositions,m_valuesBufferManager.m_valuesBuffer,m_bufferSupply.getBuffer(atom.getArity()+1),false,ExtensionTable.View.EXTENSION_THIS);
                m_retrievals.add(retrieval);
                m_workers.add(new OpenRetrieval(retrieval));
                int loopStart=m_workers.size();
                m_workers.add(new HasMoreRetrieval(afterLoop,retrieval));
                compileCheckUnboundVariableMatches(atom,retrieval,nextElement);
                compileGenerateBindings(retrieval,atom);
                m_workers.add(new CopyDependencySet(retrieval,m_unionDependencySet.m_dependencySets,m_retrievals.size()-1));
                compileBodyAtom(bodyAtomIndex+1,nextElement);
                setLabelProgramCounter(nextElement);
                m_workers.add(new NextRetrieval(retrieval));
                m_workers.add(new JumpTo(loopStart));
                setLabelProgramCounter(afterLoop);
            }
        }
        protected void compileHeads() {
            for (int dlClauseIndex=0;dlClauseIndex<getNumberOfHeads();dlClauseIndex++) {
                if (m_extensionManager.m_tableauMonitor!=null)
                    m_workers.add(new CallMatchStartedOnMonitor(m_extensionManager.m_tableauMonitor,m_dlClauseEvalautor,dlClauseIndex));
                if (getHeadLength(dlClauseIndex)==0)
                    m_workers.add(new SetClash(m_extensionManager,m_unionDependencySet));
                else if (getHeadLength(dlClauseIndex)==1) {
                    Atom atom=getHeadAtom(dlClauseIndex,0);
                    switch (atom.getArity()) {
                    case 1:
                        m_workers.add(new DeriveUnaryFact(m_extensionManager,m_valuesBufferManager.m_valuesBuffer,m_coreVariables,m_unionDependencySet,atom.getDLPredicate(),m_variables.indexOf(atom.getArgumentVariable(0))));
                        break;
                    case 2:
                        m_workers.add(new DeriveBinaryFact(m_extensionManager,m_valuesBufferManager.m_valuesBuffer,m_unionDependencySet,atom.getDLPredicate(),m_variables.indexOf(atom.getArgumentVariable(0)),m_variables.indexOf(atom.getArgumentVariable(1))));
                        break;
                    case 3:
                        m_workers.add(new DeriveTernaryFact(m_extensionManager,m_valuesBufferManager.m_valuesBuffer,m_unionDependencySet,atom.getDLPredicate(),m_variables.indexOf(atom.getArgumentVariable(0)),m_variables.indexOf(atom.getArgumentVariable(1)),m_variables.indexOf(atom.getArgumentVariable(2))));
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported atom arity.");
                    }
                }
                else {
                    int totalNumberOfArguments=0;
                    for (int headIndex=0;headIndex<getHeadLength(dlClauseIndex);headIndex++)
                        totalNumberOfArguments+=getHeadAtom(dlClauseIndex,headIndex).getArity();
                    DLPredicate[] headDLPredicates=new DLPredicate[getHeadLength(dlClauseIndex)];
                    int[] copyIsCore=new int[getHeadLength(dlClauseIndex)];
                    int[] copyValuesToArguments=new int[totalNumberOfArguments];
                    int index=0;
                    for (int headIndex=0;headIndex<getHeadLength(dlClauseIndex);headIndex++) {
                        Atom atom=getHeadAtom(dlClauseIndex,headIndex);
                        headDLPredicates[headIndex]=atom.getDLPredicate();
                        for (int argumentIndex=0;argumentIndex<atom.getArity();argumentIndex++) {
                            Variable variable=atom.getArgumentVariable(argumentIndex);
                            int variableIndex=m_variables.indexOf(variable);
                            assert variableIndex!=-1;
                            copyValuesToArguments[index++]=variableIndex;
                        }
                        if (headDLPredicates[headIndex].getArity()==1) {
                            Variable variable=atom.getArgumentVariable(0);
                            copyIsCore[headIndex]=m_variables.indexOf(variable);
                        }
                        else
                            copyIsCore[headIndex]=-1;
                    }
                    GroundDisjunctionHeader groundDisjunctionHeader=m_groundDisjunctionHeaderManager.get(headDLPredicates);
                    m_workers.add(new DeriveDisjunction(m_valuesBufferManager.m_valuesBuffer,m_coreVariables,m_unionDependencySet,m_extensionManager.m_tableau,groundDisjunctionHeader,copyIsCore,copyValuesToArguments));
                }
                if (m_extensionManager.m_tableauMonitor!=null)
                    m_workers.add(new CallMatchFinishedOnMonitor(m_extensionManager.m_tableauMonitor,m_dlClauseEvalautor,dlClauseIndex));
            }
        }
        protected void compileCheckUnboundVariableMatches(Atom atom,ExtensionTable.Retrieval retrieval,int jumpIndex) {
            for (int outerArgumentIndex=0;outerArgumentIndex<atom.getArity();outerArgumentIndex++) {
                Variable variable=atom.getArgumentVariable(outerArgumentIndex);
                if (variable!=null && !m_boundSoFar.contains(variable)) {
                    for (int innerArgumentIndex=outerArgumentIndex+1;innerArgumentIndex<atom.getArity();innerArgumentIndex++) {
                        if (variable.equals(atom.getArgument(innerArgumentIndex)))
                            m_workers.add(new BranchIfNotEqual(jumpIndex,retrieval.getTupleBuffer(),outerArgumentIndex+1,innerArgumentIndex+1));
                    }
                }
            }
        }
        protected void compileGenerateBindings(ExtensionTable.Retrieval retrieval,Atom atom) {
            for (int argumentIndex=0;argumentIndex<atom.getArity();argumentIndex++) {
                Variable variable=atom.getArgumentVariable(argumentIndex);
                if (variable!=null && !m_boundSoFar.contains(variable)) {
                    int variableIndex=m_variables.indexOf(variable);
                    if (variableIndex!=-1) {
                        m_workers.add(new CopyValues(retrieval.getTupleBuffer(),argumentIndex+1,m_valuesBufferManager.m_valuesBuffer,variableIndex));
                        m_boundSoFar.add(variable);
                    }
                }
            }
        }
        protected int addLabel() {
            int labelIndex=m_labels.size();
            m_labels.add(null);
            return -labelIndex;
        }
        protected void setLabelProgramCounter(int labelID) {
            m_labels.set(-labelID,Integer.valueOf(m_workers.size()));
        }
    }
}
TOP

Related Classes of org.semanticweb.HermiT.tableau.DLClauseEvaluator$NextRetrieval

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.