/// <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; } }); }