Update svn properties.

0.6.0-stable
Jeff Ames 2008-06-01 03:01:33 +00:00
parent ff6c89f199
commit d22a54a195
20 changed files with 14945 additions and 14949 deletions

View File

@ -1,50 +1,50 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
namespace OpenSim.Region.Environment.Modules.World.Archiver namespace OpenSim.Region.Environment.Modules.World.Archiver
{ {
/// <summary> /// <summary>
/// Constants for the archiving module /// Constants for the archiving module
/// </summary> /// </summary>
public class ArchiveConstants public class ArchiveConstants
{ {
/// <summary> /// <summary>
/// Path for the assets held in an archive /// Path for the assets held in an archive
/// </summary> /// </summary>
public static readonly string ASSETS_PATH = "assets/"; public static readonly string ASSETS_PATH = "assets/";
/// <summary> /// <summary>
/// Extension used for texture assets in archive /// Extension used for texture assets in archive
/// </summary> /// </summary>
public static readonly string TEXTURE_EXTENSION = ".jp2"; public static readonly string TEXTURE_EXTENSION = ".jp2";
/// <summary> /// <summary>
/// Path for the prims file /// Path for the prims file
/// </summary> /// </summary>
public static readonly string PRIMS_PATH = "prims.xml"; public static readonly string PRIMS_PATH = "prims.xml";
} }
} }

View File

@ -26,88 +26,83 @@
* *
*/ */
using System; using System;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog; using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
{ {
public class YP2CSConverter public class YP2CSConverter
{ {
public YP2CSConverter() public YP2CSConverter()
{ {
} }
public string Convert(string Script) public string Convert(string Script)
{ {
string CS_code = GenCode(Script); string CS_code = GenCode(Script);
return CS_code; return CS_code;
} }
static string GenCode(string myCode)
static string GenCode(string myCode) {
{ Variable TermList = new Variable();
Variable TermList = new Variable(); Variable FunctionCode = new Variable();
Variable FunctionCode = new Variable();
string CS_code = "";
string CS_code = "";
int cs_pointer = myCode.IndexOf("\n//cs");
int cs_pointer = myCode.IndexOf("\n//cs"); if (cs_pointer > 0)
if (cs_pointer > 0) {
{ CS_code = myCode.Substring(cs_pointer); // CS code comes after
CS_code = myCode.Substring(cs_pointer); // CS code comes after myCode = myCode.Substring(0, cs_pointer);
myCode = myCode.Substring(0, cs_pointer); }
} myCode.Replace("//yp", "%YPCode");
myCode.Replace("//yp", "%YPCode");
StringWriter myCS_SW = new StringWriter();
StringReader myCode_SR = new StringReader(" yp_nop_header_nop. \n "+myCode + "\n");
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);
YP.see(myCode_SR);
YP.tell(myCS_SW); //Console.WriteLine("Mycode\n ===================================\n" + myCode+"\n");
foreach (bool l1 in Parser.parseInput(TermList))
//Console.WriteLine("Mycode\n ===================================\n" + myCode+"\n"); {
foreach (bool l1 in Parser.parseInput(TermList)) foreach (bool l2 in YPCompiler.makeFunctionPseudoCode(TermList, FunctionCode))
{ {
foreach (bool l2 in YPCompiler.makeFunctionPseudoCode(TermList, FunctionCode)) ListPair VFC = new ListPair(FunctionCode, new Variable());
{ //Console.WriteLine("-------------------------")
ListPair VFC = new ListPair(FunctionCode, new Variable()); //Console.WriteLine( FunctionCode.ToString())
//Console.WriteLine("-------------------------") //Console.WriteLine("-------------------------")
//Console.WriteLine( FunctionCode.ToString()) YPCompiler.convertFunctionCSharp(FunctionCode);
//Console.WriteLine("-------------------------") //YPCompiler.convertStringCodesCSharp(VFC);
YPCompiler.convertFunctionCSharp(FunctionCode); }
//YPCompiler.convertStringCodesCSharp(VFC); }
YP.seen();
} myCS_SW.Close();
} YP.told();
YP.seen(); StringBuilder bu = myCS_SW.GetStringBuilder();
myCS_SW.Close(); string finalcode = "//YPEncoded\n" + bu.ToString();
YP.told(); // FIX script events (we're in the same script)
StringBuilder bu = myCS_SW.GetStringBuilder(); // 'YP.script_event(Atom.a(@"sayit"),' ==> 'sayit('
string finalcode = "//YPEncoded\n" + bu.ToString(); finalcode = Regex.Replace(finalcode,
// FIX script events (we're in the same script) @"YP.script_event\(Atom.a\(\@\""(.*?)""\)\,",
// 'YP.script_event(Atom.a(@"sayit"),' ==> 'sayit(' @"this.$1(",
finalcode = Regex.Replace(finalcode, RegexOptions.Compiled | RegexOptions.Singleline);
@"YP.script_event\(Atom.a\(\@\""(.*?)""\)\,", finalcode = Regex.Replace(finalcode,
@"this.$1(", @" static ",
RegexOptions.Compiled | RegexOptions.Singleline); @" ",
finalcode = Regex.Replace(finalcode, RegexOptions.Compiled | RegexOptions.Singleline);
@" static ",
@" ", finalcode = CS_code+"\n\r"+ finalcode;
RegexOptions.Compiled | RegexOptions.Singleline); finalcode = Regex.Replace(finalcode,
@"PrologCallback",
finalcode = CS_code+"\n\r"+ finalcode; @"public IEnumerable<bool> ",
finalcode = Regex.Replace(finalcode, RegexOptions.Compiled | RegexOptions.Singleline);
@"PrologCallback", return finalcode;
@"public IEnumerable<bool> ", }
RegexOptions.Compiled | RegexOptions.Singleline); }
return finalcode; }
}
}
}

View File

@ -1,218 +1,218 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public class Atom : IUnifiable public class Atom : IUnifiable
{ {
private static Dictionary<string, Atom> _atomStore = new Dictionary<string, Atom>(); private static Dictionary<string, Atom> _atomStore = new Dictionary<string, Atom>();
public readonly string _name; public readonly string _name;
public readonly Atom _module; public readonly Atom _module;
/// <summary> /// <summary>
/// You should not call this constructor, but use Atom.a instead. /// You should not call this constructor, but use Atom.a instead.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="module"></param> /// <param name="module"></param>
private Atom(string name, Atom module) private Atom(string name, Atom module)
{ {
_name = name; _name = name;
_module = module; _module = module;
} }
/// <summary> /// <summary>
/// Return the unique Atom object for name where module is null. You should use this to create /// 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. /// an Atom instead of calling the Atom constructor.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <returns></returns> /// <returns></returns>
public static Atom a(string name) public static Atom a(string name)
{ {
Atom atom; Atom atom;
if (!_atomStore.TryGetValue(name, out atom)) if (!_atomStore.TryGetValue(name, out atom))
{ {
atom = new Atom(name, null); atom = new Atom(name, null);
_atomStore[name] = atom; _atomStore[name] = atom;
} }
return atom; return atom;
} }
/// <summary> /// <summary>
/// Return an Atom object with the name and module. If module is null or Atom.NIL, /// 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. /// 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 /// 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. /// with the same name and module.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="module"></param> /// <param name="module"></param>
/// <returns></returns> /// <returns></returns>
public static Atom a(string name, Atom module) public static Atom a(string name, Atom module)
{ {
if (module == null || module == Atom.NIL) if (module == null || module == Atom.NIL)
return a(name); return a(name);
return new Atom(name, module); return new Atom(name, module);
} }
/// <summary> /// <summary>
/// If Obj is an Atom unify its _module with Module. If the Atom's _module is null, use Atom.NIL. /// If Obj is an Atom unify its _module with Module. If the Atom's _module is null, use Atom.NIL.
/// </summary> /// </summary>
/// <param name="Atom"></param> /// <param name="Atom"></param>
/// <param name="Module"></param> /// <param name="Module"></param>
/// <returns></returns> /// <returns></returns>
public static IEnumerable<bool> module(object Obj, object Module) public static IEnumerable<bool> module(object Obj, object Module)
{ {
Obj = YP.getValue(Obj); Obj = YP.getValue(Obj);
if (Obj is Atom) if (Obj is Atom)
{ {
if (((Atom)Obj)._module == null) if (((Atom)Obj)._module == null)
return YP.unify(Module, Atom.NIL); return YP.unify(Module, Atom.NIL);
else else
return YP.unify(Module, ((Atom)Obj)._module); return YP.unify(Module, ((Atom)Obj)._module);
} }
return YP.fail(); return YP.fail();
} }
public static readonly Atom NIL = Atom.a("[]"); public static readonly Atom NIL = Atom.a("[]");
public static readonly Atom DOT = Atom.a("."); public static readonly Atom DOT = Atom.a(".");
public static readonly Atom F = Atom.a("f"); public static readonly Atom F = Atom.a("f");
public static readonly Atom SLASH = Atom.a("/"); public static readonly Atom SLASH = Atom.a("/");
public static readonly Atom HAT = Atom.a("^"); public static readonly Atom HAT = Atom.a("^");
public static readonly Atom RULE = Atom.a(":-"); public static readonly Atom RULE = Atom.a(":-");
public IEnumerable<bool> unify(object arg) public IEnumerable<bool> unify(object arg)
{ {
arg = YP.getValue(arg); arg = YP.getValue(arg);
if (arg is Atom) if (arg is Atom)
return Equals(arg) ? YP.succeed() : YP.fail(); return Equals(arg) ? YP.succeed() : YP.fail();
else if (arg is Variable) else if (arg is Variable)
return ((Variable)arg).unify(this); return ((Variable)arg).unify(this);
else else
return YP.fail(); return YP.fail();
} }
public void addUniqueVariables(List<Variable> variableSet) public void addUniqueVariables(List<Variable> variableSet)
{ {
// Atom does not contain variables. // Atom does not contain variables.
} }
public object makeCopy(Variable.CopyStore copyStore) public object makeCopy(Variable.CopyStore copyStore)
{ {
// Atom does not contain variables that need to be copied. // Atom does not contain variables that need to be copied.
return this; return this;
} }
public bool termEqual(object term) public bool termEqual(object term)
{ {
return Equals(YP.getValue(term)); return Equals(YP.getValue(term));
} }
public bool ground() public bool ground()
{ {
// Atom is always ground. // Atom is always ground.
return true; return true;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (obj is Atom) if (obj is Atom)
{ {
if (_module == null && ((Atom)obj)._module == null) if (_module == null && ((Atom)obj)._module == null)
// When _declaringClass is null, we always use an identical object from _atomStore. // When _declaringClass is null, we always use an identical object from _atomStore.
return this == obj; return this == obj;
// Otherwise, ignore _declaringClass and do a normal string compare on the _name. // Otherwise, ignore _declaringClass and do a normal string compare on the _name.
return _name == ((Atom)obj)._name; return _name == ((Atom)obj)._name;
} }
return false; return false;
} }
public override string ToString() public override string ToString()
{ {
return _name; return _name;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
// Debug: need to check _declaringClass. // Debug: need to check _declaringClass.
return _name.GetHashCode(); return _name.GetHashCode();
} }
public string toQuotedString() public string toQuotedString()
{ {
if (_name.Length == 0) if (_name.Length == 0)
return "''"; return "''";
else if (this == Atom.NIL) else if (this == Atom.NIL)
return "[]"; return "[]";
StringBuilder result = new StringBuilder(_name.Length); StringBuilder result = new StringBuilder(_name.Length);
bool useQuotes = false; bool useQuotes = false;
foreach (char c in _name) foreach (char c in _name)
{ {
int cInt = (int)c; int cInt = (int)c;
if (c == '\'') if (c == '\'')
{ {
result.Append("''"); result.Append("''");
useQuotes = true; useQuotes = true;
} }
else if (c == '_' || cInt >= (int)'a' && cInt <= (int)'z' || else if (c == '_' || cInt >= (int)'a' && cInt <= (int)'z' ||
cInt >= (int)'A' && cInt <= (int)'Z' || cInt >= (int)'0' && cInt <= (int)'9') cInt >= (int)'A' && cInt <= (int)'Z' || cInt >= (int)'0' && cInt <= (int)'9')
result.Append(c); result.Append(c);
else else
{ {
// Debug: Need to handle non-printable chars. // Debug: Need to handle non-printable chars.
result.Append(c); result.Append(c);
useQuotes = true; useQuotes = true;
} }
} }
if (!useQuotes && (int)_name[0] >= (int)'a' && (int)_name[0] <= (int)'z') if (!useQuotes && (int)_name[0] >= (int)'a' && (int)_name[0] <= (int)'z')
return result.ToString(); return result.ToString();
else else
{ {
// Surround in single quotes. // Surround in single quotes.
result.Append('\''); result.Append('\'');
return "'" + result; return "'" + result;
} }
} }
/// <summary> /// <summary>
/// Return true if _name is lexicographically less than atom._name. /// Return true if _name is lexicographically less than atom._name.
/// </summary> /// </summary>
/// <param name="atom"></param> /// <param name="atom"></param>
/// <returns></returns> /// <returns></returns>
public bool lessThan(Atom atom) public bool lessThan(Atom atom)
{ {
return _name.CompareTo(atom._name) < 0; return _name.CompareTo(atom._name) < 0;
} }
} }
} }

