                (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)), 
      Begin_time = Time, 
      End_time is Time + Time_cost,
      assert(dyn(agenda(P))),

      %% update the event status to "processed", to indicated that it is 
      %% being processed. 

       New_event = dyn(event(Instance, Event, processed/ID_list, 
                             Priority, B/E, 
                            (Provider/Provider_type, Receiver/Receiver_type), 
                             Event_content)), 
      retract(E),
      assert(New_event), 

      add_process_to_agenda(T).

add_process_to_agenda(_). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% meta_exec_process
%
% Function: Allow the user to execute all of the qualified processes.
% Note: The unique event_id later on becomes a process ID
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

meta_exec_process :-

        write('>>>>> Searching for valid processes'),nl,
 
        % find all processes in the agenda ready to be executed
        findall( (Process_type, Tri_id), 
                 ( dyn(agenda(process(Process_type, Tri_id, _Content,
                                     (_Begin_time, End_time)))),
                   dyn(current_time(Time)),        % check time 
                   Time >= End_time ),
                   Process_list),  
   
        \+  Process_list = [], 

        % when there is any process in the agenda, 
        % report these processes 

        % write('********************************************'),nl,
        % write('All processes in the Agenda are given below:'),nl,nl,
        % write_list(Process_list),nl,
        % write('********************************************'),nl,

        % checking that no conflict processes are to be executed 
        % at the same time !
        % calling process conflict detector in 'conflict.pl'

        % write('* Searching for contradicatory processes...'),nl, 
        % \+ detect_conflicted_processes(Process_list),
        % write('  No contradicatory processes found.'),nl, 

        % choose and execute these processes
        choose_process(Process_list). 

meta_exec_process. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% choose process for execution from process agenda 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
choose_process( []) :- !. 

choose_process( [(Process, PID)|Tail] ) :-

       dyn(agenda(process(Instance, Process/PID, PStatus, Priority, 
              Begin_time/End_time, Time_cost, 
              (Provider/Provider_type, Receiver/Receiver_type), 
              P_Trigger, Precond, Action, Postcond))), 

       P = process(Instance, Process/PID, PStatus, Priority, 
              Begin_time/End_time, Time_cost, 
              (Provider/Provider_type, Receiver/Receiver_type), 
              P_Trigger, Precond, Action, Postcond),

        % decide whether to execute the process or not, 
        % this is determined by the user
        nl, 
        write('*****************************************'),nl,
        write('Would you like to execute this process:'),nl,nl,
        write('Process: '), write(Process_type),nl,
        write('Process/Event Instance: '),write(Tri_id),nl,
        write('The full process:'),nl, 
        pretty_print(P), nl, 
        write('*****************************************'),nl,
        write('Execution? (y/n) '), read(Ans), nl, 

      (\+ Ans = y, choose_process(Tail); 

          Ans = y, 

        write('**********************************'),nl,
        write('     Process Execution Phase      '),nl,       
        write('**********************************'),nl,

        (A) check all actions are correct, 'top.pl'
        write('* Checking the trigger....'),nl, 
        \+ triggering_conditions_satisfied(Process_type, Tri_id),
        write('  checking trigger succeed.'),nl,

        % (1) check all preconditions are satisfied, 'cond.pl'
        write('* Checking preconditions....'),nl, 
        all_preconditions_satisfied(Process_type, Tri_id),  
        write('  checking precond succeed.'),nl,

        % (B) execute the process, 'exe.pl'
        write('* Executing the process ...'),nl,
        execute_process(Process_type, Tri_id),
        write('  Process execution succeed.'),nl,

        %