lojix/prolog/src/main/com/thesett/aima/logic/fol/prolog/builtins/DefaultBuiltIn.java
public boolean proofStep(ResolutionState state)
    {
        Functor goalTerm = state.getGoalStack().peek().getFunctor();
        Functor matchTerm = state.getCurrentClause().getHead();

        // This is used to record variables bound on the domain side of the unificiation. This information seems
        // like is does not need to be kept because usually all of these bindings are in the stack frame.
        // However, this is not always the case as unification can capture a variable on the domain side.
        // These variables need to be unbound on backtracking too.
        List<Variable> domainVariables = new LinkedList<Variable>();

        // This is used to record variables bound on the query goal side of the unification. This information
        // must be kept so that the undo operation can unbind these variables before placing the goal back
        // onto the stack when backtracking.
        List<Variable> boundVariables = new LinkedList<Variable>();

        // Unify the current query goal with the possibly matching clause, creating variable bindings.
        boolean matched = state.getUnifier().unifyInternal(goalTerm, matchTerm, boundVariables, domainVariables);

        // Even if unification fails, any partial bindings created are remembered, to ensure that they are cleaned
        // up when this proof steps state is undone.
        for (Variable binding : boundVariables)
        {
            state.getVariableBindings().offer(binding);
        }

        for (Variable binding : domainVariables)
        {
            state.getVariableBindings().offer(binding);
        }

        // If the unification succeeded, establish a new state with the unified query removed from the goal stack, the
        // body of the unified with clause added to it for resolution, and the variable binding trail extended with
        // any additional bindings resulting from the unification.
        if (matched)
        {
            if (TRACE)
            {
                /*trace.fine(state.getTraceIndenter().generateTraceIndent() + "Unify " +
                    goalTerm.toString(state.getInterner(), true, true) + " against " +
                    matchTerm.toString(state.getInterner(), true, true) + ", ok.");*/
            }

            // Consume the successfully unified goal from the goal stack.
            state.getGoalStack().poll();

            // Add all functors on the body side of the unified clause onto the goal stack for resolution.
            Functor[] body = state.getCurrentClause().getBody();

            if ((body != null) && (body.length != 0))
            {
                // The new goals are placed onto the goal stack backwards. It is a stack, hence they get
                // explored first, depth first, but their insertion order is reversed for an intuitive
                // left-to-right evaluation order.
                for (int i = body.length - 1; i >= 0; i--)
                {
                    BuiltInFunctor newGoal = state.getBuiltInTransform().apply(body[i]);
                    newGoal.setParentChoicePointState(state.getLastChoicePoint());
                    state.getGoalStack().offer(newGoal);
                }
            }

            return true;
        }
        else
        {
            if (TRACE)
            {
                /*trace.fine(state.getTraceIndenter().generateTraceIndent() + "Failed to unify " +
                    goalTerm.toString(state.getInterner(), true, true) + " against " +
                    matchTerm.toString(state.getInterner(), true, true) + ".");*/
            }

            return false;
        }
    }
public boolean proofStep(ResolutionState state)
    {
        Functor goalTerm = state.getGoalStack().peek().getFunctor();
        Functor matchTerm = state.getCurrentClause().getHead();

        // This is used to record variables bound on the domain side of the unificiation. This information seems
        // like is does not need to be kept because usually all of these bindings are in the stack frame.
        // However, this is not always the case as unification can capture a variable on the domain side.
        // These variables need to be unbound on backtracking too.
        List<Variable> domainVariables = new LinkedList<Variable>();

        // This is used to record variables bound on the query goal side of the unification. This information
        // must be kept so that the undo operation can unbind these variables before placing the goal back
        // onto the stack when backtracking.
        List<Variable> boundVariables = new LinkedList<Variable>();

        // Unify the current query goal with the possibly matching clause, creating variable bindings.
        boolean matched = state.getUnifier().unifyInternal(goalTerm, matchTerm, boundVariables, domainVariables);

        // Even if unification fails, any partial bindings created are remembered, to ensure that they are cleaned
        // up when this proof steps state is undone.
        for (Variable binding : boundVariables)
        {
            state.getVariableBindings().offer(binding);
        }

        for (Variable binding : domainVariables)
        {
            state.getVariableBindings().offer(binding);
        }

        // If the unification succeeded, establish a new state with the unified query removed from the goal stack, the
        // body of the unified with clause added to it for resolution, and the variable binding trail extended with
        // any additional bindings resulting from the unification.
        if (matched)
        {
            if (TRACE)
            {
                /*trace.fine(state.getTraceIndenter().generateTraceIndent() + "Unify " +
                    goalTerm.toString(state.getInterner(), true, true) + " against " +
                    matchTerm.toString(state.getInterner(), true, true) + ", ok.");*/
            }

            // Consume the successfully unified goal from the goal stack.
            state.getGoalStack().poll();

            // Add all functors on the body side of the unified clause onto the goal stack for resolution.
            Functor[] body = state.getCurrentClause().getBody();

            if ((body != null) && (body.length != 0))
            {
                // The new goals are placed onto the goal stack backwards. It is a stack, hence they get
                // explored first, depth first, but their insertion order is reversed for an intuitive
                // left-to-right evaluation order.
                for (int i = body.length - 1; i >= 0; i--)
                {
                    BuiltInFunctor newGoal = state.getBuiltInTransform().apply(body[i]);
                    newGoal.setParentChoicePointState(state.getLastChoicePoint());
                    state.getGoalStack().offer(newGoal);
                }
            }

            return true;
        }
        else
        {
            if (TRACE)
            {
                /*trace.fine(state.getTraceIndenter().generateTraceIndent() + "Failed to unify " +
                    goalTerm.toString(state.getInterner(), true, true) + " against " +
                    matchTerm.toString(state.getInterner(), true, true) + ".");*/
            }

            return false;
        }
    }
{@inheritDoc}