/// <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); } }
public void SimpleCompile() { 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); // p(X, Y) :- q(X, Z), r(Z, Y) var clause = Clause.If(qXZ, rZY).Then(pXY); // Compile ByteCodeProgram program = new ByteCodeProgram(); clause.Compile(program); Console.WriteLine(program.ToString()); }
public ByteCodeUnifier(ByteCodeProgram program) { if (program == null) throw new ArgumentNullException("program"); _program = program; }