196 lines
No EOL
7.3 KiB
Text
196 lines
No EOL
7.3 KiB
Text
# Auto-generated by /home/maestro/repos/MV2/examples/semantics/translational/regenerate_mm.py.
|
|
|
|
# Merged run-time meta-models of 'Petri Net' and 'Port' formalisms.
|
|
# An abstract 'Top'-class (superclass of everything else), and a 'generic_link'-association (which can connect everything with everything) have also been added.
|
|
|
|
# PlantUML visualization: https://deemz.org/plantuml/pdf/hPTDZzem48Rl-HKMnqgWa0sKeAg7tKFL2ui4KezeuXWs8jYHOofLxVxtZiE7s5KatY3dm8bvF3Flp7WSoOgQHWnUg2PPkZylHZVEKgcT60XgH7p-DXq__alZMIh-Ha8qRsLzWOYv-AcTsYaRlKVd0vQBPKLIhHmv1QFp5gsFXxNPAzrqSNyPkrTsfM1_i-G2FPbsKdkvcMLCV8yezvcJJjmojiSAnL3SZJ57As5VygA5N5IjZDoByMWq1iqBQfFZoeFgIikpikwjJsx6SN6g3hOv-aold2trhYFCjQbHPaAtCRPbXPgcNszDhxNJAwHKtJBQbA2caycjwG-bbILdB6mkFmI-M5lIJUbAer72zAcpnfOBxdkjfAEyWlCmfUvwBVKUHSm-o77sWSFffGUT1j31_5O5LzYpCPKY_Qb0-X6lSsV5KwrpG9p76KhCapRGwEu__HJuzcyulCzCPtGVvti5m_4S3ubZQKFYqcqCuBYxGUycav1Iy9q2u7WqWzwbGExyhGFYA0zQA5aM59SNGN55sAuWeExmGe6KxT5aKo3O7eMIAi2x6TnaKB0yQq5SZ1JA5C_TKzWc2pe-UVKDEb4cCcWP8-EpXnHvWjoChCLWB4OZmSliSFYThzu1jbNFXTbY_dfaYuxzELy0lhUQ2x98VldbSJrW31_0E-DSIDAljLyMWGxrPV508DpNVCvr1GFEuUTPVq7yAZGNjTv0cYGFQP9uJNP-koxbfk9z5DaTr2CdjUAKpKaR_x01ifO-KWLfgyxvVVsw_Gy=
|
|
|
|
|
|
CapacityConstraint:Class
|
|
PNPlaceState:Class
|
|
WorkerSet:Class
|
|
State:Class
|
|
Stateful:Class {
|
|
abstract = True;
|
|
}
|
|
Source:Class {
|
|
abstract = True;
|
|
}
|
|
Clock:Class {
|
|
upper_cardinality = 1;
|
|
lower_cardinality = 1;
|
|
}
|
|
BerthState:Class {
|
|
constraint = ```
|
|
errors = []
|
|
numShips = get_slot_value(this, "numShips")
|
|
status = get_slot_value(this, "status")
|
|
if (numShips == 0) != (status == "empty"):
|
|
errors.append(f"Inconsistent: numShips = {numShips}, but status = {status}")
|
|
errors
|
|
```;
|
|
}
|
|
Top:Class {
|
|
abstract = True;
|
|
}
|
|
Place:Class
|
|
WorkerSetState:Class
|
|
Berth:Class
|
|
Generator:Class
|
|
PNTransition:Class
|
|
PNConnectable:Class {
|
|
abstract = True;
|
|
}
|
|
Sink:Class {
|
|
abstract = True;
|
|
}
|
|
ConnectionState:Class
|
|
PlaceState:Class
|
|
PNPlace:Class
|
|
shipCapacities:GlobalConstraint {
|
|
constraint = ```
|
|
errors = []
|
|
for _, constr in get_all_instances("CapacityConstraint"):
|
|
cap = get_slot_value(constr, "shipCapacity")
|
|
total = 0
|
|
place_names = [] # for debugging
|
|
for lnk in get_outgoing(constr, "capacityOf"):
|
|
place = get_target(lnk)
|
|
place_names.append(get_name(place))
|
|
place_state = get_source(get_incoming(place, "of")[0])
|
|
total += get_slot_value(place_state, "numShips")
|
|
if total > cap:
|
|
errors.append(f"The number of ships in places {','.join(place_names)} ({total}) exceeds the capacity ({cap}) of CapacityConstraint {get_name(constr)}.")
|
|
errors
|
|
```;
|
|
}
|
|
operatingCapacities:GlobalConstraint {
|
|
constraint = ```
|
|
errors = []
|
|
for _, workersetstate in get_all_instances("WorkerSetState"):
|
|
workerset = get_target(get_outgoing(workersetstate, "of")[0])
|
|
num_operating = len(get_outgoing(workersetstate, "isOperating"))
|
|
num_workers = get_slot_value(workerset, "numWorkers")
|
|
if num_operating > num_workers:
|
|
errors.append(f"WorkerSet {get_name(workerset)} is operating more berths ({num_operating}) than there are workers ({num_workers})")
|
|
errors
|
|
```;
|
|
}
|
|
WorkerSet_numWorkers:AttributeLink (WorkerSet -> Integer) {
|
|
constraint = `get_value(get_target(this)) >= 0`;
|
|
optional = False;
|
|
name = "numWorkers";
|
|
}
|
|
PlaceState_numShips:AttributeLink (PlaceState -> Integer) {
|
|
optional = False;
|
|
name = "numShips";
|
|
constraint = `get_value(get_target(this)) >= 0`;
|
|
}
|
|
ConnectionState_moved:AttributeLink (ConnectionState -> Boolean) {
|
|
name = "moved";
|
|
constraint = ```
|
|
result = True
|
|
all_successors_moved = True
|
|
moved = get_value(get_target(this))
|
|
conn_state = get_source(this)
|
|
conn = get_target(get_outgoing(conn_state, "of")[0])
|
|
tgt_place = get_target(conn)
|
|
next_conns = get_outgoing(tgt_place, "connection")
|
|
for next_conn in next_conns:
|
|
next_conn_state = get_source(get_incoming(next_conn, "of")[0])
|
|
if not get_slot_value(next_conn_state, "moved"):
|
|
all_successors_moved = False
|
|
if moved and not all_successors_moved:
|
|
result = f"Connection {get_name(conn)} played before its turn."
|
|
result
|
|
```;
|
|
optional = False;
|
|
}
|
|
BerthState_status:AttributeLink (BerthState -> String) {
|
|
name = "status";
|
|
constraint = ```
|
|
(
|
|
get_value(get_target(this)) in { "empty", "unserved", "served" }
|
|
)
|
|
```;
|
|
optional = False;
|
|
}
|
|
PNPlaceState_numTokens:AttributeLink (PNPlaceState -> Integer) {
|
|
optional = False;
|
|
name = "numTokens";
|
|
constraint = `"numTokens cannot be negative" if get_value(get_target(this)) < 0 else None`;
|
|
}
|
|
Clock_time:AttributeLink (Clock -> Integer) {
|
|
name = "time";
|
|
constraint = `get_value(get_target(this)) >= 0`;
|
|
optional = False;
|
|
}
|
|
CapacityConstraint_shipCapacity:AttributeLink (CapacityConstraint -> Integer) {
|
|
constraint = `get_value(get_target(this)) >= 0`;
|
|
optional = False;
|
|
name = "shipCapacity";
|
|
}
|
|
of:Association (State -> Stateful) {
|
|
target_lower_cardinality = 1;
|
|
source_upper_cardinality = 1;
|
|
source_lower_cardinality = 1;
|
|
target_upper_cardinality = 1;
|
|
}
|
|
arc:Association (PNConnectable -> PNConnectable)
|
|
canOperate:Association (WorkerSet -> Berth) {
|
|
target_lower_cardinality = 1;
|
|
}
|
|
connection:Association (Source -> Sink)
|
|
pn_of:Association (PNPlaceState -> PNPlace) {
|
|
target_upper_cardinality = 1;
|
|
target_lower_cardinality = 1;
|
|
source_upper_cardinality = 1;
|
|
source_lower_cardinality = 1;
|
|
}
|
|
generic_link:Association (Top -> Top)
|
|
isOperating:Association (WorkerSetState -> Berth) {
|
|
constraint = ```
|
|
errors = []
|
|
|
|
# get status of Berth
|
|
berth = get_target(this)
|
|
berth_state = get_source(get_incoming(berth, "of")[0])
|
|
status = get_slot_value(berth_state, "status")
|
|
if status != "unserved":
|
|
errors.append(f"Cannot operate {get_name(berth)} because there is no unserved ship there.")
|
|
|
|
# only operate Berts that we can operate
|
|
workerset = get_target(get_outgoing(get_source(this), "of")[0])
|
|
can_operate = [get_target(lnk) for lnk in get_outgoing(workerset, "canOperate")]
|
|
if berth not in can_operate:
|
|
errors.append(f"Cannot operate {get_name(berth)}.")
|
|
|
|
errors
|
|
```;
|
|
}
|
|
capacityOf:Association (CapacityConstraint -> Place) {
|
|
target_lower_cardinality = 1;
|
|
}
|
|
:Inheritance (connection -> Stateful)
|
|
:Inheritance (CapacityConstraint -> Top)
|
|
:Inheritance (Sink -> Top)
|
|
:Inheritance (generic_link -> Top)
|
|
:Inheritance (Berth -> Place)
|
|
:Inheritance (WorkerSet -> Stateful)
|
|
:Inheritance (Place -> Source)
|
|
:Inheritance (PlaceState -> State)
|
|
:Inheritance (State -> Top)
|
|
:Inheritance (Source -> Top)
|
|
:Inheritance (Clock -> Top)
|
|
:Inheritance (Stateful -> Top)
|
|
:Inheritance (Place -> Stateful)
|
|
:Inheritance (PNConnectable -> Top)
|
|
:Inheritance (WorkerSetState -> State)
|
|
:Inheritance (Place -> Sink)
|
|
:Inheritance (BerthState -> PlaceState)
|
|
:Inheritance (PNTransition -> PNConnectable)
|
|
:Inheritance (ConnectionState -> State)
|
|
:Inheritance (PNPlaceState -> Top)
|
|
:Inheritance (Generator -> Source)
|
|
:Inheritance (Berth -> Stateful)
|
|
:Inheritance (PNPlace -> PNConnectable) |