123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- include "primitives.alh"
- include "library.alh"
- include "object_operations.alh"
- include "constructors.alh"
- Element function set_copy(elem_to_copy : Element):
- Element result
- Integer i
- Integer max
- result = create_node()
- // Expand the provided list by including all elements that need to be checked
- i = 0
- max = read_nr_out(elem_to_copy)
- while (i < max):
- set_add(result, read_edge_dst(read_out(elem_to_copy, i)))
- i = i + 1
- return result
- Boolean function is_direct_instance(model : Element, instance : Element, type : Element):
- // Just check whether or not the type mapping specifies the type as the type of the instance
- return dict_read_node(model["type_mapping"], instance) == type
- Boolean function is_nominal_instance(model : Element, instance : Element, type : Element):
- return is_nominal_subtype(type, dict_read_node(model["type_mapping"], instance), model["metamodel"]["type_mapping"], model["inheritance"])
- Boolean function is_nominal_subtype(superclass : Element, subclass : Element, types : Element, inheritance_link : Element):
- Integer counter
- Integer i
- Element edge
- Element destination
- // End of recursion
- if (element_eq(superclass, subclass)):
- return True
- // Iterate over all superclasses of the found class
- counter = read_nr_out(subclass)
- i = 0
- while (i < counter):
- edge = read_out(subclass, i)
- // Check if it even has a type (to prevent errors)
- if (dict_in_node(types, edge)):
- // Check whether it is an inheritance edge, as there is no other distinction between them
- if (element_eq(dict_read_node(types, edge), inheritance_link)):
- // It is an inheritance edge, so follow it to its destination
- destination = read_edge_dst(edge)
- // Found a new superclass to test
- if (is_nominal_subtype(superclass, destination, types, inheritance_link)):
- return True
- i = i + 1
-
- // No link seems to have been found, so it is False
- return False
- Boolean function is_structural_instance(model : Element, instance : Element, type : Element):
- return is_structural_subtype(dict_read_node(model["type_mapping"], instance), type)
-
- Boolean function is_structural_subtype(subtype : Element, supertype : Element):
- // Determine whether it is just the exact type or not
- if (subtype == supertype):
- return True
- // Find all links that are required (name and type) from the specified type
- Element required_keys
- required_keys = dict_keys(supertype)
- Integer required_keys_len
- required_keys_len = dict_len(required_keys)
- String key
- Element equivalent
- Integer i
- i = 0
- // Go over all keys that we require
- while (i < required_keys_len):
- key = set_pop(required_keys)
- // Check whether they exist in the instance
- if (dict_in(subtype, key)):
- // Normally, we should still check whether they don't violate the constraints imposed on the class (i.e., are actually present)
- // For now, we ignore this and simply require that it is always there in the metamodel (not necessarily in the instance)
- // TODO
- // Still check whether the types match
- if (bool_not(is_structural_subtype(subtype[key], supertype[key]))):
- return False
- // All clear, so pass on to the next attribute
- i = i + 1
- else:
- return False
- // No violations found, so OK
- return True
- String function conformance_scd(model : Element):
- // Initialization
- Element work_node
- Element model_src
- Element metamodel_src
- Element model_dst
- Element metamodel_dst
- Element models
- Element metamodels
- models = set_copy(model["model"])
- Element typing
- typing = model["type_mapping"]
- metamodels = set_copy(model["metamodel"]["model"])
- Element inheritance
- inheritance = model["metamodel"]["inheritance"]
- Element metamodel_typing
- metamodel_typing = model["metamodel"]["type_mapping"]
- // Iterate over all model elements and check if they are typed (in "typing") and their type is in the metamodel
- while (dict_len(models) > 0):
- work_node = set_pop(models)
- // Basic check: does the element have a type
- if (bool_not(dict_in_node(typing, work_node))):
- return "Model has no type specified: " + getName(model, work_node)
- // Basic check: is the type of the element part of the metamodel
- if (bool_not(set_in_node(metamodels, dict_read_node(typing, work_node)))):
- return "Type of element not in specified metamodel: " + getName(model, work_node)
- // For edges only: check whether the source is typed according to the metamodel
- if (is_edge(work_node)):
- model_src = read_edge_src(work_node)
- metamodel_src = read_edge_src(dict_read_node(typing, work_node))
- log((getName(model, model_src) + " : ") + getName(model["metamodel"], metamodel_src))
- if (bool_not(is_nominal_instance(model, model_src, metamodel_src))):
- return "Source of model edge not typed by source of type: " + getName(model, work_node)
- // For edges only: check whether the destination is typed according to the metamodel
- if (is_edge(work_node)):
- model_dst = read_edge_dst(work_node)
- metamodel_dst = read_edge_dst(dict_read_node(typing, work_node))
- if (bool_not(is_nominal_instance(model, model_dst, metamodel_dst))):
- return "Destination of model edge not typed by destination of type: " + getName(model, work_node)
- // Structure seems fine, now do static semantics
- if (dict_in(model["metamodel"], "constraints")):
- Element constraint_function
- constraint_function = model["metamodel"]["constraints"]
- return constraint_function(model)
- else:
- return "OK"
- Element function set_model_constraints(model : Element, func : Element):
- if (dict_in(model, "constraints")):
- dict_delete(model, "constraints")
- dict_add(model, "constraints", func)
- return model
- Element function generate_bottom_type_mapping(model : Element):
- Element mm
- mm = model["metamodel"]["model"]
- dict_delete(model, "type_mapping")
- Element tm
- tm = create_node()
- dict_add(model, "type_mapping", tm)
-
- // Iterate over every element
- Element elem_keys
- Element elem
- elem_keys = dict_keys(model["model"])
- while (0 < read_nr_out(elem_keys)):
- elem = model["model"][set_pop(elem_keys)]
- if (is_edge(elem)):
- dict_add(tm, elem, mm["Edge"])
- else:
- dict_add(tm, elem, mm["Node"])
- return model
|