lojix/wam_prolog/src/main/com/thesett/aima/logic/fol/wam/compiler/InstructionCompiler.java
private SizeableLinkedList<WAMInstruction> compileHead(Functor expression)
    {
        // Used to build up the results in.
        SizeableLinkedList<WAMInstruction> instructions = new SizeableLinkedList<WAMInstruction>();

        // Allocate argument registers on the body, to all functors as outermost arguments.
        // Allocate temporary registers on the body, to all terms not already allocated.
        allocateArgumentRegisters(expression);
        allocateTemporaryRegisters(expression);

        // Program instructions are generated in the same order as the registers are assigned, the postfix
        // ordering used for queries is not needed.
        SearchMethod outInSearch = new BreadthFirstSearch<Term, Term>();
        outInSearch.reset();
        outInSearch.addStartState(expression);

        Iterator<Term> treeWalker = Searches.allSolutions(outInSearch);

        // Skip the outermost functor.
        treeWalker.next();

        // Allocate argument registers on the body, to all functors as outermost arguments.
        // Allocate temporary registers on the body, to all terms not already allocated.

        // Keep track of processing of the arguments to the outermost functor as get_val and get_var instructions
        // need to be output for variables encountered in the arguments only.
        int numOutermostArgs = expression.getArity();

        for (int j = 0; treeWalker.hasNext(); j++)
        {
            Term nextTerm = treeWalker.next();

            /*log.fine("nextTerm = " + nextTerm);*/

            // For each functor encountered: get_struc.
            if (nextTerm.isFunctor())
            {
                Functor nextFunctor = (Functor) nextTerm;
                int allocation =
                    (Integer) symbolTable.get(nextFunctor.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION);

                byte addrMode = (byte) ((allocation & 0xff00) >> 8);
                byte address = (byte) (allocation & 0xff);

                // Ouput a get_struc instruction, except on the outermost functor.
                /*log.fine("GET_STRUC " + interner.getFunctorName(nextFunctor) + "/" + nextFunctor.getArity() +
                    ((addrMode == REG_ADDR) ? ", X" : ", Y") + address);*/

                WAMInstruction instruction =
                    new WAMInstruction(WAMInstruction.WAMInstructionSet.GetStruc, addrMode, address,
                        interner.getFunctorFunctorName(nextFunctor), nextFunctor);
                instructions.add(instruction);

                // For each argument of the functor.
                int numArgs = nextFunctor.getArity();

                for (int i = 0; i < numArgs; i++)
                {
                    Term nextArg = nextFunctor.getArgument(i);
                    allocation = (Integer) symbolTable.get(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION);
                    addrMode = (byte) ((allocation & 0xff00) >> 8);
                    address = (byte) (allocation & 0xff);

                    /*log.fine("nextArg = " + nextArg);*/

                    // If it is register not seen before: unify_var.
                    // If it is register seen before: unify_val.
                    if (!seenRegisters.contains(allocation))
                    {
                        /*log.fine("UNIFY_VAR " + ((addrMode == REG_ADDR) ? "X" : "Y") + address);*/

                        seenRegisters.add(allocation);

                        instruction =
                            new WAMInstruction(WAMInstruction.WAMInstructionSet.UnifyVar, addrMode, address, nextArg);

                        // Record the way in which this variable was introduced into the clause.
                        symbolTable.put(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO,
                            VarIntroduction.Unify);
                    }
                    else
                    {
                        // Check if the variable is 'local' and use a local instruction on the first occurrence.
                        VarIntroduction introduction =
                            (VarIntroduction) symbolTable.get(nextArg.getSymbolKey(),
                                SymbolTableKeys.SYMKEY_VARIABLE_INTRO);

                        if (isLocalVariable(introduction, addrMode))
                        {
                            /*log.fine("UNIFY_LOCAL_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") +
                                address);*/

                            instruction =
                                new WAMInstruction(WAMInstruction.WAMInstructionSet.UnifyLocalVal, addrMode, address,
                                    nextArg);

                            symbolTable.put(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, null);
                        }
                        else
                        {
                            /*log.fine("UNIFY_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") + address);*/

                            instruction =
                                new WAMInstruction(WAMInstruction.WAMInstructionSet.UnifyVal, addrMode, address,
                                    nextArg);
                        }
                    }

                    instructions.add(instruction);
                }
            }
            else if (j < numOutermostArgs)
            {
                Term nextVar = (Variable) nextTerm;
                int allocation = (Integer) symbolTable.get(nextVar.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION);
                byte addrMode = (byte) ((allocation & 0xff00) >> 8);
                byte address = (byte) (allocation & 0xff);

                WAMInstruction instruction;

                // If it is register not seen before: get_var.
                // If it is register seen before: get_val.
                if (!seenRegisters.contains(allocation))
                {
                    /*log.fine("GET_VAR " + ((addrMode == REG_ADDR) ? "X" : "Y") + address + ", A" + j);*/

                    seenRegisters.add(allocation);

                    instruction =
                        new WAMInstruction(WAMInstruction.WAMInstructionSet.GetVar, addrMode, address,
                            (byte) (j & 0xff));

                    // Record the way in which this variable was introduced into the clause.
                    symbolTable.put(nextVar.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, VarIntroduction.Get);
                }
                else
                {
                    /*log.fine("GET_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") + address + ", A" + j);*/

                    instruction =
                        new WAMInstruction(WAMInstruction.WAMInstructionSet.GetVal, addrMode, address,
                            (byte) (j & 0xff));
                }

                instructions.add(instruction);
            }
        }

        return instructions;
    }
