@@ -151,6 +151,7 @@ def simulate_execution(self, node_id: str, marking: Set[str]) -> List[Set[str]]:
151151
152152 :param node_id: Identifier of the node to execute.
153153 :param marking: Current marking to simulate the execution over it.
154+
154155 :return: when it is possible to execute [node_id], list with the different markings result of such execution,
155156 otherwise, return empty list.
156157 """
@@ -197,6 +198,7 @@ def get_enabled_nodes(self, marking: Set[str]) -> Set[str]:
197198 gateway, or event) is considered to be enabled when it can be fired.
198199
199200 :param marking: marking considered as reference to compute the enabled nodes.
201+
200202 :return: a set with the IDs of the enabled nodes (no start or end events).
201203 """
202204 return {
@@ -213,6 +215,7 @@ def get_enabled_tasks_events(self, marking: Set[str]) -> Set[str]:
213215 Compute the set of enabled tasks or events (excluding start/end events) given the current [marking].
214216
215217 :param marking: marking considered as reference to compute the enabled nodes.
218+
216219 :return: a set with the IDs of the enabled tasks/events (no start or end events).
217220 """
218221 return {
@@ -258,6 +261,7 @@ def advance_full_marking(
258261 self ,
259262 marking : Set [str ],
260263 explored_markings : Optional [Set [Tuple [str ]]] = None ,
264+ treat_event_as_task : bool = False
261265 ) -> List [Tuple [str , Set [str ]]]:
262266 """
263267 Advance the current marking as much as possible without executing any task, i.e., execute gateways until there
@@ -268,6 +272,11 @@ def advance_full_marking(
268272
269273 :param marking: marking to consider as starting point to perform the advance operation.
270274 :param explored_markings: if recursive call, set of previously explored markings to avoid infinite loop.
275+ :param treat_event_as_task: if 'True', intermediate events are treated as tasks. This means there are edges
276+ in the reachability graph representing the execution of these events, and they are expected to be part of the
277+ n-gram. If 'False', intermediate events are considered as decision points, meaning that they would be traversed
278+ when necessary, without needing to be part of the n-gram.
279+
271280 :return: list of tuples with the ID of an enabled task/event as first element and the advanced marking that
272281 enabled it as second element.
273282 """
@@ -276,7 +285,7 @@ def advance_full_marking(
276285 # First advance all branches at the same time until tasks, events, or decision points (XOR-split/OR-split)
277286 advanced_marking = self .advance_marking_until_decision_point (marking )
278287 # Advance all branches together (getting all combinations of advancements)
279- tuples_fully_advanced_markings = self ._advance_marking (advanced_marking , explored_markings )
288+ tuples_fully_advanced_markings = self ._advance_marking (advanced_marking , explored_markings , treat_event_as_task )
280289 # Save only advanced marking that enabled new tasks/events
281290 for enabled_node_id , fully_advanced_marking in tuples_fully_advanced_markings :
282291 # Try to rollback the advancements in other branches as much as possible
@@ -290,6 +299,7 @@ def _advance_marking(
290299 self ,
291300 marking : Set [str ],
292301 explored_markings : Optional [Set [Tuple [str ]]] = None ,
302+ treat_event_as_task : bool = False
293303 ) -> List [Tuple [str , Set [str ]]]:
294304 """
295305 Advance the current marking as much as possible without executing any task, i.e., execute gateways until there
@@ -301,6 +311,11 @@ def _advance_marking(
301311
302312 :param marking: marking to consider as starting point to perform the advance operation.
303313 :param explored_markings: if recursive call, set of previously explored markings to avoid infinite loop.
314+ :param treat_event_as_task: if 'True', intermediate events are treated as tasks. This means there are edges
315+ in the reachability graph representing the execution of these events, and they are expected to be part of the
316+ n-gram. If 'False', intermediate events are considered as decision points, meaning that they would be traversed
317+ when necessary, without needing to be part of the n-gram.
318+
304319 :return: list of tuples with the ID of the enabled task/event as first element, and the advanced marking that
305320 enabled it as second element.
306321 """
@@ -327,9 +342,11 @@ def _advance_marking(
327342 enabled_gateways = [
328343 node_id
329344 for node_id in self .get_enabled_nodes (current_marking )
330- if self .id_to_node [node_id ].is_gateway ()
345+ # Retain gateways, and events if they are not treated as tasks
346+ if (self .id_to_node [node_id ].is_gateway () or
347+ (not treat_event_as_task and self .id_to_node [node_id ].is_event ()))
331348 ]
332- # If no enabled gateways, save fully advanced marking
349+ # If no enabled gateways (or events) , save fully advanced marking
333350 if len (enabled_gateways ) == 0 :
334351 set_tuples_final_markings |= {
335352 (enabled_node_id , current_marking_key )
@@ -351,7 +368,7 @@ def _advance_marking(
351368 in self .advance_full_marking (advanced_marking , explored_markings )
352369 }
353370 else :
354- # JOINs or XOR-split, execute and continue with advancement
371+ # JOINs or XOR-split (or event) , execute and continue with advancement
355372 next_marking_stack += self .simulate_execution (gateway_id , current_marking )
356373 # Update new marking stack
357374 current_marking_stack = next_marking_stack
@@ -385,6 +402,7 @@ def _try_rollback(self, advanced_marking: Set[str], marking: Set[str], enabled_n
385402 :param advanced_marking: advanced marking result of advancing the branches in [marking] as much as possible.
386403 :param marking: marking considered as starting point.
387404 :param enabled_node_id: identifier of the node that is enabled and must remain enabled.
405+
388406 :return: rollbacked marking.
389407 """
390408 rollbacked_marking = set ()
@@ -437,6 +455,7 @@ def _advance_combination(self, combination: Set[str]) -> List[Set[str]]:
437455 branches until no more gateways are enabled (storing all markings reached during this expansion).
438456
439457 :param combination: marking to consider as starting point to perform the advance operation.
458+
440459 :return: list with the different markings result of such advancement.
441460 """
442461 # If result in cache, retrieve, otherwise compute
@@ -478,12 +497,22 @@ def _advance_combination(self, combination: Set[str]) -> List[Set[str]]:
478497 # Return final set
479498 return final_markings
480499
481- def get_reachability_graph (self , cached_search : bool = True ) -> ReachabilityGraph :
500+ def get_reachability_graph (
501+ self ,
502+ treat_event_as_task : bool = False ,
503+ cached_search : bool = True
504+ ) -> ReachabilityGraph :
482505 """
483506 Compute the reachability graph of this BPMN model. Each marking in the reachability graph contains the enabled
484507 flows of that state, and corresponds to a state of the process where the only enabled elements are tasks,
485508 events, and decision points (XOR-split/OR-split).
486509
510+ :param treat_event_as_task: if 'True', intermediate events are treated as tasks. This means there are edges
511+ in the reachability graph representing the execution of these events, and they are expected to be part of the
512+ n-gram. If 'False', intermediate events are considered as decision points, meaning that they would be traversed
513+ when necessary, without needing to be part of the n-gram.
514+ :param cached_search: whether to cache expansion operations in the graph to save runtime.
515+
487516 :return: the reachability graph of this BPMN model.
488517 """
489518 self ._cached_search = cached_search
@@ -508,7 +537,10 @@ def get_reachability_graph(self, cached_search: bool = True) -> ReachabilityGrap
508537 # Advance the current marking, executing enabled gateways, obtaining:
509538 # An activity enabled by the advancement
510539 # The advanced marking needed to execute the activity
511- tuples_advanced_markings = self .advance_full_marking (current_marking )
540+ tuples_advanced_markings = self .advance_full_marking (
541+ current_marking ,
542+ treat_event_as_task = treat_event_as_task
543+ )
512544 # For each pair of enabled activity and advanced marking that enables it
513545 for enabled_node_id , advanced_marking in tuples_advanced_markings :
514546 enabled_node = self .id_to_node [enabled_node_id ]
0 commit comments