lojix/wam_prolog/src/main/com/thesett/aima/logic/fol/wam/builtins/Disjunction.java
public SizeableLinkedList<WAMInstruction> compileBodyArguments(Functor functor, boolean isFirstBody,
        FunctorName clauseName, int bodyNumber)
    {
        SizeableLinkedList<WAMInstruction> result = new SizeableLinkedList<WAMInstruction>();
        SizeableLinkedList<WAMInstruction> instructions;

        // Invent some unique names for choice points within a clause.
        clauseName = new FunctorName(clauseName.getName() + "_" + bodyNumber, 0);

        FunctorName choicePointRootName = new FunctorName(clauseName.getName() + "_ilc", 0);
        FunctorName continuationPointName = new FunctorName(clauseName.getName() + "_cnt", 0);

        // Labels the continuation point to jump to, when a choice point succeeds.
        WAMLabel continueLabel = new WAMLabel(continuationPointName, 0);

        // Do a loop over the children of this disjunction, and any child disjunctions encountered. This could be a
        // search? or just recursive exploration. I think it will need to be a DFS.
        List<Term> expressions = new ArrayList<Term>();
        gatherDisjunctions((Disjunction) functor, expressions);

        for (int i = 0; i < expressions.size(); i++)
        {
            Functor expression = (Functor) expressions.get(i);

            boolean isFirst = i == 0;
            boolean isLast = i == (expressions.size() - 1);

            // Labels the entry point to each choice point.
            WAMLabel entryLabel = new WAMLabel(choicePointRootName, i);

            // Label for the entry point to the next choice point, to backtrack to.
            WAMLabel retryLabel = new WAMLabel(choicePointRootName, i + 1);

            if (isFirst && !isLast)
            {
                // try me else.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.TryMeElse, retryLabel));
            }
            else if (!isFirst && !isLast)
            {
                // retry me else.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.RetryMeElse, retryLabel));
            }
            else if (isLast)
            {
                // trust me.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.TrustMe));
            }

            Integer permVarsRemaining =
                (Integer) defaultBuiltIn.getSymbolTable().get(expression.getSymbolKey(), SYMKEY_PERM_VARS_REMAINING);

            // Select a non-default built-in implementation to compile the functor with, if it is a built-in.
            BuiltIn builtIn;

            if (expression instanceof BuiltIn)
            {
                builtIn = (BuiltIn) expression;
            }
            else
            {
                builtIn = defaultBuiltIn;
            }

            // The 'isFirstBody' parameter is only set to true, when this is the first functor of a rule.
            instructions = builtIn.compileBodyArguments(expression, false, clauseName, i);
            result.addAll(instructions);

            // Call the body. The number of permanent variables remaining is specified for environment trimming.
            instructions = builtIn.compileBodyCall(expression, false, false, false, 0 /*permVarsRemaining*/);
            result.addAll(instructions);

            // Proceed if this disjunctive branch completes successfully. This does not need to be done for the last
            // branch, as the continuation point will come immediately after.
            if (!isLast)
            {
                result.add(new WAMInstruction(null, WAMInstruction.WAMInstructionSet.Continue, continueLabel));
            }
        }

        result.add(new WAMInstruction(continueLabel, WAMInstruction.WAMInstructionSet.NoOp));

        return result;
    }
public SizeableLinkedList<WAMInstruction> compileBodyArguments(Functor functor, boolean isFirstBody,
        FunctorName clauseName, int bodyNumber)
    {
        SizeableLinkedList<WAMInstruction> result = new SizeableLinkedList<WAMInstruction>();
        SizeableLinkedList<WAMInstruction> instructions;

        // Invent some unique names for choice points within a clause.
        clauseName = new FunctorName(clauseName.getName() + "_" + bodyNumber, 0);

        FunctorName choicePointRootName = new FunctorName(clauseName.getName() + "_ilc", 0);
        FunctorName continuationPointName = new FunctorName(clauseName.getName() + "_cnt", 0);

        // Labels the continuation point to jump to, when a choice point succeeds.
        WAMLabel continueLabel = new WAMLabel(continuationPointName, 0);

        // Do a loop over the children of this disjunction, and any child disjunctions encountered. This could be a
        // search? or just recursive exploration. I think it will need to be a DFS.
        List<Term> expressions = new ArrayList<Term>();
        gatherDisjunctions((Disjunction) functor, expressions);

        for (int i = 0; i < expressions.size(); i++)
        {
            Functor expression = (Functor) expressions.get(i);

            boolean isFirst = i == 0;
            boolean isLast = i == (expressions.size() - 1);

            // Labels the entry point to each choice point.
            WAMLabel entryLabel = new WAMLabel(choicePointRootName, i);

            // Label for the entry point to the next choice point, to backtrack to.
            WAMLabel retryLabel = new WAMLabel(choicePointRootName, i + 1);

            if (isFirst && !isLast)
            {
                // try me else.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.TryMeElse, retryLabel));
            }
            else if (!isFirst && !isLast)
            {
                // retry me else.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.RetryMeElse, retryLabel));
            }
            else if (isLast)
            {
                // trust me.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.TrustMe));
            }

            Integer permVarsRemaining =
                (Integer) defaultBuiltIn.getSymbolTable().get(expression.getSymbolKey(), SYMKEY_PERM_VARS_REMAINING);

            // Select a non-default built-in implementation to compile the functor with, if it is a built-in.
            BuiltIn builtIn;

            if (expression instanceof BuiltIn)
            {
                builtIn = (BuiltIn) expression;
            }
            else
            {
                builtIn = defaultBuiltIn;
            }

            // The 'isFirstBody' parameter is only set to true, when this is the first functor of a rule.
            instructions = builtIn.compileBodyArguments(expression, false, clauseName, i);
            result.addAll(instructions);

            // Call the body. The number of permanent variables remaining is specified for environment trimming.
            instructions = builtIn.compileBodyCall(expression, false, false, false, 0 /*permVarsRemaining*/);
            result.addAll(instructions);

            // Proceed if this disjunctive branch completes successfully. This does not need to be done for the last
            // branch, as the continuation point will come immediately after.
            if (!isLast)
            {
                result.add(new WAMInstruction(null, WAMInstruction.WAMInstructionSet.Continue, continueLabel));
            }
        }

        result.add(new WAMInstruction(continueLabel, WAMInstruction.WAMInstructionSet.NoOp));

        return result;
    }
{@inheritDoc}