PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/YieldProlog/Modules/ListPair.cs

https://bitbucket.org/VirtualReality/optional-modules
C# | 163 lines | 96 code | 16 blank | 51 comment | 19 complexity | 80a841f2302129b2550bf1ed10dd39f0 MD5 | raw file
  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Aurora-Sim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
  30. {
  31. public class ListPair : Functor2
  32. {
  33. public ListPair(object head, object tail) : base(Atom.DOT, head, tail)
  34. {
  35. }
  36. public static object make(List<object> list)
  37. {
  38. if (list.Count <= 0)
  39. return Atom.NIL;
  40. object result = Atom.NIL;
  41. // Start from the end.
  42. for (int i = list.Count - 1; i >= 0; --i)
  43. result = new ListPair(list[i], result);
  44. return result;
  45. }
  46. public static object make(object[] array)
  47. {
  48. if (array.Length <= 0)
  49. return Atom.NIL;
  50. object result = Atom.NIL;
  51. // Start from the end.
  52. for (int i = array.Length - 1; i >= 0; --i)
  53. result = new ListPair(array[i], result);
  54. return result;
  55. }
  56. /// <summary>
  57. /// Return a ListPair version of array, where repeated elements
  58. /// (according to YP.termEqual) are removed.
  59. /// </summary>
  60. /// <param name="array"></param>
  61. /// <returns></returns>
  62. public static object makeWithoutRepeatedTerms(object[] array)
  63. {
  64. if (array.Length <= 0)
  65. return Atom.NIL;
  66. // Start from the end.
  67. object previousTerm = array[array.Length - 1];
  68. object result = new ListPair(previousTerm, Atom.NIL);
  69. for (int i = array.Length - 2; i >= 0; --i)
  70. {
  71. object term = array[i];
  72. if (YP.termEqual(term, previousTerm))
  73. continue;
  74. result = new ListPair(term, result);
  75. previousTerm = term;
  76. }
  77. return result;
  78. }
  79. /// <summary>
  80. /// Return a ListPair version of array, where repeated elements
  81. /// (according to YP.termEqual) are removed.
  82. /// </summary>
  83. /// <param name="array"></param>
  84. /// <returns></returns>
  85. public static object makeWithoutRepeatedTerms(List<object> array)
  86. {
  87. if (array.Count <= 0)
  88. return Atom.NIL;
  89. // Start from the end.
  90. object previousTerm = array[array.Count - 1];
  91. object result = new ListPair(previousTerm, Atom.NIL);
  92. for (int i = array.Count - 2; i >= 0; --i)
  93. {
  94. object term = array[i];
  95. if (YP.termEqual(term, previousTerm))
  96. continue;
  97. result = new ListPair(term, result);
  98. previousTerm = term;
  99. }
  100. return result;
  101. }
  102. public static object make(object element1)
  103. {
  104. return new ListPair(element1, Atom.NIL);
  105. }
  106. public static object make(object element1, object element2)
  107. {
  108. return new ListPair(element1, new ListPair(element2, Atom.NIL));
  109. }
  110. public static object make(object element1, object element2, object element3)
  111. {
  112. return new ListPair(element1,
  113. new ListPair(element2, new ListPair(element3, Atom.NIL)));
  114. }
  115. /// <summary>
  116. /// Return an array of the elements in list or null if it is not
  117. /// a proper list. If list is Atom.NIL, return an array of zero elements.
  118. /// If the list or one of the tails of the list is Variable, raise an instantiation_error.
  119. /// This does not call YP.getValue on each element.
  120. /// </summary>
  121. /// <param name="list"></param>
  122. /// <returns></returns>
  123. public static object[] toArray(object list)
  124. {
  125. list = YP.getValue(list);
  126. if (list.Equals(Atom.NIL))
  127. return new object[0];
  128. List<object> result = new List<object>();
  129. object element = list;
  130. while (true) {
  131. if (element == Atom.NIL)
  132. break;
  133. if (element is Variable)
  134. throw new PrologException(Atom.a("instantiation_error"),
  135. "List tail is an unbound variable");
  136. if (!(element is Functor2 && ((Functor2)element)._name == Atom.DOT))
  137. // Not a proper list.
  138. return null;
  139. result.Add(((Functor2)element)._arg1);
  140. element = YP.getValue(((Functor2)element)._arg2);
  141. }
  142. if (result.Count <= 0)
  143. return null;
  144. return result.ToArray();
  145. }
  146. }
  147. }