Mantis#1314. Thank you kindly, Kinoc for YieldProlog.
I have added everything *except* the patch to .../LSL/Compiler.cs. The Compiler.cs patch has a namespace issue. Lets make a second patch to close the gap.0.6.0-stable
							parent
							
								
									febe78d062
								
							
						
					
					
						commit
						25b7d9944d
					
				| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
?using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
 | 
			
		||||
{
 | 
			
		||||
    public class YP2CSConverter
 | 
			
		||||
    {
 | 
			
		||||
        public YP2CSConverter()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Convert(string Script)
 | 
			
		||||
        {
 | 
			
		||||
            string CS_code = GenCode(Script);
 | 
			
		||||
            return CS_code;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        static string GenCode(string myCode)
 | 
			
		||||
        {
 | 
			
		||||
            Variable TermList = new Variable();
 | 
			
		||||
            Variable FunctionCode = new Variable();
 | 
			
		||||
 | 
			
		||||
            string CS_code = "";
 | 
			
		||||
 | 
			
		||||
            int cs_pointer = myCode.IndexOf("\n//cs");
 | 
			
		||||
            if (cs_pointer > 0)
 | 
			
		||||
            {
 | 
			
		||||
                CS_code = myCode.Substring(cs_pointer); // CS code comes after
 | 
			
		||||
                myCode = myCode.Substring(0, cs_pointer);
 | 
			
		||||
            }
 | 
			
		||||
            myCode.Replace("//yp", "%YPCode");
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            StringWriter myCS_SW = new StringWriter();
 | 
			
		||||
            StringReader myCode_SR = new StringReader(" yp_nop_header_nop. \n "+myCode + "\n");
 | 
			
		||||
 | 
			
		||||
            YP.see(myCode_SR);
 | 
			
		||||
            YP.tell(myCS_SW);
 | 
			
		||||
 | 
			
		||||
            //Console.WriteLine("Mycode\n ===================================\n" + myCode+"\n");
 | 
			
		||||
            foreach (bool l1 in Parser.parseInput(TermList))
 | 
			
		||||
            {
 | 
			
		||||
                foreach (bool l2 in YPCompiler.makeFunctionPseudoCode(TermList, FunctionCode))
 | 
			
		||||
                {
 | 
			
		||||
                    ListPair VFC = new ListPair(FunctionCode, new Variable());
 | 
			
		||||
                    //Console.WriteLine("-------------------------")
 | 
			
		||||
                    //Console.WriteLine( FunctionCode.ToString())
 | 
			
		||||
                    //Console.WriteLine("-------------------------")
 | 
			
		||||
                    YPCompiler.convertFunctionCSharp(FunctionCode);
 | 
			
		||||
                    //YPCompiler.convertStringCodesCSharp(VFC);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            YP.seen();
 | 
			
		||||
            myCS_SW.Close();
 | 
			
		||||
            YP.told();
 | 
			
		||||
            StringBuilder bu = myCS_SW.GetStringBuilder();
 | 
			
		||||
            string finalcode = "//YPEncoded\n" + bu.ToString();
 | 
			
		||||
            // FIX script events (we're in the same script)
 | 
			
		||||
            // 'YP.script_event(Atom.a(@"sayit"),' ==> 'sayit('
 | 
			
		||||
            finalcode = Regex.Replace(finalcode,
 | 
			
		||||
                                        @"YP.script_event\(Atom.a\(\@\""(.*?)""\)\,",
 | 
			
		||||
                                        @"this.$1(",
 | 
			
		||||
                                        RegexOptions.Compiled | RegexOptions.Singleline);
 | 
			
		||||
            finalcode = Regex.Replace(finalcode,
 | 
			
		||||
                            @" static ",
 | 
			
		||||
                            @" ",
 | 
			
		||||
                            RegexOptions.Compiled | RegexOptions.Singleline);
 | 
			
		||||
 | 
			
		||||
            finalcode = CS_code+"\n\r"+ finalcode;
 | 
			
		||||
            finalcode = Regex.Replace(finalcode,
 | 
			
		||||
                                        @"PrologCallback",
 | 
			
		||||
                                        @"public IEnumerable<bool> ",
 | 
			
		||||
                                        RegexOptions.Compiled | RegexOptions.Singleline);
 | 
			
		||||
            return finalcode;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,218 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public class Atom : IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        private static Dictionary<string, Atom> _atomStore = new Dictionary<string, Atom>();
 | 
			
		||||
        public readonly string _name;
 | 
			
		||||
        public readonly Atom _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 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 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>
 | 
			
		||||
        /// If Obj is an Atom unify its _module with Module.  If the Atom's _module is null, use Atom.NIL.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Atom"></param>
 | 
			
		||||
        /// <param name="Module"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static IEnumerable<bool> module(object Obj, object Module)
 | 
			
		||||
        {
 | 
			
		||||
            Obj = YP.getValue(Obj);
 | 
			
		||||
            if (Obj is Atom)
 | 
			
		||||
            {
 | 
			
		||||
                if (((Atom)Obj)._module == null)
 | 
			
		||||
                    return YP.unify(Module, Atom.NIL);
 | 
			
		||||
                else
 | 
			
		||||
                    return YP.unify(Module, ((Atom)Obj)._module);
 | 
			
		||||
            }
 | 
			
		||||
            return YP.fail();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static readonly Atom NIL = Atom.a("[]");
 | 
			
		||||
        public static readonly Atom DOT = Atom.a(".");
 | 
			
		||||
        public static readonly Atom F = Atom.a("f");
 | 
			
		||||
        public static readonly Atom SLASH = Atom.a("/");
 | 
			
		||||
        public static readonly Atom HAT = Atom.a("^");
 | 
			
		||||
        public static readonly Atom RULE = Atom.a(":-");
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> unify(object arg)
 | 
			
		||||
        {
 | 
			
		||||
            arg = YP.getValue(arg);
 | 
			
		||||
            if (arg is Atom)
 | 
			
		||||
                return Equals(arg) ? YP.succeed() : YP.fail();
 | 
			
		||||
            else if (arg is Variable)
 | 
			
		||||
                return ((Variable)arg).unify(this);
 | 
			
		||||
            else
 | 
			
		||||
                return YP.fail();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void addUniqueVariables(List<Variable> variableSet)
 | 
			
		||||
        {
 | 
			
		||||
            // Atom does not contain variables.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object makeCopy(Variable.CopyStore copyStore)
 | 
			
		||||
        {
 | 
			
		||||
            // Atom does not contain variables that need to be copied.
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool termEqual(object term)
 | 
			
		||||
        {
 | 
			
		||||
            return Equals(YP.getValue(term));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ground()
 | 
			
		||||
        {
 | 
			
		||||
            // Atom is always ground.
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is Atom)
 | 
			
		||||
            {
 | 
			
		||||
                if (_module == null && ((Atom)obj)._module == null)
 | 
			
		||||
                    // When _declaringClass is null, we always use an identical object from _atomStore.
 | 
			
		||||
                    return this == obj;
 | 
			
		||||
                // Otherwise, ignore _declaringClass and do a normal string compare on the _name.
 | 
			
		||||
                return _name == ((Atom)obj)._name;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return _name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            // Debug: need to check _declaringClass.
 | 
			
		||||
            return _name.GetHashCode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string toQuotedString() 
 | 
			
		||||
        {
 | 
			
		||||
            if (_name.Length == 0)
 | 
			
		||||
                return "''";
 | 
			
		||||
            else if (this == Atom.NIL)
 | 
			
		||||
                return "[]";
 | 
			
		||||
 | 
			
		||||
            StringBuilder result = new StringBuilder(_name.Length);
 | 
			
		||||
            bool useQuotes = false;
 | 
			
		||||
            foreach (char c in _name)
 | 
			
		||||
            {
 | 
			
		||||
                int cInt = (int)c;
 | 
			
		||||
                if (c == '\'')
 | 
			
		||||
                {
 | 
			
		||||
                    result.Append("''");
 | 
			
		||||
                    useQuotes = true;
 | 
			
		||||
                }
 | 
			
		||||
                else if (c == '_' || cInt >= (int)'a' && cInt <= (int)'z' ||
 | 
			
		||||
                         cInt >= (int)'A' && cInt <= (int)'Z' || cInt >= (int)'0' && cInt <= (int)'9')
 | 
			
		||||
                    result.Append(c);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // Debug: Need to handle non-printable chars.
 | 
			
		||||
                    result.Append(c);
 | 
			
		||||
                    useQuotes = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!useQuotes && (int)_name[0] >= (int)'a' && (int)_name[0] <= (int)'z')
 | 
			
		||||
                return result.ToString();
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // Surround in single quotes.
 | 
			
		||||
                result.Append('\'');
 | 
			
		||||
                return "'" + result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,234 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A BagofAnswers holds answers for bagof and setof.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class BagofAnswers
 | 
			
		||||
    {
 | 
			
		||||
        private object _template;
 | 
			
		||||
        private Variable[] _freeVariables;
 | 
			
		||||
        private Dictionary<object[], List<object>> _bagForFreeVariables;
 | 
			
		||||
        private List<object> _findallBagArray;
 | 
			
		||||
        private static TermArrayEqualityComparer _termArrayEqualityComparer =
 | 
			
		||||
            new TermArrayEqualityComparer();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// To get the free variables, split off any existential qualifiers from Goal such as the X in 
 | 
			
		||||
        /// "X ^ f(Y)", get the set of unbound variables in Goal that are not qualifiers, then remove
 | 
			
		||||
        /// the unbound variables that are qualifiers as well as the unbound variables in Template.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Template"></param>
 | 
			
		||||
        /// <param name="Goal"></param>
 | 
			
		||||
        public BagofAnswers(object Template, object Goal)
 | 
			
		||||
        {
 | 
			
		||||
            _template = Template;
 | 
			
		||||
 | 
			
		||||
            // First get the set of variables that are not free variables.
 | 
			
		||||
            List<Variable> variableSet = new List<Variable>();
 | 
			
		||||
            YP.addUniqueVariables(Template, variableSet);
 | 
			
		||||
            object UnqualifiedGoal = YP.getValue(Goal);
 | 
			
		||||
            while (UnqualifiedGoal is Functor2 && ((Functor2)UnqualifiedGoal)._name == Atom.HAT)
 | 
			
		||||
            {
 | 
			
		||||
                YP.addUniqueVariables(((Functor2)UnqualifiedGoal)._arg1, variableSet);
 | 
			
		||||
                UnqualifiedGoal = YP.getValue(((Functor2)UnqualifiedGoal)._arg2);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Remember how many non-free variables there are so we can find the unique free variables 
 | 
			
		||||
            //   that are added.
 | 
			
		||||
            int nNonFreeVariables = variableSet.Count;
 | 
			
		||||
            YP.addUniqueVariables(UnqualifiedGoal, variableSet);
 | 
			
		||||
            int nFreeVariables = variableSet.Count - nNonFreeVariables;
 | 
			
		||||
            if (nFreeVariables == 0)
 | 
			
		||||
            {
 | 
			
		||||
                // There were no free variables added, so we won't waste time with _bagForFreeVariables.
 | 
			
		||||
                _freeVariables = null;
 | 
			
		||||
                _findallBagArray = new List<object>();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // Copy the free variables.
 | 
			
		||||
                _freeVariables = new Variable[nFreeVariables];
 | 
			
		||||
                for (int i = 0; i < nFreeVariables; ++i)
 | 
			
		||||
                    _freeVariables[i] = variableSet[i + nNonFreeVariables];
 | 
			
		||||
 | 
			
		||||
                _bagForFreeVariables = new Dictionary<object[], List<object>>(_termArrayEqualityComparer);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void add()
 | 
			
		||||
        {
 | 
			
		||||
            if (_freeVariables == null)
 | 
			
		||||
                // The goal has bound the values in _template but we don't bother with _freeVariables.
 | 
			
		||||
                _findallBagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // The goal has bound the values in _template and _freeVariables.
 | 
			
		||||
                // Find the entry for this set of _freeVariables values.
 | 
			
		||||
                object[] freeVariableValues = new object[_freeVariables.Length];
 | 
			
		||||
                for (int i = 0; i < _freeVariables.Length; ++i)
 | 
			
		||||
                    freeVariableValues[i] = YP.getValue(_freeVariables[i]);
 | 
			
		||||
                List<object> bagArray;
 | 
			
		||||
                if (!_bagForFreeVariables.TryGetValue(freeVariableValues, out bagArray))
 | 
			
		||||
                {
 | 
			
		||||
                    bagArray = new List<object>();
 | 
			
		||||
                    _bagForFreeVariables[freeVariableValues] = bagArray;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Now copy the template and add to the bag for the freeVariables values.
 | 
			
		||||
                bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// For each result, unify the _freeVariables and unify bagArrayVariable with the associated bag.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="bagArrayVariable">this is unified with the List<object> of matches for template that 
 | 
			
		||||
        /// corresponds to the bindings for freeVariables.  Be very careful: this does not unify with a Prolog 
 | 
			
		||||
        /// list.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public IEnumerable<bool> resultArray(Variable bagArrayVariable)
 | 
			
		||||
        {
 | 
			
		||||
            if (_freeVariables == null)
 | 
			
		||||
            {
 | 
			
		||||
                // No unbound free variables, so we only filled one bag.  If empty, bagof fails.
 | 
			
		||||
                if (_findallBagArray.Count > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (bool l1 in bagArrayVariable.unify(_findallBagArray))
 | 
			
		||||
                        yield return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                foreach (KeyValuePair<object[], List<object>> valuesAndBag in _bagForFreeVariables)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (bool l1 in YP.unifyArrays(_freeVariables, valuesAndBag.Key))
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (bool l2 in bagArrayVariable.unify(valuesAndBag.Value))
 | 
			
		||||
                            yield return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Debug: Should we free memory of the answers already returned?
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// For each result, unify the _freeVariables and unify Bag with the associated bag.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Bag"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public IEnumerable<bool> result(object Bag)
 | 
			
		||||
        {
 | 
			
		||||
            Variable bagArrayVariable = new Variable();
 | 
			
		||||
            foreach (bool l1 in resultArray(bagArrayVariable))
 | 
			
		||||
            {
 | 
			
		||||
                foreach (bool l2 in YP.unify(Bag, ListPair.make((List<object>)bagArrayVariable.getValue())))
 | 
			
		||||
                    yield return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// For each result, unify the _freeVariables and unify Bag with the associated bag which is sorted
 | 
			
		||||
        /// with duplicates removed, as in setof.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Bag"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public IEnumerable<bool> resultSet(object Bag)
 | 
			
		||||
        {
 | 
			
		||||
            Variable bagArrayVariable = new Variable();
 | 
			
		||||
            foreach (bool l1 in resultArray(bagArrayVariable))
 | 
			
		||||
            {
 | 
			
		||||
                List<object> bagArray = (List<object>)bagArrayVariable.getValue();
 | 
			
		||||
                YP.sortArray(bagArray);
 | 
			
		||||
                foreach (bool l2 in YP.unify(Bag, ListPair.makeWithoutRepeatedTerms(bagArray)))
 | 
			
		||||
                    yield return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<bool> bagofArray
 | 
			
		||||
            (object Template, object Goal, IEnumerable<bool> goalIterator, Variable bagArrayVariable)
 | 
			
		||||
        {
 | 
			
		||||
            BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal);
 | 
			
		||||
            foreach (bool l1 in goalIterator)
 | 
			
		||||
                bagOfAnswers.add();
 | 
			
		||||
            return bagOfAnswers.resultArray(bagArrayVariable);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<bool> bagof
 | 
			
		||||
            (object Template, object Goal, IEnumerable<bool> goalIterator, object Bag)
 | 
			
		||||
        {
 | 
			
		||||
            BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal);
 | 
			
		||||
            foreach (bool l1 in goalIterator)
 | 
			
		||||
                bagOfAnswers.add();
 | 
			
		||||
            return bagOfAnswers.result(Bag);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IEnumerable<bool> setof
 | 
			
		||||
            (object Template, object Goal, IEnumerable<bool> goalIterator, object Bag)
 | 
			
		||||
        {
 | 
			
		||||
            BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal);
 | 
			
		||||
            foreach (bool l1 in goalIterator)
 | 
			
		||||
                bagOfAnswers.add();
 | 
			
		||||
            return bagOfAnswers.resultSet(Bag);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// A TermArrayEqualityComparer implements IEqualityComparer to compare two object arrays using YP.termEqual.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private class TermArrayEqualityComparer : IEqualityComparer<object[]>
 | 
			
		||||
        {
 | 
			
		||||
            public bool Equals(object[] array1, object[] array2)
 | 
			
		||||
            {
 | 
			
		||||
                if (array1.Length != array2.Length)
 | 
			
		||||
                    return false;
 | 
			
		||||
                for (int i = 0; i < array1.Length; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!YP.termEqual(array1[i], array2[i]))
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public int GetHashCode(object[] array)
 | 
			
		||||
            {
 | 
			
		||||
                int hashCode = 0;
 | 
			
		||||
                for (int i = 0; i < array.Length; ++i)
 | 
			
		||||
                    hashCode ^= array[i].GetHashCode();
 | 
			
		||||
                return hashCode;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,103 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A FindallAnswers holds answers for findall.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FindallAnswers
 | 
			
		||||
    {
 | 
			
		||||
        private object _template;
 | 
			
		||||
        private List<object> _bagArray;
 | 
			
		||||
 | 
			
		||||
        public FindallAnswers(object Template)
 | 
			
		||||
        {
 | 
			
		||||
            _template = Template;
 | 
			
		||||
            _bagArray = new List<object>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void add()
 | 
			
		||||
        {
 | 
			
		||||
            _bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<object> resultArray()
 | 
			
		||||
        {
 | 
			
		||||
            return _bagArray;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Unify Bag with the result. This frees the internal answers, so you can only call this once.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Bag"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public IEnumerable<bool> result(object Bag)
 | 
			
		||||
        {
 | 
			
		||||
            object result = ListPair.make(_bagArray);
 | 
			
		||||
            // Try to free the memory.
 | 
			
		||||
            _bagArray = null;
 | 
			
		||||
            return YP.unify(Bag, result);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is a simplified findall when the goal is a single call.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Template"></param>
 | 
			
		||||
        /// <param name="goal"></param>
 | 
			
		||||
        /// <param name="Bag"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static IEnumerable<bool> findall(object Template, IEnumerable<bool> goal, object Bag)
 | 
			
		||||
        {
 | 
			
		||||
            FindallAnswers findallAnswers = new FindallAnswers(Template);
 | 
			
		||||
            foreach (bool l1 in goal)
 | 
			
		||||
                findallAnswers.add();
 | 
			
		||||
            return findallAnswers.result(Bag);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Like findall, except return an array of the results.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="template"></param>
 | 
			
		||||
        /// <param name="goal"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static List<object> findallArray(object Template, IEnumerable<bool> goal)
 | 
			
		||||
        {
 | 
			
		||||
            FindallAnswers findallAnswers = new FindallAnswers(Template);
 | 
			
		||||
            foreach (bool l1 in goal)
 | 
			
		||||
                findallAnswers.add();
 | 
			
		||||
            return findallAnswers.resultArray();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,188 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public class Functor : IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        public readonly Atom _name;
 | 
			
		||||
        public readonly object[] _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 Functor(string name, object[] args)
 | 
			
		||||
            : this(Atom.a(name), args)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <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);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Call the main make, first converting name to an Atom.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="name"></param>
 | 
			
		||||
        /// <param name="args"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static object make(string name, object[] args)
 | 
			
		||||
        {
 | 
			
		||||
            return make(Atom.a(name), args);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> unify(object arg)
 | 
			
		||||
        {
 | 
			
		||||
            arg = YP.getValue(arg);
 | 
			
		||||
            if (arg is Functor)
 | 
			
		||||
            {
 | 
			
		||||
                Functor argFunctor = (Functor)arg;
 | 
			
		||||
                if (_name.Equals(argFunctor._name))
 | 
			
		||||
                    return YP.unifyArrays(_args, argFunctor._args);
 | 
			
		||||
                else
 | 
			
		||||
                    return YP.fail();
 | 
			
		||||
            }
 | 
			
		||||
            else if (arg is Variable)
 | 
			
		||||
                return ((Variable)arg).unify(this);
 | 
			
		||||
            else
 | 
			
		||||
                return YP.fail();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            string result = _name + "(" + YP.getValue(_args[0]);
 | 
			
		||||
            for (int i = 1; i < _args.Length; ++i)
 | 
			
		||||
                result += ", " + YP.getValue(_args[i]);
 | 
			
		||||
            result += ")";
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool termEqual(object term)
 | 
			
		||||
        {
 | 
			
		||||
            term = YP.getValue(term);
 | 
			
		||||
            if (term is Functor)
 | 
			
		||||
            {
 | 
			
		||||
                Functor termFunctor = (Functor)term;
 | 
			
		||||
                if (_name.Equals(termFunctor._name) && _args.Length == termFunctor._args.Length)
 | 
			
		||||
                {
 | 
			
		||||
                    for (int i = 0; i < _args.Length; ++i)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!YP.termEqual(_args[i], termFunctor._args[i]))
 | 
			
		||||
                            return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool lessThan(Functor functor)
 | 
			
		||||
        {
 | 
			
		||||
            // Do the equal check first since it is faster.
 | 
			
		||||
            if (!_name.Equals(functor._name))
 | 
			
		||||
                return _name.lessThan(functor._name);
 | 
			
		||||
 | 
			
		||||
            if (_args.Length != functor._args.Length)
 | 
			
		||||
                return _args.Length < functor._args.Length;
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < _args.Length; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                if (!YP.termEqual(_args[i], functor._args[i]))
 | 
			
		||||
                    return YP.termLessThan(_args[i], functor._args[i]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ground()
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < _args.Length; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                if (!YP.ground(_args[i]))
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void addUniqueVariables(List<Variable> variableSet)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < _args.Length; ++i)
 | 
			
		||||
                YP.addUniqueVariables(_args[i], variableSet);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object makeCopy(Variable.CopyStore copyStore)
 | 
			
		||||
        {
 | 
			
		||||
            object[] argsCopy = new object[_args.Length];
 | 
			
		||||
            for (int i = 0; i < _args.Length; ++i)
 | 
			
		||||
                argsCopy[i] = YP.makeCopy(_args[i], copyStore);
 | 
			
		||||
            return new Functor(_name, argsCopy);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,111 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public class Functor1 : IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        public readonly Atom _name;
 | 
			
		||||
        public readonly object _arg1;
 | 
			
		||||
 | 
			
		||||
        public Functor1(Atom name, object arg1)
 | 
			
		||||
        {
 | 
			
		||||
            _name = name;
 | 
			
		||||
            _arg1 = arg1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Functor1(string name, object arg1)
 | 
			
		||||
            : this(Atom.a(name), arg1)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> unify(object arg)
 | 
			
		||||
        {
 | 
			
		||||
            arg = YP.getValue(arg);
 | 
			
		||||
            if (arg is Functor1)
 | 
			
		||||
            {
 | 
			
		||||
                Functor1 argFunctor = (Functor1)arg;
 | 
			
		||||
                if (_name.Equals(argFunctor._name))
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
 | 
			
		||||
                        yield return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (arg is Variable)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (bool l1 in ((Variable)arg).unify(this))
 | 
			
		||||
                    yield return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return _name + "(" + YP.getValue(_arg1) + ")";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool termEqual(object term)
 | 
			
		||||
        {
 | 
			
		||||
            term = YP.getValue(term);
 | 
			
		||||
            if (term is Functor1)
 | 
			
		||||
            {
 | 
			
		||||
                Functor1 termFunctor = (Functor1)term;
 | 
			
		||||
                return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool lessThan(Functor1 functor)
 | 
			
		||||
        {
 | 
			
		||||
            // Do the equal check first since it is faster.
 | 
			
		||||
            if (!_name.Equals(functor._name))
 | 
			
		||||
                return _name.lessThan(functor._name);
 | 
			
		||||
 | 
			
		||||
            return YP.termLessThan(_arg1, functor._arg1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ground()
 | 
			
		||||
        {
 | 
			
		||||
            return YP.ground(_arg1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void addUniqueVariables(List<Variable> variableSet)
 | 
			
		||||
        {
 | 
			
		||||
            YP.addUniqueVariables(_arg1, variableSet);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object makeCopy(Variable.CopyStore copyStore)
 | 
			
		||||
        {
 | 
			
		||||
            return new Functor1(_name, YP.makeCopy(_arg1, copyStore));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,154 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public class Functor2 : IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        public readonly Atom _name;
 | 
			
		||||
        public readonly object _arg1;
 | 
			
		||||
        public readonly object _arg2;
 | 
			
		||||
 | 
			
		||||
        public Functor2(Atom name, object arg1, object arg2)
 | 
			
		||||
        {
 | 
			
		||||
            _name = name;
 | 
			
		||||
            _arg1 = arg1;
 | 
			
		||||
            _arg2 = arg2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Functor2(string name, object arg1, object arg2)
 | 
			
		||||
            : this(Atom.a(name), arg1, arg2)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> unify(object arg)
 | 
			
		||||
        {
 | 
			
		||||
            arg = YP.getValue(arg);
 | 
			
		||||
            if (arg is Functor2)
 | 
			
		||||
            {
 | 
			
		||||
                Functor2 argFunctor = (Functor2)arg;
 | 
			
		||||
                if (_name.Equals(argFunctor._name))
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2))
 | 
			
		||||
                            yield return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (arg is Variable)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (bool l1 in ((Variable)arg).unify(this))
 | 
			
		||||
                    yield return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            if (_name == Atom.DOT)
 | 
			
		||||
                return listPairToString(this);
 | 
			
		||||
            else
 | 
			
		||||
                return _name + "(" + YP.getValue(_arg1) + ", " +  YP.getValue(_arg2) + ")";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool termEqual(object term)
 | 
			
		||||
        {
 | 
			
		||||
            term = YP.getValue(term);
 | 
			
		||||
            if (term is Functor2)
 | 
			
		||||
            {
 | 
			
		||||
                Functor2 termFunctor = (Functor2)term;
 | 
			
		||||
                return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1)
 | 
			
		||||
                     && YP.termEqual(_arg2, termFunctor._arg2);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool lessThan(Functor2 functor)
 | 
			
		||||
        {
 | 
			
		||||
            // Do the equal check first since it is faster.
 | 
			
		||||
            if (!_name.Equals(functor._name))
 | 
			
		||||
                return _name.lessThan(functor._name);
 | 
			
		||||
 | 
			
		||||
            if (!YP.termEqual(_arg1, functor._arg1))
 | 
			
		||||
                return YP.termLessThan(_arg1, functor._arg1);
 | 
			
		||||
 | 
			
		||||
            return YP.termLessThan(_arg2, functor._arg2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ground()
 | 
			
		||||
        {
 | 
			
		||||
            return YP.ground(_arg1) && YP.ground(_arg2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void addUniqueVariables(List<Variable> variableSet)
 | 
			
		||||
        {
 | 
			
		||||
            YP.addUniqueVariables(_arg1, variableSet);
 | 
			
		||||
            YP.addUniqueVariables(_arg2, variableSet);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object makeCopy(Variable.CopyStore copyStore)
 | 
			
		||||
        {
 | 
			
		||||
            return new Functor2(_name, YP.makeCopy(_arg1, copyStore), 
 | 
			
		||||
                YP.makeCopy(_arg2, copyStore));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string listPairToString(Functor2 listPair)
 | 
			
		||||
        {
 | 
			
		||||
            string result = "[";
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                object head = YP.getValue(listPair._arg1);
 | 
			
		||||
                object tail = YP.getValue(listPair._arg2);
 | 
			
		||||
                if (tail == (object)Atom.NIL)
 | 
			
		||||
                {
 | 
			
		||||
                    result += head;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                else if (tail is Functor2 && ((Functor2)tail)._name == Atom.DOT)
 | 
			
		||||
                {
 | 
			
		||||
                    result += head + ", ";
 | 
			
		||||
                    listPair = (Functor2)tail;
 | 
			
		||||
                    // Loop again.
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // The list is not terminated with NIL.
 | 
			
		||||
                    result += head + "|" + tail;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            result += "]";
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,133 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public class Functor3 : IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        public readonly Atom _name;
 | 
			
		||||
        public readonly object _arg1;
 | 
			
		||||
        public readonly object _arg2;
 | 
			
		||||
        public readonly object _arg3;
 | 
			
		||||
 | 
			
		||||
        public Functor3(Atom name, object arg1, object arg2, object arg3)
 | 
			
		||||
        {
 | 
			
		||||
            _name = name;
 | 
			
		||||
            _arg1 = arg1;
 | 
			
		||||
            _arg2 = arg2;
 | 
			
		||||
            _arg3 = arg3;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public Functor3(string name, object arg1, object arg2, object arg3)
 | 
			
		||||
            : this(Atom.a(name), arg1, arg2, arg3)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> unify(object arg)
 | 
			
		||||
        {
 | 
			
		||||
            arg = YP.getValue(arg);
 | 
			
		||||
            if (arg is Functor3)
 | 
			
		||||
            {
 | 
			
		||||
                Functor3 argFunctor = (Functor3)arg;
 | 
			
		||||
                if (_name.Equals(argFunctor._name))
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2))
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (bool l3 in YP.unify(_arg3, argFunctor._arg3))
 | 
			
		||||
                                yield return false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (arg is Variable)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (bool l1 in ((Variable)arg).unify(this))
 | 
			
		||||
                    yield return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return _name + "(" + YP.getValue(_arg1) + ", " + YP.getValue(_arg2) + ", " +
 | 
			
		||||
                YP.getValue(_arg3) + ")";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool termEqual(object term)
 | 
			
		||||
        {
 | 
			
		||||
            term = YP.getValue(term);
 | 
			
		||||
            if (term is Functor3)
 | 
			
		||||
            {
 | 
			
		||||
                Functor3 termFunctor = (Functor3)term;
 | 
			
		||||
                return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1)
 | 
			
		||||
                     && YP.termEqual(_arg2, termFunctor._arg2)
 | 
			
		||||
                     && YP.termEqual(_arg3, termFunctor._arg3);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool lessThan(Functor3 functor)
 | 
			
		||||
        {
 | 
			
		||||
            // Do the equal check first since it is faster.
 | 
			
		||||
            if (!_name.Equals(functor._name))
 | 
			
		||||
                return _name.lessThan(functor._name);
 | 
			
		||||
 | 
			
		||||
            if (!YP.termEqual(_arg1, functor._arg1))
 | 
			
		||||
                return YP.termLessThan(_arg1, functor._arg1);
 | 
			
		||||
 | 
			
		||||
            if (!YP.termEqual(_arg2, functor._arg2))
 | 
			
		||||
                return YP.termLessThan(_arg2, functor._arg2);
 | 
			
		||||
 | 
			
		||||
            return YP.termLessThan(_arg3, functor._arg3);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ground()
 | 
			
		||||
        {
 | 
			
		||||
            return YP.ground(_arg1) && YP.ground(_arg2) && YP.ground(_arg3);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void addUniqueVariables(List<Variable> variableSet)
 | 
			
		||||
        {
 | 
			
		||||
            YP.addUniqueVariables(_arg1, variableSet);
 | 
			
		||||
            YP.addUniqueVariables(_arg2, variableSet);
 | 
			
		||||
            YP.addUniqueVariables(_arg3, variableSet);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object makeCopy(Variable.CopyStore copyStore)
 | 
			
		||||
        {
 | 
			
		||||
            return new Functor3(_name, YP.makeCopy(_arg1, copyStore),
 | 
			
		||||
                YP.makeCopy(_arg2, copyStore), YP.makeCopy(_arg3, copyStore));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,288 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// An IndexedAnswers holds answers to a query based on the values of index arguments.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class IndexedAnswers : YP.IClause
 | 
			
		||||
    {
 | 
			
		||||
        // addAnswer adds the answer here and indexes it later.
 | 
			
		||||
        private List<object[]> _allAnswers = new List<object[]>();
 | 
			
		||||
        // The key has the arity of answers with non-null values for each indexed arg.  The value
 | 
			
		||||
        //   is a list of the matching answers.  The signature is implicit in the pattern on non-null index args.
 | 
			
		||||
        private Dictionary<HashedList, List<object[]>> _indexedAnswers =
 | 
			
		||||
            new Dictionary<HashedList, List<object[]>>();
 | 
			
		||||
        // Keeps track of whether we have started adding entries to _indexedAnswers for the signature.
 | 
			
		||||
        private Dictionary<int, object> _gotAnswersForSignature = new Dictionary<int, object>();
 | 
			
		||||
        private const int MAX_INDEX_ARGS = 31;
 | 
			
		||||
 | 
			
		||||
        public IndexedAnswers()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Elements of answer must be ground, since arguments with unbound variables make this
 | 
			
		||||
        /// into a dynamic rule which we don't index.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="answer"></param>
 | 
			
		||||
        public void addAnswer(object[] answer)
 | 
			
		||||
        {
 | 
			
		||||
            // Store a copy of the answer array.
 | 
			
		||||
            object[] answerCopy = new object[answer.Length];
 | 
			
		||||
            Variable.CopyStore copyStore = new Variable.CopyStore();
 | 
			
		||||
            for (int i = 0; i < answer.Length; ++i)
 | 
			
		||||
                answerCopy[i] = YP.makeCopy(answer[i], copyStore);
 | 
			
		||||
            if (copyStore.getNUniqueVariables() > 0)
 | 
			
		||||
                throw new InvalidOperationException
 | 
			
		||||
                    ("Elements of answer must be ground, but found " + copyStore.getNUniqueVariables() +
 | 
			
		||||
                     " unbound variables");
 | 
			
		||||
            _allAnswers.Add(answerCopy);
 | 
			
		||||
 | 
			
		||||
            // If match has already indexed answers for a signature, we need to add
 | 
			
		||||
            //   this to the existing indexed answers.
 | 
			
		||||
            foreach(int signature in _gotAnswersForSignature.Keys)
 | 
			
		||||
                indexAnswerForSignature(answerCopy, signature);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void indexAnswerForSignature(object[] answer, int signature)
 | 
			
		||||
        {
 | 
			
		||||
            // First find out which of the answer values can be used as an index.
 | 
			
		||||
            object[] indexValues = new object[answer.Length];
 | 
			
		||||
            for (int i = 0; i < answer.Length; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                // We limit the number of indexed args in a 32-bit signature.
 | 
			
		||||
                if (i >= MAX_INDEX_ARGS)
 | 
			
		||||
                    indexValues[i] = null;
 | 
			
		||||
                else
 | 
			
		||||
                    indexValues[i] = getIndexValue(YP.getValue(answer[i]));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // We need an entry in indexArgs from indexValues for each 1 bit in signature.
 | 
			
		||||
            HashedList indexArgs = new HashedList(indexValues.Length);
 | 
			
		||||
            for (int i = 0; i < indexValues.Length; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                if ((signature & (1 << i)) == 0)
 | 
			
		||||
                    indexArgs.Add(null);
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (indexValues[i] == null)
 | 
			
		||||
                        // The signature wants an index value here, but we don't have one so
 | 
			
		||||
                        //   we can't add it as an answer for this signature.
 | 
			
		||||
                        return;
 | 
			
		||||
                    else
 | 
			
		||||
                        indexArgs.Add(indexValues[i]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Add the answer to the answers list for indexArgs, creating the entry if needed.
 | 
			
		||||
            List<object[]> answers;
 | 
			
		||||
            if (!_indexedAnswers.TryGetValue(indexArgs, out answers))
 | 
			
		||||
            {
 | 
			
		||||
                answers = new List<object[]>();
 | 
			
		||||
                _indexedAnswers[indexArgs] = answers;
 | 
			
		||||
            }
 | 
			
		||||
            answers.Add(answer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> match(object[] arguments)
 | 
			
		||||
        {
 | 
			
		||||
            // Set up indexArgs, up to arg position MAX_INDEX_ARGS.  The signature has a 1 bit for
 | 
			
		||||
            //   each non-null index arg.
 | 
			
		||||
            HashedList indexArgs = new HashedList(arguments.Length);
 | 
			
		||||
            bool gotAllIndexArgs = true;
 | 
			
		||||
            int signature = 0;
 | 
			
		||||
            for (int i = 0; i < arguments.Length; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                object indexValue = null;
 | 
			
		||||
                if (i < MAX_INDEX_ARGS)
 | 
			
		||||
                {
 | 
			
		||||
                    // We limit the number of args in a 32-bit signature.
 | 
			
		||||
                    indexValue = getIndexValue(YP.getValue(arguments[i]));
 | 
			
		||||
                    if (indexValue != null)
 | 
			
		||||
                        signature += (1 << i);
 | 
			
		||||
                }
 | 
			
		||||
                if (indexValue == null)
 | 
			
		||||
                    gotAllIndexArgs = false;
 | 
			
		||||
                indexArgs.Add(indexValue);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            List<object[]> answers;
 | 
			
		||||
            if (signature == 0)
 | 
			
		||||
                // No index args, so we have to match from _allAnswers.
 | 
			
		||||
                answers = _allAnswers;
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (!_gotAnswersForSignature.ContainsKey(signature))
 | 
			
		||||
                {
 | 
			
		||||
                    // We need to create the entry in _indexedAnswers.
 | 
			
		||||
                    foreach (object[] answer in _allAnswers)
 | 
			
		||||
                        indexAnswerForSignature(answer, signature);
 | 
			
		||||
                    // Mark that we did this signature.
 | 
			
		||||
                    _gotAnswersForSignature[signature] = null;
 | 
			
		||||
                }
 | 
			
		||||
                if (!_indexedAnswers.TryGetValue(indexArgs, out answers))
 | 
			
		||||
                    yield break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (gotAllIndexArgs)
 | 
			
		||||
            {
 | 
			
		||||
                // All the arguments were already bound, so we don't need to do bindings.
 | 
			
		||||
                yield return false;
 | 
			
		||||
                yield break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Find matches in answers.
 | 
			
		||||
            IEnumerator<bool>[] iterators = new IEnumerator<bool>[arguments.Length];
 | 
			
		||||
            foreach (object[] answer in answers)
 | 
			
		||||
            {
 | 
			
		||||
                bool gotMatch = true;
 | 
			
		||||
                int nIterators = 0;
 | 
			
		||||
                // Try to bind all the arguments.
 | 
			
		||||
                for (int i = 0; i < arguments.Length; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    if (indexArgs[i] != null)
 | 
			
		||||
                        // We already matched this argument by looking up _indexedAnswers.
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    IEnumerator<bool> iterator = YP.unify(arguments[i], answer[i]).GetEnumerator();
 | 
			
		||||
                    iterators[nIterators++] = iterator;
 | 
			
		||||
                    // MoveNext() is true if YP.unify succeeds.
 | 
			
		||||
                    if (!iterator.MoveNext())
 | 
			
		||||
                    {
 | 
			
		||||
                        gotMatch = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    if (gotMatch)
 | 
			
		||||
                        yield return false;
 | 
			
		||||
                }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    // Manually finalize all the iterators.
 | 
			
		||||
                    for (int i = 0; i < nIterators; ++i)
 | 
			
		||||
                        iterators[i].Dispose();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// A HashedList extends an ArrayList with methods to get a hash and to check equality
 | 
			
		||||
        /// based on the elements of the list.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public class HashedList : ArrayList
 | 
			
		||||
        {
 | 
			
		||||
            private bool _gotHashCode = false;
 | 
			
		||||
            private int _hashCode;
 | 
			
		||||
 | 
			
		||||
            public HashedList()
 | 
			
		||||
                : base()
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public HashedList(int capacity)
 | 
			
		||||
                : base(capacity)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public HashedList(ICollection c)
 | 
			
		||||
                : base(c)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Debug: Should override all the other methods that change this.
 | 
			
		||||
            public override int Add(object value)
 | 
			
		||||
            {
 | 
			
		||||
                _gotHashCode = false;
 | 
			
		||||
                return base.Add(value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override int GetHashCode()
 | 
			
		||||
            {
 | 
			
		||||
                if (!_gotHashCode)
 | 
			
		||||
                {
 | 
			
		||||
                    int hashCode = 1;
 | 
			
		||||
                    foreach (object obj in this)
 | 
			
		||||
                        hashCode = 31 * hashCode + (obj == null ? 0 : obj.GetHashCode());
 | 
			
		||||
                    _hashCode = hashCode;
 | 
			
		||||
                    _gotHashCode = true;
 | 
			
		||||
                }
 | 
			
		||||
                return _hashCode;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override bool Equals(object obj)
 | 
			
		||||
            {
 | 
			
		||||
                if (!(obj is ArrayList))
 | 
			
		||||
                    return false;
 | 
			
		||||
 | 
			
		||||
                ArrayList objList = (ArrayList)obj;
 | 
			
		||||
                if (objList.Count != Count)
 | 
			
		||||
                    return false;
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i < Count; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    object value = objList[i];
 | 
			
		||||
                    if (value == null)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (this[i] != null)
 | 
			
		||||
                            return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!value.Equals(this[i]))
 | 
			
		||||
                            return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If we keep an index on value, return the value, or null if we don't index it.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="value">the term to examine.  Assume you already called YP.getValue(value)</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static object getIndexValue(object value)
 | 
			
		||||
        {
 | 
			
		||||
            if (value is Atom || value is string || value is Int32 || value is DateTime)
 | 
			
		||||
                return value;
 | 
			
		||||
            else
 | 
			
		||||
                return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,156 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public class ListPair : Functor2
 | 
			
		||||
    {
 | 
			
		||||
        public ListPair(object head, object tail) : base(Atom.DOT, head, tail)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static object make(List<object> list)
 | 
			
		||||
        {
 | 
			
		||||
            if (list.Count <= 0)
 | 
			
		||||
                return Atom.NIL;
 | 
			
		||||
 | 
			
		||||
            object result = Atom.NIL;
 | 
			
		||||
            // Start from the end.
 | 
			
		||||
            for (int i = list.Count - 1; i >= 0; --i)
 | 
			
		||||
                result = new ListPair(list[i], result);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static object make(object[] array)
 | 
			
		||||
        {
 | 
			
		||||
            if (array.Length <= 0)
 | 
			
		||||
                return Atom.NIL;
 | 
			
		||||
 | 
			
		||||
            object result = Atom.NIL;
 | 
			
		||||
            // Start from the end.
 | 
			
		||||
            for (int i = array.Length - 1; i >= 0; --i)
 | 
			
		||||
                result = new ListPair(array[i], result);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return a ListPair version of array, where repeated elements 
 | 
			
		||||
        /// (according to YP.termEqual) are removed.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="array"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static object makeWithoutRepeatedTerms(object[] array)
 | 
			
		||||
        {
 | 
			
		||||
            if (array.Length <= 0)
 | 
			
		||||
                return Atom.NIL;
 | 
			
		||||
 | 
			
		||||
            // Start from the end.
 | 
			
		||||
            object previousTerm = array[array.Length - 1];
 | 
			
		||||
            object result = new ListPair(previousTerm, Atom.NIL);
 | 
			
		||||
            for (int i = array.Length - 2; i >= 0; --i)
 | 
			
		||||
            {
 | 
			
		||||
                object term = array[i];
 | 
			
		||||
                if (YP.termEqual(term, previousTerm))
 | 
			
		||||
                    continue;
 | 
			
		||||
                result = new ListPair(term, result);
 | 
			
		||||
                previousTerm = term;
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return a ListPair version of array, where repeated elements 
 | 
			
		||||
        /// (according to YP.termEqual) are removed.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="array"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static object makeWithoutRepeatedTerms(List<object> array)
 | 
			
		||||
        {
 | 
			
		||||
            if (array.Count <= 0)
 | 
			
		||||
                return Atom.NIL;
 | 
			
		||||
 | 
			
		||||
            // Start from the end.
 | 
			
		||||
            object previousTerm = array[array.Count - 1];
 | 
			
		||||
            object result = new ListPair(previousTerm, Atom.NIL);
 | 
			
		||||
            for (int i = array.Count - 2; i >= 0; --i)
 | 
			
		||||
            {
 | 
			
		||||
                object term = array[i];
 | 
			
		||||
                if (YP.termEqual(term, previousTerm))
 | 
			
		||||
                    continue;
 | 
			
		||||
                result = new ListPair(term, result);
 | 
			
		||||
                previousTerm = term;
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static object make(object element1)
 | 
			
		||||
        {
 | 
			
		||||
            return new ListPair(element1, Atom.NIL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static object make(object element1, object element2)
 | 
			
		||||
        {
 | 
			
		||||
            return new ListPair(element1, new ListPair(element2, Atom.NIL));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static object make(object element1, object element2, object element3)
 | 
			
		||||
        {
 | 
			
		||||
            return new ListPair(element1, 
 | 
			
		||||
                new ListPair(element2, new ListPair(element3, Atom.NIL)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return an array of the elements in list or null if it is not
 | 
			
		||||
        /// a proper list.  If list is Atom.NIL, return an array of zero elements.
 | 
			
		||||
        /// This does not call YP.getValue on each element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="list"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public static object[] toArray(object list)
 | 
			
		||||
        {
 | 
			
		||||
            list = YP.getValue(list);
 | 
			
		||||
            if (list.Equals(Atom.NIL))
 | 
			
		||||
                return new object[0];
 | 
			
		||||
 | 
			
		||||
            List<object> result = new List<object>();
 | 
			
		||||
            for (object element = list;
 | 
			
		||||
                 element is Functor2 && ((Functor2)element)._name == Atom.DOT;
 | 
			
		||||
                 element = YP.getValue(((Functor2)element)._arg2))
 | 
			
		||||
                result.Add(((Functor2)element)._arg1);
 | 
			
		||||
 | 
			
		||||
            if (result.Count <= 0)
 | 
			
		||||
                return null;
 | 
			
		||||
            return result.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A PrologException is used as the exception thrown by YP.throw(Term).
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PrologException : Exception
 | 
			
		||||
    {
 | 
			
		||||
        public readonly object _term;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Create a PrologException with the given Term.  The printable exception message is the full Term.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="Term">the term of the exception</param>
 | 
			
		||||
        /// </param>
 | 
			
		||||
        public PrologException(object Term)
 | 
			
		||||
            : base(YP.getValue(Term).ToString())
 | 
			
		||||
        {
 | 
			
		||||
            _term = YP.makeCopy(Term, new Variable.CopyStore());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Create a PrologException where the Term is error(ErrorTerm, Message).
 | 
			
		||||
        /// This uses YP.makeCopy to copy the ErrorTerm and Message so that they are valid after unbinding.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="ErrorTerm">the term of the exception</param>
 | 
			
		||||
        /// <param name="Messsage">the message, converted to a string, to use as the printable exception message
 | 
			
		||||
        /// </param>
 | 
			
		||||
        public PrologException(object ErrorTerm, object Message)
 | 
			
		||||
            : base(YP.getValue(Message).ToString())
 | 
			
		||||
        {
 | 
			
		||||
            _term = YP.makeCopy(new Functor2(Atom.a("error"), ErrorTerm, Message), new Variable.CopyStore());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object Term
 | 
			
		||||
        {
 | 
			
		||||
            get { return _term; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,405 @@
 | 
			
		|||
YPOS: YieldProlog for OpenSim
 | 
			
		||||
 | 
			
		||||
 a compiler from Prolog to OpenSim compatible C# scripts
 | 
			
		||||
 | 
			
		||||
Ported by Kino Coursey and Douglas Miles at Daxtron Labs.
 | 
			
		||||
Based on Jeff Thompson Yield Prolog,  http://yieldprolog.sourceforge.net/
 | 
			
		||||
For Prolog see  http://en.wikipedia.org/wiki/Prolog
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
INTRODUCTION
 | 
			
		||||
 | 
			
		||||
This folder contains code to implement a Prolog compiler using the "Yield Statement" found in C#, Javascript, and Python.
 | 
			
		||||
The original Yield Prolog system can transform Prolog programs into C# code.
 | 
			
		||||
In this system we detect and extract YieldProlog code (with "//YP" as the first four characters in the script) and seperate it from any c# code ("marked by "//CS").
 | 
			
		||||
The YP code is transformed to C# and prepended to the "//CS" section, and passed as a bundel to the existing C# compiler.
 | 
			
		||||
The end result is Prolog can interface to OpenSim using the existing "//CS" functionality, and C# can call the compiled Prolog.
 | 
			
		||||
As such YP allows both declaritive and procedural programming in a 3D script enabled environment.
 | 
			
		||||
 | 
			
		||||
FEATURES
 | 
			
		||||
* Allows implementation of logic programming for objects and agents.
 | 
			
		||||
* C#/Javascript/Python as intermediate language
 | 
			
		||||
* Yield Prolog has relatively high speed of execution which is important in OpenSim.  http://yieldprolog.sourceforge.net/benchmarks.html
 | 
			
		||||
* It is compatable with the existing C#/Mono based system.
 | 
			
		||||
* Yield Prolog is BSD license
 | 
			
		||||
* Calling Prolog from C# scripts
 | 
			
		||||
* Calling C# functions (with LSL and OS functions) from Prolog
 | 
			
		||||
* Prolog dynamic database
 | 
			
		||||
* Edinburgh, Cocksin & Mellish style syntax.
 | 
			
		||||
* Compiler is generated by compiling the Prolog descrition of itself into C#
 | 
			
		||||
* Same script entry interface as LSL
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TODO 
 | 
			
		||||
* Utilize ability to generate Javascript and Python code
 | 
			
		||||
* Integrate Prolog database with Sim
 | 
			
		||||
* Translation error reporting back to the editor
 | 
			
		||||
* Communications via message passing
 | 
			
		||||
* Interface to external inference engines
 | 
			
		||||
 | 
			
		||||
POSSIBILITIES
 | 
			
		||||
* Inworld expert systems
 | 
			
		||||
* Parallel logic programming and expert systems
 | 
			
		||||
* Ontology based processing
 | 
			
		||||
* Knowledge based alerting, accessing and business rules
 | 
			
		||||
   For instance, listen on channel x, filter the events and broadcast alerts on channel y
 | 
			
		||||
     or send IM, emails etc.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
USAGE:
 | 
			
		||||
 | 
			
		||||
Add "yp" as an allowed compiler
 | 
			
		||||
 
 | 
			
		||||
OpenSim.ini 
 | 
			
		||||
[ScriptEngine.DotNetEngine]
 | 
			
		||||
AllowedCompilers=lsl,cs,js,vb,yp
 | 
			
		||||
 | 
			
		||||
Enter scripts using the inworld editing process. Scripts have the following format.
 | 
			
		||||
The first line of a file must have "//yp".
 | 
			
		||||
 | 
			
		||||
//yp
 | 
			
		||||
<PROLOG CODE>
 | 
			
		||||
//CS
 | 
			
		||||
<CS CODE>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
C# code calling a Prolog Predicate:
 | 
			
		||||
-----------------------------------
 | 
			
		||||
The Prolog predicate is transformed into a C# boolean function. So the general calling format is:
 | 
			
		||||
	foreach( bool var in  prolog_predicate(ARGS)) {};
 | 
			
		||||
 | 
			
		||||
I/O is via using a string reader and writer in conjunction with YP.See() and YP.Tell()
 | 
			
		||||
 | 
			
		||||
            StringWriter PrologOutuput= new StringWriter();
 | 
			
		||||
            StringReader PrologInput= new StringReader(myInputString);
 | 
			
		||||
            YP.see(PrologInput);
 | 
			
		||||
            YP.tell(PrologOutuput);
 | 
			
		||||
	    <CALL PROLOG CODE HERE>
 | 
			
		||||
	    YP.seen();
 | 
			
		||||
	    YP.told();
 | 
			
		||||
	    StringBuilder builder = PrologOutput.GetStringBuilder();
 | 
			
		||||
	    string finaloutput = builder.ToString();
 | 
			
		||||
 | 
			
		||||
Any prolog reads and writes will be to the passed StringReader and StringWriter. In fact any TextReader/TextWriter class can be used.
 | 
			
		||||
 | 
			
		||||
Strings in Prolog are stored as Atom's and you need to use an Atom object to match.
 | 
			
		||||
 | 
			
		||||
\\yp
 | 
			
		||||
wanted('bob').
 | 
			
		||||
\\cs
 | 
			
		||||
string Who="bob";
 | 
			
		||||
foreach( bool ans in wanted(Atom.a(Who) )){};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Prolog code calling a C# function:
 | 
			
		||||
-----------------------------------
 | 
			
		||||
The prolog code uses the script_event('name_of_function',ARGS) builtin, which is transformed into the function call.
 | 
			
		||||
The C# function called uses "PrologCallback" and returns a boolean.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Dynamic database assertions:
 | 
			
		||||
-----------------------------------
 | 
			
		||||
 | 
			
		||||
void assertdb2(string predicate, string arg1, string arg2)
 | 
			
		||||
{
 | 
			
		||||
        name = Atom.a(predicate);
 | 
			
		||||
        YP.assertFact(name, new object[] { arg1, arg2 });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void retractdb2(string predicate, string arg1, string arg2)
 | 
			
		||||
{
 | 
			
		||||
        name = Atom.a(predicate);
 | 
			
		||||
        YP.retractFact(name, new object[] { arg1, arg2 });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
========================= APPENDIX A: touch test ================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 ===================================
 | 
			
		||||
Input YP Code
 | 
			
		||||
 ===================================
 | 
			
		||||
//yp
 | 
			
		||||
 mydb('field2','field1').
 | 
			
		||||
 mydb('andy','jane').
 | 
			
		||||
 mydb('carl','dan').
 | 
			
		||||
 mydb('andy','bill').
 | 
			
		||||
 mydb('andy','betty').
 | 
			
		||||
 
 | 
			
		||||
 call_me(X):-mydb(X,Y) , respond(Y).
 | 
			
		||||
 respond(X):- script_event('sayit',X).
 | 
			
		||||
 | 
			
		||||
//cs
 | 
			
		||||
  public void default_event_touch_start(int N ) 
 | 
			
		||||
  {
 | 
			
		||||
      llSay(0,"pstart1");
 | 
			
		||||
      foreach( bool ans in call_me(Atom.a(@"andy") )){};
 | 
			
		||||
      llSay(0,"pstop2");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  public void default_event_state_entry()
 | 
			
		||||
  {
 | 
			
		||||
     llSay(0,"prolog tester active.");  
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
PrologCallback sayit(object ans)
 | 
			
		||||
  {
 | 
			
		||||
      llSay(0,"sayit1");
 | 
			
		||||
      string msg = "one answer is :"+((Variable)ans).getValue();  
 | 
			
		||||
      llSay(0,msg); 
 | 
			
		||||
      yield return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 ===================================
 | 
			
		||||
Generated CS Code
 | 
			
		||||
 ===================================
 | 
			
		||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog;using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;
 | 
			
		||||
namespace SecondLife { public class Script : OpenSim.Region.ScriptEngine.Common.BuiltIn_Commands_BaseClass { 
 | 
			
		||||
static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null;public Script() {  YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); } 
 | 
			
		||||
//cs
 | 
			
		||||
  public void default_event_touch_start(int N ) 
 | 
			
		||||
  {
 | 
			
		||||
      llSay(0,"pstart1");
 | 
			
		||||
      foreach( bool ans in call_me(Atom.a(@"carl") )){};
 | 
			
		||||
      llSay(0,"pstop2");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  public void default_event_state_entry()
 | 
			
		||||
  {
 | 
			
		||||
     llSay(0,"prolog tester active.");  
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool>  sayit(object ans)
 | 
			
		||||
  {
 | 
			
		||||
      llSay(0,"sayit1");
 | 
			
		||||
      string msg = "one answer is :"+((Variable)ans).getValue();  
 | 
			
		||||
      llSay(0,msg); 
 | 
			
		||||
      yield return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//YPEncoded
 | 
			
		||||
public IEnumerable<bool> mydb(object arg1, object arg2) {
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"carl"))) {
 | 
			
		||||
      foreach (bool l3 in YP.unify(arg2, Atom.a(@"dan"))) {
 | 
			
		||||
        yield return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
 | 
			
		||||
      foreach (bool l3 in YP.unify(arg2, Atom.a(@"bill"))) {
 | 
			
		||||
        yield return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
 | 
			
		||||
      foreach (bool l3 in YP.unify(arg2, Atom.a(@"betty"))) {
 | 
			
		||||
        yield return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool> call_me(object X) {
 | 
			
		||||
  {
 | 
			
		||||
    Variable Y = new Variable();
 | 
			
		||||
    foreach (bool l2 in mydb(X, Y)) {
 | 
			
		||||
      foreach (bool l3 in respond(Y)) {
 | 
			
		||||
        yield return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool> respond(object X) {
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in this.sayit( X)) {
 | 
			
		||||
      yield return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
========================= APPENDIX B:SENSOR INFORMED SCRIPT =====================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 ===================================
 | 
			
		||||
Input YP Code
 | 
			
		||||
 ===================================
 | 
			
		||||
//yp
 | 
			
		||||
 | 
			
		||||
nop.
 | 
			
		||||
 | 
			
		||||
good('Daxxon Kinoc').
 | 
			
		||||
good('Fluffy Kitty').
 | 
			
		||||
 | 
			
		||||
bad('Eric Evil').
 | 
			
		||||
bad('Spikey Plant').
 | 
			
		||||
 | 
			
		||||
prolog_notify(X) :- good(X) , script_event('accept',X).
 | 
			
		||||
prolog_notify(X) :- bad(X) , script_event('reject',X).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//cs
 | 
			
		||||
 | 
			
		||||
public void default_event_state_entry()
 | 
			
		||||
  {
 | 
			
		||||
     llSay(0,"prolog sensor tester active.");
 | 
			
		||||
 | 
			
		||||
    // Start a sensor looking for Agents
 | 
			
		||||
     llSensorRepeat("","",AGENT, 10, PI,20); 
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
public void default_event_sensor(int number_detected )
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i=0;i< number_detected ;i++)
 | 
			
		||||
   {
 | 
			
		||||
    string dName = llDetectedName(i);
 | 
			
		||||
    string dOwner = llDetectedName(i);
 | 
			
		||||
    foreach(bool response in prolog_notify(Atom.a(dName)) ){};
 | 
			
		||||
    foreach(bool response in prolog_notify(dOwner) ){};
 | 
			
		||||
    llSay(0,"Saw "+dName);
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string decodeToString(object obj)
 | 
			
		||||
{
 | 
			
		||||
    if (obj is Variable) { return (string) ((Variable)obj).getValue();}
 | 
			
		||||
    if (obj is Atom) { return (string) ((Atom)obj)._name;}
 | 
			
		||||
    return "unknown type";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PrologCallback accept(object ans)
 | 
			
		||||
  {
 | 
			
		||||
      string msg = "Welcoming :"+decodeToString(ans);  
 | 
			
		||||
      llSay(0,msg); 
 | 
			
		||||
      yield return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
PrologCallback reject(object ans)
 | 
			
		||||
  {
 | 
			
		||||
      string msg = "Watching :"+decodeToString(ans);  
 | 
			
		||||
      llSay(0,msg); 
 | 
			
		||||
      yield return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 ===================================
 | 
			
		||||
Generated CS Code
 | 
			
		||||
 ===================================
 | 
			
		||||
 | 
			
		||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog; using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;
 | 
			
		||||
namespace SecondLife { public class Script : OpenSim.Region.ScriptEngine.Common.BuiltIn_Commands_BaseClass { 
 | 
			
		||||
static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null; public Script() {  YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); } 
 | 
			
		||||
//cs
 | 
			
		||||
 | 
			
		||||
public void default_event_state_entry()
 | 
			
		||||
  {
 | 
			
		||||
     llSay(0,"prolog sensor tester active.");
 | 
			
		||||
 | 
			
		||||
    // Start a sensor looking for Agents
 | 
			
		||||
     llSensorRepeat("","",AGENT, 10, PI,20); 
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
public void default_event_sensor(int number_detected )
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i=0;i< number_detected ;i++)
 | 
			
		||||
   {
 | 
			
		||||
    string dName = llDetectedName(i);
 | 
			
		||||
    string dOwner = llDetectedName(i);
 | 
			
		||||
    foreach(bool response in prolog_notify(Atom.a(dName)) ){};
 | 
			
		||||
    foreach(bool response in prolog_notify(dOwner) ){};
 | 
			
		||||
    llSay(0,"Saw "+dName);
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string decodeToString(object obj)
 | 
			
		||||
{
 | 
			
		||||
    if (obj is Variable) { return (string) ((Variable)obj).getValue();}
 | 
			
		||||
    if (obj is Atom) { return (string) ((Atom)obj)._name;}
 | 
			
		||||
    return "unknown type";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool>  accept(object ans)
 | 
			
		||||
  {
 | 
			
		||||
      string msg = "Welcoming :"+decodeToString(ans);  
 | 
			
		||||
      llSay(0,msg); 
 | 
			
		||||
      yield return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool>  reject(object ans)
 | 
			
		||||
  {
 | 
			
		||||
      string msg = "Watching :"+decodeToString(ans);  
 | 
			
		||||
      llSay(0,msg); 
 | 
			
		||||
      yield return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//YPEncoded
 | 
			
		||||
public IEnumerable<bool> yp_nop_header_nop() {
 | 
			
		||||
  {
 | 
			
		||||
    yield return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool> good(object arg1) {
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"Daxxon Kinoc"))) {
 | 
			
		||||
      yield return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"Fluffy Kitty"))) {
 | 
			
		||||
      yield return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool> bad(object arg1) {
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"Eric Evil"))) {
 | 
			
		||||
      yield return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in YP.unify(arg1, Atom.a(@"Spikey Plant"))) {
 | 
			
		||||
      yield return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public IEnumerable<bool> prolog_notify(object X) {
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in good(X)) {
 | 
			
		||||
      foreach (bool l3 in this.accept( X)) {
 | 
			
		||||
        yield return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    foreach (bool l2 in bad(X)) {
 | 
			
		||||
      foreach (bool l3 in this.reject( X)) {
 | 
			
		||||
        yield return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// An UndefinedPredicateException extends PrologException to create an existence_error exception.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class UndefinedPredicateException : PrologException
 | 
			
		||||
    {
 | 
			
		||||
        private Atom _predicateName;
 | 
			
		||||
        private int _arity;
 | 
			
		||||
 | 
			
		||||
        public UndefinedPredicateException(object message, Atom predicateName, int arity)
 | 
			
		||||
            : base(new Functor2
 | 
			
		||||
                   (Atom.a("existence_error"), Atom.a("procedure"), new Functor2(Atom.a("/"), predicateName, arity)),
 | 
			
		||||
                   message)
 | 
			
		||||
        {
 | 
			
		||||
            _predicateName = predicateName;
 | 
			
		||||
            _arity = arity;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Atom PredicateName
 | 
			
		||||
        {
 | 
			
		||||
            get { return _predicateName; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int Arity
 | 
			
		||||
        {
 | 
			
		||||
            get { return _arity; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,196 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2007-2008, Jeff Thompson
 | 
			
		||||
 * 
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * 
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without 
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 * 
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the 
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the copyright holder nor the names of its contributors 
 | 
			
		||||
 *       may be used to endorse or promote products derived from this software 
 | 
			
		||||
 *       without specific prior written permission.
 | 
			
		||||
 * 
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
 | 
			
		||||
{
 | 
			
		||||
    public interface IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        IEnumerable<bool> unify(object arg);
 | 
			
		||||
        void addUniqueVariables(List<Variable> variableSet);
 | 
			
		||||
        object makeCopy(Variable.CopyStore copyStore);
 | 
			
		||||
        bool termEqual(object term);
 | 
			
		||||
        bool ground();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class Variable : IUnifiable
 | 
			
		||||
    {
 | 
			
		||||
        // Use _isBound separate from _value so that it can be bound to any value,
 | 
			
		||||
        //   including null.
 | 
			
		||||
        private bool _isBound = false;
 | 
			
		||||
        private object _value;
 | 
			
		||||
 | 
			
		||||
        public object getValue()
 | 
			
		||||
        {
 | 
			
		||||
            if (!_isBound)
 | 
			
		||||
                return this;
 | 
			
		||||
 | 
			
		||||
            object result = _value;
 | 
			
		||||
            while (result is Variable)
 | 
			
		||||
            {
 | 
			
		||||
                if (!((Variable)result)._isBound)
 | 
			
		||||
                    return result;
 | 
			
		||||
 | 
			
		||||
                // Keep following the Variable chain.
 | 
			
		||||
                result = ((Variable)result)._value;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<bool> unify(object arg)
 | 
			
		||||
        {
 | 
			
		||||
            if (!_isBound)
 | 
			
		||||
            {
 | 
			
		||||
                _value = YP.getValue(arg);
 | 
			
		||||
                if (_value == this)
 | 
			
		||||
                    // We are unifying this unbound variable with itself, so leave it unbound.
 | 
			
		||||
                    yield return false;
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    _isBound = true;
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        yield return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    {
 | 
			
		||||
                        // Remove the binding.
 | 
			
		||||
                        _isBound = false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                foreach (bool l1 in YP.unify(this, arg))
 | 
			
		||||
                    yield return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            object value = getValue();
 | 
			
		||||
            if (value == this)
 | 
			
		||||
                return "Variable";
 | 
			
		||||
            else
 | 
			
		||||
                return getValue().ToString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If bound, call YP.addUniqueVariables on the value.  Otherwise, if this unbound
 | 
			
		||||
        /// variable is not already in variableSet, add it.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="variableSet"></param>
 | 
			
		||||
        public void addUniqueVariables(List<Variable> variableSet)
 | 
			
		||||
        {
 | 
			
		||||
            if (_isBound)
 | 
			
		||||
                YP.addUniqueVariables(getValue(), variableSet);
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (variableSet.IndexOf(this) < 0)
 | 
			
		||||
                    variableSet.Add(this);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If bound, return YP.makeCopy for the value, else return copyStore.getCopy(this).
 | 
			
		||||
        /// However, if copyStore is null, just return this.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="copyStore"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public object makeCopy(Variable.CopyStore copyStore)
 | 
			
		||||
        {
 | 
			
		||||
            if (_isBound)
 | 
			
		||||
                return YP.makeCopy(getValue(), copyStore);
 | 
			
		||||
            else
 | 
			
		||||
                return copyStore == null ? this : copyStore.getCopy(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool termEqual(object term)
 | 
			
		||||
        {
 | 
			
		||||
            if (_isBound)
 | 
			
		||||
                return YP.termEqual(getValue(), term);
 | 
			
		||||
            else
 | 
			
		||||
                return this == YP.getValue(term);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ground()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isBound)
 | 
			
		||||
                // This is usually called by YP.ground which already did getValue, so this
 | 
			
		||||
                //   should never be reached, but check anyway.
 | 
			
		||||
                return YP.ground(getValue());
 | 
			
		||||
            else
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// A CopyStore is used by makeCopy to track which Variable objects have
 | 
			
		||||
        /// been copied.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public class CopyStore
 | 
			
		||||
        {
 | 
			
		||||
            private List<Variable> _inVariableSet = new List<Variable>();
 | 
			
		||||
            private List<Variable> _outVariableSet = new List<Variable>();
 | 
			
		||||
 | 
			
		||||
            /// <summary>
 | 
			
		||||
            /// If inVariable has already been copied, return its copy. Otherwise,
 | 
			
		||||
            /// return a fresh Variable associated with inVariable.
 | 
			
		||||
            /// </summary>
 | 
			
		||||
            /// <param name="inVariable"></param>
 | 
			
		||||
            /// <returns></returns>
 | 
			
		||||
            public Variable getCopy(Variable inVariable)
 | 
			
		||||
            {
 | 
			
		||||
                int index = _inVariableSet.IndexOf(inVariable);
 | 
			
		||||
                if (index >= 0)
 | 
			
		||||
                    return _outVariableSet[index];
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    Variable outVariable = new Variable();
 | 
			
		||||
                    _inVariableSet.Add(inVariable);
 | 
			
		||||
                    _outVariableSet.Add(outVariable);
 | 
			
		||||
                    return outVariable;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /// <summary>
 | 
			
		||||
            /// Return the number of unique variables that have been copied.
 | 
			
		||||
            /// </summary>
 | 
			
		||||
            /// <returns></returns>
 | 
			
		||||
            public int getNUniqueVariables()
 | 
			
		||||
            {
 | 
			
		||||
                return _inVariableSet.Count;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue