Пример #1
0
        public void UnifierUsesIndexAndNotLiteralVariable()
        {
            var unifier = new ByteCodeUnifier(new ByteCodeProgram());

            var var1 = Literal.NewVariable();
            var var2 = Literal.NewVariable();

            unifier.BindVariable(1, var1);
            unifier.BindVariable(1, var2);

            // As var1 and var2 are bound to the same index, using var1 should mark var2 as used as well
            unifier.SetVariable(var1);
            Assert.IsTrue(unifier.HasVariable(var1));
            Assert.IsTrue(unifier.HasVariable(var2));
        }
Пример #2
0
        /// <summary>
        /// Compiles a clause to a bytecode program
        /// </summary>
        public static void Compile(this IClause clause, ByteCodeProgram program)
        {
            var unifier = new ByteCodeUnifier(program);

            // Take each part of the clause and retrieve the assignments for it, with the 'implies' set at the start
            var allPredicates = new[] { clause.Implies }.Concat(clause.If).ToArray();
            var assignmentList = allPredicates
                .Select(predicate => new
                {
                    Assignments = PredicateAssignmentList.FromPredicate(predicate),
                    UnificationKey = predicate.UnificationKey
                })
                .ToArray();

            // Allocate space for the arguments and any permanent variables
            var permanentVariables = PermanentVariableAssignments.PermanentVariables(assignmentList.Select(assign => assign.Assignments));
            var numArguments = assignmentList[0].Assignments.CountArguments();

            if (permanentVariables.Count > 0 || allPredicates.Length > 1)
            {
                program.Write(Operation.Allocate, permanentVariables.Count, numArguments);
            }

            // Unify with the predicate first
            unifier.ProgramUnifier.Bind(assignmentList[0].Assignments.Assignments, permanentVariables);
            unifier.ProgramUnifier.Compile(assignmentList[0].Assignments.Assignments);

            // Call the clauses
            foreach (var assignment in assignmentList.Skip(1))
            {
                unifier.QueryUnifier.Bind(assignment.Assignments.Assignments, permanentVariables);
                unifier.QueryUnifier.Compile(assignment.Assignments.Assignments);

                program.Write(Operation.Call, assignment.UnificationKey, assignment.UnificationKey.Dependencies.Count());
            }

            // Deallocate any permanent variables that we might have found
            if (permanentVariables.Count > 0 || allPredicates.Length > 1)
            {
                program.Write(Operation.Deallocate);
            }
        }
Пример #3
0
        /// <summary>
        /// Compiles a clause to a bytecode program
        /// </summary>
        public static void Compile(this IClause clause, ByteCodeProgram program)
        {
            var unifier = new ByteCodeUnifier(program);

            // Take each part of the clause and retrieve the assignments for it, with the 'implies' set at the start
            var allPredicates = new[] { clause.Implies }.Concat(clause.If).ToArray();
            var assignmentList = allPredicates
                                 .Select(predicate => new
            {
                Assignments    = PredicateAssignmentList.FromPredicate(predicate),
                UnificationKey = predicate.UnificationKey
            })
                                 .ToArray();

            // Allocate space for the arguments and any permanent variables
            var permanentVariables = PermanentVariableAssignments.PermanentVariables(assignmentList.Select(assign => assign.Assignments));
            var numArguments       = assignmentList[0].Assignments.CountArguments();

            if (permanentVariables.Count > 0 || allPredicates.Length > 1)
            {
                program.Write(Operation.Allocate, permanentVariables.Count, numArguments);
            }

            // Unify with the predicate first
            unifier.ProgramUnifier.Bind(assignmentList[0].Assignments.Assignments, permanentVariables);
            unifier.ProgramUnifier.Compile(assignmentList[0].Assignments.Assignments);

            // Call the clauses
            foreach (var assignment in assignmentList.Skip(1))
            {
                unifier.QueryUnifier.Bind(assignment.Assignments.Assignments, permanentVariables);
                unifier.QueryUnifier.Compile(assignment.Assignments.Assignments);

                program.Write(Operation.Call, assignment.UnificationKey, assignment.UnificationKey.Dependencies.Count());
            }

            // Deallocate any permanent variables that we might have found
            if (permanentVariables.Count > 0 || allPredicates.Length > 1)
            {
                program.Write(Operation.Deallocate);
            }
        }