private SizeableLinkedList<WAMInstruction> compileHead(Functor expression)
    {
        // Used to build up the results in.
        SizeableLinkedList<WAMInstruction> instructions = new SizeableLinkedList<WAMInstruction>();

        // Allocate argument registers on the body, to all functors as outermost arguments.
        // Allocate temporary registers on the body, to all terms not already allocated.
        allocateArgumentRegisters(expression);
        allocateTemporaryRegisters(expression);

        // Program instructions are generated in the same order as the registers are assigned, the postfix
        // ordering used for queries is not needed.
        SearchMethod outInSearch = new BreadthFirstSearch<Term, Term>();
        outInSearch.reset();
        outInSearch.addStartState(expression);

        Iterator<Term> treeWalker = Searches.allSolutions(outInSearch);

        // Skip the outermost functor.
        treeWalker.next();

        // Allocate argument registers on the body, to all functors as outermost arguments.
        // Allocate temporary registers on the body, to all terms not already allocated.

        // Keep track of processing of the arguments to the outermost functor as get_val and get_var instructions
        // need to be output for variables encountered in the arguments only.
        int numOutermostArgs = expression.getArity();

        for (int j = 0; treeWalker.hasNext(); j++)
        {
            Term nextTerm = treeWalker.next();

            /*log.fine("nextTerm = " + nextTerm);*/

            // For each functor encountered: get_struc.
            if (nextTerm.isFunctor())
            {
                Functor nextFunctor = (Functor) nextTerm;
                int allocation =
                    (Integer) symbolTable.get(nextFunctor.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION);

                byte addrMode = (byte) ((allocation & 0xff00) >> 8);
                byte address = (byte) (allocation & 0xff);

                // Ouput a get_struc instruction, except on the outermost functor.
                /*log.fine("GET_STRUC " + interner.getFunctorName(nextFunctor) + "/" + nextFunctor.getArity() +
                    ((addrMode == REG_ADDR) ? ", X" : ", Y") + address);*/

                WAMInstruction instruction =
                    new WAMInstruction(WAMInstruction.WAMInstructionSet.GetStruc, addrMode, address,
                        interner.getFunctorFunctorName(nextFunctor), nextFunctor);
                instructions.add(instruction);

                // For each argument of the functor.
                int numArgs = nextFunctor.getArity();

                for (int i = 0; i < numArgs; i++)
                {
                    Term nextArg = nextFunctor.getArgument(i);
                    allocation = (Integer) symbolTable.get(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION);
                    addrMode = (byte) ((allocation & 0xff00) >> 8);
                    address = (byte) (allocation & 0xff);

                    /*log.fine("nextArg = " + nextArg);*/

                    // If it is register not seen before: unify_var.
                    // If it is register seen before: unify_val.
                    if (!seenRegisters.contains(allocation))
                    {
                        /*log.fine("UNIFY_VAR " + ((addrMode == REG_ADDR) ? "X" : "Y") + address);*/

                        seenRegisters.add(allocation);

                        instruction =
                            new WAMInstruction(WAMInstruction.WAMInstructionSet.UnifyVar, addrMode, address, nextArg);

                        // Record the way in which this variable was introduced into the clause.
                        symbolTable.put(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO,
                            VarIntroduction.Unify);
                    }
                    else
                    {
                        // Check if the variable is 'local' and use a local instruction on the first occurrence.
                        VarIntroduction introduction =
                            (VarIntroduction) symbolTable.get(nextArg.getSymbolKey(),
                                SymbolTableKeys.SYMKEY_VARIABLE_INTRO);

                        if (isLocalVariable(introduction, addrMode))
                        {
                            /*log.fine("UNIFY_LOCAL_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") +
                                address);*/

                            instruction =
                                new WAMInstruction(WAMInstruction.WAMInstructionSet.UnifyLocalVal, addrMode, address,
                                    nextArg);

                            symbolTable.put(nextArg.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, null);
                        }
                        else
                        {
                            /*log.fine("UNIFY_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") + address);*/

                            instruction =
                                new WAMInstruction(WAMInstruction.WAMInstructionSet.UnifyVal, addrMode, address,
                                    nextArg);
                        }
                    }

                    instructions.add(instruction);
                }
            }
            else if (j < numOutermostArgs)
            {
                Term nextVar = (Variable) nextTerm;
                int allocation = (Integer) symbolTable.get(nextVar.getSymbolKey(), SymbolTableKeys.SYMKEY_ALLOCATION);
                byte addrMode = (byte) ((allocation & 0xff00) >> 8);
                byte address = (byte) (allocation & 0xff);

                WAMInstruction instruction;

                // If it is register not seen before: get_var.
                // If it is register seen before: get_val.
                if (!seenRegisters.contains(allocation))
                {
                    /*log.fine("GET_VAR " + ((addrMode == REG_ADDR) ? "X" : "Y") + address + ", A" + j);*/

                    seenRegisters.add(allocation);

                    instruction =
                        new WAMInstruction(WAMInstruction.WAMInstructionSet.GetVar, addrMode, address,
                            (byte) (j & 0xff));

                    // Record the way in which this variable was introduced into the clause.
                    symbolTable.put(nextVar.getSymbolKey(), SymbolTableKeys.SYMKEY_VARIABLE_INTRO, VarIntroduction.Get);
                }
                else
                {
                    /*log.fine("GET_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") + address + ", A" + j);*/

                    instruction =
                        new WAMInstruction(WAMInstruction.WAMInstructionSet.GetVal, addrMode, address,
                            (byte) (j & 0xff));
                }

                instructions.add(instruction);
            }
        }

        return instructions;
    }
