compiled.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #TODO this can be optimized even further...
  15. model_dict, b_val, type_mapping = \
  16. yield [("RD", [a, "model"]),
  17. ("RV", [b]),
  18. ("RD", [a, "type_mapping"]),
  19. ]
  20. model_instance, edges = \
  21. yield [("RD", [model_dict, b]),
  22. ("RO", [a]),
  23. ]
  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, b_val]) for i in src_nodes]
  28. if len(src_nodes) == 1:
  29. found_edges = [found_edges]
  30. for e1 in found_edges:
  31. if e1 is not None:
  32. # Found an edge!
  33. for i, e2 in enumerate(edge_types):
  34. if e1 == e2:
  35. # The instance of this edge is the one we want!
  36. edge = edges[i]
  37. edge_val = yield [("RE", [edge])]
  38. result = edge_val[1]
  39. raise PrimitiveFinished(result)
  40. else:
  41. result = yield [("RR", [])]
  42. raise PrimitiveFinished(result)
  43. raise Exception("Error in reading edge!")
  44. def precompute_cardinalities(a, **remainder):
  45. result = yield [("CN", [])]
  46. # Read out all edges from the metamodel
  47. model_dict = yield [("RD", [a, "model"])]
  48. type_mapping = yield [("RD", [a, "type_mapping"])]
  49. elems = yield [("RO", [model_dict])]
  50. elems = yield [("RE", [i]) for i in elems]
  51. elems = [i[1] for i in elems]
  52. edges = yield [("RE", [i]) for i in elems]
  53. elems = [elems[i] for i, edge_val in enumerate(edges) if edge_val is not None]
  54. # Now we have all edges in the metamodel
  55. # Read out the type of the Association defining all cardinalities
  56. metamodel = yield [("RD", [a, "metamodel"])]
  57. metamodel_dict= yield [("RD", [metamodel, "model"])]
  58. assoc = yield [("RD", [metamodel_dict, "Association"])]
  59. slc, suc, tlc, tuc = \
  60. yield [("RDE", [assoc, "source_lower_cardinality"]),
  61. ("RDE", [assoc, "source_upper_cardinality"]),
  62. ("RDE", [assoc, "target_lower_cardinality"]),
  63. ("RDE", [assoc, "target_upper_cardinality"]),
  64. ]
  65. # 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!
  66. # Just find all links typed by these links!
  67. types = yield [("RDN", [type_mapping, i]) for i in elems]
  68. cardinalities = {}
  69. for i, edge_type in enumerate(types):
  70. if edge_type == slc:
  71. t = "slc"
  72. elif edge_type == suc:
  73. t = "suc"
  74. elif edge_type == tlc:
  75. t = "tlc"
  76. elif edge_type == tuc:
  77. t = "tuc"
  78. else:
  79. continue
  80. # Found a link, so add it
  81. source, destination = yield [("RE", [elems[i]])]
  82. # The edge gives the "source" the cardinality found in "destination"
  83. cardinalities.setdefault(source, {})[t] = destination
  84. # Now we have to translate the "cardinalities" Python dictionary to a Modelverse dictionary
  85. nodes = yield [("CN", []) for i in cardinalities]
  86. yield [("CD", [result, i, node]) for i, node in zip(cardinalities, nodes)]
  87. l = list(cardinalities)
  88. values = yield [("RD", [result, i]) for i in l]
  89. for i, value in enumerate(values):
  90. cards = cardinalities[l[i]]
  91. yield [("CD", [value, card_type, cards[card_type]]) for card_type in cards]
  92. raise PrimitiveFinished(result)