View File

@ -1,234 +1,234 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
/// <summary> /// <summary>
/// A BagofAnswers holds answers for bagof and setof. /// A BagofAnswers holds answers for bagof and setof.
/// </summary> /// </summary>
public class BagofAnswers public class BagofAnswers
{ {
private object _template; private object _template;
private Variable[] _freeVariables; private Variable[] _freeVariables;
private Dictionary<object[], List<object>> _bagForFreeVariables; private Dictionary<object[], List<object>> _bagForFreeVariables;
private List<object> _findallBagArray; private List<object> _findallBagArray;
private static TermArrayEqualityComparer _termArrayEqualityComparer = private static TermArrayEqualityComparer _termArrayEqualityComparer =
new TermArrayEqualityComparer(); new TermArrayEqualityComparer();
/// <summary> /// <summary>
/// To get the free variables, split off any existential qualifiers from Goal such as the X in /// 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 /// "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. /// the unbound variables that are qualifiers as well as the unbound variables in Template.
/// </summary> /// </summary>
/// <param name="Template"></param> /// <param name="Template"></param>
/// <param name="Goal"></param> /// <param name="Goal"></param>
public BagofAnswers(object Template, object Goal) public BagofAnswers(object Template, object Goal)
{ {
_template = Template; _template = Template;
// First get the set of variables that are not free variables. // First get the set of variables that are not free variables.
List<Variable> variableSet = new List<Variable>(); List<Variable> variableSet = new List<Variable>();
YP.addUniqueVariables(Template, variableSet); YP.addUniqueVariables(Template, variableSet);
object UnqualifiedGoal = YP.getValue(Goal); object UnqualifiedGoal = YP.getValue(Goal);
while (UnqualifiedGoal is Functor2 && ((Functor2)UnqualifiedGoal)._name == Atom.HAT) while (UnqualifiedGoal is Functor2 && ((Functor2)UnqualifiedGoal)._name == Atom.HAT)
{ {
YP.addUniqueVariables(((Functor2)UnqualifiedGoal)._arg1, variableSet); YP.addUniqueVariables(((Functor2)UnqualifiedGoal)._arg1, variableSet);
UnqualifiedGoal = YP.getValue(((Functor2)UnqualifiedGoal)._arg2); UnqualifiedGoal = YP.getValue(((Functor2)UnqualifiedGoal)._arg2);
} }
// Remember how many non-free variables there are so we can find the unique free variables // Remember how many non-free variables there are so we can find the unique free variables
// that are added. // that are added.
int nNonFreeVariables = variableSet.Count; int nNonFreeVariables = variableSet.Count;
YP.addUniqueVariables(UnqualifiedGoal, variableSet); YP.addUniqueVariables(UnqualifiedGoal, variableSet);
int nFreeVariables = variableSet.Count - nNonFreeVariables; int nFreeVariables = variableSet.Count - nNonFreeVariables;
if (nFreeVariables == 0) if (nFreeVariables == 0)
{ {
// There were no free variables added, so we won't waste time with _bagForFreeVariables. // There were no free variables added, so we won't waste time with _bagForFreeVariables.
_freeVariables = null; _freeVariables = null;
_findallBagArray = new List<object>(); _findallBagArray = new List<object>();
} }
else else
{ {
// Copy the free variables. // Copy the free variables.
_freeVariables = new Variable[nFreeVariables]; _freeVariables = new Variable[nFreeVariables];
for (int i = 0; i < nFreeVariables; ++i) for (int i = 0; i < nFreeVariables; ++i)
_freeVariables[i] = variableSet[i + nNonFreeVariables]; _freeVariables[i] = variableSet[i + nNonFreeVariables];
_bagForFreeVariables = new Dictionary<object[], List<object>>(_termArrayEqualityComparer); _bagForFreeVariables = new Dictionary<object[], List<object>>(_termArrayEqualityComparer);
} }
} }
public void add() public void add()
{ {
if (_freeVariables == null) if (_freeVariables == null)
// The goal has bound the values in _template but we don't bother with _freeVariables. // The goal has bound the values in _template but we don't bother with _freeVariables.
_findallBagArray.Add(YP.makeCopy(_template, new Variable.CopyStore())); _findallBagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
else else
{ {
// The goal has bound the values in _template and _freeVariables. // The goal has bound the values in _template and _freeVariables.
// Find the entry for this set of _freeVariables values. // Find the entry for this set of _freeVariables values.
object[] freeVariableValues = new object[_freeVariables.Length]; object[] freeVariableValues = new object[_freeVariables.Length];
for (int i = 0; i < _freeVariables.Length; ++i) for (int i = 0; i < _freeVariables.Length; ++i)
freeVariableValues[i] = YP.getValue(_freeVariables[i]); freeVariableValues[i] = YP.getValue(_freeVariables[i]);
List<object> bagArray; List<object> bagArray;
if (!_bagForFreeVariables.TryGetValue(freeVariableValues, out bagArray)) if (!_bagForFreeVariables.TryGetValue(freeVariableValues, out bagArray))
{ {
bagArray = new List<object>(); bagArray = new List<object>();
_bagForFreeVariables[freeVariableValues] = bagArray; _bagForFreeVariables[freeVariableValues] = bagArray;
} }
// Now copy the template and add to the bag for the freeVariables values. // Now copy the template and add to the bag for the freeVariables values.
bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore())); bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
} }
} }
/// <summary> /// <summary>
/// For each result, unify the _freeVariables and unify bagArrayVariable with the associated bag. /// For each result, unify the _freeVariables and unify bagArrayVariable with the associated bag.
/// </summary> /// </summary>
/// <param name="bagArrayVariable">this is unified with the List<object> of matches for template that /// <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 /// corresponds to the bindings for freeVariables. Be very careful: this does not unify with a Prolog
/// list.</param> /// list.</param>
/// <returns></returns> /// <returns></returns>
public IEnumerable<bool> resultArray(Variable bagArrayVariable) public IEnumerable<bool> resultArray(Variable bagArrayVariable)
{ {
if (_freeVariables == null) if (_freeVariables == null)
{ {
// No unbound free variables, so we only filled one bag. If empty, bagof fails. // No unbound free variables, so we only filled one bag. If empty, bagof fails.
if (_findallBagArray.Count > 0) if (_findallBagArray.Count > 0)
{ {
foreach (bool l1 in bagArrayVariable.unify(_findallBagArray)) foreach (bool l1 in bagArrayVariable.unify(_findallBagArray))
yield return false; yield return false;
} }
} }
else else
{ {
foreach (KeyValuePair<object[], List<object>> valuesAndBag in _bagForFreeVariables) foreach (KeyValuePair<object[], List<object>> valuesAndBag in _bagForFreeVariables)
{ {
foreach (bool l1 in YP.unifyArrays(_freeVariables, valuesAndBag.Key)) foreach (bool l1 in YP.unifyArrays(_freeVariables, valuesAndBag.Key))
{ {
foreach (bool l2 in bagArrayVariable.unify(valuesAndBag.Value)) foreach (bool l2 in bagArrayVariable.unify(valuesAndBag.Value))
yield return false; yield return false;
} }
// Debug: Should we free memory of the answers already returned? // Debug: Should we free memory of the answers already returned?
} }
} }
} }
/// <summary> /// <summary>
/// For each result, unify the _freeVariables and unify Bag with the associated bag. /// For each result, unify the _freeVariables and unify Bag with the associated bag.
/// </summary> /// </summary>
/// <param name="Bag"></param> /// <param name="Bag"></param>
/// <returns></returns> /// <returns></returns>
public IEnumerable<bool> result(object Bag) public IEnumerable<bool> result(object Bag)
{ {
Variable bagArrayVariable = new Variable(); Variable bagArrayVariable = new Variable();
foreach (bool l1 in resultArray(bagArrayVariable)) foreach (bool l1 in resultArray(bagArrayVariable))
{ {
foreach (bool l2 in YP.unify(Bag, ListPair.make((List<object>)bagArrayVariable.getValue()))) foreach (bool l2 in YP.unify(Bag, ListPair.make((List<object>)bagArrayVariable.getValue())))
yield return false; yield return false;
} }
} }
/// <summary> /// <summary>
/// For each result, unify the _freeVariables and unify Bag with the associated bag which is sorted /// For each result, unify the _freeVariables and unify Bag with the associated bag which is sorted
/// with duplicates removed, as in setof. /// with duplicates removed, as in setof.
/// </summary> /// </summary>
/// <param name="Bag"></param> /// <param name="Bag"></param>
/// <returns></returns> /// <returns></returns>
public IEnumerable<bool> resultSet(object Bag) public IEnumerable<bool> resultSet(object Bag)
{ {
Variable bagArrayVariable = new Variable(); Variable bagArrayVariable = new Variable();
foreach (bool l1 in resultArray(bagArrayVariable)) foreach (bool l1 in resultArray(bagArrayVariable))
{ {
List<object> bagArray = (List<object>)bagArrayVariable.getValue(); List<object> bagArray = (List<object>)bagArrayVariable.getValue();
YP.sortArray(bagArray); YP.sortArray(bagArray);
foreach (bool l2 in YP.unify(Bag, ListPair.makeWithoutRepeatedTerms(bagArray))) foreach (bool l2 in YP.unify(Bag, ListPair.makeWithoutRepeatedTerms(bagArray)))
yield return false; yield return false;
} }
} }
public static IEnumerable<bool> bagofArray public static IEnumerable<bool> bagofArray
(object Template, object Goal, IEnumerable<bool> goalIterator, Variable bagArrayVariable) (object Template, object Goal, IEnumerable<bool> goalIterator, Variable bagArrayVariable)
{ {
BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal); BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal);
foreach (bool l1 in goalIterator) foreach (bool l1 in goalIterator)
bagOfAnswers.add(); bagOfAnswers.add();
return bagOfAnswers.resultArray(bagArrayVariable); return bagOfAnswers.resultArray(bagArrayVariable);
} }
public static IEnumerable<bool> bagof public static IEnumerable<bool> bagof
(object Template, object Goal, IEnumerable<bool> goalIterator, object Bag) (object Template, object Goal, IEnumerable<bool> goalIterator, object Bag)
{ {
BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal); BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal);
foreach (bool l1 in goalIterator) foreach (bool l1 in goalIterator)
bagOfAnswers.add(); bagOfAnswers.add();
return bagOfAnswers.result(Bag); return bagOfAnswers.result(Bag);
} }
public static IEnumerable<bool> setof public static IEnumerable<bool> setof
(object Template, object Goal, IEnumerable<bool> goalIterator, object Bag) (object Template, object Goal, IEnumerable<bool> goalIterator, object Bag)
{ {
BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal); BagofAnswers bagOfAnswers = new BagofAnswers(Template, Goal);
foreach (bool l1 in goalIterator) foreach (bool l1 in goalIterator)
bagOfAnswers.add(); bagOfAnswers.add();
return bagOfAnswers.resultSet(Bag); return bagOfAnswers.resultSet(Bag);
} }
/// <summary> /// <summary>
/// A TermArrayEqualityComparer implements IEqualityComparer to compare two object arrays using YP.termEqual. /// A TermArrayEqualityComparer implements IEqualityComparer to compare two object arrays using YP.termEqual.
/// </summary> /// </summary>
private class TermArrayEqualityComparer : IEqualityComparer<object[]> private class TermArrayEqualityComparer : IEqualityComparer<object[]>
{ {
public bool Equals(object[] array1, object[] array2) public bool Equals(object[] array1, object[] array2)
{ {
if (array1.Length != array2.Length) if (array1.Length != array2.Length)
return false; return false;
for (int i = 0; i < array1.Length; ++i) for (int i = 0; i < array1.Length; ++i)
{ {
if (!YP.termEqual(array1[i], array2[i])) if (!YP.termEqual(array1[i], array2[i]))
return false; return false;
} }
return true; return true;
} }
public int GetHashCode(object[] array) public int GetHashCode(object[] array)
{ {
int hashCode = 0; int hashCode = 0;
for (int i = 0; i < array.Length; ++i) for (int i = 0; i < array.Length; ++i)
hashCode ^= array[i].GetHashCode(); hashCode ^= array[i].GetHashCode();
return hashCode; return hashCode;
} }
} }
} }
} }