private SizeableLinkedList < WAMInstruction > compileHead ( Functor expression ) { // Used to build up the results in. SizeableLinkedList < WAMInstruction > instructions = new SizeableLinkedList < WAMInstruction > ( ) ; // Allocate argument registers on the body, to all functors as outermost arguments. // Allocate temporary registers on the body, to all terms not already allocated. allocateArgumentRegisters ( expression ) ; allocateTemporaryRegisters ( expression ) ; // Program instructions are generated in the same order as the registers are assigned, the postfix // ordering used for queries is not needed. SearchMethod outInSearch = new BreadthFirstSearch < Term , Term > ( ) ; outInSearch . reset ( ) ; outInSearch . addStartState ( expression ) ; Iterator < Term > treeWalker = Searches . allSolutions ( outInSearch ) ; // Skip the outermost functor. treeWalker . next ( ) ; // Allocate argument registers on the body, to all functors as outermost arguments. // Allocate temporary registers on the body, to all terms not already allocated. // Keep track of processing of the arguments to the outermost functor as get_val and get_var instructions // need to be output for variables encountered in the arguments only. int numOutermostArgs = expression . getArity ( ) ; for ( int j = 0 ; treeWalker . hasNext ( ) ; j ++ ) { Term nextTerm = treeWalker . next ( ) ; /*log.fine("nextTerm = " + nextTerm);*/ // For each functor encountered: get_struc. if ( nextTerm . isFunctor ( ) ) { Functor nextFunctor = ( Functor ) nextTerm ; int allocation = ( Integer ) symbolTable . get ( nextFunctor . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_ALLOCATION ) ; byte addrMode = ( byte ) ( ( allocation & 0xff00 ) >> 8 ) ; byte address = ( byte ) ( allocation & 0xff ) ; // Ouput a get_struc instruction, except on the outermost functor. /*log.fine("GET_STRUC " + interner.getFunctorName(nextFunctor) + "/" + nextFunctor.getArity() +
                    ((addrMode == REG_ADDR) ? ", X" : ", Y") + address);*/ WAMInstruction instruction = new WAMInstruction ( WAMInstruction . WAMInstructionSet . GetStruc , addrMode , address , interner . getFunctorFunctorName ( nextFunctor ) , nextFunctor ) ; instructions . add ( instruction ) ; // For each argument of the functor. int numArgs = nextFunctor . getArity ( ) ; for ( int i = 0 ; i < numArgs ; i ++ ) { Term nextArg = nextFunctor . getArgument ( i ) ; allocation = ( Integer ) symbolTable . get ( nextArg . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_ALLOCATION ) ; addrMode = ( byte ) ( ( allocation & 0xff00 ) >> 8 ) ; address = ( byte ) ( allocation & 0xff ) ; /*log.fine("nextArg = " + nextArg);*/ // If it is register not seen before: unify_var. // If it is register seen before: unify_val. if ( ! seenRegisters . contains ( allocation ) ) { /*log.fine("UNIFY_VAR " + ((addrMode == REG_ADDR) ? "X" : "Y") + address);*/ seenRegisters . add ( allocation ) ; instruction = new WAMInstruction ( WAMInstruction . WAMInstructionSet . UnifyVar , addrMode , address , nextArg ) ; // Record the way in which this variable was introduced into the clause. symbolTable . put ( nextArg . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_VARIABLE_INTRO , VarIntroduction . Unify ) ; } else { // Check if the variable is 'local' and use a local instruction on the first occurrence. VarIntroduction introduction = ( VarIntroduction ) symbolTable . get ( nextArg . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_VARIABLE_INTRO ) ; if ( isLocalVariable ( introduction , addrMode ) ) { /*log.fine("UNIFY_LOCAL_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") +
                                address);*/ instruction = new WAMInstruction ( WAMInstruction . WAMInstructionSet . UnifyLocalVal , addrMode , address , nextArg ) ; symbolTable . put ( nextArg . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_VARIABLE_INTRO , null ) ; } else { /*log.fine("UNIFY_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") + address);*/ instruction = new WAMInstruction ( WAMInstruction . WAMInstructionSet . UnifyVal , addrMode , address , nextArg ) ; } } instructions . add ( instruction ) ; } } else if ( j < numOutermostArgs ) { Term nextVar = ( Variable ) nextTerm ; int allocation = ( Integer ) symbolTable . get ( nextVar . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_ALLOCATION ) ; byte addrMode = ( byte ) ( ( allocation & 0xff00 ) >> 8 ) ; byte address = ( byte ) ( allocation & 0xff ) ; WAMInstruction instruction ; // If it is register not seen before: get_var. // If it is register seen before: get_val. if ( ! seenRegisters . contains ( allocation ) ) { /*log.fine("GET_VAR " + ((addrMode == REG_ADDR) ? "X" : "Y") + address + ", A" + j);*/ seenRegisters . add ( allocation ) ; instruction = new WAMInstruction ( WAMInstruction . WAMInstructionSet . GetVar , addrMode , address , ( byte ) ( j & 0xff ) ) ; // Record the way in which this variable was introduced into the clause. symbolTable . put ( nextVar . getSymbolKey ( ) , SymbolTableKeys . SYMKEY_VARIABLE_INTRO , VarIntroduction . Get ) ; } else { /*log.fine("GET_VAL " + ((addrMode == REG_ADDR) ? "X" : "Y") + address + ", A" + j);*/ instruction = new WAMInstruction ( WAMInstruction . WAMInstructionSet . GetVal , addrMode , address , ( byte ) ( j & 0xff ) ) ; } instructions . add ( instruction ) ; } } return instructions ; }
Compiles the head of a clause into an instruction listing in WAM.

@param  expression The clause head to compile.

@return A listing of the instructions for the clause head in the WAM instruction set.
Compiles the head of a clause into an instruction listing in WAM .