lojix/wam_prolog/src/main/com/thesett/aima/logic/fol/wam/optimizer/OptimizeInstructions.java
public void apply(WAMInstruction next)
    {
        shift(next);

        // Anonymous or singleton variable optimizations.
        if ((UnifyVar == next.getMnemonic()) && isVoidVariable(next))
        {
            if (state != State.UVE)
            {
                voidCount = 0;
            }

            discard((voidCount == 0) ? 1 : 2);

            WAMInstruction unifyVoid = new WAMInstruction(UnifyVoid, WAMInstruction.REG_ADDR, (byte) ++voidCount);
            shift(unifyVoid);
            state = State.UVE;

            /*log.fine(next + " -> " + unifyVoid);*/
        }
        else if ((SetVar == next.getMnemonic()) && isVoidVariable(next))
        {
            if (state != State.SVE)
            {
                voidCount = 0;
            }

            discard((voidCount == 0) ? 1 : 2);

            WAMInstruction setVoid = new WAMInstruction(SetVoid, WAMInstruction.REG_ADDR, (byte) ++voidCount);
            shift(setVoid);
            state = State.SVE;

            /*log.fine(next + " -> " + setVoid);*/
        }
        else if ((GetVar == next.getMnemonic()) && (next.getMode1() == WAMInstruction.REG_ADDR) &&
                (next.getReg1() == next.getReg2()))
        {
            discard(1);

            /*log.fine(next + " -> eliminated");*/

            state = State.NM;
        }

        // Constant optimizations.
        else if ((UnifyVar == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);

            FunctorName functorName = interner.getDeinternedFunctorName(next.getFunctorNameReg1());
            WAMInstruction unifyConst = new WAMInstruction(UnifyConstant, functorName);
            shift(unifyConst);
            flush();
            state = State.NM;

            /*log.fine(next + " -> " + unifyConst);*/
        }
        else if ((GetStruc == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
            state = State.NM;

            /*log.fine(next + " -> eliminated");*/
        }
        else if ((GetStruc == next.getMnemonic()) && isConstant(next) && !isNonArg(next))
        {
            discard(1);

            WAMInstruction getConst = new WAMInstruction(GetConstant, next.getMode1(), next.getReg1(), next.getFn());
            shift(getConst);
            flush();
            state = State.NM;

            /*log.fine(next + " -> " + getConst);*/
        }
        else if ((PutStruc == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
            state = State.NM;

            /*log.fine(next + " -> eliminated");*/
        }
        else if ((PutStruc == next.getMnemonic()) && isConstant(next) && !isNonArg(next))
        {
            discard(1);

            WAMInstruction putConst = new WAMInstruction(PutConstant, next.getMode1(), next.getReg1(), next.getFn());
            shift(putConst);
            state = State.NM;

            /*log.fine(next + " -> " + putConst);*/
        }
        else if ((SetVal == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);

            FunctorName functorName = interner.getDeinternedFunctorName(next.getFunctorNameReg1());
            WAMInstruction setConst = new WAMInstruction(SetConstant, functorName);
            shift(setConst);
            flush();
            state = State.NM;

            /*log.fine(next + " -> " + setConst);*/
        }

        // List optimizations.
        else if ((GetStruc == next.getMnemonic()) &&
                ("cons".equals(next.getFn().getName()) && (next.getFn().getArity() == 2)))
        {
            discard(1);

            WAMInstruction getList = new WAMInstruction(GetList, next.getMode1(), next.getReg1());
            shift(getList);
            state = State.NM;

            /*log.fine(next + " -> " + getList);*/
        }
        else if ((PutStruc == next.getMnemonic()) &&
                ("cons".equals(next.getFn().getName()) && (next.getFn().getArity() == 2)))
        {
            discard(1);

            WAMInstruction putList = new WAMInstruction(PutList, next.getMode1(), next.getReg1());
            shift(putList);
            state = State.NM;

            /*log.fine(next + " -> " + putList);*/
        }

        // Default.
        else
        {
            state = State.NM;
            flush();
        }
    }
public void apply(WAMInstruction next)
    {
        shift(next);

        // Anonymous or singleton variable optimizations.
        if ((UnifyVar == next.getMnemonic()) && isVoidVariable(next))
        {
            if (state != State.UVE)
            {
                voidCount = 0;
            }

            discard((voidCount == 0) ? 1 : 2);

            WAMInstruction unifyVoid = new WAMInstruction(UnifyVoid, WAMInstruction.REG_ADDR, (byte) ++voidCount);
            shift(unifyVoid);
            state = State.UVE;

            /*log.fine(next + " -> " + unifyVoid);*/
        }
        else if ((SetVar == next.getMnemonic()) && isVoidVariable(next))
        {
            if (state != State.SVE)
            {
                voidCount = 0;
            }

            discard((voidCount == 0) ? 1 : 2);

            WAMInstruction setVoid = new WAMInstruction(SetVoid, WAMInstruction.REG_ADDR, (byte) ++voidCount);
            shift(setVoid);
            state = State.SVE;

            /*log.fine(next + " -> " + setVoid);*/
        }
        else if ((GetVar == next.getMnemonic()) && (next.getMode1() == WAMInstruction.REG_ADDR) &&
                (next.getReg1() == next.getReg2()))
        {
            discard(1);

            /*log.fine(next + " -> eliminated");*/

            state = State.NM;
        }

        // Constant optimizations.
        else if ((UnifyVar == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);

            FunctorName functorName = interner.getDeinternedFunctorName(next.getFunctorNameReg1());
            WAMInstruction unifyConst = new WAMInstruction(UnifyConstant, functorName);
            shift(unifyConst);
            flush();
            state = State.NM;

            /*log.fine(next + " -> " + unifyConst);*/
        }
        else if ((GetStruc == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
            state = State.NM;

            /*log.fine(next + " -> eliminated");*/
        }
        else if ((GetStruc == next.getMnemonic()) && isConstant(next) && !isNonArg(next))
        {
            discard(1);

            WAMInstruction getConst = new WAMInstruction(GetConstant, next.getMode1(), next.getReg1(), next.getFn());
            shift(getConst);
            flush();
            state = State.NM;

            /*log.fine(next + " -> " + getConst);*/
        }
        else if ((PutStruc == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);
            state = State.NM;

            /*log.fine(next + " -> eliminated");*/
        }
        else if ((PutStruc == next.getMnemonic()) && isConstant(next) && !isNonArg(next))
        {
            discard(1);

            WAMInstruction putConst = new WAMInstruction(PutConstant, next.getMode1(), next.getReg1(), next.getFn());
            shift(putConst);
            state = State.NM;

            /*log.fine(next + " -> " + putConst);*/
        }
        else if ((SetVal == next.getMnemonic()) && isConstant(next) && isNonArg(next))
        {
            discard(1);

            FunctorName functorName = interner.getDeinternedFunctorName(next.getFunctorNameReg1());
            WAMInstruction setConst = new WAMInstruction(SetConstant, functorName);
            shift(setConst);
            flush();
            state = State.NM;

            /*log.fine(next + " -> " + setConst);*/
        }

        // List optimizations.
        else if ((GetStruc == next.getMnemonic()) &&
                ("cons".equals(next.getFn().getName()) && (next.getFn().getArity() == 2)))
        {
            discard(1);

            WAMInstruction getList = new WAMInstruction(GetList, next.getMode1(), next.getReg1());
            shift(getList);
            state = State.NM;

            /*log.fine(next + " -> " + getList);*/
        }
        else if ((PutStruc == next.getMnemonic()) &&
                ("cons".equals(next.getFn().getName()) && (next.getFn().getArity() == 2)))
        {
            discard(1);

            WAMInstruction putList = new WAMInstruction(PutList, next.getMode1(), next.getReg1());
            shift(putList);
            state = State.NM;

            /*log.fine(next + " -> " + putList);*/
        }

        // Default.
        else
        {
            state = State.NM;
            flush();
        }
    }
{@inheritDoc}