public Functor3(Atom name, object arg1, object arg2, object arg3) { _name = name; _arg1 = arg1; _arg2 = arg2; _arg3 = arg3; }
/// <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; }
/// <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); }
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; }
public Functor1(Atom name, object arg1) { _name = name; _arg1 = arg1; }
/// <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; }
/// <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; }
public TypeErrorInfo(Atom Type, object Culprit, object Message) { _Type = Type; _Culprit = Culprit; _Message = Message; }
public Functor2(Atom name, object arg1, object arg2) { _name = name; _arg1 = arg1; _arg2 = arg2; }
/// <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); }
/// <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; }
/// <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; }