compiled.py 9.1 KB

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