compiled.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. from modelverse_kernel.primitives import PrimitiveFinished
  2. import modelverse_jit.runtime as jit_runtime
  3. import time
  4. def reverseKeyLookupMulti(a, b, **remainder):
  5. edges, b_val, result = yield [("RO", [a]), ("RV", [b]), ("CN", [])]
  6. expanded_edges = yield [("RE", [i]) for i in edges]
  7. values = yield [("RV", [i[1]]) for i in expanded_edges]
  8. # Keep results in a local Python set, as we want to bundle as many requests as possible
  9. todo = set()
  10. for i, edge in enumerate(values):
  11. if b_val == edge:
  12. todo.add(i)
  13. outgoings = yield [("RO", [edges[i]]) for i in todo]
  14. values = yield [("RE", [outgoing[0]]) for outgoing in outgoings]
  15. edges = yield [("CE", [result, result]) for value in values]
  16. yield [("CE", [edge, value[1]]) for edge, value in zip(edges, values)]
  17. raise PrimitiveFinished(result)
  18. def reverseKeyLookup(a, b, **remainder):
  19. edges_out, edges_in = yield [("RO", [a]), ("RI", [b])]
  20. options = set(edges_out) & set(edges_in)
  21. if options:
  22. # Select one option randomly
  23. edge = options.pop()
  24. out_edges, = yield [("RO", [edge])]
  25. # Select one option randomly
  26. out_edge = out_edges.pop()
  27. e, = yield [("RE", [out_edge])]
  28. result = e[1]
  29. else:
  30. result, = yield [("CNV", [""])]
  31. raise PrimitiveFinished(result)
  32. def instantiated_name(a, b, **remainder):
  33. name_value, = yield [("RV", [b])]
  34. if name_value == "":
  35. b, = yield [("CNV", ["__" + str(a)])]
  36. raise PrimitiveFinished(b)
  37. def set_merge(a, b, **remainder):
  38. keys, = yield [("RDK", [b])]
  39. edges = yield [("CE", [a, a]) for key in keys]
  40. _ = yield [("CE", [edge, key]) for edge, key in zip(edges, keys)]
  41. raise PrimitiveFinished(a)
  42. def has_value(a, **remainder):
  43. v, = yield [("RV", [a])]
  44. if v is None:
  45. result, = yield [("CNV", [False])]
  46. else:
  47. result, = yield [("CNV", [True])]
  48. raise PrimitiveFinished(result)
  49. def make_reverse_dictionary(a, **remainder):
  50. reverse, = yield [("CN", [])]
  51. key_nodes, = yield [("RDK", [a])]
  52. values = yield [("RDN", [a, i]) for i in key_nodes]
  53. yield [("CD", [reverse, str(v), k]) for k, v in zip(key_nodes, values)]
  54. raise PrimitiveFinished(reverse)
  55. def dict_eq(a, b, **remainder):
  56. key_nodes, = yield [("RDK", [a])]
  57. key_values = yield [("RV", [i]) for i in key_nodes]
  58. values = yield [("RD", [a, i]) for i in key_values]
  59. values = yield [("RV", [i]) for i in values]
  60. a_dict = dict(zip(key_values, values))
  61. key_nodes, = yield [("RDK", [b])]
  62. key_values = yield [("RV", [i]) for i in key_nodes]
  63. values = yield [("RD", [b, i]) for i in key_values]
  64. values = yield [("RV", [i]) for i in values]
  65. b_dict = dict(zip(key_values, values))
  66. result, = yield [("CNV", [a_dict == b_dict])]
  67. raise PrimitiveFinished(result)
  68. def string_substr(a, b, c, **remainder):
  69. a_val, b_val, c_val = yield [("RV", [a]),
  70. ("RV", [b]),
  71. ("RV", [c])]
  72. try:
  73. new_value = a_val[b_val:c_val]
  74. except:
  75. new_value = ""
  76. result, = yield [("CNV", [new_value])]
  77. raise PrimitiveFinished(result)
  78. def integer_gt(a, b, **remainder):
  79. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  80. result, = yield [("CNV", [a_value > b_value])]
  81. raise PrimitiveFinished(result)
  82. def integer_neg(a, **remainder):
  83. a_value, = yield [("RV", [a])]
  84. result, = yield [("CNV", [-a_value])]
  85. raise PrimitiveFinished(result)
  86. def float_gt(a, b, **remainder):
  87. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  88. result, = yield [("CNV", [a_value > b_value])]
  89. raise PrimitiveFinished(result)
  90. def float_neg(a, **remainder):
  91. a_value, = yield [("RV", [a])]
  92. result, = yield [("CNV", [-a_value])]
  93. raise PrimitiveFinished(result)
  94. def value_neq(a, b, **remainder):
  95. a_value, b_value = yield [("RV", [a]), ("RV", [b])]
  96. result, = yield [("CNV", [a_value != b_value])]
  97. raise PrimitiveFinished(result)
  98. def element_neq(a, b, **remainder):
  99. result, = yield [("CNV", [a != b])]
  100. raise PrimitiveFinished(result)
  101. def list_append(a, b, **remainder):
  102. a_outgoing, = yield [("RO", [a])]
  103. _ = yield [("CD", [a, len(a_outgoing), b])]
  104. raise PrimitiveFinished(a)
  105. def list_read(a, b, **remainder):
  106. b_value, = yield [("RV", [b])]
  107. result, = yield [("RD", [a, b_value])]
  108. if result is None:
  109. raise Exception("List read out of bounds: %s" % b_value)
  110. raise PrimitiveFinished(result)
  111. def list_len(a, **remainder):
  112. outgoings, = yield [("RO", [a])]
  113. result, = yield [("CNV", [len(outgoings)])]
  114. raise PrimitiveFinished(result)
  115. def dict_add(a, b, c, **remainder):
  116. new_edge, = yield [("CE", [a, c])]
  117. yield [("CE", [new_edge, b])]
  118. raise PrimitiveFinished(a)
  119. def dict_len(a, **remainder):
  120. outgoings, = yield [("RO", [a])]
  121. result, = yield [("CNV", [len(outgoings)])]
  122. raise PrimitiveFinished(result)
  123. def set_add(a, b, **remainder):
  124. v, = yield [("RV", [b])]
  125. is_in, = yield [("RD", [a, v])]
  126. if not is_in:
  127. _, = yield [("CD", [a, v, a])]
  128. raise PrimitiveFinished(a)
  129. def set_add_node(a, b, **remainder):
  130. is_in, = yield [("RDN", [a, b])]
  131. if not is_in:
  132. edge, = yield [("CE", [a, a])]
  133. _, = yield [("CE", [edge, b])]
  134. raise PrimitiveFinished(a)
  135. def set_pop(a, **remainder):
  136. outgoing, = yield [("RO", [a])]
  137. if outgoing:
  138. outgoing = outgoing[0]
  139. new_outgoing, = yield [("RO", [outgoing])]
  140. new_outgoing = new_outgoing[0]
  141. edge, _ = yield [("RE", [new_outgoing]), ("DE", [outgoing])]
  142. raise PrimitiveFinished(edge[1])
  143. else:
  144. raise Exception("POP from empty set")
  145. print("Pop from empty set!")
  146. raise PrimitiveFinished(remainder["root"])
  147. def set_create(**remainder):
  148. result, = yield [("CN", [])]
  149. raise PrimitiveFinished(result)
  150. def list_create(**remainder):
  151. result, = yield [("CN", [])]
  152. raise PrimitiveFinished(result)
  153. def dict_create(**remainder):
  154. result, = yield [("CN", [])]
  155. raise PrimitiveFinished(result)
  156. def create_tuple(a, b, **remainder):
  157. result, = yield [("CN", [])]
  158. _, _ = yield [("CD", [result, 0, a]),
  159. ("CD", [result, 1, b]),
  160. ]
  161. raise PrimitiveFinished(result)
  162. def set_overlap(a, b, **remainder):
  163. a_keys, b_keys, res = yield [("RDK", [a]), ("RDK", [b]), ("CN", [])]
  164. a_values = yield [("RV", [i]) for i in a_keys]
  165. b_values = yield [("RV", [i]) for i in b_keys]
  166. result = set(a_values) & set(b_values)
  167. yield [("CD", [res, value, res]) for value in result]
  168. raise PrimitiveFinished(res)
  169. def get_superclasses(a, b, **remainder):
  170. model, name = a, b
  171. model_dict, tm_dict, name_value = yield [("RD", [a, "model"]),
  172. ("RD", [a, "type_mapping"]),
  173. ("RV", [b])]
  174. worklist = set([name_value])
  175. found = set([])
  176. cache_value = {}
  177. while worklist:
  178. name = worklist.pop()
  179. if name in found:
  180. continue
  181. elem, = yield [("RD", [model_dict, name])]
  182. found.add(name)
  183. # Iterate over all outgoing links
  184. outgoing, = yield [("RO", [elem])]
  185. outgoing = set(outgoing)
  186. while (outgoing):
  187. link = outgoing.pop()
  188. # If the link is typed by "Inheritance", we add its destination
  189. link_name_node, = yield [("CALL_ARGS", [reverseKeyLookup, [model_dict, link]])]
  190. link_name, = yield [("RV", [link_name_node])]
  191. t_edge, = yield [("RD", [tm_dict, link_name])]
  192. t_edge, = yield [("RV", [t_edge])]
  193. if t_edge == "Inheritance":
  194. edge, = yield [("RE", [link])]
  195. src, dst = edge
  196. # Look up dst's name and add it
  197. if dst not in cache_value:
  198. dst_name, = yield [("CALL_ARGS", [reverseKeyLookup, [model_dict, dst]])]
  199. dst_name_value, = yield [("RV", [dst_name])]
  200. cache_value[dst] = dst_name_value
  201. dst_name_value = cache_value[dst]
  202. worklist.add(dst_name_value)
  203. result, = yield [("CN", [])]
  204. yield [("CD", [result, i, result]) for i in found]
  205. raise PrimitiveFinished(result)
  206. def list_pop_final(a, **remainder):
  207. lst, = yield [("RO", [a])]
  208. length = len(lst)
  209. result, result_edge = yield [("RD", [a, length - 1]),
  210. ("RDE", [a, length -1])]
  211. _, = yield [("DE", [result_edge])]
  212. raise PrimitiveFinished(result)