|
@@ -123,3 +123,59 @@ def set_copy(a, **remainder):
|
|
|
exp_links = [exp_links]
|
|
|
_ = yield [("CE", [b, i[1]]) for i in exp_links]
|
|
|
raise PrimitiveFinished(b)
|
|
|
+
|
|
|
+def allInstances(a, b, **remainder):
|
|
|
+ b_val = yield [("RV", [b])]
|
|
|
+ model_dict= yield [("RD", [a, "model"])]
|
|
|
+ metamodel = yield [("RD", [a, "metamodel"])]
|
|
|
+ mm_dict = yield [("RD", [metamodel, "model"])]
|
|
|
+ typing = yield [("RD", [a, "type_mapping"])]
|
|
|
+ elem_keys = yield [("RDK", [model_dict])]
|
|
|
+ elems = yield [("RDN", [model_dict, i]) for i in elem_keys]
|
|
|
+ mms = yield [("RDN", [typing, i]) for i in elems]
|
|
|
+
|
|
|
+ # Have the type for each name
|
|
|
+ types_to_name_nodes = {}
|
|
|
+ for key, mm in zip(elem_keys, mms):
|
|
|
+ types_to_name_nodes.setdefault(mm, set()).add(key)
|
|
|
+ # And now we have the inverse mapping: for each type, we have the node containing the name
|
|
|
+
|
|
|
+ # Get the inheritance link type
|
|
|
+ inheritance_type = yield [("RD", [metamodel, "inheritance"])]
|
|
|
+
|
|
|
+ # Now we figure out which types are valid for the specified model
|
|
|
+ desired_types = set()
|
|
|
+ mm_element = yield [("RD", [mm_dict, b_val])]
|
|
|
+ work_list = []
|
|
|
+ work_list.append(mm_element)
|
|
|
+ mm_typing = yield [("RD", [metamodel, "type_mapping"])]
|
|
|
+
|
|
|
+ while work_list:
|
|
|
+ mm_element = work_list.pop()
|
|
|
+ if mm_element in desired_types:
|
|
|
+ # Already been here, so stop
|
|
|
+ continue
|
|
|
+
|
|
|
+ # New element, so continue
|
|
|
+ desired_types.add(mm_element)
|
|
|
+
|
|
|
+ # Follow all inheritance links that COME IN this node, as all these are subtypes and should also match
|
|
|
+ incoming = yield [("RI", [mm_element])]
|
|
|
+ for i in incoming:
|
|
|
+ t = yield [("RDN", [mm_typing, i])]
|
|
|
+ if t == inheritance_type:
|
|
|
+ e = yield [("RE", [i])]
|
|
|
+ # Add the source of the inheritance link to the work list
|
|
|
+ work_list.append(e[0])
|
|
|
+
|
|
|
+ # Now desired_types holds all the direct types that we are interested in!
|
|
|
+ # Construct the result out of all models that are direct instances of our specified type
|
|
|
+ final = set()
|
|
|
+ for t in desired_types:
|
|
|
+ final |= types_to_name_nodes.get(t, set())
|
|
|
+
|
|
|
+ # Result is a Python set with nodes, so just make this a Mv set
|
|
|
+ result = yield [("CN", [])]
|
|
|
+ v = yield [("RV", [i]) for i in final]
|
|
|
+ _ = yield [("CE", [result, i]) for i in final]
|
|
|
+ raise PrimitiveFinished(result)
|