Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright The Sett Ltd, 2005 to 2014.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.thesett.aima.logic.fol.wam.optimizer;
 
 import static java.lang.Boolean.TRUE;
 
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.GetConstant;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.GetList;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.GetStruc;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.GetVar;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.PutConstant;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.PutList;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.PutStruc;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.SetConstant;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.SetVal;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.SetVar;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.SetVoid;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.UnifyConstant;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.UnifyVar;
 import static com.thesett.aima.logic.fol.wam.compiler.WAMInstruction.WAMInstructionSet.UnifyVoid;
Performs an optimization pass for specialized constant instructions.

CRC Card
Responsibilities Collaborations
Optimize constant instructions in the head of a clause.

Author(s):
Rupert Smith
 
 {
    
Used for debugging.
 
     private static final java.util.logging.Logger log =
         java.util.logging.Logger.getLogger(OptimizeInstructions.class.getName());

    
Defines the possible states that this state machine can be in.
 
     private enum State
     {
        
No Match.
 
         NM,

        
UnifyVar to UnifyVoid elimination.
 
         UVE,

        
SetVar to SetVoid elimination.
 
         SVE;
     }

    
Holds the matcher that is driving this state machine.
 
     private Matcher<WAMInstructionWAMInstructionmatcher;

    
Holds the current state machine state.
 
     private State state = .;

    
Holds a buffer of pending instructions to output.
 
     private LinkedList<WAMInstructionbuffer = new LinkedList<WAMInstruction>();

    
The symbol table.
 
     protected final SymbolTable<IntegerStringObjectsymbolTable;

    
Holds the variable and functor name interner for the machine.
 
     private final VariableAndFunctorInterner interner;

    
Counts the number of void variables seen in a row.
 
     private int voidCount = 0;

    
Builds an instruction optimizer.

Parameters:
symbolTable The symbol table to get instruction analysis from.
interner The functor and variable name interner.
 
     public OptimizeInstructions(SymbolTable<IntegerStringObjectsymbolTableVariableAndFunctorInterner interner)
     {
         this. = symbolTable;
         this. = interner;
     }

    
    public void apply(WAMInstruction next)
    {
        shift(next);
        // Anonymous or singleton variable optimizations.
        if (( == next.getMnemonic()) && isVoidVariable(next))
        {
            if ( != .)
            {
                 = 0;
            }
            discard(( == 0) ? 1 : 2);
            WAMInstruction unifyVoid = new WAMInstruction(., (byte) ++);
            shift(unifyVoid);
             = .;
            .fine(next + " -> " + unifyVoid);
        }
        else if (( == next.getMnemonic()) && isVoidVariable(next))
        {
            if ( != .)
            {
                 = 0;
            }
            discard(( == 0) ? 1 : 2);
            WAMInstruction setVoid = new WAMInstruction(., (byte) ++);
            shift(setVoid);
             = .;
            .fine(next + " -> " + setVoid);
        }
        else if (( == next.getMnemonic()) && (next.getMode1() == .) &&
                (next.getReg1() == next.getReg2()))
        {
            discard(1);
            .fine(next + " -> eliminated");
             = .;
        }
        // Constant optimizations.
        else if (( == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
            FunctorName functorName = .getDeinternedFunctorName(next.getFunctorNameReg1());
            WAMInstruction unifyConst = new WAMInstruction(functorName);
            shift(unifyConst);
            flush();
             = .;
            .fine(next + " -> " + unifyConst);
        }
        else if (( == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
             = .;
            .fine(next + " -> eliminated");
        }
        else if (( == next.getMnemonic()) && isConstant(next) && !isNonArg(next))
        {
            discard(1);
            WAMInstruction getConst = new WAMInstruction(next.getMode1(), next.getReg1(), next.getFn());
            shift(getConst);
            flush();
             = .;
            .fine(next + " -> " + getConst);
        }
        else if (( == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
             = .;
            .fine(next + " -> eliminated");
        }
        else if (( == next.getMnemonic()) && isConstant(next) && !isNonArg(next))
        {
            discard(1);
            WAMInstruction putConst = new WAMInstruction(next.getMode1(), next.getReg1(), next.getFn());
            shift(putConst);
             = .;
            .fine(next + " -> " + putConst);
        }
        else if (( == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
            FunctorName functorName = .getDeinternedFunctorName(next.getFunctorNameReg1());
            WAMInstruction setConst = new WAMInstruction(functorName);
            shift(setConst);
            flush();
             = .;
            .fine(next + " -> " + setConst);
        }
        // List optimizations.
        else if (( == next.getMnemonic()) &&
                ("cons".equals(next.getFn().getName()) && (next.getFn().getArity() == 2)))
        {
            discard(1);
            WAMInstruction getList = new WAMInstruction(next.getMode1(), next.getReg1());
            shift(getList);
             = .;
            .fine(next + " -> " + getList);
        }
        else if (( == next.getMnemonic()) &&
                ("cons".equals(next.getFn().getName()) && (next.getFn().getArity() == 2)))
        {
            discard(1);
            WAMInstruction putList = new WAMInstruction(next.getMode1(), next.getReg1());
            shift(putList);
             = .;
            .fine(next + " -> " + putList);
        }
        // Default.
        else
        {
             = .;
            flush();
        }
    }

    
    public void end()
    {
        flush();
    }

    
    public void setMatcher(Matcher<WAMInstructionWAMInstructionmatcher)
    {
        this. = matcher;
    }

    
Checks if the term argument to an instruction was a constant.

Parameters:
instruction The instruction to test.
Returns:
true iff the term argument to an instruction was a constant. false will be returned if this information was not recorded, and cannot be determined.
    public boolean isConstant(WAMInstruction instruction)
    {
        Integer name = instruction.getFunctorNameReg1();
        if (name != null)
        {
            FunctorName functorName = .getDeinternedFunctorName(name);
            if (functorName.getArity() == 0)
            {
                return true;
            }
        }
        return false;
    }

    
Checks if the term argument to an instruction was a singleton, non-argument position variable. The variable must also be non-permanent to ensure that singleton variables in queries are created.

Parameters:
instruction The instruction to test.
Returns:
true iff the term argument to the instruction was a singleton, non-argument position variable.
    private boolean isVoidVariable(WAMInstruction instruction)
    {
        SymbolKey symbolKey = instruction.getSymbolKeyReg1();
        if (symbolKey != null)
        {
            Integer count = (Integer.get(symbolKey.);
            Boolean nonArgPositionOnly = (Boolean.get(symbolKey.);
            Integer allocation = (Integer.get(symbolKey.);
            boolean singleton = (count != null) && count.equals(1);
            boolean nonArgPosition = (nonArgPositionOnly != null) && .equals(nonArgPositionOnly);
            boolean permanent =
                (allocation != null) && ((byte) ((allocation & 0xff00) >> 8) == .);
            if (singleton && nonArgPosition && !permanent)
            {
                return true;
            }
        }
        return false;
    }

    
Checks if the term argument to an instruction was in a non-argument position.

Parameters:
instruction The instruction to test.
Returns:
true iff the term argument to an instruction was in a non-argument position. false will be returned if this information was not recorded, and cannot be determined.
    private boolean isNonArg(WAMInstruction instruction)
    {
        SymbolKey symbolKey = instruction.getSymbolKeyReg1();
        if (symbolKey != null)
        {
            Boolean nonArgPositionOnly = (Boolean.get(symbolKey.);
            if (.equals(nonArgPositionOnly))
            {
                return true;
            }
        }
        return false;
    }

    
Discards the specified number of most recent instructions from the output buffer.

Parameters:
n The number of instructions to discard.
    private void discard(int n)
    {
        for (int i = 0; i < ni++)
        {
            .pollLast();
        }
    }

    
Adds an instruction to the output buffer.

Parameters:
instruction The instruction to add.
    private void shift(WAMInstruction instruction)
    {
        .offer(instruction);
    }

    
Flushes the output buffer.
    private void flush()
    {
        .sinkAll();
    }
New to GrepCode? Check out our FAQ X