@@ -92,6 +92,15 @@ def pending_tokens(self):
9292 marked_flows .append (flow_id )
9393 return marked_flows
9494
95+ def pending_tokens_dict (self ):
96+ left_tokens = {}
97+ for flow_id in self .tokens :
98+ if self .tokens [flow_id ] > 0 :
99+ left_tokens [flow_id ] = self .tokens [flow_id ]
100+ else :
101+ left_tokens [flow_id ] = 0
102+ return left_tokens
103+
95104
96105class BPMNGraph :
97106 def __init__ (self ):
@@ -313,18 +322,20 @@ def update_process_state(self, e_id, p_state):
313322 random .shuffle (enabled_tasks )
314323 return enabled_tasks
315324
316- def remove_tasks_from_enabled (self , enabled_elements : deque ) -> deque :
325+ def remove_from_enabled (self , enabled_elements : deque , fired_or_splits : set ) -> deque :
317326 """
318- Remove TASK elements from the enabled elements deque.
327+ Remove TASK elements and elements in fired_or_splits from the enabled elements deque.
319328
320329 Args:
321330 enabled_elements: A deque containing [ElementInfo, flow_id] pairs
331+ fired_or_splits: A set of element IDs to be removed
322332
323333 Returns:
324- A new deque with TASK elements filtered out
334+ A new deque with filtered elements
325335 """
326336 return deque (
327- [elem for elem in enabled_elements if elem [0 ].type is not BPMNNodeType .TASK ]
337+ [elem for elem in enabled_elements
338+ if elem [0 ].type is not BPMNNodeType .TASK and elem [0 ].id not in fired_or_splits ]
328339 )
329340
330341
@@ -336,7 +347,7 @@ def replay_trace(
336347 p_state = ProcessState (self )
337348 fired_tasks = list ()
338349 fired_or_splits = set ()
339- # fired_or_joins = set ()
350+ missed_tokens = dict ()
340351
341352 for flow_id in self .element_info [self .starting_event ].outgoing_flows :
342353 p_state .flow_date [flow_id ] = self ._c_trace [0 ].started_at if self ._c_trace is not None else None
@@ -350,9 +361,6 @@ def replay_trace(
350361 el_id = self .from_name .get (task_sequence [current_index ])
351362 fired_tasks .append (False )
352363
353- if el_id == "F" :
354- print ("Hola" )
355-
356364 in_flow = self .element_info [el_id ].incoming_flows [0 ]
357365 task_enabling .append (p_state .flow_date [in_flow ] if in_flow in p_state .flow_date else None )
358366 if self ._c_trace :
@@ -392,11 +400,23 @@ def replay_trace(
392400 fired_or_splits ,
393401 )
394402
403+ for or_id in fired_or_splits :
404+ or_info = self .element_info [or_id ]
405+ for flow_id in or_info .outgoing_flows :
406+
407+ target_id = self .flow_arcs [flow_id ][1 ]
408+ target_info = self .element_info [target_id ]
409+
410+ if target_info .type == BPMNNodeType .TASK :
411+ if target_info .name not in task_sequence :
412+ if flow_id in p_state .frequency_count :
413+ p_state .frequency_count [flow_id ] = 0
414+
395415 # Firing End Event
396416 enabled_end , or_fired , path_decisions = self ._find_enabled_predecessors (
397417 self .element_info [self .end_event ], p_state
398418 )
399- enabled_end = self .remove_tasks_from_enabled (enabled_end )
419+ enabled_end = self .remove_from_enabled (enabled_end , fired_or_splits )
400420
401421 self ._fire_enabled_predecessors (
402422 enabled_end ,
@@ -424,7 +444,17 @@ def replay_trace(
424444 if post_p :
425445 self .postprocess_unfired_tasks (task_sequence , fired_tasks , f_arcs_frequency , task_enabling )
426446 self ._c_trace = None
427- return is_correct , fired_tasks , p_state .pending_tokens (), p_state .frequency_count
447+
448+ for i , fired in enumerate (fired_tasks ):
449+ if not fired and i < len (task_sequence ):
450+ activity = task_sequence [i ]
451+ if activity in self .from_name :
452+ task_id = self .from_name [activity ]
453+ for flow_id in self .element_info [task_id ].incoming_flows :
454+ missed_tokens [flow_id ] = missed_tokens .get (flow_id , 0 ) + 1
455+ p_state .increment_frequency (flow_id )
456+
457+ return is_correct , fired_tasks , p_state .pending_tokens_dict (), p_state .frequency_count , missed_tokens
428458
429459 def update_flow_dates (self , e_info : ElementInfo , p_state : ProcessState , last_date ):
430460 visited_elements = set ()
@@ -563,14 +593,7 @@ def try_firing_alternative(
563593 task_info = self .element_info [el_id ]
564594 if not p_state .has_token (task_info .incoming_flows [0 ]):
565595 enabled_pred , or_fired , path_decisions = self ._find_enabled_predecessors (task_info , p_state )
566- enabled_pred = self .remove_tasks_from_enabled (enabled_pred ) # TO BE considered: might have implications to certain cases
567-
568- # # # Increment frequency of force enabled flow arc
569- # flow_id = task_info.incoming_flows[0]
570- # if flow_id not in f_arcs_frequency:
571- # f_arcs_frequency[flow_id] = 1
572- # else:
573- # f_arcs_frequency[flow_id] += 1
596+ enabled_pred = self .remove_from_enabled (enabled_pred , fired_or_splits ) # TO BE considered: might have implications to certain cases
574597
575598 firing_index = self .find_firing_index (task_index , from_index , task_sequence , path_decisions , enabled_pred )
576599 if firing_index == from_index :
@@ -589,10 +612,6 @@ def try_firing_alternative(
589612 if p_state .has_token (task_info .incoming_flows [0 ]):
590613 flow_id = task_info .incoming_flows [0 ]
591614 p_state .remove_token (flow_id )
592- # if flow_id not in f_arcs_frequency:
593- # f_arcs_frequency[flow_id] = 1
594- # else:
595- # f_arcs_frequency[flow_id] += 1
596615 fired_tasks [task_index ] = True
597616 if self ._c_trace :
598617 self .current_attributes = self ._c_trace [task_index ].attributes
@@ -853,41 +872,6 @@ def try_firing_or_join(self, enabled_pred, p_state, or_firing, path_decisions, f
853872 del or_firing [or_id ]
854873
855874
856- # def try_firing_or_join(self, enabled_pred, p_state, or_firing, path_decisions, f_arcs_frequency):
857- # fired = set()
858- # fired_flows = set()
859- # or_firing_list = list()
860- # for or_join_id in or_firing:
861- # or_firing_list.append(or_join_id)
862- # for or_join_id in or_firing_list:
863- # if self._is_enabled(or_join_id, p_state) or not enabled_pred:
864- # fired.add(or_join_id)
865- # e_info = self.element_info[or_join_id]
866- #
867- # if e_info.outgoing_flows[0] in fired_flows:
868- # p_state.increment_frequency(e_info.outgoing_flows[0])
869- # else:
870- #
871- # self._update_next(
872- # e_info.outgoing_flows[0],
873- # enabled_pred,
874- # p_state,
875- # or_firing,
876- # path_decisions,
877- # f_arcs_frequency,
878- # )
879- # for in_flow in e_info.incoming_flows:
880- # fired_flows.add(in_flow)
881- # p_state.remove_token(in_flow)
882- # if enabled_pred:
883- # break
884- # if len(or_firing_list) != len(or_firing):
885- # for e_id in or_firing:
886- # if e_id not in or_firing_list:
887- # or_firing_list.append(e_id)
888- # for or_id in fired:
889- # del or_firing[or_id]
890-
891875 def check_unfired_or_splits (self , or_splits , f_arcs_frequency , p_state ):
892876 for or_id in or_splits :
893877 for flow_id in self .element_info [or_id ].outgoing_flows :
0 commit comments