/// <inheritdoc /> public override bool Call(object[] arglist, TextBuffer output, BindingEnvironment env, MethodCallFrame predecessor, Step.Continuation k) { ArgumentCountException.Check(this, Arity, arglist); // Check types and find the shortest list of candidate tuples that match var candidateTuples = tuples; for (var i = 0; i < Arity; i++) { var arg = arglist[i]; if (arg is LogicVariable) { continue; } ArgumentTypeException.Check(this, Signature[i], arg, arglist); var index = indices[i]; if (index != null) { if (!index.TryGetValue(arg, out var indexedTuples)) { // There are literally no tuples with the specified argument value return(false); } if (indexedTuples.Count < candidateTuples.Count) { candidateTuples = indexedTuples; } } } // Attempt to unify each candidate tuple with the argument list foreach (var t in Shuffler(candidateTuples)) { if (env.UnifyArrays(arglist, t, out BindingList <LogicVariable> unifications)) { if (k(output, unifications, env.State, predecessor)) { return(true); } } } return(false); }
private static bool TaskCalls(object[] args, TextBuffer o, BindingEnvironment e, MethodCallFrame predecessor, Step.Continuation k) { var m = e.Module; ArgumentCountException.Check(nameof(TaskCalls), 2, args); ArgumentTypeException.Check(nameof(TaskCalls), typeof(CompoundTask), args[0], args, true); var callerVar = args[0] as LogicVariable; var callerTask = args[0] as CompoundTask; var callee = args[1]; var calleeVar = callee as LogicVariable; if (callerVar == null) { // First arg is input if (calleeVar == null) { // in in if (m.TaskCalls(callerTask, callee)) { return(k(o, e.Unifications, e.State, predecessor)); } } else { // in out foreach (var c in m.Callees(callerTask)) { if (k(o, BindingList <LogicVariable> .Bind(e.Unifications, calleeVar, c), e.State, predecessor)) { return(true); } } } } else { // First arg is output if (calleeVar == null) { // out in foreach (var caller in m.DefinedTasks) { if (m.TaskCalls(caller, callee)) { if (k(o, BindingList <LogicVariable> .Bind(e.Unifications, callerVar, caller), e.State, predecessor)) { return(true); } } } } else { // out out foreach (var caller in m.DefinedTasks) { foreach (var c in m.Callees(caller)) { if (k(o, BindingList <LogicVariable> .Bind(e.Unifications, callerVar, caller).Bind(calleeVar, c), e.State, predecessor)) { return(true); } } } } } return(false); }