test_factorial.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import unittest
  2. from modelverse_kernel.main import ModelverseKernel
  3. from utils import execute_until_finished, MvSWrapper, get_inst, get_phase, get_returnvalue, get_phase_ref, read_primitive_interfaces, get_inst_ref, add_new_task
  4. import math
  5. class TestFactorial(unittest.TestCase):
  6. def setUp(self):
  7. self.mvs = MvSWrapper()
  8. self.root = self.mvs.execute("RR", [])
  9. print("Root: %s" % self.root)
  10. self.mvk = ModelverseKernel(self.root)
  11. self.primitives = read_primitive_interfaces(self.root, self.mvs)
  12. execute_until_finished(self.mvk, self.mvs, "load_primitives", [])
  13. def test_factorial_1(self):
  14. # Test for 'no recursion'
  15. self.helper_construct_and_invoke(1, math.factorial(1))
  16. def test_factorial_2(self):
  17. # Test for 'single recursion'
  18. self.helper_construct_and_invoke(2, math.factorial(2))
  19. def test_factorial_5(self):
  20. # Test for 'multiple recursion'
  21. self.helper_construct_and_invoke(5, math.factorial(5))
  22. def test_factorial_10(self):
  23. # Test for 'many recursion'
  24. self.helper_construct_and_invoke(10, math.factorial(10))
  25. def test_factorial_20(self):
  26. # Test for 'high numbers recursion'
  27. self.helper_construct_and_invoke(20, math.factorial(20))
  28. def helper_construct_and_invoke(self, param, result, fail=False):
  29. # Try to follow the same naming as in the dot file
  30. var_value_4 = self.mvs.execute("CN", [])
  31. var_4 = self.mvs.execute("CNV", ["accumulation"])
  32. signature_4 = self.mvs.execute("CN", [])
  33. params_4 = self.mvs.execute("CN", [])
  34. body_4 = self.mvs.execute("CN", [])
  35. params_4_a = self.mvs.execute("CN", [])
  36. invoke_params = self.mvs.execute("CN", [])
  37. var_1 = self.primitives["integer_subtraction"]
  38. var_2 = self.primitives["integer_multiplication"]
  39. var_3 = self.primitives["integer_gt"]
  40. param_1a = self.mvs.execute("CN", [])
  41. param_1b = self.mvs.execute("CN", [])
  42. param_2a = self.mvs.execute("CN", [])
  43. param_2b = self.mvs.execute("CN", [])
  44. param_3a = self.mvs.execute("CN", [])
  45. param_3b = self.mvs.execute("CN", [])
  46. param_4a = self.mvs.execute("CN", [])
  47. param_4b = self.mvs.execute("CN", [])
  48. params_4_a = self.mvs.execute("CN", [])
  49. value_1 = self.mvs.execute("CNV", [1])
  50. value_2 = self.mvs.execute("CNV", [1])
  51. value_3 = self.mvs.execute("CNV", [1])
  52. value_4 = self.mvs.execute("CNV", [param])
  53. value_a = self.mvs.execute("CNV", ["a"])
  54. value_b = self.mvs.execute("CNV", ["b"])
  55. value_c = self.mvs.execute("CNV", ["c"])
  56. value_a2 = self.mvs.execute("CNV", ["a"])
  57. value_b2 = self.mvs.execute("CNV", ["b"])
  58. value_a3 = self.mvs.execute("CNV", ["a"])
  59. value_b3 = self.mvs.execute("CNV", ["b"])
  60. value_n = self.mvs.execute("CNV", ["n"])
  61. value_n2 = self.mvs.execute("CNV", ["n"])
  62. access_resolve_4 = self.mvs.execute("CNV", [{"value":"access"}])
  63. access_resolve_7 = self.mvs.execute("CNV", [{"value":"access"}])
  64. if_1 = self.mvs.execute("CNV", [{"value":"if"}])
  65. call_1 = self.mvs.execute("CNV", [{"value":"call"}])
  66. call_2 = self.mvs.execute("CNV", [{"value":"call"}])
  67. call_3 = self.mvs.execute("CNV", [{"value":"call"}])
  68. call_4 = self.mvs.execute("CNV", [{"value":"call"}])
  69. invoke_factorial = self.mvs.execute("CNV", [{"value":"call"}])
  70. resolve_2 = self.mvs.execute("CNV", [{"value":"resolve"}])
  71. resolve_4 = self.mvs.execute("CNV", [{"value":"resolve"}])
  72. resolve_6 = self.mvs.execute("CNV", [{"value":"resolve"}])
  73. resolve_7 = self.mvs.execute("CNV", [{"value":"resolve"}])
  74. resolve_10 = self.mvs.execute("CNV", [{"value":"resolve"}])
  75. access_1 = self.mvs.execute("CNV", [{"value":"access"}])
  76. access_2 = self.mvs.execute("CNV", [{"value":"access"}])
  77. access_3 = self.mvs.execute("CNV", [{"value":"access"}])
  78. return_1 = self.mvs.execute("CNV", [{"value":"return"}])
  79. return_2 = self.mvs.execute("CNV", [{"value":"return"}])
  80. const_1 = self.mvs.execute("CNV", [{"value":"constant"}])
  81. const_2 = self.mvs.execute("CNV", [{"value":"constant"}])
  82. const_3 = self.mvs.execute("CNV", [{"value":"constant"}])
  83. const_4 = self.mvs.execute("CNV", [{"value":"constant"}])
  84. const_5 = self.mvs.execute("CNV", [{"value":"constant"}])
  85. # Rebind the invoke_factorial to the initial IP
  86. root = self.root
  87. _globals = self.mvs.execute("RD", [root, "__hierarchy"])
  88. self.mvs.execute("DE", [self.mvs.execute("RDE", [_globals, "__IP"])])
  89. self.mvs.execute("CD", [_globals, "__IP", invoke_factorial])
  90. t = self.mvs.execute("CE", [_globals, var_value_4])
  91. self.mvs.execute("CE", [t, var_4])
  92. self.mvs.execute("CD", [var_value_4, "value", signature_4])
  93. self.mvs.execute("CD", [signature_4, "body", if_1])
  94. self.mvs.execute("CD", [signature_4, "params", params_4])
  95. self.mvs.execute("CD", [params_4, "n", params_4_a])
  96. self.mvs.execute("CD", [if_1, "cond", call_1])
  97. self.mvs.execute("CD", [if_1, "then", return_2])
  98. self.mvs.execute("CD", [if_1, "else", return_1])
  99. node_3 = self.mvs.execute("CNV", [{"value":"constant"}])
  100. self.mvs.execute("CD", [call_1, "func", node_3])
  101. self.mvs.execute("CD", [node_3, "node", self.primitives["integer_gt"]])
  102. self.mvs.execute("CD", [call_1, "params", param_1a])
  103. self.mvs.execute("CD", [param_1a, "name", value_a])
  104. self.mvs.execute("CD", [param_1a, "value", access_1])
  105. self.mvs.execute("CD", [access_1, "var", resolve_2])
  106. self.mvs.execute("CD", [resolve_2, "var", params_4_a])
  107. self.mvs.execute("CD", [param_1a, "next_param", param_1b])
  108. self.mvs.execute("CD", [param_1b, "name", value_b])
  109. self.mvs.execute("CD", [param_1b, "value", const_1])
  110. self.mvs.execute("CD", [const_1, "node", value_1])
  111. self.mvs.execute("CD", [call_1, "last_param", param_1b])
  112. self.mvs.execute("CD", [return_1, "value", const_2])
  113. self.mvs.execute("CD", [const_2, "node", value_2])
  114. self.mvs.execute("CD", [return_2, "value", call_2])
  115. node_2 = self.mvs.execute("CNV", [{"value":"constant"}])
  116. self.mvs.execute("CD", [call_2, "func", node_2])
  117. self.mvs.execute("CD", [node_2, "node", self.primitives["integer_multiplication"]])
  118. self.mvs.execute("CD", [call_2, "params", param_2a])
  119. self.mvs.execute("CD", [call_2, "last_param", param_2b])
  120. self.mvs.execute("CD", [param_2a, "name", value_a2])
  121. self.mvs.execute("CD", [param_2a, "value", access_2])
  122. self.mvs.execute("CD", [param_2a, "next_param", param_2b])
  123. self.mvs.execute("CD", [access_2, "var", resolve_10])
  124. self.mvs.execute("CD", [resolve_10, "var", params_4_a])
  125. self.mvs.execute("CD", [param_2b, "name", value_b2])
  126. self.mvs.execute("CD", [param_2b, "value", call_3])
  127. self.mvs.execute("CD", [call_3, "func", access_resolve_4])
  128. self.mvs.execute("CD", [access_resolve_4, "var", resolve_4])
  129. self.mvs.execute("CD", [resolve_4, "var", var_4])
  130. self.mvs.execute("CD", [call_3, "params", param_3a])
  131. self.mvs.execute("CD", [call_3, "last_param", param_3a])
  132. self.mvs.execute("CD", [param_3a, "name", value_n])
  133. self.mvs.execute("CD", [param_3a, "value", call_4])
  134. node_1 = self.mvs.execute("CNV", [{"value":"constant"}])
  135. self.mvs.execute("CD", [call_4, "func", node_1])
  136. self.mvs.execute("CD", [node_1, "node", self.primitives["integer_subtraction"]])
  137. self.mvs.execute("CD", [call_4, "params", param_4a])
  138. self.mvs.execute("CD", [param_4a, "name", value_a3])
  139. self.mvs.execute("CD", [param_4a, "value", access_3])
  140. self.mvs.execute("CD", [access_3, "var", resolve_6])
  141. self.mvs.execute("CD", [resolve_6, "var", params_4_a])
  142. self.mvs.execute("CD", [param_4a, "next_param", param_4b])
  143. self.mvs.execute("CD", [param_4b, "name", value_b3])
  144. self.mvs.execute("CD", [param_4b, "value", const_3])
  145. self.mvs.execute("CD", [const_3, "node", value_3])
  146. self.mvs.execute("CD", [call_4, "last_param", param_4b])
  147. self.mvs.execute("CD", [invoke_factorial, "func", access_resolve_7])
  148. self.mvs.execute("CD", [access_resolve_7, "var", resolve_7])
  149. self.mvs.execute("CD", [resolve_7, "var", var_4])
  150. self.mvs.execute("CD", [invoke_factorial, "params", invoke_params])
  151. self.mvs.execute("CD", [invoke_factorial, "last_param", invoke_params])
  152. self.mvs.execute("CD", [invoke_params, "value", const_4])
  153. self.mvs.execute("CD", [invoke_params, "name", value_n2])
  154. self.mvs.execute("CD", [const_4, "node", value_4])
  155. self.mvs.execute("CD", [invoke_factorial, "next", const_5])
  156. self.mvs.execute("CD", [const_5, "node", value_c])
  157. execute_until_finished(self.mvk, self.mvs, "initialize_new_task", [])
  158. t = self.mvs.execute("CE", [self.mvs.execute("RD", [self.mvs.execute("RD", [root, "task_1"]), "globals"]), var_value_4])
  159. self.mvs.execute("CE", [t, var_4])
  160. ### Execute rules
  161. self.assertEquals(get_inst(self.root, self.mvs), "call")
  162. self.assertEquals(get_phase(self.root, self.mvs), "init")
  163. execute_until_finished(self.mvk, self.mvs)
  164. #i = 0
  165. while (get_inst_ref(self.root, self.mvs) != const_5) or (get_phase(self.root, self.mvs) != "init"):
  166. #print("EXEC (%s) -- (%s, %s)" % (i, get_inst(self.root, self.mvs), get_phase(self.root, self.mvs)))
  167. #i += 1
  168. #self.mvs.mvs.dump(0, "%i.dot" % i)
  169. execute_until_finished(self.mvk, self.mvs)
  170. if not fail:
  171. self.assertEquals(get_returnvalue(self.root, self.mvs), result)