View File

@ -1,103 +1,103 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
/// <summary> /// <summary>
/// A FindallAnswers holds answers for findall. /// A FindallAnswers holds answers for findall.
/// </summary> /// </summary>
public class FindallAnswers public class FindallAnswers
{ {
private object _template; private object _template;
private List<object> _bagArray; private List<object> _bagArray;
public FindallAnswers(object Template) public FindallAnswers(object Template)
{ {
_template = Template; _template = Template;
_bagArray = new List<object>(); _bagArray = new List<object>();
} }
public void add() public void add()
{ {
_bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore())); _bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
} }
public List<object> resultArray() public List<object> resultArray()
{ {
return _bagArray; return _bagArray;
} }
/// <summary> /// <summary>
/// Unify Bag with the result. This frees the internal answers, so you can only call this once. /// Unify Bag with the result. This frees the internal answers, so you can only call this once.
/// </summary> /// </summary>
/// <param name="Bag"></param> /// <param name="Bag"></param>
/// <returns></returns> /// <returns></returns>
public IEnumerable<bool> result(object Bag) public IEnumerable<bool> result(object Bag)
{ {
object result = ListPair.make(_bagArray); object result = ListPair.make(_bagArray);
// Try to free the memory. // Try to free the memory.
_bagArray = null; _bagArray = null;
return YP.unify(Bag, result); return YP.unify(Bag, result);
} }
/// <summary> /// <summary>
/// This is a simplified findall when the goal is a single call. /// This is a simplified findall when the goal is a single call.
/// </summary> /// </summary>
/// <param name="Template"></param> /// <param name="Template"></param>
/// <param name="goal"></param> /// <param name="goal"></param>
/// <param name="Bag"></param> /// <param name="Bag"></param>
/// <returns></returns> /// <returns></returns>
public static IEnumerable<bool> findall(object Template, IEnumerable<bool> goal, object Bag) public static IEnumerable<bool> findall(object Template, IEnumerable<bool> goal, object Bag)
{ {
FindallAnswers findallAnswers = new FindallAnswers(Template); FindallAnswers findallAnswers = new FindallAnswers(Template);
foreach (bool l1 in goal) foreach (bool l1 in goal)
findallAnswers.add(); findallAnswers.add();
return findallAnswers.result(Bag); return findallAnswers.result(Bag);
} }
/// <summary> /// <summary>
/// Like findall, except return an array of the results. /// Like findall, except return an array of the results.
/// </summary> /// </summary>
/// <param name="template"></param> /// <param name="template"></param>
/// <param name="goal"></param> /// <param name="goal"></param>
/// <returns></returns> /// <returns></returns>
public static List<object> findallArray(object Template, IEnumerable<bool> goal) public static List<object> findallArray(object Template, IEnumerable<bool> goal)
{ {
FindallAnswers findallAnswers = new FindallAnswers(Template); FindallAnswers findallAnswers = new FindallAnswers(Template);
foreach (bool l1 in goal) foreach (bool l1 in goal)
findallAnswers.add(); findallAnswers.add();
return findallAnswers.resultArray(); return findallAnswers.resultArray();
} }
} }
} }

View File

@ -1,188 +1,188 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public class Functor : IUnifiable public class Functor : IUnifiable
{ {
public readonly Atom _name; public readonly Atom _name;
public readonly object[] _args; public readonly object[] _args;
public Functor(Atom name, object[] args) public Functor(Atom name, object[] args)
{ {
if (args.Length <= 3) if (args.Length <= 3)
{ {
if (args.Length == 0) if (args.Length == 0)
throw new Exception("For arity 0 functor, just use name as an Atom"); throw new Exception("For arity 0 functor, just use name as an Atom");
else if (args.Length == 1) else if (args.Length == 1)
throw new Exception("For arity 1 functor, use Functor1"); throw new Exception("For arity 1 functor, use Functor1");
else if (args.Length == 2) else if (args.Length == 2)
throw new Exception("For arity 2 functor, use Functor2"); throw new Exception("For arity 2 functor, use Functor2");
else if (args.Length == 3) else if (args.Length == 3)
throw new Exception("For arity 3 functor, use Functor3"); throw new Exception("For arity 3 functor, use Functor3");
else else
// (This shouldn't happen, but include it for completeness. // (This shouldn't happen, but include it for completeness.
throw new Exception("Cannot create a Functor of arity " + args.Length); throw new Exception("Cannot create a Functor of arity " + args.Length);
} }
_name = name; _name = name;
_args = args; _args = args;
} }
public Functor(string name, object[] args) public Functor(string name, object[] args)
: this(Atom.a(name), args) : this(Atom.a(name), args)
{ {
} }
/// <summary> /// <summary>
/// Return an Atom, Functor1, Functor2, Functor3 or Functor depending on the /// Return an Atom, Functor1, Functor2, Functor3 or Functor depending on the
/// length of args. /// length of args.
/// Note that this is different than the Functor constructor which requires /// Note that this is different than the Functor constructor which requires
/// the length of args to be greater than 3. /// the length of args to be greater than 3.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="args"></param> /// <param name="args"></param>
/// <returns></returns> /// <returns></returns>
public static object make(Atom name, object[] args) public static object make(Atom name, object[] args)
{ {
if (args.Length <= 0) if (args.Length <= 0)
return name; return name;
else if (args.Length == 1) else if (args.Length == 1)
return new Functor1(name, args[0]); return new Functor1(name, args[0]);
else if (args.Length == 2) else if (args.Length == 2)
return new Functor2(name, args[0], args[1]); return new Functor2(name, args[0], args[1]);
else if (args.Length == 3) else if (args.Length == 3)
return new Functor3(name, args[0], args[1], args[2]); return new Functor3(name, args[0], args[1], args[2]);
else else
return new Functor(name, args); return new Functor(name, args);
} }
/// <summary> /// <summary>
/// Call the main make, first converting name to an Atom. /// Call the main make, first converting name to an Atom.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="args"></param> /// <param name="args"></param>
/// <returns></returns> /// <returns></returns>
public static object make(string name, object[] args) public static object make(string name, object[] args)
{ {
return make(Atom.a(name), args); return make(Atom.a(name), args);
} }
public IEnumerable<bool> unify(object arg) public IEnumerable<bool> unify(object arg)
{ {
arg = YP.getValue(arg); arg = YP.getValue(arg);
if (arg is Functor) if (arg is Functor)
{ {
Functor argFunctor = (Functor)arg; Functor argFunctor = (Functor)arg;
if (_name.Equals(argFunctor._name)) if (_name.Equals(argFunctor._name))
return YP.unifyArrays(_args, argFunctor._args); return YP.unifyArrays(_args, argFunctor._args);
else else
return YP.fail(); return YP.fail();
} }
else if (arg is Variable) else if (arg is Variable)
return ((Variable)arg).unify(this); return ((Variable)arg).unify(this);
else else
return YP.fail(); return YP.fail();
} }
public override string ToString() public override string ToString()
{ {
string result = _name + "(" + YP.getValue(_args[0]); string result = _name + "(" + YP.getValue(_args[0]);
for (int i = 1; i < _args.Length; ++i) for (int i = 1; i < _args.Length; ++i)
result += ", " + YP.getValue(_args[i]); result += ", " + YP.getValue(_args[i]);
result += ")"; result += ")";
return result; return result;
} }
public bool termEqual(object term) public bool termEqual(object term)
{ {
term = YP.getValue(term); term = YP.getValue(term);
if (term is Functor) if (term is Functor)
{ {
Functor termFunctor = (Functor)term; Functor termFunctor = (Functor)term;
if (_name.Equals(termFunctor._name) && _args.Length == termFunctor._args.Length) if (_name.Equals(termFunctor._name) && _args.Length == termFunctor._args.Length)
{ {
for (int i = 0; i < _args.Length; ++i) for (int i = 0; i < _args.Length; ++i)
{ {
if (!YP.termEqual(_args[i], termFunctor._args[i])) if (!YP.termEqual(_args[i], termFunctor._args[i]))
return false; return false;
} }
return true; return true;
} }
} }
return false; return false;
} }
public bool lessThan(Functor functor) public bool lessThan(Functor functor)
{ {
// Do the equal check first since it is faster. // Do the equal check first since it is faster.
if (!_name.Equals(functor._name)) if (!_name.Equals(functor._name))
return _name.lessThan(functor._name); return _name.lessThan(functor._name);
if (_args.Length != functor._args.Length) if (_args.Length != functor._args.Length)
return _args.Length < functor._args.Length; return _args.Length < functor._args.Length;
for (int i = 0; i < _args.Length; ++i) for (int i = 0; i < _args.Length; ++i)
{ {
if (!YP.termEqual(_args[i], functor._args[i])) if (!YP.termEqual(_args[i], functor._args[i]))
return YP.termLessThan(_args[i], functor._args[i]); return YP.termLessThan(_args[i], functor._args[i]);
} }
return false; return false;
} }
public bool ground() public bool ground()
{ {
for (int i = 0; i < _args.Length; ++i) for (int i = 0; i < _args.Length; ++i)
{ {
if (!YP.ground(_args[i])) if (!YP.ground(_args[i]))
return false; return false;
} }
return true; return true;
} }
public void addUniqueVariables(List<Variable> variableSet) public void addUniqueVariables(List<Variable> variableSet)
{ {
for (int i = 0; i < _args.Length; ++i) for (int i = 0; i < _args.Length; ++i)
YP.addUniqueVariables(_args[i], variableSet); YP.addUniqueVariables(_args[i], variableSet);
} }
public object makeCopy(Variable.CopyStore copyStore) public object makeCopy(Variable.CopyStore copyStore)
{ {
object[] argsCopy = new object[_args.Length]; object[] argsCopy = new object[_args.Length];
for (int i = 0; i < _args.Length; ++i) for (int i = 0; i < _args.Length; ++i)
argsCopy[i] = YP.makeCopy(_args[i], copyStore); argsCopy[i] = YP.makeCopy(_args[i], copyStore);
return new Functor(_name, argsCopy); return new Functor(_name, argsCopy);
} }
} }
} }

