 (4) update time and state_id, and get new triggers

top(Step) :-
    dyn(flag(done_matching))), 
    dyn(flag(done_execution))), 

    Step > 0,
    Current_step is Step - 1,
    
    % update time
    dyn(current_time(Time)),
    Newtime is Time + 1,
    retract(dyn(current_time(Time))),
    assert(dyn(current_time(Newtime))),

    % If any changes are made to the state, update state.
    % Otherwise, do not. 

    (          dyn(flag(state_changed)), 
       retract(dyn(flag(state_changed)), 
       update_state;  
       true
    ),

    write('* Finish one enactment step/time unit. '), nl, 
    write('* Enactment time ends at: '), write(Time),nl, 
    write('* Enactment steps left: '), write(Current_step),nl, 
  
%   query_for_adding_triggers,
    top(Current_step). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% user interfact need to specify the entity instances
% and its types, and its parents, if there is an alternative
% parents.

% Meta level of handing processes, i.e. to determine which
% process should be queued, and which one should be executed.
% It also handles changes of the system status, and enable
% dependency backtracking if necessary.

% check events, identify process, identify entities,
% put process in the agenda, retract event.

% Check how notatin of time has been decided in the agenda.
% Actions of a process is committed at its end-time !

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

meta_match_process :-
        write('>>>>> Searching for new events... '),nl,

        dyn(event(Instance, Event, Tstate, Priority, 
                Begin_time/End_time, 
                (Provider/Provider_type, Receiver/Receiver_type), 
                 Event_content)), 

        %% (1) check timing 
        dyn(current_time(Time)), Time >= Begin_time,

        %% get short-hand variable
        T = dyn(event(Instance, Event, TStatus, Priority, 
                Begin_time/End_time, 
                (Provider/Provider_type, Receiver/Receiver_type), 
                 Event_content)), 

        TState = Status/IDlist, 

        \+ Status = suspended, \+ Status = cancelled, 
        \+ Status = finished, 

        %%%%% identify and add triggered process to process agenda 
        add_process_to_agenda(T), 

        %% to allow all eligible events to be processed in the same state
        meta_match_process. 

meta_match_process. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Given an external event, trigger all relevant processes. 
% 
% Note: in the current implementation, a process may or may not 
%       have a trigger. 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

add_process_to_agenda(E) :-
    
  %%%%%% get new events as potential triggering conditions 
  E = dyn(event(Instance, Event, EStatus, Priority, B/E, 
          (Provider/Provider_type, Receiver/Receiver_type), 
          Event_content)), 

  EStatus = _/ID_list, 

  %%%%%%%%%%%%%%%%%% match process %%%%%%%%%%%%%%%
  process(Instance, Process/PID, PStatus, Priority, 
          Begin_time/End_time, Time_cost, 
          (Provider/Provider_type, Receiver/Receiver_type), 
          P_Trigger, Precond, Action, Postcond), 

    ( P_Trigger = [true]; P_Trigger = [E] ), 

  P = process(Instance, Process/PID, PStatus, Priority, 
              Begin_time/End_time, Time_cost, 
              (Provider/Provider_type, Receiver/Receiver_type), 
              P_Trigger, Precond, Action, Postcond), 

  %%% match junctions: if it is followed by a start junction, or 
  %%%                  if it is followed by a control-link, or 
  %%%                  if it is followed by an and-joint junction, or 
  %%%                  if it is followed by an and-split junction, or 
  %%%                  if it is followed by an or-joint junction, or 
  %%%                  if it is followed by an or-split junction, 
  %%% and it fits the process, add it to the agenda

    ( EStatus = received/[], start[PID];
      EStatus = processed/List, control_link(A, PID), 
      member(A, List);

      EStatus = processed/List, and_split(A, Blist), 
      member(A, List), member(PID, Blist);
      EStatus = processed/List, or_split(A, Blist), 
      member(A, List), member(PID, Blist);
      
      EStatus = processed/List, and_joint(Alist, PID), 
      subset(Alist, List); 
      EStatus = processed/List, or_joint(Alist, PID), 
      member(X, List), member(X, Alist); )

      %%% update process time, and 
      %%% add process to process agenda 

      dyn(current_time(Time)), 
