lojix/wam_prolog/src/main/com/thesett/aima/logic/fol/wam/machine/WAMResolvingMachine.java
protected Term decodeHeap(int start, Map<Integer, Variable> variableContext)
    {
        /*log.fine("private Term decodeHeap(int start = " + start + ", Map<Integer, Variable> variableContext = " +
            variableContext + "): called");*/

        // Used to hold the decoded argument in.
        Term result = null;

        // Dereference the initial heap pointer.
        int addr = deref(start);
        byte tag = getDerefTag();
        int val = getDerefVal();

        /*log.fine("addr = " + addr);*/
        /*log.fine("tag = " + tag);*/
        /*log.fine("val = " + val);*/

        switch (tag)
        {
        case REF:
        {
            // Check if a variable for the address has already been created in this context, and use it if so.
            Variable var = variableContext.get(val);

            if (var == null)
            {
                var = new Variable(varNameId.decrementAndGet(), null, false);

                variableContext.put(val, var);
            }

            result = var;

            break;
        }

        case STR:
        {
            // Decode f/n from the STR data.
            int fn = getHeap(val);
            int f = fn & 0x00ffffff;

            /*log.fine("fn = " + fn);*/
            /*log.fine("f = " + f);*/

            // Look up and initialize this functor name from the symbol table.
            FunctorName functorName = getDeinternedFunctorName(f);

            // Fill in this functors name and arity and allocate storage space for its arguments.
            int arity = functorName.getArity();
            Term[] arguments = new Term[arity];

            // Loop over all of the functors arguments, recursively decoding them.
            for (int i = 0; i < arity; i++)
            {
                arguments[i] = decodeHeap(val + 1 + i, variableContext);
            }

            // Create a new functor to hold the decoded data.
            result = new Functor(f, arguments);

            break;
        }

        case WAMInstruction.CON:
        {
            //Decode f/n from the CON data.
            int f = val & 0x3fffffff;

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

            // Create a new functor to hold the decoded data.
            result = new Functor(f, null);

            break;
        }

        case WAMInstruction.LIS:
        {
            FunctorName functorName = new FunctorName("cons", 2);
            int f = internFunctorName(functorName);

            // Fill in this functors name and arity and allocate storage space for its arguments.
            int arity = functorName.getArity();
            Term[] arguments = new Term[arity];

            // Loop over all of the functors arguments, recursively decoding them.
            for (int i = 0; i < arity; i++)
            {
                arguments[i] = decodeHeap(val + i, variableContext);
            }

            // Create a new functor to hold the decoded data.
            result = new Functor(f, arguments);

            break;
        }

        default:
            throw new IllegalStateException("Encountered unknown tag type on the heap.");
        }

        return result;
    }
protected Term decodeHeap(int start, Map<Integer, Variable> variableContext)
    {
        /*log.fine("private Term decodeHeap(int start = " + start + ", Map<Integer, Variable> variableContext = " +
            variableContext + "): called");*/

        // Used to hold the decoded argument in.
        Term result = null;

        // Dereference the initial heap pointer.
        int addr = deref(start);
        byte tag = getDerefTag();
        int val = getDerefVal();

        /*log.fine("addr = " + addr);*/
        /*log.fine("tag = " + tag);*/
        /*log.fine("val = " + val);*/

        switch (tag)
        {
        case REF:
        {
            // Check if a variable for the address has already been created in this context, and use it if so.
            Variable var = variableContext.get(val);

            if (var == null)
            {
                var = new Variable(varNameId.decrementAndGet(), null, false);

                variableContext.put(val, var);
            }

            result = var;

            break;
        }

        case STR:
        {
            // Decode f/n from the STR data.
            int fn = getHeap(val);
            int f = fn & 0x00ffffff;

            /*log.fine("fn = " + fn);*/
            /*log.fine("f = " + f);*/

            // Look up and initialize this functor name from the symbol table.
            FunctorName functorName = getDeinternedFunctorName(f);

            // Fill in this functors name and arity and allocate storage space for its arguments.
            int arity = functorName.getArity();
            Term[] arguments = new Term[arity];

            // Loop over all of the functors arguments, recursively decoding them.
            for (int i = 0; i < arity; i++)
            {
                arguments[i] = decodeHeap(val + 1 + i, variableContext);
            }

            // Create a new functor to hold the decoded data.
            result = new Functor(f, arguments);

            break;
        }

        case WAMInstruction.CON:
        {
            //Decode f/n from the CON data.
            int f = val & 0x3fffffff;

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

            // Create a new functor to hold the decoded data.
            result = new Functor(f, null);

            break;
        }

        case WAMInstruction.LIS:
        {
            FunctorName functorName = new FunctorName("cons", 2);
            int f = internFunctorName(functorName);

            // Fill in this functors name and arity and allocate storage space for its arguments.
            int arity = functorName.getArity();
            Term[] arguments = new Term[arity];

            // Loop over all of the functors arguments, recursively decoding them.
            for (int i = 0; i < arity; i++)
            {
                arguments[i] = decodeHeap(val + i, variableContext);
            }

            // Create a new functor to hold the decoded data.
            result = new Functor(f, arguments);

            break;
        }

        default:
            throw new IllegalStateException("Encountered unknown tag type on the heap.");
        }

        return result;
    }
Decodes a term from the raw byte representation on the machines heap, into an abstract syntax tree.

@param  start           The start offset of the term on the heap.
@param  variableContext The variable context for the decoded variables. This may be shared amongst all variables
decoded for a particular unifcation.

@return The term decoded from its heap representation.