View File

@ -1,111 +1,111 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public class Functor1 : IUnifiable public class Functor1 : IUnifiable
{ {
public readonly Atom _name; public readonly Atom _name;
public readonly object _arg1; public readonly object _arg1;
public Functor1(Atom name, object arg1) public Functor1(Atom name, object arg1)
{ {
_name = name; _name = name;
_arg1 = arg1; _arg1 = arg1;
} }
public Functor1(string name, object arg1) public Functor1(string name, object arg1)
: this(Atom.a(name), arg1) : this(Atom.a(name), arg1)
{ {
} }
public IEnumerable<bool> unify(object arg) public IEnumerable<bool> unify(object arg)
{ {
arg = YP.getValue(arg); arg = YP.getValue(arg);
if (arg is Functor1) if (arg is Functor1)
{ {
Functor1 argFunctor = (Functor1)arg; Functor1 argFunctor = (Functor1)arg;
if (_name.Equals(argFunctor._name)) if (_name.Equals(argFunctor._name))
{ {
foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1)) foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
yield return false; yield return false;
} }
} }
else if (arg is Variable) else if (arg is Variable)
{ {
foreach (bool l1 in ((Variable)arg).unify(this)) foreach (bool l1 in ((Variable)arg).unify(this))
yield return false; yield return false;
} }
} }
public override string ToString() public override string ToString()
{ {
return _name + "(" + YP.getValue(_arg1) + ")"; return _name + "(" + YP.getValue(_arg1) + ")";
} }
public bool termEqual(object term) public bool termEqual(object term)
{ {
term = YP.getValue(term); term = YP.getValue(term);
if (term is Functor1) if (term is Functor1)
{ {
Functor1 termFunctor = (Functor1)term; Functor1 termFunctor = (Functor1)term;
return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1); return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1);
} }
return false; return false;
} }
public bool lessThan(Functor1 functor) public bool lessThan(Functor1 functor)
{ {
// Do the equal check first since it is faster. // Do the equal check first since it is faster.
if (!_name.Equals(functor._name)) if (!_name.Equals(functor._name))
return _name.lessThan(functor._name); return _name.lessThan(functor._name);
return YP.termLessThan(_arg1, functor._arg1); return YP.termLessThan(_arg1, functor._arg1);
} }
public bool ground() public bool ground()
{ {
return YP.ground(_arg1); return YP.ground(_arg1);
} }
public void addUniqueVariables(List<Variable> variableSet) public void addUniqueVariables(List<Variable> variableSet)
{ {
YP.addUniqueVariables(_arg1, variableSet); YP.addUniqueVariables(_arg1, variableSet);
} }
public object makeCopy(Variable.CopyStore copyStore) public object makeCopy(Variable.CopyStore copyStore)
{ {
return new Functor1(_name, YP.makeCopy(_arg1, copyStore)); return new Functor1(_name, YP.makeCopy(_arg1, copyStore));
} }
} }
} }

View File

@ -1,154 +1,154 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public class Functor2 : IUnifiable public class Functor2 : IUnifiable
{ {
public readonly Atom _name; public readonly Atom _name;
public readonly object _arg1; public readonly object _arg1;
public readonly object _arg2; public readonly object _arg2;
public Functor2(Atom name, object arg1, object arg2) public Functor2(Atom name, object arg1, object arg2)
{ {
_name = name; _name = name;
_arg1 = arg1; _arg1 = arg1;
_arg2 = arg2; _arg2 = arg2;
} }
public Functor2(string name, object arg1, object arg2) public Functor2(string name, object arg1, object arg2)
: this(Atom.a(name), arg1, arg2) : this(Atom.a(name), arg1, arg2)
{ {
} }
public IEnumerable<bool> unify(object arg) public IEnumerable<bool> unify(object arg)
{ {
arg = YP.getValue(arg); arg = YP.getValue(arg);
if (arg is Functor2) if (arg is Functor2)
{ {
Functor2 argFunctor = (Functor2)arg; Functor2 argFunctor = (Functor2)arg;
if (_name.Equals(argFunctor._name)) if (_name.Equals(argFunctor._name))
{ {
foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1)) foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
{ {
foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2)) foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2))
yield return false; yield return false;
} }
} }
} }
else if (arg is Variable) else if (arg is Variable)
{ {
foreach (bool l1 in ((Variable)arg).unify(this)) foreach (bool l1 in ((Variable)arg).unify(this))
yield return false; yield return false;
} }
} }
public override string ToString() public override string ToString()
{ {
if (_name == Atom.DOT) if (_name == Atom.DOT)
return listPairToString(this); return listPairToString(this);
else else
return _name + "(" + YP.getValue(_arg1) + ", " + YP.getValue(_arg2) + ")"; return _name + "(" + YP.getValue(_arg1) + ", " + YP.getValue(_arg2) + ")";
} }
public bool termEqual(object term) public bool termEqual(object term)
{ {
term = YP.getValue(term); term = YP.getValue(term);
if (term is Functor2) if (term is Functor2)
{ {
Functor2 termFunctor = (Functor2)term; Functor2 termFunctor = (Functor2)term;
return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1) return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1)
&& YP.termEqual(_arg2, termFunctor._arg2); && YP.termEqual(_arg2, termFunctor._arg2);
} }
return false; return false;
} }
public bool lessThan(Functor2 functor) public bool lessThan(Functor2 functor)
{ {
// Do the equal check first since it is faster. // Do the equal check first since it is faster.
if (!_name.Equals(functor._name)) if (!_name.Equals(functor._name))
return _name.lessThan(functor._name); return _name.lessThan(functor._name);
if (!YP.termEqual(_arg1, functor._arg1)) if (!YP.termEqual(_arg1, functor._arg1))
return YP.termLessThan(_arg1, functor._arg1); return YP.termLessThan(_arg1, functor._arg1);
return YP.termLessThan(_arg2, functor._arg2); return YP.termLessThan(_arg2, functor._arg2);
} }
public bool ground() public bool ground()
{ {
return YP.ground(_arg1) && YP.ground(_arg2); return YP.ground(_arg1) && YP.ground(_arg2);
} }
public void addUniqueVariables(List<Variable> variableSet) public void addUniqueVariables(List<Variable> variableSet)
{ {
YP.addUniqueVariables(_arg1, variableSet); YP.addUniqueVariables(_arg1, variableSet);
YP.addUniqueVariables(_arg2, variableSet); YP.addUniqueVariables(_arg2, variableSet);
} }
public object makeCopy(Variable.CopyStore copyStore) public object makeCopy(Variable.CopyStore copyStore)
{ {
return new Functor2(_name, YP.makeCopy(_arg1, copyStore), return new Functor2(_name, YP.makeCopy(_arg1, copyStore),
YP.makeCopy(_arg2, copyStore)); YP.makeCopy(_arg2, copyStore));
} }
private static string listPairToString(Functor2 listPair) private static string listPairToString(Functor2 listPair)
{ {
string result = "["; string result = "[";
while (true) while (true)
{ {
object head = YP.getValue(listPair._arg1); object head = YP.getValue(listPair._arg1);
object tail = YP.getValue(listPair._arg2); object tail = YP.getValue(listPair._arg2);
if (tail == (object)Atom.NIL) if (tail == (object)Atom.NIL)
{ {
result += head; result += head;
break; break;
} }
else if (tail is Functor2 && ((Functor2)tail)._name == Atom.DOT) else if (tail is Functor2 && ((Functor2)tail)._name == Atom.DOT)
{ {
result += head + ", "; result += head + ", ";
listPair = (Functor2)tail; listPair = (Functor2)tail;
// Loop again. // Loop again.
} }
else else
{ {
// The list is not terminated with NIL. // The list is not terminated with NIL.
result += head + "|" + tail; result += head + "|" + tail;
break; break;
} }
} }
result += "]"; result += "]";
return result; return result;
} }
} }
} }

View File

@ -1,133 +1,133 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public class Functor3 : IUnifiable public class Functor3 : IUnifiable
{ {
public readonly Atom _name; public readonly Atom _name;
public readonly object _arg1; public readonly object _arg1;
public readonly object _arg2; public readonly object _arg2;
public readonly object _arg3; public readonly object _arg3;
public Functor3(Atom name, object arg1, object arg2, object arg3) public Functor3(Atom name, object arg1, object arg2, object arg3)
{ {
_name = name; _name = name;
_arg1 = arg1; _arg1 = arg1;
_arg2 = arg2; _arg2 = arg2;
_arg3 = arg3; _arg3 = arg3;
} }
public Functor3(string name, object arg1, object arg2, object arg3) public Functor3(string name, object arg1, object arg2, object arg3)
: this(Atom.a(name), arg1, arg2, arg3) : this(Atom.a(name), arg1, arg2, arg3)
{ {
} }
public IEnumerable<bool> unify(object arg) public IEnumerable<bool> unify(object arg)
{ {
arg = YP.getValue(arg); arg = YP.getValue(arg);
if (arg is Functor3) if (arg is Functor3)
{ {
Functor3 argFunctor = (Functor3)arg; Functor3 argFunctor = (Functor3)arg;
if (_name.Equals(argFunctor._name)) if (_name.Equals(argFunctor._name))
{ {
foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1)) foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
{ {
foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2)) foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2))
{ {
foreach (bool l3 in YP.unify(_arg3, argFunctor._arg3)) foreach (bool l3 in YP.unify(_arg3, argFunctor._arg3))
yield return false; yield return false;
} }
} }
} }
} }
else if (arg is Variable) else if (arg is Variable)
{ {
foreach (bool l1 in ((Variable)arg).unify(this)) foreach (bool l1 in ((Variable)arg).unify(this))
yield return false; yield return false;
} }
} }
public override string ToString() public override string ToString()
{ {
return _name + "(" + YP.getValue(_arg1) + ", " + YP.getValue(_arg2) + ", " + return _name + "(" + YP.getValue(_arg1) + ", " + YP.getValue(_arg2) + ", " +
YP.getValue(_arg3) + ")"; YP.getValue(_arg3) + ")";
} }
public bool termEqual(object term) public bool termEqual(object term)
{ {
term = YP.getValue(term); term = YP.getValue(term);
if (term is Functor3) if (term is Functor3)
{ {
Functor3 termFunctor = (Functor3)term; Functor3 termFunctor = (Functor3)term;
return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1) return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1)
&& YP.termEqual(_arg2, termFunctor._arg2) && YP.termEqual(_arg2, termFunctor._arg2)
&& YP.termEqual(_arg3, termFunctor._arg3); && YP.termEqual(_arg3, termFunctor._arg3);
} }
return false; return false;
} }
public bool lessThan(Functor3 functor) public bool lessThan(Functor3 functor)
{ {
// Do the equal check first since it is faster. // Do the equal check first since it is faster.
if (!_name.Equals(functor._name)) if (!_name.Equals(functor._name))
return _name.lessThan(functor._name); return _name.lessThan(functor._name);
if (!YP.termEqual(_arg1, functor._arg1)) if (!YP.termEqual(_arg1, functor._arg1))
return YP.termLessThan(_arg1, functor._arg1); return YP.termLessThan(_arg1, functor._arg1);
if (!YP.termEqual(_arg2, functor._arg2)) if (!YP.termEqual(_arg2, functor._arg2))
return YP.termLessThan(_arg2, functor._arg2); return YP.termLessThan(_arg2, functor._arg2);
return YP.termLessThan(_arg3, functor._arg3); return YP.termLessThan(_arg3, functor._arg3);
} }
public bool ground() public bool ground()
{ {
return YP.ground(_arg1) && YP.ground(_arg2) && YP.ground(_arg3); return YP.ground(_arg1) && YP.ground(_arg2) && YP.ground(_arg3);
} }
public void addUniqueVariables(List<Variable> variableSet) public void addUniqueVariables(List<Variable> variableSet)
{ {
YP.addUniqueVariables(_arg1, variableSet); YP.addUniqueVariables(_arg1, variableSet);
YP.addUniqueVariables(_arg2, variableSet); YP.addUniqueVariables(_arg2, variableSet);
YP.addUniqueVariables(_arg3, variableSet); YP.addUniqueVariables(_arg3, variableSet);
} }
public object makeCopy(Variable.CopyStore copyStore) public object makeCopy(Variable.CopyStore copyStore)
{ {
return new Functor3(_name, YP.makeCopy(_arg1, copyStore), return new Functor3(_name, YP.makeCopy(_arg1, copyStore),
YP.makeCopy(_arg2, copyStore), YP.makeCopy(_arg3, copyStore)); YP.makeCopy(_arg2, copyStore), YP.makeCopy(_arg3, copyStore));
} }
} }
} }

