Add 'simplified' version of the FTG+PM++ formalism with operational semantics
This commit is contained in:
parent
ced3edbd08
commit
d00b9c25db
16 changed files with 1135 additions and 0 deletions
|
|
@ -0,0 +1,2 @@
|
|||
# Match the model
|
||||
model:RAM_pm_Model
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
model:RAM_pm_Model
|
||||
|
||||
# Check if the model isn't already connected to a process trace
|
||||
start_trace:RAM_pt_StartTrace
|
||||
:RAM_pt_Starts (start_trace -> model)
|
||||
end_trace:RAM_pt_EndTrace
|
||||
:RAM_pt_Ends (end_trace -> model)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Keep the left hand side
|
||||
model:RAM_pm_Model
|
||||
|
||||
# Connect a process trace to it
|
||||
start_trace:RAM_pt_StartTrace
|
||||
starts:RAM_pt_Starts (start_trace -> model)
|
||||
|
||||
end_trace:RAM_pt_EndTrace
|
||||
ends:RAM_pt_Ends (end_trace -> model)
|
||||
|
||||
# Connect the start with the end
|
||||
:RAM_pt_IsFollowedBy (start_trace -> end_trace)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# When a control port is active and is connected to an activity, we want to execute the activity
|
||||
# But, if the activity has input_and (input_or = False). It only can be activated if all its inputs are active
|
||||
|
||||
|
||||
# Match the model
|
||||
model:RAM_pm_Model
|
||||
|
||||
# Match the a python automated activity
|
||||
py_activity:RAM_pm_PythonAutomatedActivity {
|
||||
# Check if all connected ports are active in case of input_and
|
||||
condition = ```
|
||||
all_active = True
|
||||
|
||||
# Check for or / and
|
||||
if not get_slot_value(this, "input_or"):
|
||||
# Get all the ctrl in ports
|
||||
for has_ctrl_in in get_outgoing(this, "pm_HasCtrlIn"):
|
||||
c_in_state = get_source(get_incoming(get_target(has_ctrl_in), "pm_Of")[0])
|
||||
# Check if the port is active or not
|
||||
if not get_slot_value(c_in_state, "active"):
|
||||
all_active = False
|
||||
break
|
||||
|
||||
all_active
|
||||
```;
|
||||
} model_to_activity:RAM_pm_Owns (model -> py_activity)
|
||||
|
||||
|
||||
# Match a control activity in port that is active
|
||||
ctrl_in:RAM_pm_CtrlActivityIn
|
||||
|
||||
ctrl_in_state:RAM_pm_CtrlPortState {
|
||||
RAM_active = `get_value(this)`;
|
||||
}
|
||||
|
||||
state_to_port:RAM_pm_Of (ctrl_in_state -> ctrl_in)
|
||||
|
||||
# Match the activity link to the port
|
||||
activity_to_port:RAM_pm_HasCtrlIn (py_activity -> ctrl_in)
|
||||
|
||||
# Match the end of the trace
|
||||
end_trace:RAM_pt_EndTrace
|
||||
ends:RAM_pt_Ends (end_trace -> model)
|
||||
|
||||
# Match the previous trace element before the end trace
|
||||
prev_trace_element:RAM_pt_Event
|
||||
|
||||
followed_by:RAM_pt_IsFollowedBy (prev_trace_element -> end_trace)
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
model:RAM_pm_Model
|
||||
|
||||
py_activity:RAM_pm_PythonAutomatedActivity {
|
||||
|
||||
condition = ```
|
||||
start_activity = create_object(None, "pt_StartActivity")
|
||||
create_activity_links(odapi, start_activity, matched("prev_trace_element"), matched("ctrl_in"))
|
||||
input_data = extract_input_data(odapi, this)
|
||||
result = execute_activity(odapi, globals()["packages"], this, input_data)
|
||||
if len(result) == 3:
|
||||
status_code, output_data, input_used = result
|
||||
else:
|
||||
status_code, output_data, input_used = *result, None
|
||||
if input_used:
|
||||
handle_artefact(odapi, start_activity, "pt_Artefact", "pt_Consumes", get(input_used), input_data[input_used], direction="DataFlowOut")
|
||||
end_activity = create_object(None, "pt_EndActivity")
|
||||
ctrl_out = get(status_code)
|
||||
create_activity_links(odapi, end_activity, start_activity, ctrl_out, end_trace=matched("end_trace"))
|
||||
if output_data:
|
||||
port, data = output_data
|
||||
handle_artefact(odapi, end_activity, "pt_Artefact", "pt_Produces", get(port), data, direction="DataFlowIn")
|
||||
update_control_states(odapi, this, ctrl_out)
|
||||
```;
|
||||
}
|
||||
|
||||
model_to_activity:RAM_pm_Owns
|
||||
|
||||
ctrl_in:RAM_pm_CtrlActivityIn
|
||||
|
||||
ctrl_in_state:RAM_pm_CtrlPortState {
|
||||
RAM_active = `False`;
|
||||
}
|
||||
|
||||
state_to_port:RAM_pm_Of (ctrl_in_state -> ctrl_in)
|
||||
|
||||
activity_to_port:RAM_pm_HasCtrlIn (py_activity -> ctrl_in)
|
||||
|
||||
end_trace:RAM_pt_EndTrace
|
||||
ends:RAM_pt_Ends (end_trace -> model)
|
||||
|
||||
prev_trace_element:RAM_pt_Event
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# When a control port is active and is connected to an activity, we want to execute the activity. If it is a composite one, we execute the inner workflow of it
|
||||
# But, if the activity has input_and (input_or = False). It only can be activated if all its inputs are active
|
||||
|
||||
|
||||
# Match the model
|
||||
model:RAM_pm_Model
|
||||
|
||||
# Match the a python automated activity
|
||||
activity:RAM_pm_Activity {
|
||||
|
||||
RAM_composite = `True`;
|
||||
|
||||
} model_to_activity:RAM_pm_Owns (model -> activity)
|
||||
|
||||
|
||||
# Match a control activity in port that is active
|
||||
ctrl_in:RAM_pm_CtrlActivityIn
|
||||
|
||||
ctrl_in_state:RAM_pm_CtrlPortState {
|
||||
RAM_active = `get_value(this)`;
|
||||
}
|
||||
|
||||
state_to_port:RAM_pm_Of (ctrl_in_state -> ctrl_in)
|
||||
|
||||
# Match the activity link to the port
|
||||
activity_to_port:RAM_pm_HasCtrlIn (activity -> ctrl_in)
|
||||
|
||||
# Match the end of the trace
|
||||
end_trace:RAM_pt_EndTrace
|
||||
ends:RAM_pt_Ends (end_trace -> model)
|
||||
|
||||
# Match the previous trace element before the end trace
|
||||
prev_trace_element:RAM_pt_Event
|
||||
|
||||
followed_by:RAM_pt_IsFollowedBy (prev_trace_element -> end_trace)
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
model:RAM_pm_Model
|
||||
|
||||
activity:RAM_pm_Activity {
|
||||
|
||||
RAM_composite = `True`;
|
||||
|
||||
condition = ```
|
||||
# Execute inner workflow
|
||||
execute_composite_workflow(odapi, this, matched("ctrl_in"), globals()["composite_linkage"], globals()["packages"], matched)
|
||||
```;
|
||||
}
|
||||
|
||||
model_to_activity:RAM_pm_Owns
|
||||
|
||||
ctrl_in:RAM_pm_CtrlActivityIn
|
||||
|
||||
ctrl_in_state:RAM_pm_CtrlPortState {
|
||||
RAM_active = `False`;
|
||||
}
|
||||
|
||||
state_to_port:RAM_pm_Of (ctrl_in_state -> ctrl_in)
|
||||
|
||||
activity_to_port:RAM_pm_HasCtrlIn (activity -> ctrl_in)
|
||||
|
||||
end_trace:RAM_pt_EndTrace
|
||||
ends:RAM_pt_Ends (end_trace -> model)
|
||||
|
||||
prev_trace_element:RAM_pt_Event
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# Match an active control output port
|
||||
out_state:RAM_pm_CtrlPortState {
|
||||
RAM_active = `get_value(this)`;
|
||||
}
|
||||
|
||||
out:RAM_pm_CtrlOut
|
||||
|
||||
state_to_out:RAM_pm_Of (out_state -> out)
|
||||
|
||||
# Match an inactive control input port
|
||||
in_state:RAM_pm_CtrlPortState {
|
||||
RAM_active = `not get_value(this)`;
|
||||
}
|
||||
|
||||
in:RAM_pm_CtrlIn
|
||||
|
||||
state_to_in:RAM_pm_Of (in_state -> in)
|
||||
|
||||
# Match the connection between those two ports
|
||||
flow:RAM_pm_CtrlFlow (out -> in)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# Copy the left hand side
|
||||
|
||||
out_state:RAM_pm_CtrlPortState {
|
||||
# Only set the output port to inactive if all connected input ports are set to active
|
||||
RAM_active = ```
|
||||
set_to_active = False
|
||||
|
||||
output_port = matched("out")
|
||||
outgoing_flows = get_outgoing(output_port, "pm_CtrlFlow")
|
||||
|
||||
# for each flow: pm_CtrlFlow -> pm_CtrlIn <- pm_Of <- pm_CtrlPortState == state
|
||||
all_input_port_states = [get_source(get_incoming(get_target(flow), "pm_Of")[0]) for flow in outgoing_flows]
|
||||
input_port_state = matched("in_state")
|
||||
|
||||
for state in all_input_port_states:
|
||||
is_active = get_slot_value(state, "active")
|
||||
|
||||
# If the state is not active and it is not the input port state we have matched and planned to set active
|
||||
# Then we can't yet set this output port state to active
|
||||
if not is_active and state != input_port_state:
|
||||
set_to_active = True
|
||||
break
|
||||
|
||||
# Set the attribute to the assigned value
|
||||
set_to_active
|
||||
```;
|
||||
}
|
||||
|
||||
out:RAM_pm_CtrlOut
|
||||
|
||||
state_to_out:RAM_pm_Of (out_state -> out)
|
||||
|
||||
in_state:RAM_pm_CtrlPortState {
|
||||
# Set the input port active
|
||||
RAM_active = `True`;
|
||||
}
|
||||
|
||||
in:RAM_pm_CtrlIn
|
||||
|
||||
state_to_in:RAM_pm_Of (in_state -> in)
|
||||
|
||||
flow:RAM_pm_CtrlFlow (out -> in)
|
||||
Loading…
Add table
Add a link
Reference in a new issue