/// <summary>
        /// Returns a function that solves a list of subclauses
        /// </summary>
        private Func<bool> SolveAllSubclauses(IEnumerable<AssignmentData> assignments, SimpleUnifier unifier)
        {
            // The first solution is always true once
            bool solvedOnce = false;
            Func<bool> solve = () =>
            {
                if (solvedOnce)
                {
                    // Reset the unifier to its original state and give up
                    unifier.ResetTrail();
                    return false;
                }
                else
                {
                    solvedOnce = true;
                    return true;
                }
            };

            // Chain the solutions for each subclause to generate the final result
            foreach (var clause in assignments)
            {
                solve = SolveSubclause(clause, unifier, solve);
            }

            // This generates the result
            return solve;
        }
        /// <summary>
        /// Solves a subclause
        /// </summary>
        private Func<bool> SolveSubclause(AssignmentData clause, SimpleUnifier unifier, Func<bool> solvePreviousClause)
        {
            // Create a new trail
            unifier.PushTrail();

            Func<bool> nextInThisClause = null;

            return () =>
            {
                if (nextInThisClause == null || !nextInThisClause())
                {
                    // Reset the state and get the solution for the previous clause
                    unifier.ResetTrail();

                    if (!solvePreviousClause())
                    {
                        return false;
                    }

                    // Push a new trail for this clause
                    unifier.PushTrail();

                    // Solve this clause
                    unifier.QueryUnifier.Bind(clause.Assignments);
                    if (!unifier.QueryUnifier.Compile(clause.Assignments))
                    {
                        return false;
                    }

                    // Call the predicate
                    nextInThisClause = _subclauseSolver.Call(clause.PredicateName, unifier.GetArgumentVariables(clause.NumArguments));

                    // Result depends on the next item in this clause
                    return nextInThisClause();
                }
                else
                {
                    // nextInThisClause() returned true, so this clause was solved
                    return true;
                }
            };
        }