Browse Source

and now pattern matching also works with typing information added to the graph

Joeri Exelmans 11 months ago
parent
commit
700a4d103f
3 changed files with 47 additions and 23 deletions
  1. 31 17
      pattern_matching/mvs_adapter.py
  2. 3 0
      services/scd.py
  3. 13 6
      transformation/ramify.py

+ 31 - 17
pattern_matching/mvs_adapter.py

@@ -1,6 +1,7 @@
 from state.base import State
 from uuid import UUID
 from services.bottom.V0 import Bottom
+from services.scd import SCD
 from pattern_matching.matcher import Graph, Edge, Vertex
 import itertools
 import re
@@ -88,19 +89,28 @@ def model_to_graph(state: State, model: UUID):
                 tgt=ref_model.vtxs[0], # which node to link to?? dirty
                 label="modelref"))
 
-        # # Add typing information
-        # for i,node in enumerate(bottom.read_outgoing_elements(model)):
-        #     type_node, = bottom.read_outgoing_elements(node, "Morphism")
-        #     print('node', node, 'has type', type_node)
-        #     # We create a Vertex storing the type
-        #     type_vertex = Vertex(value=IS_TYPE(type_node))
-        #     graph.vtxs.append(type_vertex)
-        #     type_edge = Edge(
-        #         src=uuid_to_vtx[node],
-        #         tgt=type_vertex,
-        #         label="type")
-        #     print(type_edge)
-        #     graph.edges.append(type_edge)
+        def add_types(node):
+            type_node, = bottom.read_outgoing_elements(node, "Morphism")
+            print('node', node, 'has type', type_node)
+            # We create a Vertex storing the type
+            type_vertex = Vertex(value=IS_TYPE(type_node))
+            graph.vtxs.append(type_vertex)
+            type_edge = Edge(
+                src=uuid_to_vtx[node],
+                tgt=type_vertex,
+                label="type")
+            print(type_edge)
+            graph.edges.append(type_edge)
+
+
+        # Add typing information of classes, attributes, and associations
+        scd = SCD(model, state)
+        for name,node in scd.get_classes().items():
+            add_types(node)
+            for attr_name,attr_node in scd.get_attributes(name):
+                add_types(attr_node)
+        for _,node in scd.get_associations().items():
+            add_types(node)
 
         return graph
 
@@ -141,13 +151,17 @@ class RAMCompare:
             return False
 
         # types only match with their supertypes
+        # we assume that 'RAMifies'-traceability links have been created between guest and host types
+        # we need these links, because the guest types are different types (RAMified)
         if isinstance(g_val, IS_TYPE):
             if not isinstance(h_val, IS_TYPE):
                 return False
-            g_val_original_type = self.bottom.read_outgoing_elements(g_val.type, "RAMifies")
-            result = self.is_subtype_of(h_val.type, g_val_original_type)
-            print("RESULT", result)
-            return result
+            g_val_original_types = self.bottom.read_outgoing_elements(g_val.type, "RAMifies")
+            if len(g_val_original_types) > 0:
+                result = self.is_subtype_of(h_val.type, g_val_original_types[0])
+                return result
+            else:
+                return False
 
         if isinstance(h_val, IS_TYPE):
             return False

+ 3 - 0
services/scd.py

@@ -128,6 +128,7 @@ class SCD:
             set_cardinality("target_lower", tgt_min_c)
         if tgt_max_c != None:
             set_cardinality("target_upper", tgt_max_c)
+        return assoc_edge
 
     def create_global_constraint(self, name: str):
         """
@@ -208,6 +209,7 @@ class SCD:
         scd_link, = self.bottom.read_outgoing_elements(self.scd_model, "AttributeLink_optional")
         self.bottom.create_edge(optional_node, scd_node, "Morphism")
         self.bottom.create_edge(optional_link, scd_link, "Morphism")
+        return assoc_edge
 
     def create_model_ref(self, name: str, model: UUID):
         """
@@ -251,6 +253,7 @@ class SCD:
         self.bottom.create_edge(self.model, inh_edge, f"{child_name}_inh_{parent_name}")  # attach to model
         scd_node, = self.bottom.read_outgoing_elements(self.scd_model, "Inheritance")  # retrieve type
         self.bottom.create_edge(inh_edge, scd_node, "Morphism")  # create morphism link
+        return inh_edge
 
     def get_class_name(self, cls: UUID):
         for key in self.bottom.read_keys(self.model):

+ 13 - 6
transformation/ramify.py

@@ -99,7 +99,7 @@ def ramify(state: State, model: UUID) -> UUID:
             attr_name = bottom.read_value(string)
             ref_type = bottom.read_edge_target(attr_edge)
             typ = navigate_modelref(ref_type)
-            result.append((attr_name, typ))
+            result.append((attr_name, attr_edge))
         return result
 
     ramified = state.create_node()
@@ -118,15 +118,18 @@ def ramify(state: State, model: UUID) -> UUID:
         upper_card = find_cardinality(class_node, class_upper_card_node)
         print('creating class', class_name, "with card 0 ..", upper_card)
         ramified_class = ramified_scd.create_class(class_name, abstract=None, max_c=upper_card)
-
         # traceability link
         bottom.create_edge(ramified_class, class_node, "RAMifies")
 
-        for (attr_name, attr_type) in get_attributes(class_node):
+        for (attr_name, attr_edge) in get_attributes(class_node):
             print('  creating attribute', attr_name, "with type String")
             # Every attribute becomes 'string' type
             # The string will be a Python expression
-            ramified_scd._create_attribute_link(class_name, string_modelref, attr_name, optional=False)
+            ramified_attr_link = ramified_scd._create_attribute_link(class_name, string_modelref, attr_name, optional=False)
+            # traceability link
+            bottom.create_edge(ramified_attr_link, attr_edge, "RAMifies")
+
+
 
     associations = scd.get_associations()
     for assoc_name, assoc_node in associations.items():
@@ -140,16 +143,20 @@ def ramify(state: State, model: UUID) -> UUID:
         src = scd.get_class_name(bottom.read_edge_source(assoc_node))
         tgt = scd.get_class_name(bottom.read_edge_target(assoc_node))
         print('creating assoc', src, "->", tgt, ", name =", assoc_name, ", src card = 0 ..", src_upper_card, "and tgt card = 0 ..", tgt_upper_card)
-        ramified_scd.create_association(assoc_name, src, tgt,
+        ramified_assoc = ramified_scd.create_association(assoc_name, src, tgt,
             src_max_c=src_upper_card,
             tgt_max_c=tgt_upper_card)
+        # traceability link
+        bottom.create_edge(ramified_assoc, assoc_node, "RAMifies")
+
 
     for inh_name, inh_node in scd.get_inheritances().items():
         # Re-create inheritance links like in our original model:
         src = scd.get_class_name(bottom.read_edge_source(inh_node))
         tgt = scd.get_class_name(bottom.read_edge_target(inh_node))
         print('creating inheritance link', src, '->', tgt)
-        ramified_scd.create_inheritance(src, tgt)
+        ramified_inh_link = ramified_scd.create_inheritance(src, tgt)
+
 
     # The RAMified meta-model should also conform to 'SCD':
     conf = Conformance(state, ramified, scd_metamodel)