|
@@ -176,16 +176,16 @@ class Verifier(object):
|
|
|
|
|
|
def verify_associations(self):
|
|
def verify_associations(self):
|
|
"""
|
|
"""
|
|
- 1. If an association between two types is present in all example models, it is mandatory and must
|
|
|
|
- therefore be present in the instance model (if it contains the same two types).
|
|
|
|
|
|
+ 1. An edge between two types is mandatory if in every example model that contains nodes of both types, every
|
|
|
|
+ node is connected with an edge to the other type.
|
|
2. For every association in the instance model, the types of the source and target must correspond
|
|
2. For every association in the instance model, the types of the source and target must correspond
|
|
to the types of an association in some example model. This check should not be necessary since this
|
|
to the types of an association in some example model. This check should not be necessary since this
|
|
is already enforced while instance modeling (see im_scene.py, draw_edge() which checks this when trying
|
|
is already enforced while instance modeling (see im_scene.py, draw_edge() which checks this when trying
|
|
to connect two nodes).
|
|
to connect two nodes).
|
|
"""
|
|
"""
|
|
|
|
|
|
- # get a set of mandatory edges (= edges that occur in every example model)
|
|
|
|
- all_edges = {model: set() for model in self._example_models}
|
|
|
|
|
|
+ # construct the set of mandatory edges
|
|
|
|
+ all_edges = set()
|
|
for exm in self._example_models:
|
|
for exm in self._example_models:
|
|
all_links = mv.all_instances(exm, "Edge")
|
|
all_links = mv.all_instances(exm, "Edge")
|
|
for link in all_links:
|
|
for link in all_links:
|
|
@@ -193,8 +193,29 @@ class Verifier(object):
|
|
dest_id = mv.read_association_destination(exm, link)[0]
|
|
dest_id = mv.read_association_destination(exm, link)[0]
|
|
src_type = commons.get_node_type(exm, src_id)
|
|
src_type = commons.get_node_type(exm, src_id)
|
|
dest_type = commons.get_node_type(exm, dest_id)
|
|
dest_type = commons.get_node_type(exm, dest_id)
|
|
- all_edges[exm].add(Edge(src_type, dest_type))
|
|
|
|
- mandatory_edges = set.intersection(*all_edges.values())
|
|
|
|
|
|
+ all_edges.add(Edge(src_type, dest_type))
|
|
|
|
+ edge_mandatory = {e:True for e in all_edges}
|
|
|
|
+
|
|
|
|
+ for cand_edge, _ in edge_mandatory.iteritems():
|
|
|
|
+ # check every example model if it contains the required types
|
|
|
|
+ # and if there are two noes of the type which are not connected -> not mandatory
|
|
|
|
+ found = False
|
|
|
|
+ for exm in self._example_models:
|
|
|
|
+ if found:
|
|
|
|
+ break
|
|
|
|
+ typed_nodes_a = commons.all_nodes_with_type(exm, cand_edge.n1)
|
|
|
|
+ typed_nodes_b = commons.all_nodes_with_type(exm, cand_edge.n2)
|
|
|
|
+ if not typed_nodes_a or not typed_nodes_b:
|
|
|
|
+ # example model does not contain the two types
|
|
|
|
+ continue
|
|
|
|
+ for src_node in typed_nodes_a:
|
|
|
|
+ # if this node is not connected to a node typed by the required type, the edge is not mandatory
|
|
|
|
+ if not commons.has_edge_to_type(exm, src_node, cand_edge.n2):
|
|
|
|
+ edge_mandatory[cand_edge] = False
|
|
|
|
+ found = True
|
|
|
|
+
|
|
|
|
+ mandatory_edges = [edge for edge,mandatory in edge_mandatory.iteritems() if mandatory]
|
|
|
|
+ print(mandatory_edges)
|
|
|
|
|
|
# check if instance model contains the types and the edge
|
|
# check if instance model contains the types and the edge
|
|
for edge in mandatory_edges:
|
|
for edge in mandatory_edges:
|
|
@@ -202,13 +223,18 @@ class Verifier(object):
|
|
continue
|
|
continue
|
|
if not commons.model_contains_type(self._instance_model, edge.n2):
|
|
if not commons.model_contains_type(self._instance_model, edge.n2):
|
|
continue
|
|
continue
|
|
- # instance model contains both types
|
|
|
|
|
|
+ # instance model contains both types -> are they connected?
|
|
for node in commons.all_nodes_with_type(self._instance_model, edge.n1):
|
|
for node in commons.all_nodes_with_type(self._instance_model, edge.n1):
|
|
if not commons.has_edge_to_type(self._instance_model, node, edge.n2):
|
|
if not commons.has_edge_to_type(self._instance_model, node, edge.n2):
|
|
return {"OK":False, "error": "Edge between {} and {} mandatory".format(edge.n1, edge.n2),
|
|
return {"OK":False, "error": "Edge between {} and {} mandatory".format(edge.n1, edge.n2),
|
|
"affected":[]}
|
|
"affected":[]}
|
|
|
|
+ # other way round
|
|
|
|
+ for node in commons.all_nodes_with_type(self._instance_model, edge.n2):
|
|
|
|
+ if not commons.has_edge_to_type(self._instance_model, node, edge.n1):
|
|
|
|
+ return {"OK":False, "error": "Edge between {} and {} mandatory".format(edge.n2, edge.n1),
|
|
|
|
+ "affected":[]}
|
|
|
|
|
|
- # lastly, check if all edges in the instance model are actually supported
|
|
|
|
|
|
+ # lastly, check if all edges in the instance model are actually valid
|
|
all_edges = mv.all_instances(self._instance_model, "Edge")
|
|
all_edges = mv.all_instances(self._instance_model, "Edge")
|
|
for edge in all_edges:
|
|
for edge in all_edges:
|
|
src_id = mv.read_association_source(self._instance_model, edge)[0]
|
|
src_id = mv.read_association_source(self._instance_model, edge)[0]
|
|
@@ -216,7 +242,7 @@ class Verifier(object):
|
|
src_type = commons.get_node_type(self._instance_model, src_id)
|
|
src_type = commons.get_node_type(self._instance_model, src_id)
|
|
dest_type = commons.get_node_type(self._instance_model, dest_id)
|
|
dest_type = commons.get_node_type(self._instance_model, dest_id)
|
|
if not commons.is_edge_supported(src_type, dest_type):
|
|
if not commons.is_edge_supported(src_type, dest_type):
|
|
- return {"OK":False, "error": "Edge between {} and {} not supported".format(edge.n1, edge.n2),
|
|
|
|
|
|
+ return {"OK":False, "error": "Edge between {} and {} not valid".format(edge.n1, edge.n2),
|
|
"affected":[src_id, dest_id]}
|
|
"affected":[src_id, dest_id]}
|
|
|
|
|
|
return {"OK": True, "error": None, "affected":[]}
|
|
return {"OK": True, "error": None, "affected":[]}
|