|
@@ -509,3 +509,66 @@ def dict_copy(a, **remainder):
|
|
|
keys = yield [("RV", [i]) for i in keys]
|
|
|
yield [("CD", [new, k, v]) for k, v in zip(keys, values)]
|
|
|
yield [("RETURN", [{'id': new}])]
|
|
|
+
|
|
|
+def read_attribute(a, b, c, root, **remainder):
|
|
|
+ if "value" not in b:
|
|
|
+ b["value"], = yield [("RV", [b['id']])]
|
|
|
+ if "value" not in c:
|
|
|
+ c["value"], = yield [("RV", [c['id']])]
|
|
|
+
|
|
|
+ m, metamodel = yield [("RD", [a['id'], "model"]), ("RD", [a['id'], "metamodel"])]
|
|
|
+ mm, elem, tm = yield [("RD", [metamodel, "model"]), ("RD", [m, b['value']]), ("RD", [a['id'], "type_mapping"])]
|
|
|
+
|
|
|
+ if elem is not None:
|
|
|
+ # Read all outgoing links and their names
|
|
|
+ outgoing_edges, tm = yield [("RO", [elem]), ("RD", [tm, "root"])]
|
|
|
+
|
|
|
+ if outgoing_edges:
|
|
|
+ outgoing_names = []
|
|
|
+ backlinks = {}
|
|
|
+ edges_out, = yield [("RO", [m])]
|
|
|
+ edges_out = set(edges_out)
|
|
|
+ for i in outgoing_edges:
|
|
|
+ edges_in, = yield [("RI", [i])]
|
|
|
+
|
|
|
+ if edges_in is None:
|
|
|
+ continue
|
|
|
+
|
|
|
+ for edge in edges_in:
|
|
|
+ if edge in edges_out:
|
|
|
+ out_edges, = yield [("RO", [edge])]
|
|
|
+ # Select one option randomly
|
|
|
+ if out_edges:
|
|
|
+ out_edge = out_edges.pop()
|
|
|
+ e, = yield [("RE", [out_edge])]
|
|
|
+ val, = yield [("RV", [e[1]])]
|
|
|
+ backlinks[val] = i
|
|
|
+ outgoing_names.append(val)
|
|
|
+
|
|
|
+ if outgoing_names:
|
|
|
+ # Read out the types and flatten
|
|
|
+ types = yield [("RD", [tm, i]) for i in outgoing_names]
|
|
|
+ types = yield [("RV", [i]) for i in types]
|
|
|
+ edges = yield [("RD", [mm, i]) for i in types]
|
|
|
+ sources = yield [("RE", [i]) for i in edges]
|
|
|
+ sources = {i[0] for i in sources}
|
|
|
+ backlinks = {e: backlinks[s] for e, s in zip(edges, outgoing_names)}
|
|
|
+
|
|
|
+ # List the outgoing links with the attribute in it
|
|
|
+ vals = yield [("RDE", [i, c['value']]) for i in sources]
|
|
|
+ vals = [v for v in vals if v is not None]
|
|
|
+
|
|
|
+ if vals:
|
|
|
+ # Found the link and stored in vals[0]
|
|
|
+ edge = vals[0]
|
|
|
+
|
|
|
+ # Get the instance of this link
|
|
|
+ if edge in backlinks:
|
|
|
+ val, = yield [("RE", [backlinks[edge]])]
|
|
|
+ yield [("RETURN", [{'id': val[1]}])]
|
|
|
+ else:
|
|
|
+ outgoing_edges, = yield [("RO", [elem])]
|
|
|
+ ee = yield [("RE", [i]) for i in outgoing_edges]
|
|
|
+ vals = yield [("RV", [i[1]]) for i in ee]
|
|
|
+
|
|
|
+ yield [("RETURN", [{'id': root}])]
|