compiled.py 12 KB

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