|
@@ -21,7 +21,10 @@ Boolean function is_nominal_instance(model : Element, instance : String, type :
|
|
// doesn't even have a type
|
|
// doesn't even have a type
|
|
return False
|
|
return False
|
|
|
|
|
|
- return is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)
|
|
|
|
|
|
+ Boolean result
|
|
|
|
+ result = is_nominal_subtype(model["metamodel"], reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][instance])), type)
|
|
|
|
+
|
|
|
|
+ return result
|
|
|
|
|
|
Boolean function is_nominal_subtype(metamodel : Element, subclass : String, superclass : String):
|
|
Boolean function is_nominal_subtype(metamodel : Element, subclass : String, superclass : String):
|
|
if (element_eq(metamodel["model"][subclass], metamodel["model"][superclass])):
|
|
if (element_eq(metamodel["model"][subclass], metamodel["model"][superclass])):
|
|
@@ -63,6 +66,12 @@ String function conformance_scd(model : Element):
|
|
Element scd
|
|
Element scd
|
|
Integer instances
|
|
Integer instances
|
|
|
|
|
|
|
|
+ Element spo_cache
|
|
|
|
+ Element spi_cache
|
|
|
|
+
|
|
|
|
+ spo_cache = create_node()
|
|
|
|
+ spi_cache = create_node()
|
|
|
|
+
|
|
// Load in variables
|
|
// Load in variables
|
|
scd = import_node("models/SimpleClassDiagrams")
|
|
scd = import_node("models/SimpleClassDiagrams")
|
|
metamodel = model["metamodel"]
|
|
metamodel = model["metamodel"]
|
|
@@ -71,36 +80,34 @@ String function conformance_scd(model : Element):
|
|
|
|
|
|
// Create dictionary with all associations and allowed cardinalities
|
|
// Create dictionary with all associations and allowed cardinalities
|
|
if (list_len(model["model"]) > 0):
|
|
if (list_len(model["model"]) > 0):
|
|
- keys = dict_keys(metamodel["model"])
|
|
|
|
Integer slc
|
|
Integer slc
|
|
Integer suc
|
|
Integer suc
|
|
Integer tlc
|
|
Integer tlc
|
|
Integer tuc
|
|
Integer tuc
|
|
String key
|
|
String key
|
|
Element tmp_dict
|
|
Element tmp_dict
|
|
|
|
+ String type_name
|
|
|
|
|
|
- log("Start attribute read")
|
|
|
|
|
|
+ keys = allInstances(metamodel, "Association")
|
|
while (0 < list_len(keys)):
|
|
while (0 < list_len(keys)):
|
|
key = set_pop(keys)
|
|
key = set_pop(keys)
|
|
- if (is_nominal_instance(metamodel, key, "Association")):
|
|
|
|
- tmp_dict = create_node()
|
|
|
|
- slc = read_attribute(metamodel, key, "source_lower_cardinality")
|
|
|
|
- suc = read_attribute(metamodel, key, "source_upper_cardinality")
|
|
|
|
- tlc = read_attribute(metamodel, key, "target_lower_cardinality")
|
|
|
|
- tuc = read_attribute(metamodel, key, "target_upper_cardinality")
|
|
|
|
-
|
|
|
|
- if (element_neq(slc, read_root())):
|
|
|
|
- dict_add(tmp_dict, "slc", slc)
|
|
|
|
- if (element_neq(suc, read_root())):
|
|
|
|
- dict_add(tmp_dict, "suc", suc)
|
|
|
|
- if (element_neq(tlc, read_root())):
|
|
|
|
- dict_add(tmp_dict, "tlc", tlc)
|
|
|
|
- if (element_neq(tuc, read_root())):
|
|
|
|
- dict_add(tmp_dict, "tuc", tuc)
|
|
|
|
-
|
|
|
|
- if (list_len(tmp_dict) > 0):
|
|
|
|
- dict_add(cardinalities, key, tmp_dict)
|
|
|
|
- log("Finish attribute read")
|
|
|
|
|
|
+ tmp_dict = create_node()
|
|
|
|
+ slc = read_attribute(metamodel, key, "source_lower_cardinality")
|
|
|
|
+ suc = read_attribute(metamodel, key, "source_upper_cardinality")
|
|
|
|
+ tlc = read_attribute(metamodel, key, "target_lower_cardinality")
|
|
|
|
+ tuc = read_attribute(metamodel, key, "target_upper_cardinality")
|
|
|
|
+
|
|
|
|
+ if (element_neq(slc, read_root())):
|
|
|
|
+ dict_add(tmp_dict, "slc", slc)
|
|
|
|
+ if (element_neq(suc, read_root())):
|
|
|
|
+ dict_add(tmp_dict, "suc", suc)
|
|
|
|
+ if (element_neq(tlc, read_root())):
|
|
|
|
+ dict_add(tmp_dict, "tlc", tlc)
|
|
|
|
+ if (element_neq(tuc, read_root())):
|
|
|
|
+ dict_add(tmp_dict, "tuc", tuc)
|
|
|
|
+
|
|
|
|
+ if (list_len(tmp_dict) > 0):
|
|
|
|
+ dict_add(cardinalities, key, tmp_dict)
|
|
|
|
|
|
// Iterate over each element of the model, finding out whether everything is fine
|
|
// Iterate over each element of the model, finding out whether everything is fine
|
|
keys = dict_keys(model["model"])
|
|
keys = dict_keys(model["model"])
|
|
@@ -108,6 +115,7 @@ String function conformance_scd(model : Element):
|
|
model_name = set_pop(keys)
|
|
model_name = set_pop(keys)
|
|
log("Check " + model_name)
|
|
log("Check " + model_name)
|
|
element = model["model"][model_name]
|
|
element = model["model"][model_name]
|
|
|
|
+ type_name = reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))
|
|
|
|
|
|
if (bool_not(dict_in_node(typing, element))):
|
|
if (bool_not(dict_in_node(typing, element))):
|
|
return "Model has no type specified: " + model_name
|
|
return "Model has no type specified: " + model_name
|
|
@@ -115,7 +123,7 @@ String function conformance_scd(model : Element):
|
|
if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
|
|
if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
|
|
return "Type of element not in specified metamodel: " + model_name
|
|
return "Type of element not in specified metamodel: " + model_name
|
|
|
|
|
|
- if (bool_not(is_nominal_instance(model, model_name, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))))):
|
|
|
|
|
|
+ if (bool_not(is_nominal_instance(model, model_name, type_name))):
|
|
return "Element is not an instance of its specified type: " + model_name
|
|
return "Element is not an instance of its specified type: " + model_name
|
|
|
|
|
|
if (is_edge(element)):
|
|
if (is_edge(element)):
|
|
@@ -136,7 +144,9 @@ String function conformance_scd(model : Element):
|
|
// A ---------------------> B
|
|
// A ---------------------> B
|
|
//
|
|
//
|
|
// First the incoming, so we are at B in the above figure
|
|
// First the incoming, so we are at B in the above figure
|
|
- check_list = selectPossibleOutgoing(model, model_name, dict_keys(cardinalities))
|
|
|
|
|
|
+ if (bool_not(dict_in(spo_cache, type_name))):
|
|
|
|
+ dict_add(spo_cache, type_name, selectPossibleOutgoing(metamodel, type_name, dict_keys(cardinalities)))
|
|
|
|
+ check_list = spo_cache[type_name]
|
|
while (0 < list_len(check_list)):
|
|
while (0 < list_len(check_list)):
|
|
check_type = set_pop(check_list)
|
|
check_type = set_pop(check_list)
|
|
if (dict_in(cardinalities, check_type)):
|
|
if (dict_in(cardinalities, check_type)):
|
|
@@ -146,14 +156,22 @@ String function conformance_scd(model : Element):
|
|
if (dict_in(cardinalities[check_type], "tlc")):
|
|
if (dict_in(cardinalities[check_type], "tlc")):
|
|
// A lower cardinality was defined at the target
|
|
// A lower cardinality was defined at the target
|
|
if (integer_gt(cardinalities[check_type]["tlc"], instances)):
|
|
if (integer_gt(cardinalities[check_type]["tlc"], instances)):
|
|
|
|
+ log("Instances: " + cast_i2s(instances))
|
|
|
|
+ log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
|
|
|
|
+ log("Type: " + check_type)
|
|
return "Lower cardinality violation for outgoing edge at " + model_name
|
|
return "Lower cardinality violation for outgoing edge at " + model_name
|
|
if (dict_in(cardinalities[check_type], "tuc")):
|
|
if (dict_in(cardinalities[check_type], "tuc")):
|
|
// An upper cardinality was defined at the target
|
|
// An upper cardinality was defined at the target
|
|
if (integer_lt(cardinalities[check_type]["tuc"], instances)):
|
|
if (integer_lt(cardinalities[check_type]["tuc"], instances)):
|
|
|
|
+ log("Instances: " + cast_i2s(instances))
|
|
|
|
+ log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
|
|
|
|
+ log("Type: " + check_type)
|
|
return "Upper cardinality violation for outgoing edge at " + model_name
|
|
return "Upper cardinality violation for outgoing edge at " + model_name
|
|
|
|
|
|
// Identical, but for outgoing, and thus for A in the figure
|
|
// Identical, but for outgoing, and thus for A in the figure
|
|
- check_list = selectPossibleIncoming(model, model_name, dict_keys(cardinalities))
|
|
|
|
|
|
+ if (bool_not(dict_in(spi_cache, type_name))):
|
|
|
|
+ dict_add(spi_cache, type_name, selectPossibleIncoming(metamodel, type_name, dict_keys(cardinalities)))
|
|
|
|
+ check_list = spi_cache[type_name]
|
|
while (0 < list_len(check_list)):
|
|
while (0 < list_len(check_list)):
|
|
check_type = set_pop(check_list)
|
|
check_type = set_pop(check_list)
|
|
if (dict_in(cardinalities, check_type)):
|
|
if (dict_in(cardinalities, check_type)):
|
|
@@ -163,10 +181,16 @@ String function conformance_scd(model : Element):
|
|
if (dict_in(cardinalities[check_type], "slc")):
|
|
if (dict_in(cardinalities[check_type], "slc")):
|
|
// A lower cardinality was defined at the source
|
|
// A lower cardinality was defined at the source
|
|
if (integer_gt(cardinalities[check_type]["slc"], instances)):
|
|
if (integer_gt(cardinalities[check_type]["slc"], instances)):
|
|
|
|
+ log("Instances: " + cast_i2s(instances))
|
|
|
|
+ log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
|
|
|
|
+ log("Type: " + check_type)
|
|
return "Lower cardinality violation for incoming edge at " + model_name
|
|
return "Lower cardinality violation for incoming edge at " + model_name
|
|
if (dict_in(cardinalities[check_type], "suc")):
|
|
if (dict_in(cardinalities[check_type], "suc")):
|
|
// An upper cardinality was defined at the source
|
|
// An upper cardinality was defined at the source
|
|
if (integer_lt(cardinalities[check_type]["suc"], instances)):
|
|
if (integer_lt(cardinalities[check_type]["suc"], instances)):
|
|
|
|
+ log("Instances: " + cast_i2s(instances))
|
|
|
|
+ log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
|
|
|
|
+ log("Type: " + check_type)
|
|
return "Upper cardinality violation for incoming edge at " + model_name
|
|
return "Upper cardinality violation for incoming edge at " + model_name
|
|
|
|
|
|
Element constraint_function
|
|
Element constraint_function
|
|
@@ -177,7 +201,6 @@ String function conformance_scd(model : Element):
|
|
if (result != "OK"):
|
|
if (result != "OK"):
|
|
return result
|
|
return result
|
|
|
|
|
|
- log("Start multiplicities")
|
|
|
|
// Check multiplicities, if they are defined (optional)
|
|
// Check multiplicities, if they are defined (optional)
|
|
Element metamodel_keys
|
|
Element metamodel_keys
|
|
String metamodel_element
|
|
String metamodel_element
|
|
@@ -200,7 +223,6 @@ String function conformance_scd(model : Element):
|
|
// We have defined a lower cardinality, so check number of instances!
|
|
// We have defined a lower cardinality, so check number of instances!
|
|
if (attr_value < list_len(allInstances(model, metamodel_element))):
|
|
if (attr_value < list_len(allInstances(model, metamodel_element))):
|
|
return "Upper cardinality violated for class: " + metamodel_element
|
|
return "Upper cardinality violated for class: " + metamodel_element
|
|
- log("Finished multiplicities")
|
|
|
|
|
|
|
|
// Structure seems fine, now do static semantics
|
|
// Structure seems fine, now do static semantics
|
|
if (dict_in(metamodel, "constraints")):
|
|
if (dict_in(metamodel, "constraints")):
|