Remove unmaintained and unused YieldProlog scripting language

This hasn't been mainntained since 2008 and has not been kept up with the rest of the language infrastructure.
Hence, it almost certainly doesn't work and has never been used, afaik
If this is wrong, please say on the opensim-users/dev mailing list.
Removing to reduce maintenance burden (since it still needs to be made to compile).
0.8.0.3
Justin Clark-Casey (justincc) 2014-03-26 00:59:57 +00:00
parent cffea984f1
commit d3387d591a
17 changed files with 0 additions and 15906 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,33 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.Shared.YieldProlog")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://opensimulator.org")]
[assembly: AssemblyProduct("OpenSim")]
[assembly: AssemblyCopyright("OpenSimulator developers")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8df98e6b-0425-44d6-8d91-2b3b4c56acdf")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("0.7.6.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

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

View File

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

View File

@ -2221,38 +2221,6 @@
</Files>
</Project>
<Project frameworkVersion="v4_0" name="OpenSim.Region.ScriptEngine.Shared.YieldProlog" path="OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Data"/>
<Reference name="System.Web"/>
<Reference name="System.Xml"/>
<Reference name="OpenMetaverseTypes" path="../../../../../../../bin/"/>
<Reference name="OpenSim"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
<Reference name="Nini" path="../../../../../../../bin/"/>
<Reference name="log4net" path="../../../../../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="false"/>
</Files>
</Project>
<Project frameworkVersion="v4_0" name="OpenSim.Region.ScriptEngine.Shared.Api" path="OpenSim/Region/ScriptEngine/Shared/Api/Implementation" type="Library">
<Configuration name="Debug">
<Options>