public static object EvalMemberExpression(object obj, object memberExpression, PrologContext context) { obj = Eval(obj, context); memberExpression = Term.Deref(memberExpression); var methodCall = memberExpression as Structure; if (methodCall != null) { // Method call var args = new object[methodCall.Arity]; for (var i = 0; i < args.Length; i++) { args[i] = Eval(methodCall.Argument(i), context); } return(obj.InvokeMethod(methodCall.Functor.Name, args)); } var propName = memberExpression as Symbol; if (propName != null) { // Field or property reference return(obj.GetPropertyOrField(propName.Name)); } throw new ArgumentException( "Invalid member expression: " + ISOPrologWriter.WriteToString(new Structure(Symbol.Dot, obj, memberExpression))); }
/// <summary> /// Count references to variables in ARG /// </summary> private void CountVariableReferences(object arg, bool isHead, byte argRegister) { arg = Term.Deref(arg); if (arg is LogicVariable) { var l = arg as LogicVariable; if (isHead) { VariableInfo variableInfo = env[l]; if (argRegister != NoRegister && variableInfo.register == NoRegister) { variableInfo.register = argRegister; variableInfo.LockInRegister = true; } env.MarkHeadReference(l); } else { env.MarkBodyReference(l); } } else { var structure = arg as Structure; if (structure != null) { foreach (var structureArg in structure.Arguments) { this.CountVariableReferences(structureArg, isHead, NoRegister); } } } }
private void WalkGoal(KnowledgeBase kb, KnowledgeBaseRule rule, object goal) { goal = Term.Deref(goal); var atom = goal as Symbol; if (atom != null) { var p = new PredicateIndicator(atom, 0); if (PrologPrimitives.IsDefined(p)) { return; } var predicate = kb.CheckForPredicateInfo(p); if (predicate == null) { rule.PrintWarning("undefined predicate {0}", p); } else { MarkReferenced(predicate); } } else { var s = goal as Structure; if (s != null) { WalkGoal(kb, rule, s); } else if (!(goal is LogicVariable) && !(goal is bool)) { rule.PrintWarning("malformed goal: {0}", goal); } } }
public static int PrologListLength(object prologList) { object current = Term.Deref(prologList); int index = 0; while (current != null) { var t = current as Structure; if (t == null) { if (current is LogicVariable) { throw new ArgumentException("List is incomplete (i.e. it ends in a logic variable).", "prologList"); } throw new ArgumentException("Argument is not a valid Prolog list", "prologList"); } if (t.IsFunctor(Symbol.PrologListConstructor, 2)) { index++; current = t.Argument(1); } else { throw new ArgumentException("Argument is not a valid Prolog list", "prologList"); } } return(index); }
public static object PrologListElement(object prologList, int index) { object current = Term.Deref(prologList); while (current != null) { var t = current as Structure; if (t == null) { if (current is LogicVariable) { throw new ArgumentException("List is incomplete (i.e. it ends in a logic variable).", "prologList"); } throw new ArgumentException("Argument is not a valid Prolog list", "prologList"); } if (t.IsFunctor(Symbol.PrologListConstructor, 2)) { if (index-- == 0) { // Done. return(t.Argument(0)); } current = t.Argument(1); } else { throw new ArgumentException("Argument is not a valid Prolog list", "prologList"); } } // Hit the end of the list throw new IndexOutOfRangeException(); }
public PredicateArgumentIndexer(object argument) { argument = Term.Deref(argument); if (argument == null) { this.Type = IndexerType.Null; this.Functor = null; this.Arity = 0; } else { if (argument is LogicVariable || argument is Indexical) { this.Type = IndexerType.Variable; this.Functor = null; this.Arity = 0; } else { var s = argument as Structure; if (s != null) { this.Type = IndexerType.Structure; this.Functor = s.Functor; this.Arity = (byte)s.Arity; } else { this.Type = IndexerType.Atom; this.Functor = argument; this.Arity = 0; } } } }
public static bool TryQuery(object term, PrologContext context, out ELNode foundNode, out ELNodeEnumerator enumerator) { // Dereference any top-level variables. var t = Term.Deref(term); // Dereference indexicals var i = t as Indexical; if (i != null) t = i.GetValue(context); // A game object means the gameobject's EL KB. var g = t as GameObject; if (g != null) t = g.KnowledgeBase().ELRoot; // If it's already an ELNode, use that. var n = t as ELNode; if (n != null) { foundNode = n; enumerator = null; return true; } // Otherwise, it's an expression, so evaluate it. var s = t as Structure; if (s != null) return TryQueryStructure(s, context, out foundNode, out enumerator); var v = t as LogicVariable; if (v != null && !v.IsBound) throw new Exception("EL query root is an unbound variable: " + v); throw new Exception("Malformed EL query: " + ISOPrologWriter.WriteToString(term)); }
// // these write a single nodes, so they don't need to loop like queries do. // /// <summary> /// Write TERM to EL KB, creating any nodes that need to be cerated. /// </summary> /// <param name="term">Prolog-format term to store into KB</param> /// <param name="knowledgeBase">KB in which to assert the term.</param> /// <returns></returns> public static ELNode Update(object term, KnowledgeBase knowledgeBase) { term = Term.Deref(term); var s = term as Structure; if (s != null) return UpdateStructure(s, knowledgeBase); var n = term as ELNode; if (n != null) return n; throw new Exception("Malformed EL assertion: " + ISOPrologWriter.WriteToString(term)); }
public static PredicateIndicator FromExpression(object expression) { var s = Term.Deref(expression) as Structure; if (s == null || (!s.IsFunctor(Symbol.Slash, 2) && !s.IsFunctor(Symbol.SlashSlash, 2)) || !(s.Argument(0) is Symbol) || !(s.Argument(1) is int)) { throw new ArgumentException("Predicate indicator should be of the form functor/arity, but got " + ISOPrologWriter.WriteToString(expression)); } return(new PredicateIndicator((Symbol)s.Argument(0), (int)s.Argument(1))); }
private void CompileMatcher(byte register, byte argument, object obj) { obj = Term.Deref(obj); var lv = obj as LogicVariable; if (lv != null) { var info = env[lv]; if (register != NoRegister || info.register != argument) // If top level and first occurance, don't bother. { env.InsureAllocated(info); if (info.AlreadyStored) { Emit(Opcode.MatchVar, info.register); } else { Emit(Opcode.MatchVarFirst, SymbolTable.IndexOf(lv.Name), info.register); } EmitOperand(register, argument); } env.OneUseCompiled(info); } else { var structure = obj as Structure; if (structure != null) { Structure s = structure; byte destinationRegister = (register == NoRegister)?argument:this.env.GetRegister(); this.Emit(Opcode.MatchStructure, SymbolTable.IndexOf(s.Functor), (byte)s.Arity); ushort backPatchAddress = this.CurrentPC; this.EmitUShort(0); this.EmitOperand(register, argument, destinationRegister); for (byte i = 0; i < s.Arity; i++) { this.CompileMatcher(destinationRegister, i, s.Argument(i)); } this.BackPatch(backPatchAddress, this.CurrentPC); if (register != NoRegister) { this.env.FreeRegister(destinationRegister); } } else { this.Emit(Opcode.MatchLiteral, GlobalLiteralTable.IndexOf(obj)); this.EmitOperand(register, argument); } } }
public static IEnumerable PrologListItems(object prologList) { object current = Term.Deref(prologList); while (current != null) { var t = current as Structure; if (t == null) { throw new ArgumentException("List is not a proper list; it ends with: " + current); } yield return(t.Argument(0)); current = t.Argument(1); } }
public static List <object> PrologListToIList(object prologList) { object current = Term.Deref(prologList); var schemeList = new List <object>(PrologListLength(prologList)); while (current != null) { var t = current as Structure; if (t == null) { throw new ArgumentException("List is not a proper list; it ends with: " + current); } schemeList.Add(t.Argument(0)); current = t.Argument(1); } return(schemeList); }
public static object[] PrologListToArray(object prologList) { object current = Term.Deref(prologList); var array = new object[PrologListLength(prologList)]; int index = 0; while (current != null) { var t = current as Structure; if (t == null) { throw new ArgumentException("List is not a proper list; it ends with: " + current); } array[index++] = t.Argument(0); current = t.Argument(1); } return(array); }
private object DecodeOperand(PrologContext context, int framePointer, ref ushort pc) { int registerNumber = code[pc++]; object value = Term.Deref(context.GetStack(framePointer, registerNumber & 0x7f)); if (registerNumber < 0x80) { return(value); } int argNumber = code[pc++]; value = ((Structure)value).Argument(argNumber & 0x7f); if (argNumber >= 0x80) { context.SetStack(framePointer, code[pc++], value); } return(value); }
private void SetOperand(PrologContext context, int framePointer, ref ushort pc, object newValue) { int registerNumber = code[pc++]; if (registerNumber < 0x80) { context.SetStack(framePointer, registerNumber, newValue); } else { object s = Term.Deref(context.GetStack(framePointer, registerNumber & 0x7f)); int argNumber = code[pc++]; object value = ((Structure)s).Arguments[argNumber & 0x7f] = newValue; if (argNumber >= 0x80) { context.SetStack(framePointer, code[pc++], value); } } }
internal static IEnumerable <CutState> SetImplementation(object[] args, PrologContext context) { if (args.Length != 2) { throw new ArgumentCountException("set", args, new object[] { "Variable", "NewValue" }); } object value = Term.CopyInstantiation(args[1]); if (value is LogicVariable) { throw new UninstantiatedVariableException((LogicVariable)args[1], "Value argument should be a data object, not an uninstantiated (unbound) variable."); } var functor = Term.Deref(args[0]) as Symbol; if (functor == null) { throw new ArgumentTypeException("set", "functor", args[0], typeof(Symbol)); } List <KnowledgeBaseEntry> entries = context.KnowledgeBase.EntryListForStoring(new PredicateIndicator(functor, 1)); switch (entries.Count) { case 0: entries.Add(new KnowledgeBaseVariable(value)); return(CutStateSequencer.Succeed()); case 1: var v = entries[0] as KnowledgeBaseVariable; if (v == null) { throw new ArgumentException("Functor is not a variable; it has another entry defined for it."); } v.CurrentValue = value; return(CutStateSequencer.Succeed()); default: throw new ArgumentException("Functor is not a variable; it has multiple entries defined for it."); } }
private void FUNCTIONAL(Structure tp, string termname, int options) { if ((options & NUMBERVARS) != 0 && USDVAR(termname) && __ARITY(tp) == 1) { int varno; Object tp2; tp2 = __LASTARG(tp, 1); tp2 = Term.Deref(tp2); if (tp2 is int) { varno = (int)tp2; if (lastitem == IDENTIFIER_ITEM) { PUTCHAR(' '); } PUTCHAR((char)(varno % 26 + 'A')); if ((varno = varno / 26) != 0) { LowLevelWrite(varno); } lastitem = IDENTIFIER_ITEM; return; } } showname(termname, options); PUTSOLO('('); for (int i = 1; i < __ARITY(tp); i++) { recwriteterm(__ARG(tp, i), options, 1000, 1201); PUTSOLO(','); } if (__ARITY(tp) > 0) { recwriteterm(__LASTARG(tp, __ARITY(tp)), options, 1000, 1201); } PUTSOLO(')'); }
private void recwriteterm(Object tp, int options, int termpri, int atompri) /* * recursive writeterm routine */ { int prepri, inpri, postpri, spec; tp = Term.Deref(tp); if (tp == null) { LowLevelWrite(tp); return; } if (tp is int) { int intval = (int)tp; if (intval < 0) { if (lastitem == GRAPHIC_ITEM) { PUTCHAR(' '); } PUTCHAR('-'); intval = -intval; } else { if (lastitem == NUMERIC_ITEM || lastitem == IDENTIFIER_ITEM) { PUTCHAR(' '); } } LowLevelWrite(intval); lastitem = NUMERIC_ITEM; } else { var symbol = tp as Symbol; if (symbol != null) { bool brackets = false; string atomname = symbol.Name; if (atompri == 1201) { this.showname(atomname, options); } else { if (ISOPrologReader.Operator(atomname, out prepri, out inpri, out postpri, out spec)) { if (prepri >= atompri) { brackets = true; } if (inpri >= atompri) { brackets = true; } if (postpri >= atompri) { brackets = true; } if (ISOPrologReader.comma_char(atomname[0]) && atomname.Length == 1) { brackets = true; } } if (brackets) { this.PUTSOLO('('); } this.showname(atomname, options); if (brackets) { this.PUTSOLO(')'); } } } else if (tp is float) { float ff = (float)tp; if (ff < 0.0) { if (this.lastitem == GRAPHIC_ITEM) { this.PUTCHAR(' '); } } else { if (this.lastitem == NUMERIC_ITEM || this.lastitem == IDENTIFIER_ITEM) { this.PUTCHAR(' '); } } this.LowLevelWrite(ff); this.lastitem = NUMERIC_ITEM; } else if (tp is Structure) { Structure str = tp as Structure; string termname = str.Functor.Name; int termarity = str.Arguments.Length; if ((options & IGNORE_OPS) != 0 || termarity > 2) { this.FUNCTIONAL(str, termname, options); } else /* operator definitions are now in effect */ if (termarity == 2) { if (str.Functor == Symbol.PrologListConstructor) { /* list constructor */ bool first = true; this.PUTSOLO('['); do { if (first) { first = false; } else { this.PUTSOLO(','); } this.recwriteterm(__ARG(str, 1), options, 1000, 1201); tp = __LASTARG(str, 2); tp = Term.Deref(tp); str = tp as Structure; } while (str != null && str.Functor == Symbol.PrologListConstructor); if (!(tp is Symbol) && tp != null) { this.PUTSOLO('|'); this.recwriteterm(tp, options, 1000, 1201); } this.PUTSOLO(']'); } else if (ISOPrologReader.Operator(termname, out prepri, out inpri, out postpri, out spec) && ISOPrologReader.isinfix(spec) && (inpri != 0)) { if (inpri >= termpri || (options & WLTERM) != 0 && ISOPrologReader.isxfy(spec) && inpri + 1 == termpri) { this.PUTSOLO('('); } if (ISOPrologReader.isyfx(spec)) { this.recwriteterm(__ARG(str, 1), options | WLTERM, inpri + 1, 0); } else { this.recwriteterm(__ARG(str, 1), options & OPTIONMASK, inpri, 0); } if (str.Functor == Symbol.Comma) { this.PUTSOLO(','); } else { this.showname(termname, options); } this.recwriteterm(__LASTARG(str, 2), options, ISOPrologReader.isxfy(spec) ? inpri + 1 : inpri, 0); if (inpri >= termpri || (options & WLTERM) != 0 && ISOPrologReader.isxfy(spec) && inpri + 1 == termpri) { this.PUTSOLO(')'); } } else { this.FUNCTIONAL(str, termname, options); } } else if (termarity == 1) { if (ISOPrologReader.Operator(termname, out prepri, out inpri, out postpri, out spec)) { if (ISOPrologReader.isprefix(spec) && ISOPrologReader.ispostfix(spec)) { /* in case of ambiguity: * select the associative operator over the nonassociative * select prefix over postfix */ if (ISOPrologReader.isfy(spec)) { spec = ISOPrologReader.FY; } else if (ISOPrologReader.isyf(spec)) { spec = ISOPrologReader.YF; } else { spec = ISOPrologReader.FX; } } if (ISOPrologReader.isprefix(spec) && prepri != 0) { if (prepri >= termpri || (options & WLTERM) != 0 && ISOPrologReader.isfy(spec) && prepri + 1 == termpri) { this.PUTSOLO('('); } this.showname(termname, options); if (needspace(tp, ISOPrologReader.isfy(spec) ? prepri + 1 : prepri)) { this.PUTSOLO(' '); } this.recwriteterm(__LASTARG(str, 1), options, ISOPrologReader.isfy(spec) ? prepri + 1 : prepri, 0); if (prepri >= termpri || (options & WLTERM) != 0 && ISOPrologReader.isfy(spec) && prepri + 1 == termpri) { this.PUTSOLO(')'); } } else if (ISOPrologReader.ispostfix(spec) && postpri != 0) { if (postpri >= termpri) { this.PUTSOLO('('); } if (ISOPrologReader.isyf(spec)) { this.recwriteterm(__LASTARG(str, 1), options | WLTERM, postpri + 1, 0); } else { this.recwriteterm(__LASTARG(str, 1), options, postpri, 0); } this.showname(termname, options); if (postpri >= termpri) { this.PUTSOLO(')'); } } else { this.FUNCTIONAL(str, termname, options); } } else if (str.Functor == Symbol.CurlyBrackets) { /* curly brackets */ this.PUTSOLO('{'); this.recwriteterm(__LASTARG(str, 1), options, 1201, 1201); this.PUTSOLO('}'); } else { this.FUNCTIONAL(str, termname, options); } } else { this.FUNCTIONAL(str, termname, options); } } else { var variable = tp as LogicVariable; if (variable != null) { if (this.lastitem == IDENTIFIER_ITEM) { this.PUTCHAR(' '); } this.LowLevelWrite(variable); this.lastitem = IDENTIFIER_ITEM; /* same properties as variable */ } else { this.LowLevelWrite(tp); } } } }
private static bool needspace(Object tp, int termpri) /* * checks whether the term tp will be displayed between * brackets, given the priority level termpri. In that * case a space need to be inserted before the left bracket. */ { int prepri, inpri, postpri, spec; if (tp == null) { return(false); } tp = Term.Deref(tp); var symbol = tp as Symbol; if (symbol != null) { return(ISOPrologReader.Operator(symbol.Name, out prepri, out inpri, out postpri, out spec)); } else { var structure = tp as Structure; if (structure != null) { Structure str = structure; if (ISOPrologReader.Operator(str.Functor.Name, out prepri, out inpri, out postpri, out spec)) { if (__ARITY(str) == 2) { return(inpri >= termpri); } if (__ARITY(str) == 1) { if (ISOPrologReader.isprefix(spec) && ISOPrologReader.ispostfix(spec)) { /* in case of ambiguity: * select the associative operator over the nonassociative * select prefix over postfix */ if (ISOPrologReader.isfy(spec)) { spec = ISOPrologReader.FY; } else if (ISOPrologReader.isyf(spec)) { spec = ISOPrologReader.YF; } else { spec = ISOPrologReader.FX; } } if (ISOPrologReader.isprefix(spec)) { return(prepri >= termpri); } else { return(postpri >= termpri); } } else { return(false); } } else { return(false); } } else { return(false); } } }
void PrintNextQuerySolution() { try { PrologContext.ResetStepLimit(); timer.Reset(); timer.Start(); bool gotOne = prologModeAnswerStream.MoveNext(); timer.Stop(); if (gotOne) { if (freeVariablesInCurrentQuery.Count > 0) { foundOneSolution = true; foreach (LogicVariable v in freeVariablesInCurrentQuery) { Output.WriteLine("{0} = {1}", v.Name, Term.ToStringInPrologFormat(Term.Deref(v))); } } else { Output.WriteLine("yes"); prologModeAnswerStream = null; } } else { Output.WriteLine(foundOneSolution?"no more solutions found":"no"); prologModeAnswerStream = null; } if (timeCommands) { double ms = timer.Elapsed.TotalMilliseconds; Output.WriteLine("{0:###}ms, {1} inference steps, {2:0.##} KLIPS.\n", ms, prologContext.StepsUsed, prologContext.StepsUsed / ms); } } catch (Exception) { prologModeAnswerStream = null; throw; } }
private IEnumerable <CutState> BinaryPrimitiveImplementation(object[] args, PrologContext context) { if (args.Length != 2) { throw new ArgumentCountException(Name, args, expectedArguments); } var arg1 = Term.Deref(args[0]); var arg2 = Term.Deref(args[1]); var arg1AsLogicVariable = arg1 as LogicVariable; if (arg1AsLogicVariable != null) { var arg2AsLogicVariable = arg2 as LogicVariable; if (arg2AsLogicVariable != null) { // Enumerating both arguments if (doubleEnumerator == null) { throw new InstantiationException( arg1AsLogicVariable, "At least one argument to " + Name + "/2 must be instantiated."); } if (arg1AsLogicVariable == arg2AsLogicVariable) { throw new InvalidOperationException(Name + "(X,X) is not supported."); } return(EnumerateBothDriver(arg1AsLogicVariable, arg2AsLogicVariable, context)); } if (!(arg2 is T2)) { throw new ArgumentTypeException(this.Name, this.arg2Name, arg1, typeof(T1)); } if (arg1Function != null) { // It's left-unique T1 arg1Value; if (arg1Function((T2)arg2, out arg1Value)) { return(Term.UnifyAndReturnCutState(arg1, arg1Value)); } return(PrologPrimitives.FailImplementation); } // It's not left-unique if (arg1Enumerator == null) { throw new InstantiationException(arg1AsLogicVariable, Name + "/2: first argument must be instantiated."); } return(this.EnumerateArg1Driver(arg1AsLogicVariable, (T2)arg2, context)); } var variable1 = arg2 as LogicVariable; if (variable1 != null) { if (!(arg1 is T1)) { throw new ArgumentTypeException(this.Name, this.arg1Name, arg1, typeof(T1)); } if (arg2Function != null) { // It's right-unique T2 arg2Value; if (arg2Function((T1)arg1, out arg2Value)) { return(Term.UnifyAndReturnCutState(arg2, arg2Value)); } return(PrologPrimitives.FailImplementation); } // It's not right-unqiue if (arg2Enumerator == null) { throw new InstantiationException(variable1, Name + "/2: second argument must be instantiated."); } return(this.EnumerateArg2Driver((T1)arg1, variable1, context)); } // Filtering if (!(arg1 is T1)) { throw new ArgumentTypeException(this.Name, this.arg1Name, arg1, typeof(T1)); } if (!(arg2 is T2)) { throw new ArgumentTypeException(this.Name, this.arg1Name, arg1, typeof(T1)); } if (filter == null) { throw new InstantiatedVariableException(null, Name + ": at least one argument must be uninstantiated."); } return(CutStateSequencer.FromBoolean(this.filter((T1)arg1, (T2)arg2))); }
private void Render(object renderingOperation) { renderingOperation = Term.Deref(renderingOperation); if (renderingOperation == null) { return; } var op = renderingOperation as Structure; if (op != null) { switch (op.Functor.Name) { case "cons": Render(op.Argument(0)); Render(op.Argument(1)); break; case "line": foreach (var arg in op.Arguments) { Render(arg); } textBuilder.AppendLine(); break; case "color": textBuilder.AppendFormat("<color={0}>", op.Argument(0)); for (int i = 1; i < op.Arity; i++) { Render(op.Argument(i)); } textBuilder.Append("</color>"); break; case "size": textBuilder.AppendFormat("<size={0}>", op.Argument(0)); for (int i = 1; i < op.Arity; i++) { Render(op.Argument(i)); } textBuilder.Append("</size>"); break; case "bold": textBuilder.AppendFormat("<b>"); for (int i = 0; i < op.Arity; i++) { Render(op.Argument(i)); } textBuilder.Append("</b>"); break; case "italic": textBuilder.AppendFormat("<i>"); for (int i = 0; i < op.Arity; i++) { Render(op.Argument(i)); } textBuilder.Append("</i>"); break; case "term": textBuilder.Append(ISOPrologWriter.WriteToString(op.Argument(0))); break; case "table": MakeTable(op.Argument(0)); break; default: textBuilder.Append(ISOPrologWriter.WriteToString(op)); break; } } else { var str = renderingOperation as string; textBuilder.Append(str ?? ISOPrologWriter.WriteToString(renderingOperation)); } }
public static object Eval(object term, PrologContext context) { term = Term.Deref(term); var indexical = term as Indexical; if (indexical != null) { return(indexical.GetValue(context)); } var offendingVariable = term as LogicVariable; if (offendingVariable != null) { throw new InstantiationException(offendingVariable, "arithmetic expression cannot be evaluated because it includes an uninstantiated variable."); } var t = term as Structure; if (t == null) { //var s = term as Symbol; //if (s != null) // throw new BadProcedureException(s, 0); //throw new BadProcedureException(term); return(term); // It's a literal. } switch (t.Functor.Name) { case "+": if (t.Arguments.Length != 2) { throw new ArgumentCountException("+", t.Arguments, "number1", "number2"); } return(GenericArithmetic.Add(Eval(t.Arguments[0], context), Eval(t.Arguments[1], context))); case "-": if (t.Arguments.Length == 2) { return(GenericArithmetic.Subtract(Eval(t.Arguments[0], context), Eval(t.Arguments[1], context))); } if (t.Arguments.Length == 1) { return(GenericArithmetic.Subtract(Eval(t.Arguments[0], context))); } throw new ArgumentException("Wrong number of arguments in - expression; should be 1 or 2."); case "*": if (t.Arguments.Length != 2) { throw new ArgumentCountException("*", t.Arguments, "number1", "number2"); } return(GenericArithmetic.Multiply(Eval(t.Arguments[0], context), Eval(t.Arguments[1], context))); case "/": if (t.Arguments.Length != 2) { throw new ArgumentCountException("/", t.Arguments, "number1", "number2"); } return(GenericArithmetic.Divide(Eval(t.Arguments[0], context), Eval(t.Arguments[1], context))); case "mod": if (t.Arguments.Length != 2) { throw new ArgumentCountException("mod", t.Arguments, "number1", "number2"); } return(Convert.ToInt32(Eval(t.Arguments[0], context)) % Convert.ToInt32((Eval(t.Arguments[1], context)))); case "//": if (t.Arguments.Length != 2) { throw new ArgumentCountException("//", t.Arguments, "number1", "number2"); } return(Convert.ToInt32(Eval(t.Arguments[0], context)) / Convert.ToInt32(Eval(t.Arguments[1], context))); case "sqrt": if (t.Arguments.Length != 1) { throw new ArgumentCountException("sqrt", t.Arguments, "number"); } return(Math.Sqrt(Convert.ToDouble(Eval(t.Arguments[0], context)))); case "abs": if (t.Arguments.Length != 1) { throw new ArgumentCountException("abs", t.Arguments, "number"); } return(Math.Abs(Convert.ToDouble(Eval(t.Arguments[0], context)))); case "log": if (t.Arguments.Length != 1) { throw new ArgumentCountException("log", t.Arguments, "number"); } return(Math.Log(Convert.ToDouble(Eval(t.Arguments[0], context)))); case "exp": if (t.Arguments.Length != 1) { throw new ArgumentCountException("exp", t.Arguments, "number"); } return(Math.Exp(Convert.ToDouble(Eval(t.Arguments[0], context)))); case "floor": if (t.Arguments.Length != 1) { throw new ArgumentCountException("floor", t.Arguments, "number"); } return(Math.Floor(Convert.ToDouble(Eval(t.Arguments[0], context)))); case "float": if (t.Arguments.Length != 1) { throw new ArgumentCountException("floor", t.Arguments, "number"); } return(Convert.ToSingle(Eval(t.Arguments[0], context))); case "min": if (t.Arguments.Length != 2) { throw new ArgumentCountException("min", t.Arguments, "number1", "number2"); } return(GenericArithmetic.Min(Eval(t.Arguments[0], context), Eval(t.Arguments[1], context))); case "max": if (t.Arguments.Length != 2) { throw new ArgumentCountException("max", t.Arguments, "number1", "number2"); } return(GenericArithmetic.Max(Eval(t.Arguments[0], context), Eval(t.Arguments[1], context))); case "magnitude": { if (t.Arguments.Length != 1) { throw new ArgumentCountException("magnitude", t.Arguments, "Vector3"); } object v = Eval(t.Argument(0), context); if (!(v is Vector3)) { throw new ArgumentTypeException("magnitude", "vector", v, typeof(Vector3)); } return(((Vector3)v).magnitude); } case "magnitude_squared": { if (t.Arguments.Length != 1) { throw new ArgumentCountException("magnitude_squared", t.Arguments, "Vector3"); } object v = Eval(t.Argument(0), context); if (!(v is Vector3)) { throw new ArgumentTypeException("magnitude_squared", "vector", v, typeof(Vector3)); } return(((Vector3)v).sqrMagnitude); } case "distance": { if (t.Arguments.Length != 2) { throw new ArgumentCountException("distance", t.Arguments, "v1", "v2"); } object v1 = Eval(t.Argument(0), context); if (v1 is GameObject) { v1 = ((GameObject)v1).transform.position; } object v2 = Eval(t.Argument(1), context); if (v2 is GameObject) { v2 = ((GameObject)v2).transform.position; } if (!(v1 is Vector3)) { throw new ArgumentTypeException("distance", "v1", v1, typeof(Vector3)); } if (!(v2 is Vector3)) { throw new ArgumentTypeException("distance", "v2", v2, typeof(Vector3)); } return(Vector3.Distance((Vector3)v1, (Vector3)v2)); } case "distance_squared": { if (t.Arguments.Length != 2) { throw new ArgumentCountException("distance_squared", t.Arguments, "v1", "v2"); } object v1 = Eval(t.Argument(0), context); if (v1 is GameObject) { v1 = ((GameObject)v1).transform.position; } object v2 = Eval(t.Argument(1), context); if (v2 is GameObject) { v2 = ((GameObject)v2).transform.position; } if (!(v1 is Vector3)) { throw new ArgumentTypeException("distance_squared", "v1", v1, typeof(Vector3)); } if (!(v2 is Vector3)) { throw new ArgumentTypeException("distance_squared", "v2", v2, typeof(Vector3)); } return(Vector3.SqrMagnitude((Vector3)v1 - (Vector3)v2)); } case "position": { if (t.Arguments.Length != 1) { throw new ArgumentCountException("position", t.Arguments, "gameObject"); } var gameObject = Eval(t.Argument(0), context); var go = gameObject as GameObject; if (go == null) { throw new ArgumentTypeException("position", "gameObject", gameObject, typeof(GameObject)); } return(go.transform.position); } case ".": if (t.Arguments.Length != 2) { throw new ArgumentCountException(".", t.Arguments, "object"); } return(EvalMemberExpression(t.Arguments[0], t.Arguments[1], context)); case "property": { if (t.Arguments.Length != 2) { throw new ArgumentCountException("property", t.Arguments, "object", "property_name"); } object o = t.Argument(0); if (o is Structure) { o = Eval(o, context); } var name = t.Argument(1) as Symbol; if (name == null) { throw new ArgumentTypeException("property", "property_name", t.Argument(1), typeof(Symbol)); } return(o.GetPropertyOrField(name.Name)); } case "vector": { if (t.Arguments.Length != 3) { throw new ArgumentCountException("vector", t.Arguments, "x", "y", "z"); } return(new Vector3(Convert.ToSingle(Eval(t.Argument(0), context)), Convert.ToSingle(Eval(t.Argument(1), context)), Convert.ToSingle(Eval(t.Argument(2), context)))); } case "instance_id": { if (t.Arguments.Length != 1) { throw new ArgumentCountException("instance_id", t.Arguments, "game_object"); } var arg = t.Argument(0) as Object; if (arg == null) { throw new ArgumentTypeException("instance_id", "object", t.Argument(0), typeof(Object)); } return(arg.GetInstanceID()); } default: throw new BadProcedureException(t.Functor, t.Arguments.Length); } }
private object Register(PrologContext context, int framePointer, ushort pc) { return(Term.Deref(context.GetStack(framePointer, code[pc]))); }