compiled_legacy.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. from modelverse_kernel.primitives import PrimitiveFinished
  2. def reverseKeyLookup(a, b, **remainder):
  3. edges, = yield [("RO", [a])]
  4. expanded_edges = yield [("RE", [i]) for i in edges]
  5. for i, edge in enumerate(expanded_edges):
  6. if b == edge[1]:
  7. # Found our edge: edges[i]
  8. outgoing, = yield [("RO", [edges[i]])]
  9. result, = yield [("RE", [outgoing[0]])]
  10. raise PrimitiveFinished(result[1])
  11. result, = yield [("CNV", ["(unknown: %s)" % b])]
  12. raise PrimitiveFinished(result)
  13. """
  14. def read_attribute(a, b, c, **remainder):
  15. model_dict, b_val, c_val, type_mapping = \
  16. yield [("RD", [a, "model"]),
  17. ("RV", [b]),
  18. ("RV", [c]),
  19. ("RD", [a, "type_mapping"]),
  20. ]
  21. model_instance, = \
  22. yield [("RD", [model_dict, b_val])]
  23. edges, = yield [("RO", [model_instance])]
  24. edge_types = yield [("RDN", [type_mapping, i]) for i in edges]
  25. type_edge_val = yield [("RE", [i]) for i in edge_types]
  26. src_nodes = set([i[0] for i in type_edge_val])
  27. found_edges = yield [("RDE", [i, c_val]) for i in src_nodes]
  28. for e1 in found_edges:
  29. if e1 is not None:
  30. # Found an edge!
  31. for i, e2 in enumerate(edge_types):
  32. if e1 == e2:
  33. # The instance of this edge is the one we want!
  34. edge = edges[i]
  35. edge_val, = yield [("RE", [edge])]
  36. result = edge_val[1]
  37. raise PrimitiveFinished(result)
  38. else:
  39. result, = yield [("RR", [])]
  40. raise PrimitiveFinished(result)
  41. raise Exception("Error in reading edge!")
  42. """
  43. def set_copy(a, **remainder):
  44. b, = yield [("CN", [])]
  45. links, = yield [("RO", [a])]
  46. exp_links = yield [("RE", [i]) for i in links]
  47. _ = yield [("CE", [b, i[1]]) for i in exp_links]
  48. raise PrimitiveFinished(b)
  49. """
  50. def allInstances(a, b, **remainder):
  51. b_val, = yield [("RV", [b])]
  52. model_dict,= yield [("RD", [a, "model"])]
  53. metamodel, = yield [("RD", [a, "metamodel"])]
  54. m3, = yield [("RD", [metamodel, "metamodel"])]
  55. m3_model, = yield [("RD", [m3, "model"])]
  56. mm_dict, = yield [("RD", [metamodel, "model"])]
  57. typing, = yield [("RD", [a, "type_mapping"])]
  58. elem_keys, = yield [("RDK", [model_dict])]
  59. elems = yield [("RDN", [model_dict, i]) for i in elem_keys]
  60. mms = yield [("RDN", [typing, i]) for i in elems]
  61. # Have the type for each name
  62. types_to_name_nodes = {}
  63. for key, mm in zip(elem_keys, mms):
  64. types_to_name_nodes.setdefault(mm, set()).add(key)
  65. # And now we have the inverse mapping: for each type, we have the node containing the name
  66. # Get the inheritance link type
  67. inheritance_type, = yield [("RD", [m3_model, "Inheritance"])]
  68. # Now we figure out which types are valid for the specified model
  69. desired_types = set()
  70. mm_element, = yield [("RD", [mm_dict, b_val])]
  71. work_list = []
  72. work_list.append(mm_element)
  73. mm_typing, = yield [("RD", [metamodel, "type_mapping"])]
  74. while work_list:
  75. mm_element = work_list.pop()
  76. if mm_element in desired_types:
  77. # Already been here, so stop
  78. continue
  79. # New element, so continue
  80. desired_types.add(mm_element)
  81. # Follow all inheritance links that COME IN this node, as all these are subtypes and should also match
  82. incoming, = yield [("RI", [mm_element])]
  83. for i in incoming:
  84. t, = yield [("RDN", [mm_typing, i])]
  85. if t == inheritance_type:
  86. e, = yield [("RE", [i])]
  87. # Add the source of the inheritance link to the work list
  88. work_list.append(e[0])
  89. # Now desired_types holds all the direct types that we are interested in!
  90. # Construct the result out of all models that are direct instances of our specified type
  91. final = set()
  92. for t in desired_types:
  93. final |= types_to_name_nodes.get(t, set())
  94. # Result is a Python set with nodes, so just make this a Mv set
  95. result, = yield [("CN", [])]
  96. v = yield [("RV", [i]) for i in final]
  97. _ = yield [("CE", [result, i]) for i in final]
  98. raise PrimitiveFinished(result)
  99. """
  100. """
  101. def add_AL(a, b, **remainder):
  102. worklist = [(b, "funcdef")]
  103. added = set()
  104. type_cache = {}
  105. model_dict, = yield [("RD", [a, "model"])]
  106. metamodel, = yield [("RD", [a, "metamodel"])]
  107. metamodel_dict, = yield [("RD", [metamodel, "model"])]
  108. type_map, = yield [("RD", [a, "type_mapping"])]
  109. outgoing, = yield [("RO", [model_dict])]
  110. edges = yield [("RE", [i]) for i in outgoing]
  111. added |= set([i[1] for i in edges])
  112. result, = yield [("CNV", ["__%s" % b])]
  113. # All the action language elements and their expected output links
  114. type_links = {
  115. "if": [("cond", ""), ("then", ""), ("else", ""), ("next", "")],
  116. "while": [("cond", ""), ("body", ""), ("next", "")],
  117. "assign": [("var", ""), ("value", ""), ("next", "")],
  118. "break": [("while", "while")],
  119. "continue": [("while", "while")],
  120. "return": [("value", "")],
  121. "resolve": [("var", "")],
  122. "access": [("var", "")],
  123. "constant": [("node", "")],
  124. "output": [("node", ""), ("next", "")],
  125. "global": [("var", "String"), ("next", "")],
  126. "param": [("name", "String"), ("value", ""), ("next_param", "param")],
  127. "funcdef": [("body", ""), ("next", "")],
  128. "call": [("func", ""), ("params", "param"), ("last_param", "param"), ("next", "")],
  129. }
  130. # Already add some often used types to the type cache, so we don't have to check for their presence
  131. to_str, string = yield [("RD", [metamodel_dict, "to_str"]),
  132. ("RD", [metamodel_dict, "String"])]
  133. type_cache = {"to_str": to_str,
  134. "String": string}
  135. while worklist:
  136. # Fetch the element and see if we need to add it
  137. worknode, expected_type = worklist.pop(0)
  138. if worknode in added:
  139. continue
  140. # Determine type of element
  141. if expected_type == "":
  142. value, = yield [("RV", [worknode])]
  143. if (isinstance(value, dict)) and ("value" in value):
  144. v = value["value"]
  145. if v in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]:
  146. expected_type = v
  147. else:
  148. expected_type = "Any"
  149. else:
  150. expected_type = "Any"
  151. # Fill the cache
  152. if expected_type not in type_cache:
  153. type_cache[expected_type], = yield [("RD", [metamodel_dict, expected_type])]
  154. # Need to add it now
  155. yield [("CD", [model_dict, "__%s" % worknode, worknode])]
  156. added.add(worknode)
  157. # NOTE can't just use CD here, as the key is a node and not a value
  158. t1, = yield [("CE", [type_map, type_cache[expected_type]])]
  159. t2, = yield [("CE", [t1, worknode])]
  160. if t1 is None or t2 is None:
  161. raise Exception("ERROR")
  162. # Now add all its outgoing links, depending on the type we actually saw
  163. links = type_links.get(expected_type, [])
  164. for link in links:
  165. link_name, destination_type = link
  166. # Check if the link actually exists
  167. destination, = yield [("RD", [worknode, link_name])]
  168. if destination is not None:
  169. # If so, we add it and continue
  170. edge, = yield [("RDE", [worknode, link_name])]
  171. edge_outlinks, = yield [("RO", [edge])]
  172. edge_outlink = edge_outlinks[0]
  173. edge_name, = yield [("RE", [edge_outlink])]
  174. edge_name = edge_name[1]
  175. # Now add: edge, edge_outlink, edge_name
  176. # Add 'edge'
  177. yield [("CD", [model_dict, "__%s" % edge, edge])]
  178. added.add(edge)
  179. link_type = "%s_%s" % (expected_type, link_name)
  180. if link_type not in type_cache:
  181. type_cache[link_type], = yield [("RD", [metamodel_dict, link_type])]
  182. t, = yield [("CE", [type_map, type_cache[link_type]])]
  183. yield [("CE", [t, edge])]
  184. # Add 'edge_outlink'
  185. yield [("CD", [model_dict, "__%s" % edge_outlink, edge_outlink])]
  186. added.add(edge_outlink)
  187. t, = yield [("CE", [type_map, type_cache["to_str"]])]
  188. yield [("CE", [t, edge_outlink])]
  189. # Add 'edge_name' (if not present)
  190. if edge_name not in added:
  191. yield [("CD", [model_dict, "__%s" % edge_name, edge_name])]
  192. t, = yield [("CE", [type_map, type_cache["String"]])]
  193. yield [("CE", [t, edge_name])]
  194. added.add(edge_name)
  195. # Add the destination to the worklist
  196. worklist.append((destination, destination_type))
  197. raise PrimitiveFinished(result)
  198. """
  199. """
  200. def get_superclasses(a, b, **remainder):
  201. mm, = yield [("RD", [a, "metamodel"])]
  202. mm, = yield [("RD", [mm, "metamodel"])]
  203. m, = yield [("RD", [mm, "model"])]
  204. inheritance, = yield [("RD", [m, "Inheritance"])]
  205. model_dict, = yield [("RD", [a, "model"])]
  206. b_v, = yield [("RV", [b])]
  207. subclass, = yield [("RD", [model_dict, b_v])]
  208. type_mapping, = yield [("RD", [a, "type_mapping"])]
  209. names, = yield [("RDK", [model_dict])]
  210. elems = yield [("RDN", [model_dict, i]) for i in names]
  211. elem_to_name = dict(zip(elems, names))
  212. result, = yield [("CN", [])]
  213. worklist = [subclass]
  214. touched = set()
  215. while worklist:
  216. subclass = worklist.pop()
  217. res = elem_to_name[subclass]
  218. if subclass not in touched:
  219. touched.add(subclass)
  220. yield [("CE", [result, res])]
  221. outgoing, = yield [("RO", [subclass])]
  222. types = yield [("RDN", [type_mapping, i]) for i in outgoing]
  223. for i, t in enumerate(types):
  224. if t == inheritance:
  225. # Found an inheritance link!
  226. elem = outgoing[i]
  227. srcdst, = yield [("RE", [elem])]
  228. src, dst = srcdst
  229. # Find elem in elems
  230. worklist.append(dst)
  231. raise PrimitiveFinished(result)
  232. """
  233. """
  234. def selectPossibleIncoming(a, b, c, **remainder):
  235. model_dict, = yield [("RD", [a, "model"])]
  236. limit_set_links, = \
  237. yield [("RO", [c])]
  238. limit_set = yield [("RE", [i]) for i in limit_set_links]
  239. limit_set_names = [i[1] for i in limit_set]
  240. name_values = yield [("RV", [i]) for i in limit_set_names]
  241. limit_set = yield [("RD", [model_dict, i]) for i in name_values]
  242. try:
  243. gen = get_superclasses(a, b)
  244. inp = None
  245. while 1:
  246. inp = yield gen.send(inp)
  247. except PrimitiveFinished as e:
  248. superclasses = e.result
  249. vals, = yield [("RO", [superclasses])]
  250. superclasses = yield [("RE", [i]) for i in vals]
  251. superclasses = [i[1] for i in superclasses]
  252. superclass_names = yield [("RV", [i]) for i in superclasses]
  253. elems = yield [("RD", [model_dict, i]) for i in superclass_names]
  254. result, = yield [("CN", [])]
  255. for i, edge in enumerate(limit_set):
  256. srcdst, = yield [("RE", [edge])]
  257. src, dst = srcdst
  258. if dst in elems:
  259. yield [("CE", [result, limit_set_names[i]])]
  260. raise PrimitiveFinished(result)
  261. """
  262. """
  263. def selectPossibleOutgoing(a, b, c, **remainder):
  264. model_dict, = yield [("RD", [a, "model"])]
  265. limit_set_links, = \
  266. yield [("RO", [c])]
  267. limit_set = yield [("RE", [i]) for i in limit_set_links]
  268. limit_set_names = \
  269. [i[1] for i in limit_set]
  270. name_values = yield [("RV", [i]) for i in limit_set_names]
  271. limit_set = yield [("RD", [model_dict, i]) for i in name_values]
  272. try:
  273. gen = get_superclasses(a, b)
  274. inp = None
  275. while 1:
  276. inp = yield gen.send(inp)
  277. except PrimitiveFinished as e:
  278. superclasses = e.result
  279. vals, = yield [("RO", [superclasses])]
  280. superclasses = yield [("RE", [i]) for i in vals]
  281. superclasses = [i[1] for i in superclasses]
  282. superclass_names = yield [("RV", [i]) for i in superclasses]
  283. elems = yield [("RD", [model_dict, i]) for i in superclass_names]
  284. result, = yield [("CN", [])]
  285. for i, edge in enumerate(limit_set):
  286. srcdst, = yield [("RE", [edge])]
  287. src, dst = srcdst
  288. if src in elems:
  289. yield [("CE", [result, limit_set_names[i]])]
  290. raise PrimitiveFinished(result)
  291. """
  292. def check_symbols(a, b, c, **remainder):
  293. symbols = {}
  294. function_name, = yield [("RV", [b])]
  295. symbols[function_name] = False
  296. object_links, = yield [("RO", [c])]
  297. set_elements = yield [("RE", [i]) for i in object_links]
  298. set_elements = [i[1] for i in set_elements]
  299. set_values = yield [("RV", [i]) for i in set_elements]
  300. set_elements = yield [("RD", [a, i]) for i in set_values]
  301. symbols_set = yield [("RD", [i, "symbols"]) for i in set_elements]
  302. all_keys = yield [("RDK", [i]) for i in symbols_set]
  303. for i, s in zip(all_keys, symbols_set):
  304. # For each object we have found
  305. keys = yield [("RV", [j]) for j in i]
  306. values = yield [("RD", [s, j]) for j in keys]
  307. values = yield [("RV", [j]) for j in values]
  308. for key, value in zip(keys, values):
  309. k = key
  310. v = value
  311. if v and symbols.get(k, False):
  312. result = yield [("CNV", ["ERROR: multiple definition of symbol " + str(key)])]
  313. raise PrimitiveFinished(result)
  314. elif v and not symbols.get(k, False):
  315. symbols[k] = True
  316. elif not v and k not in symbols:
  317. symbols[k] = False
  318. for i, j in symbols.items():
  319. if i == "input" or i == "output":
  320. continue
  321. if not j:
  322. result, = yield [("CNV", ["ERROR: undefined symbol " + str(i)])]
  323. raise PrimitiveFinished(result)
  324. result, = yield [("CNV", ["OK"])]
  325. raise PrimitiveFinished(result)
  326. def construct_const(**remainder):
  327. v, = yield [("CNV", [{"value": "constant"}])]
  328. # Get input: keep trying until we get something
  329. try:
  330. gen = __get_input(remainder)
  331. inp = None
  332. while 1:
  333. inp = yield gen.send(inp)
  334. except PrimitiveFinished as e:
  335. inp = e.result
  336. yield [("CD", [v, "node", inp])]
  337. raise PrimitiveFinished(v)
  338. def instantiated_name(a, b, **remainder):
  339. name_value, = yield [("RV", [b])]
  340. if name_value == "":
  341. b, = yield [("CNV", ["__" + str(a)])]
  342. raise PrimitiveFinished(b)
  343. def __get_input(parameters):
  344. mvk = parameters["mvk"]
  345. task_root = parameters["task_root"]
  346. while 1:
  347. try:
  348. gen = mvk.input_init(task_root)
  349. inp = None
  350. while 1:
  351. inp = yield gen.send(inp)
  352. except StopIteration:
  353. # Finished
  354. if mvk.success:
  355. # Got some input, so we can access it
  356. raise PrimitiveFinished(mvk.input_value)
  357. else:
  358. # No input, so yield None but don't stop
  359. yield None