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 constraint = $ String function constraint(model : Element, name : String): Element outgoing_edges outgoing_edges = allOutgoingAssociationInstances(model, name, "Next") if list_len(outgoing_edges) !=1: return "A start node should have one outgoing control flow"! else: return "OK"! $ } 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 either one incoming control flow or decision flow"! else: return "OK"! $ } Class Fork : Activity { constraint = $ String function constraint(model : Element, name : String): Element outgoing_edges Element incoming_edges outgoing_edges = allOutgoingAssociationInstances(model, name, "Next") incoming_edges = allIncomingAssociationInstances(model, name, "Next") if bool_or(list_len(outgoing_edges) <2, list_len(incoming_edges) !=1): return "All Fork nodes should have one incoming control flow and at least two outgoing control flows"! else: return "OK"! $ } Class Join : Activity { constraint = $ String function constraint(model : Element, name : String): Element outgoing_edges Element incoming_edges outgoing_edges = allOutgoingAssociationInstances(model, name, "Next") incoming_edges = allIncomingAssociationInstances(model, name, "Next") if bool_or(list_len(outgoing_edges) !=1, list_len(incoming_edges) <2): return "All Join nodes should have at least two incoming and one outgoing control flow"! else: return "OK"! $ } Class Decision : Activity { constraint = $ String function constraint(model : Element, name : String): Element outgoing_edges Element incoming_edges Element consumes consumes = allOutgoingAssociationInstances(model, name, "DecisionConsumes") outgoing_edges = allOutgoingAssociationInstances(model, name, "Next") incoming_edges = allIncomingAssociationInstances(model, name, "Next") if bool_or(list_len(outgoing_edges) <2, list_len(incoming_edges) !=1): return "All Decision nodes should have at least one incoming flow and two outgoing flows"! elif list_len(consumes) != 1: return "All Decision nodes should have exactly one incoming data flow"! else: return "OK"! $ } Class Exec : Activity { name : MvCName sccd_class_id ?: String lower_cardinality = 1 constraint = $ String function constraint(model : Element, name : String): Element outgoing_edges Element incoming_edges outgoing_edges = allOutgoingAssociationInstances(model, name, "Next") incoming_edges = allIncomingAssociationInstances(model, name, "Next") if bool_or(list_len(outgoing_edges) !=1, list_len(incoming_edges) !=1): return "All Executable nodes should have exactly one incoming and one outgoing control flow"! else: return "OK"! $ } Class Data { id : String name : MvCName type : MvCName constraint = $ String function constraint(model : Element, name : String): Element outgoing_edges Element incoming_edges outgoing_edges = allIncomingAssociationInstances(model, name, "Consumes") incoming_edges = allIncomingAssociationInstances(model, name, "Produces") if bool_or(list_len(outgoing_edges) <1, list_len(incoming_edges) <1): return "All Data nodes should have al-least one incoming Produces and one outgoing Consumes flow"! else: return "OK"! $ } Association Produces : Edge (Exec, Data) {} Association Consumes : Edge (Exec, Data) {} Association DecisionConsumes : Edge (Decision, Data) {} Association Next : Edge (Activity, Activity) { value ?: MvCName } 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 }