compiled.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. def read_attribute(a, b, c, **remainder):
  14. def make_list(v, l):
  15. return [v] if l else v
  16. #TODO this can be optimized even further...
  17. model_dict, b_val, c_val, type_mapping = \
  18. yield [("RD", [a, "model"]),
  19. ("RV", [b]),
  20. ("RV", [c]),
  21. ("RD", [a, "type_mapping"]),
  22. ]
  23. model_instance = \
  24. yield [("RD", [model_dict, b_val])]
  25. edges = yield [("RO", [model_instance])]
  26. edge_types = yield [("RDN", [type_mapping, i]) for i in edges]
  27. edge_types = make_list(edge_types, len(edges) == 1)
  28. type_edge_val = yield [("RE", [i]) for i in edge_types]
  29. type_edge_val = make_list(type_edge_val, len(edges) == 1)
  30. src_nodes = set([i[0] for i in type_edge_val])
  31. found_edges = yield [("RDE", [i, c_val]) for i in src_nodes]
  32. found_edges = make_list(found_edges, len(src_nodes) == 1)
  33. for e1 in found_edges:
  34. if e1 is not None:
  35. # Found an edge!
  36. for i, e2 in enumerate(edge_types):
  37. if e1 == e2:
  38. # The instance of this edge is the one we want!
  39. edge = edges[i]
  40. edge_val = yield [("RE", [edge])]
  41. result = edge_val[1]
  42. raise PrimitiveFinished(result)
  43. else:
  44. result = yield [("RR", [])]
  45. raise PrimitiveFinished(result)
  46. raise Exception("Error in reading edge!")
  47. def precompute_cardinalities(a, **remainder):
  48. result = yield [("CN", [])]
  49. # Read out all edges from the metamodel
  50. a = yield [("RD", [a, "metamodel"])]
  51. model_dict = yield [("RD", [a, "model"])]
  52. model_keys = yield [("RDK", [model_dict])]
  53. type_mapping = yield [("RD", [a, "type_mapping"])]
  54. elems = yield [("RDN", [model_dict, k]) for k in model_keys]
  55. model_keys_str= yield [("RV", [i]) for i in model_keys]
  56. elem_to_name = dict(zip(elems, model_keys_str))
  57. edges = yield [("RE", [i]) for i in elems]
  58. elems = [elems[i] for i, edge_val in enumerate(edges) if edge_val is not None]
  59. # Now we have all edges in the metamodel
  60. # Read out the type of the Association defining all cardinalities
  61. metamodel = yield [("RD", [a, "metamodel"])]
  62. metametamodel = yield [("RD", [metamodel, "metamodel"])]
  63. metametamodel_dict = \
  64. yield [("RD", [metametamodel, "model"])]
  65. assoc = yield [("RD", [metametamodel_dict, "Association"])]
  66. print(assoc)
  67. slc, suc, tlc, tuc = \
  68. yield [("RDE", [assoc, "source_lower_cardinality"]),
  69. ("RDE", [assoc, "source_upper_cardinality"]),
  70. ("RDE", [assoc, "target_lower_cardinality"]),
  71. ("RDE", [assoc, "target_upper_cardinality"]),
  72. ]
  73. print("===================================================================================")
  74. print(slc)
  75. print(suc)
  76. print(tlc)
  77. print(tuc)
  78. print("===================================================================================")
  79. print(elems)
  80. # All that we now have to do is find, for each edge, whether or not it has an edge typed by any of these links!
  81. # Just find all links typed by these links!
  82. types = yield [("RDN", [type_mapping, i]) for i in elems]
  83. print(types)
  84. cardinalities = {}
  85. for i, edge_type in enumerate(types):
  86. if edge_type == slc:
  87. t = "slc"
  88. elif edge_type == suc:
  89. t = "suc"
  90. elif edge_type == tlc:
  91. t = "tlc"
  92. elif edge_type == tuc:
  93. t = "tuc"
  94. else:
  95. continue
  96. print("HIT CARDINALITY!")
  97. # Found a link, so add it
  98. source, destination = yield [("RE", [elems[i]])]
  99. # The edge gives the "source" the cardinality found in "destination"
  100. cardinalities.setdefault(elem_to_name[source], {})[t] = destination
  101. # Now we have to translate the "cardinalities" Python dictionary to a Modelverse dictionary
  102. nodes = yield [("CN", []) for i in cardinalities]
  103. yield [("CD", [result, i, node]) for i, node in zip(cardinalities.keys(), nodes)]
  104. print("Create dict entries for " + str(cardinalities.keys()))
  105. l = cardinalities.keys()
  106. values = yield [("RD", [result, i]) for i in l]
  107. for i, value in enumerate(values):
  108. cards = cardinalities[l[i]]
  109. yield [("CD", [value, card_type, cards[card_type]]) for card_type in cards]
  110. print("CD %s --> %s" % (card_type, cards[card_type]))
  111. raise PrimitiveFinished(result)