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

This commit is contained in:
Joeri Exelmans 2024-09-06 21:32:03 +02:00
parent 4160a8953e
commit 700a4d103f
3 changed files with 47 additions and 23 deletions

View file

@ -1,6 +1,7 @@
from state.base import State from state.base import State
from uuid import UUID from uuid import UUID
from services.bottom.V0 import Bottom from services.bottom.V0 import Bottom
from services.scd import SCD
from pattern_matching.matcher import Graph, Edge, Vertex from pattern_matching.matcher import Graph, Edge, Vertex
import itertools import itertools
import re 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 tgt=ref_model.vtxs[0], # which node to link to?? dirty
label="modelref")) label="modelref"))
# # Add typing information def add_types(node):
# for i,node in enumerate(bottom.read_outgoing_elements(model)): type_node, = bottom.read_outgoing_elements(node, "Morphism")
# type_node, = bottom.read_outgoing_elements(node, "Morphism") print('node', node, 'has type', type_node)
# print('node', node, 'has type', type_node) # We create a Vertex storing the type
# # We create a Vertex storing the type type_vertex = Vertex(value=IS_TYPE(type_node))
# type_vertex = Vertex(value=IS_TYPE(type_node)) graph.vtxs.append(type_vertex)
# graph.vtxs.append(type_vertex) type_edge = Edge(
# type_edge = Edge( src=uuid_to_vtx[node],
# src=uuid_to_vtx[node], tgt=type_vertex,
# tgt=type_vertex, label="type")
# label="type") print(type_edge)
# print(type_edge) graph.edges.append(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 return graph
@ -141,13 +151,17 @@ class RAMCompare:
return False return False
# types only match with their supertypes # 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 isinstance(g_val, IS_TYPE):
if not isinstance(h_val, IS_TYPE): if not isinstance(h_val, IS_TYPE):
return False return False
g_val_original_type = self.bottom.read_outgoing_elements(g_val.type, "RAMifies") g_val_original_types = self.bottom.read_outgoing_elements(g_val.type, "RAMifies")
result = self.is_subtype_of(h_val.type, g_val_original_type) if len(g_val_original_types) > 0:
print("RESULT", result) result = self.is_subtype_of(h_val.type, g_val_original_types[0])
return result return result
else:
return False
if isinstance(h_val, IS_TYPE): if isinstance(h_val, IS_TYPE):
return False return False

View file

@ -128,6 +128,7 @@ class SCD:
set_cardinality("target_lower", tgt_min_c) set_cardinality("target_lower", tgt_min_c)
if tgt_max_c != None: if tgt_max_c != None:
set_cardinality("target_upper", tgt_max_c) set_cardinality("target_upper", tgt_max_c)
return assoc_edge
def create_global_constraint(self, name: str): 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") 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_node, scd_node, "Morphism")
self.bottom.create_edge(optional_link, scd_link, "Morphism") self.bottom.create_edge(optional_link, scd_link, "Morphism")
return assoc_edge
def create_model_ref(self, name: str, model: UUID): 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 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 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 self.bottom.create_edge(inh_edge, scd_node, "Morphism") # create morphism link
return inh_edge
def get_class_name(self, cls: UUID): def get_class_name(self, cls: UUID):
for key in self.bottom.read_keys(self.model): for key in self.bottom.read_keys(self.model):

View file

@ -99,7 +99,7 @@ def ramify(state: State, model: UUID) -> UUID:
attr_name = bottom.read_value(string) attr_name = bottom.read_value(string)
ref_type = bottom.read_edge_target(attr_edge) ref_type = bottom.read_edge_target(attr_edge)
typ = navigate_modelref(ref_type) typ = navigate_modelref(ref_type)
result.append((attr_name, typ)) result.append((attr_name, attr_edge))
return result return result
ramified = state.create_node() 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) upper_card = find_cardinality(class_node, class_upper_card_node)
print('creating class', class_name, "with card 0 ..", upper_card) print('creating class', class_name, "with card 0 ..", upper_card)
ramified_class = ramified_scd.create_class(class_name, abstract=None, max_c=upper_card) ramified_class = ramified_scd.create_class(class_name, abstract=None, max_c=upper_card)
# traceability link # traceability link
bottom.create_edge(ramified_class, class_node, "RAMifies") 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") print(' creating attribute', attr_name, "with type String")
# Every attribute becomes 'string' type # Every attribute becomes 'string' type
# The string will be a Python expression # 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() associations = scd.get_associations()
for assoc_name, assoc_node in associations.items(): 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)) src = scd.get_class_name(bottom.read_edge_source(assoc_node))
tgt = scd.get_class_name(bottom.read_edge_target(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) 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, src_max_c=src_upper_card,
tgt_max_c=tgt_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(): for inh_name, inh_node in scd.get_inheritances().items():
# Re-create inheritance links like in our original model: # Re-create inheritance links like in our original model:
src = scd.get_class_name(bottom.read_edge_source(inh_node)) src = scd.get_class_name(bottom.read_edge_source(inh_node))
tgt = scd.get_class_name(bottom.read_edge_target(inh_node)) tgt = scd.get_class_name(bottom.read_edge_target(inh_node))
print('creating inheritance link', src, '->', tgt) 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': # The RAMified meta-model should also conform to 'SCD':
conf = Conformance(state, ramified, scd_metamodel) conf = Conformance(state, ramified, scd_metamodel)