include "primitives.alh" include "object_operations.alh" include "modelling.alh" SimpleAttribute String {} SimpleAttribute MvCName { constraint = $ String function constraint(model : Element, name : String): if (bool_not(is_physical_string(model["model"][name]))): return "MvCName has no string value"! else: return "OK"! $ } SimpleAttribute Natural { constraint =$ String function constraint(model: Element, id: String): if (bool_not(is_physical_int(model["model"][id]))): return "Natural has no integer value at " + id! elif (integer_lt(model["model"][id], 0)): return "Natural does not have a positive or zero value at " + id! else: return "OK"! $ } Class Model { items_creation_order ?: String SCCD_id : String } Class Activity { id : String } Class Edge { id : String } Class Start : Activity { lower_cardinality = 1 upper_cardinality = 1 } Class Finish : Activity { lower_cardinality = 1 constraint = $ String function constraint(model : Element, name : String): Element incoming_edges incoming_edges = allIncomingAssociationInstances(model, name, "Next") if list_len(incoming_edges) !=1: return "A finish node should have exactly one incoming control-flow at " + name! else: return "OK"! $ } Class Fork : Activity { constraint = $ String function constraint(model : Element, name : String): Element incoming_edges incoming_edges = allIncomingAssociationInstances(model, name, "Next") if list_len(incoming_edges) <1: return "A Fork node should have at-least one incoming control-flow at " + name! else: return "OK"! $ } Class Join : Activity { constraint = $ String function constraint(model : Element, name : String): Element incoming_edges Element source String type incoming_edges = allIncomingAssociationInstances(model, name, "Next") if list_len(incoming_edges) >0: Integer i i = 0 while i < list_len (incoming_edges): source = readAssociationSource(model, list_read(incoming_edges, i)) type = read_type(model, source) if type == "Start": return "A join node can not have a Start node as an incoming flow at "+name! if list_len(incoming_edges) <2: return "A Join node should have at least two incoming control flows at " + name! else: return "OK"! $ } Class Decision : Activity { constraint = $ String function constraint(model : Element, name : String): Element incoming_edges incoming_edges = allIncomingAssociationInstances(model, name, "Next") if list_len(incoming_edges) <1: return "A Decision node should have at least one incoming control-flows at " + name! else: return "OK"! $ } Class Exec : Activity { name : MvCName sccd_class_id ?: String lower_cardinality = 1 constraint = $ String function constraint(model : Element, name : String): Element incoming_edges incoming_edges = allIncomingAssociationInstances(model, name, "Next") if list_len(incoming_edges) <1: return "An Executable node should have at-least one incoming control-flow at " + name! else: return "OK"! $ } Class Data { id : String name : MvCName type : MvCName } Association Produces : Edge (Exec, Data) { source_lower_cardinality = 1 } Association Consumes : Edge (Exec, Data) {} Association DecisionConsumes : Edge (Decision, Data) { target_lower_cardinality = 1 target_upper_cardinality = 1 } Association Next : Edge (Activity, Activity) { value ?: MvCName } Association S2A : Next(Start, Activity){ target_lower_cardinality = 1 target_upper_cardinality = 1 } Association E2A : Next(Exec, Activity){ target_lower_cardinality = 1 target_upper_cardinality = 1 } Association F2A : Next(Fork, Activity){ target_lower_cardinality = 2 } Association J2A : Next(Join, Activity){ target_lower_cardinality = 1 target_upper_cardinality = 1 } Association D2A : Next(Decision, Activity){ target_lower_cardinality = 2 } Class CanvasPosition{ x1: Natural y1: Natural x2 ?: Natural y2 ?: Natural } Association activity_position (Activity, CanvasPosition){} Association data_position (Data, CanvasPosition){} Association produces_positions (Produces, CanvasPosition){ order: Natural } Association consumes_positions (Consumes, CanvasPosition){ order: Natural } Association decision_consumes_positions (DecisionConsumes, CanvasPosition){ order: Natural } Association next_positions (Next, CanvasPosition){ order: Natural }