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 } } } }
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; }
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; }
// 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 (); }