View File

@ -1,288 +1,288 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
/// <summary> /// <summary>
/// An IndexedAnswers holds answers to a query based on the values of index arguments. /// An IndexedAnswers holds answers to a query based on the values of index arguments.
/// </summary> /// </summary>
public class IndexedAnswers : YP.IClause public class IndexedAnswers : YP.IClause
{ {
// addAnswer adds the answer here and indexes it later. // addAnswer adds the answer here and indexes it later.
private List<object[]> _allAnswers = new List<object[]>(); private List<object[]> _allAnswers = new List<object[]>();
// The key has the arity of answers with non-null values for each indexed arg. The value // 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. // 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 = private Dictionary<HashedList, List<object[]>> _indexedAnswers =
new Dictionary<HashedList, List<object[]>>(); new Dictionary<HashedList, List<object[]>>();
// Keeps track of whether we have started adding entries to _indexedAnswers for the signature. // Keeps track of whether we have started adding entries to _indexedAnswers for the signature.
private Dictionary<int, object> _gotAnswersForSignature = new Dictionary<int, object>(); private Dictionary<int, object> _gotAnswersForSignature = new Dictionary<int, object>();
private const int MAX_INDEX_ARGS = 31; private const int MAX_INDEX_ARGS = 31;
public IndexedAnswers() public IndexedAnswers()
{ {
} }
/// <summary> /// <summary>
/// Elements of answer must be ground, since arguments with unbound variables make this /// Elements of answer must be ground, since arguments with unbound variables make this
/// into a dynamic rule which we don't index. /// into a dynamic rule which we don't index.
/// </summary> /// </summary>
/// <param name="answer"></param> /// <param name="answer"></param>
public void addAnswer(object[] answer) public void addAnswer(object[] answer)
{ {
// Store a copy of the answer array. // Store a copy of the answer array.
object[] answerCopy = new object[answer.Length]; object[] answerCopy = new object[answer.Length];
Variable.CopyStore copyStore = new Variable.CopyStore(); Variable.CopyStore copyStore = new Variable.CopyStore();
for (int i = 0; i < answer.Length; ++i) for (int i = 0; i < answer.Length; ++i)
answerCopy[i] = YP.makeCopy(answer[i], copyStore); answerCopy[i] = YP.makeCopy(answer[i], copyStore);
if (copyStore.getNUniqueVariables() > 0) if (copyStore.getNUniqueVariables() > 0)
throw new InvalidOperationException throw new InvalidOperationException
("Elements of answer must be ground, but found " + copyStore.getNUniqueVariables() + ("Elements of answer must be ground, but found " + copyStore.getNUniqueVariables() +
" unbound variables"); " unbound variables");
_allAnswers.Add(answerCopy); _allAnswers.Add(answerCopy);
// If match has already indexed answers for a signature, we need to add // If match has already indexed answers for a signature, we need to add
// this to the existing indexed answers. // this to the existing indexed answers.
foreach(int signature in _gotAnswersForSignature.Keys) foreach(int signature in _gotAnswersForSignature.Keys)
indexAnswerForSignature(answerCopy, signature); indexAnswerForSignature(answerCopy, signature);
} }
private void indexAnswerForSignature(object[] answer, int signature) private void indexAnswerForSignature(object[] answer, int signature)
{ {
// First find out which of the answer values can be used as an index. // First find out which of the answer values can be used as an index.
object[] indexValues = new object[answer.Length]; object[] indexValues = new object[answer.Length];
for (int i = 0; i < answer.Length; ++i) for (int i = 0; i < answer.Length; ++i)
{ {
// We limit the number of indexed args in a 32-bit signature. // We limit the number of indexed args in a 32-bit signature.
if (i >= MAX_INDEX_ARGS) if (i >= MAX_INDEX_ARGS)
indexValues[i] = null; indexValues[i] = null;
else else
indexValues[i] = getIndexValue(YP.getValue(answer[i])); indexValues[i] = getIndexValue(YP.getValue(answer[i]));
} }
// We need an entry in indexArgs from indexValues for each 1 bit in signature. // We need an entry in indexArgs from indexValues for each 1 bit in signature.
HashedList indexArgs = new HashedList(indexValues.Length); HashedList indexArgs = new HashedList(indexValues.Length);
for (int i = 0; i < indexValues.Length; ++i) for (int i = 0; i < indexValues.Length; ++i)
{ {
if ((signature & (1 << i)) == 0) if ((signature & (1 << i)) == 0)
indexArgs.Add(null); indexArgs.Add(null);
else else
{ {
if (indexValues[i] == null) if (indexValues[i] == null)
// The signature wants an index value here, but we don't have one so // 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. // we can't add it as an answer for this signature.
return; return;
else else
indexArgs.Add(indexValues[i]); indexArgs.Add(indexValues[i]);
} }
} }
// Add the answer to the answers list for indexArgs, creating the entry if needed. // Add the answer to the answers list for indexArgs, creating the entry if needed.
List<object[]> answers; List<object[]> answers;
if (!_indexedAnswers.TryGetValue(indexArgs, out answers)) if (!_indexedAnswers.TryGetValue(indexArgs, out answers))
{ {
answers = new List<object[]>(); answers = new List<object[]>();
_indexedAnswers[indexArgs] = answers; _indexedAnswers[indexArgs] = answers;
} }
answers.Add(answer); answers.Add(answer);
} }
public IEnumerable<bool> match(object[] arguments) public IEnumerable<bool> match(object[] arguments)
{ {
// Set up indexArgs, up to arg position MAX_INDEX_ARGS. The signature has a 1 bit for // Set up indexArgs, up to arg position MAX_INDEX_ARGS. The signature has a 1 bit for
// each non-null index arg. // each non-null index arg.
HashedList indexArgs = new HashedList(arguments.Length); HashedList indexArgs = new HashedList(arguments.Length);
bool gotAllIndexArgs = true; bool gotAllIndexArgs = true;
int signature = 0; int signature = 0;
for (int i = 0; i < arguments.Length; ++i) for (int i = 0; i < arguments.Length; ++i)
{ {
object indexValue = null; object indexValue = null;
if (i < MAX_INDEX_ARGS) if (i < MAX_INDEX_ARGS)
{ {
// We limit the number of args in a 32-bit signature. // We limit the number of args in a 32-bit signature.
indexValue = getIndexValue(YP.getValue(arguments[i])); indexValue = getIndexValue(YP.getValue(arguments[i]));
if (indexValue != null) if (indexValue != null)
signature += (1 << i); signature += (1 << i);
} }
if (indexValue == null) if (indexValue == null)
gotAllIndexArgs = false; gotAllIndexArgs = false;
indexArgs.Add(indexValue); indexArgs.Add(indexValue);
} }
List<object[]> answers; List<object[]> answers;
if (signature == 0) if (signature == 0)
// No index args, so we have to match from _allAnswers. // No index args, so we have to match from _allAnswers.
answers = _allAnswers; answers = _allAnswers;
else else
{ {
if (!_gotAnswersForSignature.ContainsKey(signature)) if (!_gotAnswersForSignature.ContainsKey(signature))
{ {
// We need to create the entry in _indexedAnswers. // We need to create the entry in _indexedAnswers.
foreach (object[] answer in _allAnswers) foreach (object[] answer in _allAnswers)
indexAnswerForSignature(answer, signature); indexAnswerForSignature(answer, signature);
// Mark that we did this signature. // Mark that we did this signature.
_gotAnswersForSignature[signature] = null; _gotAnswersForSignature[signature] = null;
} }
if (!_indexedAnswers.TryGetValue(indexArgs, out answers)) if (!_indexedAnswers.TryGetValue(indexArgs, out answers))
yield break; yield break;
} }
if (gotAllIndexArgs) if (gotAllIndexArgs)
{ {
// All the arguments were already bound, so we don't need to do bindings. // All the arguments were already bound, so we don't need to do bindings.
yield return false; yield return false;
yield break; yield break;
} }
// Find matches in answers. // Find matches in answers.
IEnumerator<bool>[] iterators = new IEnumerator<bool>[arguments.Length]; IEnumerator<bool>[] iterators = new IEnumerator<bool>[arguments.Length];
foreach (object[] answer in answers) foreach (object[] answer in answers)
{ {
bool gotMatch = true; bool gotMatch = true;
int nIterators = 0; int nIterators = 0;
// Try to bind all the arguments. // Try to bind all the arguments.
for (int i = 0; i < arguments.Length; ++i) for (int i = 0; i < arguments.Length; ++i)
{ {
if (indexArgs[i] != null) if (indexArgs[i] != null)
// We already matched this argument by looking up _indexedAnswers. // We already matched this argument by looking up _indexedAnswers.
continue; continue;
IEnumerator<bool> iterator = YP.unify(arguments[i], answer[i]).GetEnumerator(); IEnumerator<bool> iterator = YP.unify(arguments[i], answer[i]).GetEnumerator();
iterators[nIterators++] = iterator; iterators[nIterators++] = iterator;
// MoveNext() is true if YP.unify succeeds. // MoveNext() is true if YP.unify succeeds.
if (!iterator.MoveNext()) if (!iterator.MoveNext())
{ {
gotMatch = false; gotMatch = false;
break; break;
} }
} }
try try
{ {
if (gotMatch) if (gotMatch)
yield return false; yield return false;
} }
finally finally
{ {
// Manually finalize all the iterators. // Manually finalize all the iterators.
for (int i = 0; i < nIterators; ++i) for (int i = 0; i < nIterators; ++i)
iterators[i].Dispose(); iterators[i].Dispose();
} }
} }
} }
/// <summary> /// <summary>
/// A HashedList extends an ArrayList with methods to get a hash and to check equality /// A HashedList extends an ArrayList with methods to get a hash and to check equality
/// based on the elements of the list. /// based on the elements of the list.
/// </summary> /// </summary>
public class HashedList : ArrayList public class HashedList : ArrayList
{ {
private bool _gotHashCode = false; private bool _gotHashCode = false;
private int _hashCode; private int _hashCode;
public HashedList() public HashedList()
: base() : base()
{ {
} }
public HashedList(int capacity) public HashedList(int capacity)
: base(capacity) : base(capacity)
{ {
} }
public HashedList(ICollection c) public HashedList(ICollection c)
: base(c) : base(c)
{ {
} }
// Debug: Should override all the other methods that change this. // Debug: Should override all the other methods that change this.
public override int Add(object value) public override int Add(object value)
{ {
_gotHashCode = false; _gotHashCode = false;
return base.Add(value); return base.Add(value);
} }
public override int GetHashCode() public override int GetHashCode()
{ {
if (!_gotHashCode) if (!_gotHashCode)
{ {
int hashCode = 1; int hashCode = 1;
foreach (object obj in this) foreach (object obj in this)
hashCode = 31 * hashCode + (obj == null ? 0 : obj.GetHashCode()); hashCode = 31 * hashCode + (obj == null ? 0 : obj.GetHashCode());
_hashCode = hashCode; _hashCode = hashCode;
_gotHashCode = true; _gotHashCode = true;
} }
return _hashCode; return _hashCode;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (!(obj is ArrayList)) if (!(obj is ArrayList))
return false; return false;
ArrayList objList = (ArrayList)obj; ArrayList objList = (ArrayList)obj;
if (objList.Count != Count) if (objList.Count != Count)
return false; return false;
for (int i = 0; i < Count; ++i) for (int i = 0; i < Count; ++i)
{ {
object value = objList[i]; object value = objList[i];
if (value == null) if (value == null)
{ {
if (this[i] != null) if (this[i] != null)
return false; return false;
} }
else else
{ {
if (!value.Equals(this[i])) if (!value.Equals(this[i]))
return false; return false;
} }
} }
return true; return true;
} }
} }
/// <summary> /// <summary>
/// If we keep an index on value, return the value, or null if we don't index it. /// If we keep an index on value, return the value, or null if we don't index it.
/// </summary> /// </summary>
/// <param name="value">the term to examine. Assume you already called YP.getValue(value)</param> /// <param name="value">the term to examine. Assume you already called YP.getValue(value)</param>
/// <returns></returns> /// <returns></returns>
public static object getIndexValue(object value) public static object getIndexValue(object value)
{ {
if (value is Atom || value is string || value is Int32 || value is DateTime) if (value is Atom || value is string || value is Int32 || value is DateTime)
return value; return value;
else else
return null; return null;
} }
} }
} }

