Browse Source

Added compiled version of allInstances

Yentl Van Tendeloo 9 years ago
parent
commit
3d7218189d
1 changed files with 56 additions and 0 deletions
  1. 56 0
      kernel/modelverse_kernel/compiled.py

+ 56 - 0
kernel/modelverse_kernel/compiled.py

@@ -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)