コード例 #1
0
ファイル: Solver.cs プロジェクト: Logicalshift/Reason
        /// <summary>
        /// Queries a solver for a goal
        /// </summary>
        public static IQueryResult Query(this ISolver solver, ILiteral goal)
        {
            // Result is false for something without a key
            if (goal.UnificationKey == null)
            {
                return new BasicQueryResult(false, new EmptyBinding(null));
            }

            // Compile the query
            var unifier = new SimpleUnifier();
            var assignments = new PredicateAssignmentList();

            // Assume we have a basic predicate
            foreach (var arg in goal.Dependencies)
            {
                assignments.AddArgument(arg);
            }

            // Run through the unifier
            var freeVariableNames = unifier.QueryUnifier.Bind(assignments.Assignments);
            var freeVariables = freeVariableNames.Select(variable => unifier.GetVariableLocation(variable).Dereference());
            unifier.QueryUnifier.Compile(assignments.Assignments);

            // Call via the solver
            var moveNext = solver.Call(goal.UnificationKey, unifier.GetArgumentVariables(assignments.CountArguments()));

            Func<IQueryResult> nextResult = () =>
                {
                    // Update the variables to the next result
                    var succeeded = moveNext();

                    // Nothing to do if we didn't succeed
                    if (!succeeded)
                    {
                        return new BasicQueryResult(false, new EmptyBinding(null));
                    }

                    // Bind the variables
                    var variableValues = freeVariables
                        .Select(varRef => varRef.Freeze())
                        .Zip(freeVariableNames, (value, name) => new { Value = value, Name = name }).ToArray();
                    var binding = new BasicBinding(null, variableValues.ToDictionary(val => val.Name, val => val.Value));

                    // Return the result
                    return new BasicQueryResult(true, binding);
                };

            // Chain to produce the final result
            return new ChainedResult(nextResult(), () => Task.FromResult(nextResult()));
        }
コード例 #2
0
        /// <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;
                }
            };
        }