compiled.py 12 KB

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