test_factorial.py 9.9 KB

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