View File

@ -1,156 +1,156 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public class ListPair : Functor2 public class ListPair : Functor2
{ {
public ListPair(object head, object tail) : base(Atom.DOT, head, tail) public ListPair(object head, object tail) : base(Atom.DOT, head, tail)
{ {
} }
public static object make(List<object> list) public static object make(List<object> list)
{ {
if (list.Count <= 0) if (list.Count <= 0)
return Atom.NIL; return Atom.NIL;
object result = Atom.NIL; object result = Atom.NIL;
// Start from the end. // Start from the end.
for (int i = list.Count - 1; i >= 0; --i) for (int i = list.Count - 1; i >= 0; --i)
result = new ListPair(list[i], result); result = new ListPair(list[i], result);
return result; return result;
} }
public static object make(object[] array) public static object make(object[] array)
{ {
if (array.Length <= 0) if (array.Length <= 0)
return Atom.NIL; return Atom.NIL;
object result = Atom.NIL; object result = Atom.NIL;
// Start from the end. // Start from the end.
for (int i = array.Length - 1; i >= 0; --i) for (int i = array.Length - 1; i >= 0; --i)
result = new ListPair(array[i], result); result = new ListPair(array[i], result);
return result; return result;
} }
/// <summary> /// <summary>
/// Return a ListPair version of array, where repeated elements /// Return a ListPair version of array, where repeated elements
/// (according to YP.termEqual) are removed. /// (according to YP.termEqual) are removed.
/// </summary> /// </summary>
/// <param name="array"></param> /// <param name="array"></param>
/// <returns></returns> /// <returns></returns>
public static object makeWithoutRepeatedTerms(object[] array) public static object makeWithoutRepeatedTerms(object[] array)
{ {
if (array.Length <= 0) if (array.Length <= 0)
return Atom.NIL; return Atom.NIL;
// Start from the end. // Start from the end.
object previousTerm = array[array.Length - 1]; object previousTerm = array[array.Length - 1];
object result = new ListPair(previousTerm, Atom.NIL); object result = new ListPair(previousTerm, Atom.NIL);
for (int i = array.Length - 2; i >= 0; --i) for (int i = array.Length - 2; i >= 0; --i)
{ {
object term = array[i]; object term = array[i];
if (YP.termEqual(term, previousTerm)) if (YP.termEqual(term, previousTerm))
continue; continue;
result = new ListPair(term, result); result = new ListPair(term, result);
previousTerm = term; previousTerm = term;
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Return a ListPair version of array, where repeated elements /// Return a ListPair version of array, where repeated elements
/// (according to YP.termEqual) are removed. /// (according to YP.termEqual) are removed.
/// </summary> /// </summary>
/// <param name="array"></param> /// <param name="array"></param>
/// <returns></returns> /// <returns></returns>
public static object makeWithoutRepeatedTerms(List<object> array) public static object makeWithoutRepeatedTerms(List<object> array)
{ {
if (array.Count <= 0) if (array.Count <= 0)
return Atom.NIL; return Atom.NIL;
// Start from the end. // Start from the end.
object previousTerm = array[array.Count - 1]; object previousTerm = array[array.Count - 1];
object result = new ListPair(previousTerm, Atom.NIL); object result = new ListPair(previousTerm, Atom.NIL);
for (int i = array.Count - 2; i >= 0; --i) for (int i = array.Count - 2; i >= 0; --i)
{ {
object term = array[i]; object term = array[i];
if (YP.termEqual(term, previousTerm)) if (YP.termEqual(term, previousTerm))
continue; continue;
result = new ListPair(term, result); result = new ListPair(term, result);
previousTerm = term; previousTerm = term;
} }
return result; return result;
} }
public static object make(object element1) public static object make(object element1)
{ {
return new ListPair(element1, Atom.NIL); return new ListPair(element1, Atom.NIL);
} }
public static object make(object element1, object element2) public static object make(object element1, object element2)
{ {
return new ListPair(element1, new ListPair(element2, Atom.NIL)); return new ListPair(element1, new ListPair(element2, Atom.NIL));
} }
public static object make(object element1, object element2, object element3) public static object make(object element1, object element2, object element3)
{ {
return new ListPair(element1, return new ListPair(element1,
new ListPair(element2, new ListPair(element3, Atom.NIL))); new ListPair(element2, new ListPair(element3, Atom.NIL)));
} }
/// <summary> /// <summary>
/// Return an array of the elements in list or null if it is not /// 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. /// a proper list. If list is Atom.NIL, return an array of zero elements.
/// This does not call YP.getValue on each element. /// This does not call YP.getValue on each element.
/// </summary> /// </summary>
/// <param name="list"></param> /// <param name="list"></param>
/// <returns></returns> /// <returns></returns>
public static object[] toArray(object list) public static object[] toArray(object list)
{ {
list = YP.getValue(list); list = YP.getValue(list);
if (list.Equals(Atom.NIL)) if (list.Equals(Atom.NIL))
return new object[0]; return new object[0];
List<object> result = new List<object>(); List<object> result = new List<object>();
for (object element = list; for (object element = list;
element is Functor2 && ((Functor2)element)._name == Atom.DOT; element is Functor2 && ((Functor2)element)._name == Atom.DOT;
element = YP.getValue(((Functor2)element)._arg2)) element = YP.getValue(((Functor2)element)._arg2))
result.Add(((Functor2)element)._arg1); result.Add(((Functor2)element)._arg1);
if (result.Count <= 0) if (result.Count <= 0)
return null; return null;
return result.ToArray(); return result.ToArray();
} }
} }
} }

View File

@ -1,71 +1,71 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
/// <summary> /// <summary>
/// A PrologException is used as the exception thrown by YP.throw(Term). /// A PrologException is used as the exception thrown by YP.throw(Term).
/// </summary> /// </summary>
public class PrologException : Exception public class PrologException : Exception
{ {
public readonly object _term; public readonly object _term;
/// <summary> /// <summary>
/// Create a PrologException with the given Term. The printable exception message is the full Term. /// Create a PrologException with the given Term. The printable exception message is the full Term.
/// </summary> /// </summary>
/// <param name="Term">the term of the exception</param> /// <param name="Term">the term of the exception</param>
/// </param> /// </param>
public PrologException(object Term) public PrologException(object Term)
: base(YP.getValue(Term).ToString()) : base(YP.getValue(Term).ToString())
{ {
_term = YP.makeCopy(Term, new Variable.CopyStore()); _term = YP.makeCopy(Term, new Variable.CopyStore());
} }
/// <summary> /// <summary>
/// Create a PrologException where the Term is error(ErrorTerm, Message). /// 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. /// This uses YP.makeCopy to copy the ErrorTerm and Message so that they are valid after unbinding.
/// </summary> /// </summary>
/// <param name="ErrorTerm">the term of the exception</param> /// <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 name="Messsage">the message, converted to a string, to use as the printable exception message
/// </param> /// </param>
public PrologException(object ErrorTerm, object Message) public PrologException(object ErrorTerm, object Message)
: base(YP.getValue(Message).ToString()) : base(YP.getValue(Message).ToString())
{ {
_term = YP.makeCopy(new Functor2(Atom.a("error"), ErrorTerm, Message), new Variable.CopyStore()); _term = YP.makeCopy(new Functor2(Atom.a("error"), ErrorTerm, Message), new Variable.CopyStore());
} }
public object Term public object Term
{ {
get { return _term; } get { return _term; }
} }
} }
} }

View File

