Пример #1
0
        /// <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);
        }
Пример #2
0
        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);
        }