Esempio n. 1
0
        public void PicksCorrectVariablesInSimpleCase()
        {
            // Predicate p(X,Y) :- q(X, Z), r(Z,Y) should have Z and Y as permanent variables
            var p = Literal.NewAtom();
            var q = Literal.NewAtom();
            var r = Literal.NewAtom();

            var X = Literal.NewVariable();
            var Y = Literal.NewVariable();
            var Z = Literal.NewVariable();

            var pXY = Literal.NewFunctor(2).With(X, Y);
            var qXZ = Literal.NewFunctor(2).With(X, Z);
            var rZY = Literal.NewFunctor(2).With(Z, Y);

            // Create the clause
            var clause = Clause.If(qXZ, rZY).Then(pXY);

            // Compile to assignments
            var allPredicates = new[] { clause.Implies }.Concat(clause.If).ToArray();
            var assignmentList = allPredicates.Select(predicate => PredicateAssignmentList.FromPredicate(predicate));

            // Get the set of permanent variables
            var permanent = PermanentVariableAssignments.PermanentVariables(assignmentList);

            // Z and Y are the only permanent variables
            Assert.IsFalse(permanent.Contains(X));
            Assert.IsTrue(permanent.Contains(Y));
            Assert.IsTrue(permanent.Contains(Z));
            Assert.AreEqual(2, permanent.Count);
        }
Esempio n. 2
0
        /// <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())));
        }