示例#1
0
 public Functor3(Atom name, object arg1, object arg2, object arg3)
 {
     _name = name;
     _arg1 = arg1;
     _arg2 = arg2;
     _arg3 = arg3;
 }
示例#2
0
 /// <summary>
 /// Return the unique Atom object for name where module is null. You should use this to create
 /// an Atom instead of calling the Atom constructor.
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 public static Atom a(string name)
 {
     Atom atom;
     if (!_atomStore.TryGetValue(name, out atom))
     {
         atom = new Atom(name, null);
         _atomStore[name] = atom;
     }
     return atom;
 }
示例#3
0
 /// <summary>
 /// Return an Atom, Functor1, Functor2, Functor3 or Functor depending on the
 /// length of args.  
 /// Note that this is different than the Functor constructor which requires
 /// the length of args to be greater than 3.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="args"></param>
 /// <returns></returns>
 public static object make(Atom name, object[] args) 
 {
     if (args.Length <= 0)
         return name;
     else if (args.Length == 1)
         return new Functor1(name, args[0]);
     else if (args.Length == 2)
         return new Functor2(name, args[0], args[1]);
     else if (args.Length == 3)
         return new Functor3(name, args[0], args[1], args[2]);
     else
         return new Functor(name, args);
 }
示例#4
0
        public Functor(Atom name, object[] args)
        {
            if (args.Length <= 3)
            {
                if (args.Length == 0)
                    throw new Exception("For arity 0 functor, just use name as an Atom");
                else if (args.Length == 1)
                    throw new Exception("For arity 1 functor, use Functor1");
                else if (args.Length == 2)
                    throw new Exception("For arity 2 functor, use Functor2");
                else if (args.Length == 3)
                    throw new Exception("For arity 3 functor, use Functor3");
                else
                    // (This shouldn't happen, but include it for completeness.
                    throw new Exception("Cannot create a Functor of arity " + args.Length);
            }

            _name = name;
            _args = args;
        }
示例#5
0
 public Functor1(Atom name, object arg1)
 {
     _name = name;
     _arg1 = arg1;
 }
示例#6
0
        /// <summary>
        /// Return true if there is a dynamic or static predicate with name and arity.
        /// This returns false for built-in predicates.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="arity"></param>
        /// <param name="declaringClass">used to resolve references to the default 
        /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is
        ///   null, return false</param>
        /// <returns></returns>
        public static bool isCurrentPredicate(Atom name, int arity, Type declaringClass)
        {
            CompilerState state = new CompilerState();
            Variable FunctionName = new Variable();
            foreach (bool l1 in functorCallFunctionName(state, name, arity, FunctionName))
            {
                Atom functionNameAtom = ((Atom)FunctionName.getValue());
                if (functionNameAtom == Atom.NIL)
                    // name is for a dynamic predicate.
                    return YP.isDynamicCurrentPredicate(name, arity);

                string methodName = functionNameAtom._name;

                if (methodName.StartsWith("YP."))
                    // current_predicate/1 should fail for built-ins.
                    return false;
                if (methodName.Contains("."))
                    // We don't support calling inner classes, etc.
                    return false;
                if (declaringClass == null)
                    return false;

                foreach (MemberInfo member in declaringClass.GetMember(methodName))
                {
                    MethodInfo method = member as MethodInfo;
                    if (method == null)
                        continue;
                    if ((method.Attributes | MethodAttributes.Static) == 0)
                        // Not a static method.
                        continue;
                    if (method.GetParameters().Length == arity)
                        return true;
                }
            }

            return false;
        }
