Пример #1
0
        public void Unify_NonUnifiableNames_False(string n1, string n2, Refactorization r)
        {
            IEnumerable <Substitution> bindings = new List <Substitution>();
            var isUnifiable = true;

            if (r == Refactorization.Current)
            {
                var name1 = Name.BuildName(n1);
                var name2 = Name.BuildName(n2);
                for (int i = 0; i < unifierReps; i++)
                {
                    isUnifiable = Unifier.Unify(name1, name2, out bindings);
                }
            }
            else if (r == Refactorization.New)
            {
                var name1 = new SimpleName(n1);
                var name2 = new SimpleName(n2);
                for (int i = 0; i < unifierReps; i++)
                {
                    isUnifiable = SimpleUnifier.Unify(name1, name2, out bindings);
                }
            }
            Assert.That(!isUnifiable);
            Assert.That(bindings == null);
        }
Пример #2
0
        public void Unify_UnifiableNames_True(string n1, string n2, string[] result, Refactorization r)
        {
            var expectedBindings = result.Select(s => new Substitution(s));
            IEnumerable <Substitution> bindings = null;
            var isUnifiable = false;

            if (r == Refactorization.Current)
            {
                var name1 = Name.BuildName(n1);
                var name2 = Name.BuildName(n2);
                for (int i = 0; i < unifierReps; i++)
                {
                    isUnifiable = Unifier.Unify(name1, name2, out bindings);
                }
            }
            else if (r == Refactorization.New)
            {
                var name1 = new SimpleName(n1);
                var name2 = new SimpleName(n2);

                for (int i = 0; i < unifierReps; i++)
                {
                    isUnifiable = SimpleUnifier.Unify(name1, name2, out bindings);
                }
            }
            Assert.That(isUnifiable);
            if (result.Any())
            {
                Assert.That(bindings, Is.EquivalentTo(expectedBindings));
            }
            else
            {
                Assert.That(bindings.Count() == 0);
            }
        }
Пример #3
0
        public void FindFreeVariableInMoreComplicatedFunctor()
        {
            var functor = GetQueryAndProgram1().Item1;
            var unifier = new SimpleUnifier();

            var freeVars = unifier.QueryUnifier.Compile(functor).ToList();

            Assert.AreEqual(2, freeVars.Count);
        }
Пример #4
0
        public void AtomIsNotFreeVariable()
        {
            var atom    = Literal.NewAtom();
            var unifier = new SimpleUnifier();

            var freeVars = unifier.QueryUnifier.Compile(atom).ToList();

            Assert.AreEqual(0, freeVars.Count);
        }
Пример #5
0
        public void VariableIsFreeVariable()
        {
            var variable = Literal.NewVariable();
            var unifier  = new SimpleUnifier();

            var freeVars = unifier.QueryUnifier.Compile(variable).ToList();

            Assert.AreEqual(1, freeVars.Count);
            Assert.AreEqual(variable, freeVars[0]);
        }
Пример #6
0
        public void FindFreeVariableInFunctor()
        {
            var variable = Literal.NewVariable();
            var functor  = Literal.NewFunctor(1).With(variable);
            var unifier  = new SimpleUnifier();

            var freeVars = unifier.QueryUnifier.Compile(functor).ToList();

            Assert.AreEqual(1, freeVars.Count);
            Assert.AreEqual(variable, freeVars[0]);
        }
Пример #7
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())));
        }
Пример #8
0
        public void ManualUnification()
        {
            var simpleUnifier = new SimpleUnifier();
            var unifier       = new TraceUnifier(simpleUnifier);
            var X             = new[] { new Variable(), new Variable(), new Variable(), new Variable(), new Variable(), new Variable(), new Variable(), new Variable() };
            var h2            = new UnboundFunctor(2);
            var f1            = new UnboundFunctor(1);
            var p3            = new UnboundFunctor(3);
            var a0            = new UnboundFunctor(0);

            unifier.BindVariable(0, X[1]);
            unifier.BindVariable(1, X[2]);
            unifier.BindVariable(2, X[3]);
            unifier.BindVariable(3, X[4]);
            unifier.BindVariable(4, X[5]);
            unifier.BindVariable(5, X[6]);
            unifier.BindVariable(6, X[7]);

            unifier.PutStructure(h2, 2, X[3]);
            unifier.SetVariable(X[2]);
            unifier.SetVariable(X[5]);
            unifier.PutStructure(f1, 1, X[4]);
            unifier.SetValue(X[5]);
            unifier.PutStructure(p3, 3, X[1]);
            unifier.SetValue(X[2]);
            unifier.SetValue(X[3]);
            unifier.SetValue(X[4]);

            unifier.GetStructure(p3, 3, X[1]);
            unifier.UnifyVariable(X[2]);
            unifier.UnifyVariable(X[3]);
            unifier.UnifyVariable(X[4]);
            unifier.GetStructure(f1, 1, X[2]);
            unifier.UnifyVariable(X[5]);
            unifier.GetStructure(h2, 2, X[3]);
            unifier.UnifyValue(X[4]);
            unifier.UnifyVariable(X[6]);
            unifier.GetStructure(f1, 1, X[6]);
            unifier.UnifyVariable(X[7]);
            unifier.GetStructure(a0, 0, X[7]);

            var result = simpleUnifier.UnifiedValue(X[1]);

            Assert.IsNotNull(result);
        }
Пример #9
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;
                }
            });
        }
Пример #10
0
        public Func <bool> Call(ILiteral predicate, params IReferenceLiteral[] arguments)
        {
            // Assume that predicate is correct

            // Load the arguments into a simple unifier
            var unifier = new SimpleUnifier();

            unifier.LoadArguments(arguments);

            // Unify using the predicate
            unifier.ProgramUnifier.Bind(_clauseAssignments[0].Assignments);
            if (!unifier.ProgramUnifier.Compile(_clauseAssignments[0].Assignments))
            {
                // Fail if we can't unify
                return(() => false);
            }

            // Call using the clauses
            return(SolveAllSubclauses(_clauseAssignments.Skip(1), unifier));
        }
Пример #11
0
        /// <summary>
        /// Returns the possible ways that a query term can unify with a program term
        /// </summary>
        public static IBindings Unify(this ILiteral query, ILiteral program, IBindings bindings = null)
        {
            var simpleUnifier = new SimpleUnifier();
            var freeVariables = new HashSet <ILiteral>();

            // Run the unifier
            var queryFreeVars = simpleUnifier.QueryUnifier.Compile(query, bindings);

            if (queryFreeVars == null)
            {
                return(null);
            }

            simpleUnifier.PrepareToRunProgram();

            var programFreeVars = simpleUnifier.ProgramUnifier.Compile(program, bindings);

            if (programFreeVars == null)
            {
                return(null);
            }

            freeVariables.UnionWith(queryFreeVars);

            // Retrieve the unified value for the program
            var result = simpleUnifier.UnifiedValue(query.UnificationKey ?? query);

            // If the result was valid, return as the one value from this function
            if (result != null)
            {
                var variableBindings = freeVariables.ToDictionary(variable => variable,
                                                                  variable => simpleUnifier.UnifiedValue(variable));

                return(new BasicBinding(result, variableBindings));
            }
            else
            {
                return(null);
            }
        }
Пример #12
0
        /// <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);
        }