private static Goal CreateGoal(ArgumentInstantiator visitor, Compiled.Goal goalDef) { var arguments = goalDef.Arguments.Select(a => a.Accept(visitor)).ToArray(); var predicate = goalDef.Predicate; var goal = predicate.Accept(new GoalInstantiator()); goal.Arguments = arguments; goal.Definition = goalDef; goal.Restart(); return(goal); }
Frame Unify(Compiled.Clause clause) { var boundVariables = new BoundVariableSet(); var argumentInstantiator = new ArgumentInstantiator(); var clauseHeadArguments = clause.Head.Arguments.Select(a => a.Accept(argumentInstantiator)).ToArray(); if (boundVariables.ZipUnify(Arguments, clauseHeadArguments)) { Goal [] goals = EngineInternals.InstantiateGoals(clause.Body, argumentInstantiator); return(new Frame(goals, this, boundVariables, argumentInstantiator.Variables)); } return(null); }
// ReSharper disable ParameterTypeCanBeEnumerable.Global internal static Goal [] InstantiateGoals(Compiled.Goal [] goalDefs, ArgumentInstantiator argumentInstantiator) // ReSharper restore ParameterTypeCanBeEnumerable.Global { return(goalDefs.Select(goalDef => CreateGoal(argumentInstantiator, goalDef)).ToArray()); }
public IEnumerable <IDebugEvent> Solve(Compiled.Goal [] goalDefs) { // Instantiate the goals. var queryArgumentInstantiator = new ArgumentInstantiator(); var goals = InstantiateGoals(goalDefs, queryArgumentInstantiator); frame = new Frame(goals, null, new BoundVariableSet(), queryArgumentInstantiator.Variables); // ReSharper disable ConditionIsAlwaysTrueOrFalse while (frame != null) // ReSharper restore ConditionIsAlwaysTrueOrFalse { if (frame.GoalsProven == frame.Goals.Length) { // No more goals to prove or it's a fact. System.Diagnostics.Debug.Assert(frame.Goals.All(g => g.CurrentFrame != null)); if (frame.Parent == null) { yield return(new Solution(frame)); foreach (var e in GoToLastChoicePoint()) { yield return(e); } } else { // go on and prove the next parent goal. frame = frame.Parent; frame.GoalsProven++; } continue; } var goal = frame.Goals [frame.GoalsProven]; // Check that the same goal is not on the stack to prevent infinite loops. if (AlreadyOnTheStack(goal)) { foreach (var e in Backtrack()) { yield return(e); } } else { var newFrame = goal.GetNextFrame(); if (newFrame == null) { foreach (var e in Backtrack()) { yield return(e); } } else { yield return(new Enter(newFrame)); frame = newFrame; // decend the tree } } } }