示例#7
0
        /// <summary>
        /// If the functor with name and args can be called directly as determined by
        ///   functorCallFunctionName, then call it and return its iterator.  If the predicate is
        ///   dynamic and undefined, or if static and the method cannot be found, return
        ///   the result of YP.unknownPredicate.
        /// This returns null if the functor has a special form than needs to be compiled 
        ///   (including ,/2 and ;/2).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="args"></param>
        /// <param name="declaringClass">used to resolve references to the default 
        /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is
        ///   null, this throws a PrologException for existence_error</param>
        /// <returns></returns>
        public static IEnumerable<bool> getSimpleIterator(Atom name, object[] args, Type declaringClass)
        {
            CompilerState state = new CompilerState();
            Variable FunctionName = new Variable();
            foreach (bool l1 in functorCallFunctionName(state, name, args.Length, FunctionName))
            {
                Atom functionNameAtom = ((Atom)FunctionName.getValue());
                if (functionNameAtom == Atom.NIL)
                    // name is for a dynamic predicate.
                    return YP.matchDynamic(name, args);

                string methodName = functionNameAtom._name;
                // Set the default for the method to call.
                Type methodClass = declaringClass;

                bool checkMode = false;
                if (methodName.StartsWith("YP."))
                {
                    // Assume we only check mode in calls to standard Prolog predicates in YP.
                    checkMode = true;

                    // Use the method in class YP.
                    methodName = methodName.Substring(3);
                    methodClass = typeof(YP);
                }
                if (methodName.Contains("."))
                    // We don't support calling inner classes, etc.
                    return null;

                if (methodClass == null)
                    return YP.unknownPredicate
                        (name, args.Length,
                         "Cannot find predicate function for: " + name + "/" + args.Length + 
                         " because declaringClass is null.  Set declaringClass to the class containing " +
                         methodName);
                try
                {
                    if (checkMode)
                    {
                        assertYPPred(state);
                        object functor = Functor.make(name, args);
                        if (CompilerState.isDetNoneOut(state, functor))
                        {
                            methodClass.InvokeMember
                                (methodName, BindingFlags.InvokeMethod, null, null, args);
                            return YP.succeed();
                        }
                        if (CompilerState.isSemidetNoneOut(state, functor))
                        {
                            if ((bool)methodClass.InvokeMember
                                 (methodName, BindingFlags.InvokeMethod, null, null, args))
                                return YP.succeed();
                            else
                                return YP.fail();
                        }

                    }
                    return (IEnumerable<bool>)methodClass.InvokeMember
                      (methodName, BindingFlags.InvokeMethod, null, null, args);
                }
                catch (TargetInvocationException exception)
                {
                    throw exception.InnerException;
                }
                catch (MissingMethodException)
                {
                    return YP.unknownPredicate
                        (name, args.Length,
                         "Cannot find predicate function " + methodName + " for " + name + "/" + args.Length + 
                         " in " + methodClass.FullName);
                }
            }

            return null;
        }
示例#8
0
 public TypeErrorInfo(Atom Type, object Culprit, object Message)
 {
     _Type = Type;
     _Culprit = Culprit;
     _Message = Message;
 }
示例#9
0
 public Functor2(Atom name, object arg1, object arg2)
 {
     _name = name;
     _arg1 = arg1;
     _arg2 = arg2;
 }
示例#10
0
 /// <summary>
 /// Return an Atom object with the name and module.  If module is null or Atom.NIL,
 /// this behaves like Atom.a(name) and returns the unique object where the module is null.
 /// If module is not null or Atom.NIL, this may or may not be the same object as another Atom
 /// with the same name and module.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="module"></param>
 /// <returns></returns>
 public static Atom a(string name, Atom module)
 {
     if (module == null || module == Atom.NIL)
         return a(name);
     return new Atom(name, module);
 }
示例#11
0
 /// <summary>
 /// You should not call this constructor, but use Atom.a instead.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="module"></param>
 private Atom(string name, Atom module)
 {
     _name = name;
     _module = module;
 }
示例#12
0
 /// <summary>
 /// Return true if _name is lexicographically less than atom._name.
 /// </summary>
 /// <param name="atom"></param>
 /// <returns></returns>
 public bool LessThan(Atom atom)
 {
     return _name.CompareTo(atom._name) < 0;
 }