@ -1,405 +1,405 @@
YPOS: YieldProlog for OpenSim YPOS: YieldProlog for OpenSim
a compiler from Prolog to OpenSim compatible C# scripts a compiler from Prolog to OpenSim compatible C# scripts
Ported by Kino Coursey and Douglas Miles at Daxtron Labs. Ported by Kino Coursey and Douglas Miles at Daxtron Labs.
Based on Jeff Thompson Yield Prolog, http://yieldprolog.sourceforge.net/ Based on Jeff Thompson Yield Prolog, http://yieldprolog.sourceforge.net/
For Prolog see http://en.wikipedia.org/wiki/Prolog For Prolog see http://en.wikipedia.org/wiki/Prolog
INTRODUCTION INTRODUCTION
This folder contains code to implement a Prolog compiler using the "Yield Statement" found in C#, Javascript, and Python. 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. 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"). 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 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. 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. As such YP allows both declaritive and procedural programming in a 3D script enabled environment.
FEATURES FEATURES
* Allows implementation of logic programming for objects and agents. * Allows implementation of logic programming for objects and agents.
* C#/Javascript/Python as intermediate language * 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 * 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. * It is compatable with the existing C#/Mono based system.
* Yield Prolog is BSD license * Yield Prolog is BSD license
* Calling Prolog from C# scripts * Calling Prolog from C# scripts
* Calling C# functions (with LSL and OS functions) from Prolog * Calling C# functions (with LSL and OS functions) from Prolog
* Prolog dynamic database * Prolog dynamic database
* Edinburgh, Cocksin & Mellish style syntax. * Edinburgh, Cocksin & Mellish style syntax.
* Compiler is generated by compiling the Prolog descrition of itself into C# * Compiler is generated by compiling the Prolog descrition of itself into C#
* Same script entry interface as LSL * Same script entry interface as LSL
TODO TODO
* Utilize ability to generate Javascript and Python code * Utilize ability to generate Javascript and Python code
* Integrate Prolog database with Sim * Integrate Prolog database with Sim
* Translation error reporting back to the editor * Translation error reporting back to the editor
* Communications via message passing * Communications via message passing
* Interface to external inference engines * Interface to external inference engines
POSSIBILITIES POSSIBILITIES
* Inworld expert systems * Inworld expert systems
* Parallel logic programming and expert systems * Parallel logic programming and expert systems
* Ontology based processing * Ontology based processing
* Knowledge based alerting, accessing and business rules * Knowledge based alerting, accessing and business rules
For instance, listen on channel x, filter the events and broadcast alerts on channel y For instance, listen on channel x, filter the events and broadcast alerts on channel y
or send IM, emails etc. or send IM, emails etc.
USAGE: USAGE:
Add "yp" as an allowed compiler Add "yp" as an allowed compiler
OpenSim.ini OpenSim.ini
[ScriptEngine.DotNetEngine] [ScriptEngine.DotNetEngine]
AllowedCompilers=lsl,cs,js,vb,yp AllowedCompilers=lsl,cs,js,vb,yp
Enter scripts using the inworld editing process. Scripts have the following format. Enter scripts using the inworld editing process. Scripts have the following format.
The first line of a file must have "//yp". The first line of a file must have "//yp".
//yp //yp
<PROLOG CODE> <PROLOG CODE>
//CS //CS
<CS CODE> <CS CODE>
C# code calling a Prolog Predicate: C# code calling a Prolog Predicate:
----------------------------------- -----------------------------------
The Prolog predicate is transformed into a C# boolean function. So the general calling format is: The Prolog predicate is transformed into a C# boolean function. So the general calling format is:
foreach( bool var in prolog_predicate(ARGS)) {}; 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() I/O is via using a string reader and writer in conjunction with YP.See() and YP.Tell()
StringWriter PrologOutuput= new StringWriter(); StringWriter PrologOutuput= new StringWriter();
StringReader PrologInput= new StringReader(myInputString); StringReader PrologInput= new StringReader(myInputString);
YP.see(PrologInput); YP.see(PrologInput);
YP.tell(PrologOutuput); YP.tell(PrologOutuput);
<CALL PROLOG CODE HERE> <CALL PROLOG CODE HERE>
YP.seen(); YP.seen();
YP.told(); YP.told();
StringBuilder builder = PrologOutput.GetStringBuilder(); StringBuilder builder = PrologOutput.GetStringBuilder();
string finaloutput = builder.ToString(); 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. 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. Strings in Prolog are stored as Atom's and you need to use an Atom object to match.
\\yp \\yp
wanted('bob'). wanted('bob').
\\cs \\cs
string Who="bob"; string Who="bob";
foreach( bool ans in wanted(Atom.a(Who) )){}; foreach( bool ans in wanted(Atom.a(Who) )){};
Prolog code calling a C# function: 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 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. The C# function called uses "PrologCallback" and returns a boolean.
Dynamic database assertions: Dynamic database assertions:
----------------------------------- -----------------------------------
void assertdb2(string predicate, string arg1, string arg2) void assertdb2(string predicate, string arg1, string arg2)
{ {
name = Atom.a(predicate); name = Atom.a(predicate);
YP.assertFact(name, new object[] { arg1, arg2 }); YP.assertFact(name, new object[] { arg1, arg2 });
} }
void retractdb2(string predicate, string arg1, string arg2) void retractdb2(string predicate, string arg1, string arg2)
{ {
name = Atom.a(predicate); name = Atom.a(predicate);
YP.retractFact(name, new object[] { arg1, arg2 }); YP.retractFact(name, new object[] { arg1, arg2 });
} }
========================= APPENDIX A: touch test ================================ ========================= APPENDIX A: touch test ================================
=================================== ===================================
Input YP Code Input YP Code
=================================== ===================================
//yp //yp
mydb('field2','field1'). mydb('field2','field1').
mydb('andy','jane'). mydb('andy','jane').
mydb('carl','dan'). mydb('carl','dan').
mydb('andy','bill'). mydb('andy','bill').
mydb('andy','betty'). mydb('andy','betty').
call_me(X):-mydb(X,Y) , respond(Y). call_me(X):-mydb(X,Y) , respond(Y).
respond(X):- script_event('sayit',X). respond(X):- script_event('sayit',X).
//cs //cs
public void default_event_touch_start(int N ) public void default_event_touch_start(int N )
{ {
llSay(0,"pstart1"); llSay(0,"pstart1");
foreach( bool ans in call_me(Atom.a(@"andy") )){}; foreach( bool ans in call_me(Atom.a(@"andy") )){};
llSay(0,"pstop2"); llSay(0,"pstop2");
} }
public void default_event_state_entry() public void default_event_state_entry()
{ {
llSay(0,"prolog tester active."); llSay(0,"prolog tester active.");
} }
PrologCallback sayit(object ans) PrologCallback sayit(object ans)
{ {
llSay(0,"sayit1"); llSay(0,"sayit1");
string msg = "one answer is :"+((Variable)ans).getValue(); string msg = "one answer is :"+((Variable)ans).getValue();
llSay(0,msg); llSay(0,msg);
yield return false; yield return false;
} }
=================================== ===================================
Generated CS Code Generated CS Code
=================================== ===================================
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog;using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic; 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 { 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(); } static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null;public Script() { YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); }
//cs //cs
public void default_event_touch_start(int N ) public void default_event_touch_start(int N )
{ {
llSay(0,"pstart1"); llSay(0,"pstart1");
foreach( bool ans in call_me(Atom.a(@"carl") )){}; foreach( bool ans in call_me(Atom.a(@"carl") )){};
llSay(0,"pstop2"); llSay(0,"pstop2");
} }
public void default_event_state_entry() public void default_event_state_entry()
{ {
llSay(0,"prolog tester active."); llSay(0,"prolog tester active.");
} }
public IEnumerable<bool> sayit(object ans) public IEnumerable<bool> sayit(object ans)
{ {
llSay(0,"sayit1"); llSay(0,"sayit1");
string msg = "one answer is :"+((Variable)ans).getValue(); string msg = "one answer is :"+((Variable)ans).getValue();
llSay(0,msg); llSay(0,msg);
yield return false; yield return false;
} }
//YPEncoded //YPEncoded
public IEnumerable<bool> mydb(object arg1, object arg2) { public IEnumerable<bool> mydb(object arg1, object arg2) {
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"carl"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"carl"))) {
foreach (bool l3 in YP.unify(arg2, Atom.a(@"dan"))) { foreach (bool l3 in YP.unify(arg2, Atom.a(@"dan"))) {
yield return false; yield return false;
} }
} }
} }
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
foreach (bool l3 in YP.unify(arg2, Atom.a(@"bill"))) { foreach (bool l3 in YP.unify(arg2, Atom.a(@"bill"))) {
yield return false; yield return false;
} }
} }
} }
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
foreach (bool l3 in YP.unify(arg2, Atom.a(@"betty"))) { foreach (bool l3 in YP.unify(arg2, Atom.a(@"betty"))) {
yield return false; yield return false;
} }
} }
} }
} }
public IEnumerable<bool> call_me(object X) { public IEnumerable<bool> call_me(object X) {
{ {
Variable Y = new Variable(); Variable Y = new Variable();
foreach (bool l2 in mydb(X, Y)) { foreach (bool l2 in mydb(X, Y)) {
foreach (bool l3 in respond(Y)) { foreach (bool l3 in respond(Y)) {
yield return false; yield return false;
} }
} }
} }
} }
public IEnumerable<bool> respond(object X) { public IEnumerable<bool> respond(object X) {
{ {
foreach (bool l2 in this.sayit( X)) { foreach (bool l2 in this.sayit( X)) {
yield return false; yield return false;
} }
} }
} }
} } } }
========================= APPENDIX B:SENSOR INFORMED SCRIPT ===================== ========================= APPENDIX B:SENSOR INFORMED SCRIPT =====================
=================================== ===================================
Input YP Code Input YP Code
=================================== ===================================
//yp //yp
nop. nop.
good('Daxxon Kinoc'). good('Daxxon Kinoc').
good('Fluffy Kitty'). good('Fluffy Kitty').
bad('Eric Evil'). bad('Eric Evil').
bad('Spikey Plant'). bad('Spikey Plant').
prolog_notify(X) :- good(X) , script_event('accept',X). prolog_notify(X) :- good(X) , script_event('accept',X).
prolog_notify(X) :- bad(X) , script_event('reject',X). prolog_notify(X) :- bad(X) , script_event('reject',X).
//cs //cs
public void default_event_state_entry() public void default_event_state_entry()
{ {
llSay(0,"prolog sensor tester active."); llSay(0,"prolog sensor tester active.");
// Start a sensor looking for Agents // Start a sensor looking for Agents
llSensorRepeat("","",AGENT, 10, PI,20); llSensorRepeat("","",AGENT, 10, PI,20);
} }
public void default_event_sensor(int number_detected ) public void default_event_sensor(int number_detected )
{ {
int i; int i;
for(i=0;i< number_detected ;i++) for(i=0;i< number_detected ;i++)
{ {
string dName = llDetectedName(i); string dName = llDetectedName(i);
string dOwner = llDetectedName(i); string dOwner = llDetectedName(i);
foreach(bool response in prolog_notify(Atom.a(dName)) ){}; foreach(bool response in prolog_notify(Atom.a(dName)) ){};
foreach(bool response in prolog_notify(dOwner) ){}; foreach(bool response in prolog_notify(dOwner) ){};
llSay(0,"Saw "+dName); llSay(0,"Saw "+dName);
} }
} }
string decodeToString(object obj) string decodeToString(object obj)
{ {
if (obj is Variable) { return (string) ((Variable)obj).getValue();} if (obj is Variable) { return (string) ((Variable)obj).getValue();}
if (obj is Atom) { return (string) ((Atom)obj)._name;} if (obj is Atom) { return (string) ((Atom)obj)._name;}
return "unknown type"; return "unknown type";
} }
PrologCallback accept(object ans) PrologCallback accept(object ans)
{ {
string msg = "Welcoming :"+decodeToString(ans); string msg = "Welcoming :"+decodeToString(ans);
llSay(0,msg); llSay(0,msg);
yield return false; yield return false;
} }
PrologCallback reject(object ans) PrologCallback reject(object ans)
{ {
string msg = "Watching :"+decodeToString(ans); string msg = "Watching :"+decodeToString(ans);
llSay(0,msg); llSay(0,msg);
yield return false; yield return false;
} }
=================================== ===================================
Generated CS Code Generated CS Code
=================================== ===================================
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog; using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic; 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 { 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(); } static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null; public Script() { YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); }
//cs //cs
public void default_event_state_entry() public void default_event_state_entry()
{ {
llSay(0,"prolog sensor tester active."); llSay(0,"prolog sensor tester active.");
// Start a sensor looking for Agents // Start a sensor looking for Agents
llSensorRepeat("","",AGENT, 10, PI,20); llSensorRepeat("","",AGENT, 10, PI,20);
} }
public void default_event_sensor(int number_detected ) public void default_event_sensor(int number_detected )
{ {
int i; int i;
for(i=0;i< number_detected ;i++) for(i=0;i< number_detected ;i++)
{ {
string dName = llDetectedName(i); string dName = llDetectedName(i);
string dOwner = llDetectedName(i); string dOwner = llDetectedName(i);
foreach(bool response in prolog_notify(Atom.a(dName)) ){}; foreach(bool response in prolog_notify(Atom.a(dName)) ){};
foreach(bool response in prolog_notify(dOwner) ){}; foreach(bool response in prolog_notify(dOwner) ){};
llSay(0,"Saw "+dName); llSay(0,"Saw "+dName);
} }
} }
string decodeToString(object obj) string decodeToString(object obj)
{ {
if (obj is Variable) { return (string) ((Variable)obj).getValue();} if (obj is Variable) { return (string) ((Variable)obj).getValue();}
if (obj is Atom) { return (string) ((Atom)obj)._name;} if (obj is Atom) { return (string) ((Atom)obj)._name;}
return "unknown type"; return "unknown type";
} }
public IEnumerable<bool> accept(object ans) public IEnumerable<bool> accept(object ans)
{ {
string msg = "Welcoming :"+decodeToString(ans); string msg = "Welcoming :"+decodeToString(ans);
llSay(0,msg); llSay(0,msg);
yield return false; yield return false;
} }
public IEnumerable<bool> reject(object ans) public IEnumerable<bool> reject(object ans)
{ {
string msg = "Watching :"+decodeToString(ans); string msg = "Watching :"+decodeToString(ans);
llSay(0,msg); llSay(0,msg);
yield return false; yield return false;
} }
//YPEncoded //YPEncoded
public IEnumerable<bool> yp_nop_header_nop() { public IEnumerable<bool> yp_nop_header_nop() {
{ {
yield return false; yield return false;
} }
} }
public IEnumerable<bool> good(object arg1) { public IEnumerable<bool> good(object arg1) {
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"Daxxon Kinoc"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"Daxxon Kinoc"))) {
yield return false; yield return false;
} }
} }
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"Fluffy Kitty"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"Fluffy Kitty"))) {
yield return false; yield return false;
} }
} }
} }
public IEnumerable<bool> bad(object arg1) { public IEnumerable<bool> bad(object arg1) {
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"Eric Evil"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"Eric Evil"))) {
yield return false; yield return false;
} }
} }
{ {
foreach (bool l2 in YP.unify(arg1, Atom.a(@"Spikey Plant"))) { foreach (bool l2 in YP.unify(arg1, Atom.a(@"Spikey Plant"))) {
yield return false; yield return false;
} }
} }
} }
public IEnumerable<bool> prolog_notify(object X) { public IEnumerable<bool> prolog_notify(object X) {
{ {
foreach (bool l2 in good(X)) { foreach (bool l2 in good(X)) {
foreach (bool l3 in this.accept( X)) { foreach (bool l3 in this.accept( X)) {
yield return false; yield return false;
} }
} }
} }
{ {
foreach (bool l2 in bad(X)) { foreach (bool l2 in bad(X)) {
foreach (bool l3 in this.reject( X)) { foreach (bool l3 in this.reject( X)) {
yield return false; yield return false;
} }
} }
} }
} }
} } } }

