Functor.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (C) 2007-2008, Jeff Thompson
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of the copyright holder nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  26. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. using System;
  31. using System.Collections.Generic;
  32. namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
  33. {
  34. public class Functor : IUnifiable
  35. {
  36. public readonly Atom _name;
  37. public readonly object[] _args;
  38. public Functor(Atom name, object[] args)
  39. {
  40. if (args.Length <= 3)
  41. {
  42. if (args.Length == 0)
  43. throw new Exception("For arity 0 functor, just use name as an Atom");
  44. else if (args.Length == 1)
  45. throw new Exception("For arity 1 functor, use Functor1");
  46. else if (args.Length == 2)
  47. throw new Exception("For arity 2 functor, use Functor2");
  48. else if (args.Length == 3)
  49. throw new Exception("For arity 3 functor, use Functor3");
  50. else
  51. // (This shouldn't happen, but include it for completeness.
  52. throw new Exception("Cannot create a Functor of arity " + args.Length);
  53. }
  54. _name = name;
  55. _args = args;
  56. }
  57. public Functor(string name, object[] args)
  58. : this(Atom.a(name), args)
  59. {
  60. }
  61. /// <summary>
  62. /// Return an Atom, Functor1, Functor2, Functor3 or Functor depending on the
  63. /// length of args.
  64. /// Note that this is different than the Functor constructor which requires
  65. /// the length of args to be greater than 3.
  66. /// </summary>
  67. /// <param name="name"></param>
  68. /// <param name="args"></param>
  69. /// <returns></returns>
  70. public static object make(Atom name, object[] args)
  71. {
  72. if (args.Length <= 0)
  73. return name;
  74. else if (args.Length == 1)
  75. return new Functor1(name, args[0]);
  76. else if (args.Length == 2)
  77. return new Functor2(name, args[0], args[1]);
  78. else if (args.Length == 3)
  79. return new Functor3(name, args[0], args[1], args[2]);
  80. else
  81. return new Functor(name, args);
  82. }
  83. /// <summary>
  84. /// Call the main make, first converting name to an Atom.
  85. /// </summary>
  86. /// <param name="name"></param>
  87. /// <param name="args"></param>
  88. /// <returns></returns>
  89. public static object make(string name, object[] args)
  90. {
  91. return make(Atom.a(name), args);
  92. }
  93. public IEnumerable<bool> unify(object arg)
  94. {
  95. arg = YP.getValue(arg);
  96. if (arg is Functor)
  97. {
  98. Functor argFunctor = (Functor)arg;
  99. if (_name.Equals(argFunctor._name))
  100. return YP.unifyArrays(_args, argFunctor._args);
  101. else
  102. return YP.fail();
  103. }
  104. else if (arg is Variable)
  105. return ((Variable)arg).unify(this);
  106. else
  107. return YP.fail();
  108. }
  109. public override string ToString()
  110. {
  111. string result = _name + "(" + YP.getValue(_args[0]);
  112. for (int i = 1; i < _args.Length; ++i)
  113. result += ", " + YP.getValue(_args[i]);
  114. result += ")";
  115. return result;
  116. }
  117. public bool termEqual(object term)
  118. {
  119. term = YP.getValue(term);
  120. if (term is Functor)
  121. {
  122. Functor termFunctor = (Functor)term;
  123. if (_name.Equals(termFunctor._name) && _args.Length == termFunctor._args.Length)
  124. {
  125. for (int i = 0; i < _args.Length; ++i)
  126. {
  127. if (!YP.termEqual(_args[i], termFunctor._args[i]))
  128. return false;
  129. }
  130. return true;
  131. }
  132. }
  133. return false;
  134. }
  135. public bool lessThan(Functor functor)
  136. {
  137. // Do the equal check first since it is faster.
  138. if (!_name.Equals(functor._name))
  139. return _name.lessThan(functor._name);
  140. if (_args.Length != functor._args.Length)
  141. return _args.Length < functor._args.Length;
  142. for (int i = 0; i < _args.Length; ++i)
  143. {
  144. if (!YP.termEqual(_args[i], functor._args[i]))
  145. return YP.termLessThan(_args[i], functor._args[i]);
  146. }
  147. return false;
  148. }
  149. public bool ground()
  150. {
  151. for (int i = 0; i < _args.Length; ++i)
  152. {
  153. if (!YP.ground(_args[i]))
  154. return false;
  155. }
  156. return true;
  157. }
  158. public void addUniqueVariables(List<Variable> variableSet)
  159. {
  160. for (int i = 0; i < _args.Length; ++i)
  161. YP.addUniqueVariables(_args[i], variableSet);
  162. }
  163. public object makeCopy(Variable.CopyStore copyStore)
  164. {
  165. object[] argsCopy = new object[_args.Length];
  166. for (int i = 0; i < _args.Length; ++i)
  167. argsCopy[i] = YP.makeCopy(_args[i], copyStore);
  168. return new Functor(_name, argsCopy);
  169. }
  170. }
  171. }