View File

@ -1,62 +1,62 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
/// <summary> /// <summary>
/// An UndefinedPredicateException extends PrologException to create an existence_error exception. /// An UndefinedPredicateException extends PrologException to create an existence_error exception.
/// </summary> /// </summary>
public class UndefinedPredicateException : PrologException public class UndefinedPredicateException : PrologException
{ {
private Atom _predicateName; private Atom _predicateName;
private int _arity; private int _arity;
public UndefinedPredicateException(object message, Atom predicateName, int arity) public UndefinedPredicateException(object message, Atom predicateName, int arity)
: base(new Functor2 : base(new Functor2
(Atom.a("existence_error"), Atom.a("procedure"), new Functor2(Atom.a("/"), predicateName, arity)), (Atom.a("existence_error"), Atom.a("procedure"), new Functor2(Atom.a("/"), predicateName, arity)),
message) message)
{ {
_predicateName = predicateName; _predicateName = predicateName;
_arity = arity; _arity = arity;
} }
public Atom PredicateName public Atom PredicateName
{ {
get { return _predicateName; } get { return _predicateName; }
} }
public int Arity public int Arity
{ {
get { return _arity; } get { return _arity; }
} }
} }
} }

View File

@ -1,196 +1,196 @@
/* /*
* Copyright (C) 2007-2008, Jeff Thompson * Copyright (C) 2007-2008, Jeff Thompson
* *
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the copyright holder nor the names of its contributors * * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog
{ {
public interface IUnifiable public interface IUnifiable
{ {
IEnumerable<bool> unify(object arg); IEnumerable<bool> unify(object arg);
void addUniqueVariables(List<Variable> variableSet); void addUniqueVariables(List<Variable> variableSet);
object makeCopy(Variable.CopyStore copyStore); object makeCopy(Variable.CopyStore copyStore);
bool termEqual(object term); bool termEqual(object term);
bool ground(); bool ground();
} }
public class Variable : IUnifiable public class Variable : IUnifiable
{ {
// Use _isBound separate from _value so that it can be bound to any value, // Use _isBound separate from _value so that it can be bound to any value,
// including null. // including null.
private bool _isBound = false; private bool _isBound = false;
private object _value; private object _value;
public object getValue() public object getValue()
{ {
if (!_isBound) if (!_isBound)
return this; return this;
object result = _value; object result = _value;
while (result is Variable) while (result is Variable)
{ {
if (!((Variable)result)._isBound) if (!((Variable)result)._isBound)
return result; return result;
// Keep following the Variable chain. // Keep following the Variable chain.
result = ((Variable)result)._value; result = ((Variable)result)._value;
} }
return result; return result;
} }
public IEnumerable<bool> unify(object arg) public IEnumerable<bool> unify(object arg)
{ {
if (!_isBound) if (!_isBound)
{ {
_value = YP.getValue(arg); _value = YP.getValue(arg);
if (_value == this) if (_value == this)
// We are unifying this unbound variable with itself, so leave it unbound. // We are unifying this unbound variable with itself, so leave it unbound.
yield return false; yield return false;
else else
{ {
_isBound = true; _isBound = true;
try try
{ {
yield return false; yield return false;
} }
finally finally
{ {
// Remove the binding. // Remove the binding.
_isBound = false; _isBound = false;
} }
} }
} }
else else
{ {
foreach (bool l1 in YP.unify(this, arg)) foreach (bool l1 in YP.unify(this, arg))
yield return false; yield return false;
} }
} }
public override string ToString() public override string ToString()
{ {
object value = getValue(); object value = getValue();
if (value == this) if (value == this)
return "Variable"; return "Variable";
else else
return getValue().ToString(); return getValue().ToString();
} }
/// <summary> /// <summary>
/// If bound, call YP.addUniqueVariables on the value. Otherwise, if this unbound /// If bound, call YP.addUniqueVariables on the value. Otherwise, if this unbound
/// variable is not already in variableSet, add it. /// variable is not already in variableSet, add it.
/// </summary> /// </summary>
/// <param name="variableSet"></param> /// <param name="variableSet"></param>
public void addUniqueVariables(List<Variable> variableSet) public void addUniqueVariables(List<Variable> variableSet)
{ {
if (_isBound) if (_isBound)
YP.addUniqueVariables(getValue(), variableSet); YP.addUniqueVariables(getValue(), variableSet);
else else
{ {
if (variableSet.IndexOf(this) < 0) if (variableSet.IndexOf(this) < 0)
variableSet.Add(this); variableSet.Add(this);
} }
} }
/// <summary> /// <summary>
/// If bound, return YP.makeCopy for the value, else return copyStore.getCopy(this). /// If bound, return YP.makeCopy for the value, else return copyStore.getCopy(this).
/// However, if copyStore is null, just return this. /// However, if copyStore is null, just return this.
/// </summary> /// </summary>
/// <param name="copyStore"></param> /// <param name="copyStore"></param>
/// <returns></returns> /// <returns></returns>
public object makeCopy(Variable.CopyStore copyStore) public object makeCopy(Variable.CopyStore copyStore)
{ {
if (_isBound) if (_isBound)
return YP.makeCopy(getValue(), copyStore); return YP.makeCopy(getValue(), copyStore);
else else
return copyStore == null ? this : copyStore.getCopy(this); return copyStore == null ? this : copyStore.getCopy(this);
} }
public bool termEqual(object term) public bool termEqual(object term)
{ {
if (_isBound) if (_isBound)
return YP.termEqual(getValue(), term); return YP.termEqual(getValue(), term);
else else
return this == YP.getValue(term); return this == YP.getValue(term);
} }
public bool ground() public bool ground()
{ {
if (_isBound) if (_isBound)
// This is usually called by YP.ground which already did getValue, so this // This is usually called by YP.ground which already did getValue, so this
// should never be reached, but check anyway. // should never be reached, but check anyway.
return YP.ground(getValue()); return YP.ground(getValue());
else else
return false; return false;
} }
/// <summary> /// <summary>
/// A CopyStore is used by makeCopy to track which Variable objects have /// A CopyStore is used by makeCopy to track which Variable objects have
/// been copied. /// been copied.
/// </summary> /// </summary>
public class CopyStore public class CopyStore
{ {
private List<Variable> _inVariableSet = new List<Variable>(); private List<Variable> _inVariableSet = new List<Variable>();
private List<Variable> _outVariableSet = new List<Variable>(); private List<Variable> _outVariableSet = new List<Variable>();
/// <summary> /// <summary>
/// If inVariable has already been copied, return its copy. Otherwise, /// If inVariable has already been copied, return its copy. Otherwise,
/// return a fresh Variable associated with inVariable. /// return a fresh Variable associated with inVariable.
/// </summary> /// </summary>
/// <param name="inVariable"></param> /// <param name="inVariable"></param>
/// <returns></returns> /// <returns></returns>
public Variable getCopy(Variable inVariable) public Variable getCopy(Variable inVariable)
{ {
int index = _inVariableSet.IndexOf(inVariable); int index = _inVariableSet.IndexOf(inVariable);
if (index >= 0) if (index >= 0)
return _outVariableSet[index]; return _outVariableSet[index];
else else
{ {
Variable outVariable = new Variable(); Variable outVariable = new Variable();
_inVariableSet.Add(inVariable); _inVariableSet.Add(inVariable);
_outVariableSet.Add(outVariable); _outVariableSet.Add(outVariable);
return outVariable; return outVariable;
} }
} }
/// <summary> /// <summary>
/// Return the number of unique variables that have been copied. /// Return the number of unique variables that have been copied.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int getNUniqueVariables() public int getNUniqueVariables()
{ {
return _inVariableSet.Count; return _inVariableSet.Count;
} }
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,7 @@ property_map = {
".build" : text, ".build" : text,
".cfg" : text, ".cfg" : text,
".cgi" : text, ".cgi" : text,
".conf" : text,
".config" : text, ".config" : text,
".cs" : text, ".cs" : text,
".csproj" : text, ".csproj" : text,