%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% exe.pl         6/25/2002 
%%
%% execute one action, this program calls library.pl
%% that use_module(library(lists)). 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

:- multifile exec/2. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

exec(_, create(X)) :-
    assert(dyn(X)). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

exec(_, delete(X) ) :-
     retract(dyn(X)). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
% x is the new value 
exec(_, update(X)) :-

    %% checking the correctness of the update action    
    X = instance_att(Instance, Att, _),

    dyn(instance_att(Instance, Att, _)), 
    retract(dyn(instance_att(Instance, Att, _))), 
    assert(dyn(X)). 

%%%%% check update actions 

exec(_, update(X)) :-

    %%% checking the correctness of the update action    
    ( \+ current_predicate(_, X) ;
      X = instance_of(Instance, _Entity) ; 
      X = instance_att(Instance, Att, _),
      \+ instance_att(Instance,  Att, _)
    ), 

    write('Error: the below update operation has been failed: '), 
    write(X),nl, 
    write('Analysis: the process has either tried to update an instance 
or an attribute that does not exist. To update an instance, one needs
to delete it and create it from scratch. To insert a new attribute,
use create/1 command.'), nl, fail. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

exec(Instance/Process, cond_action(_X, Y)) :- 
     all_preconditions_satisfied(Process, Instance),  
     exec_process(Y). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    

exec(Instance/Process, update_event_status(Instance, New_status)):-

    dyn(agenda(process(Instance, Process/PID, Status, Priority, 
               Begin_time/End_time, Time_cost, 
               (Provider/Provider_type, Receiver/Receiver_type), 
                P_Trigger, Precond, Action, Postcond))), 
  
    Old = dyn(agenda(process(Instance, Process/PID, Status, Priority, 
                        Begin_time/End_time, Time_cost, 
                       (Provider/Provider_type, Receiver/Receiver_type), 
                        P_Trigger, Precond, Action, Postcond))), 

    Status = _/IDList, 
    New = dyn(agenda(process(Instance, Process/PID, 
                             New_status/IDList, Priority, 
                             Begin_time/End_time, Time_cost, 
                            (Provider/Provider_type, Receiver/Receiver_type), 
                             P_Trigger, Precond, Action, Postcond ))), 
    retract(Old), 
    assert(New). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

exec(_, report(Title, Content)) :-

   write('************** Report *************'), nl, 
   write(Title), nl, nl, 
   write(Content). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Domain Actions 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% predicate not used !! 

exec(Instance/Process, 
     store_customer_requirements(Event_content)) :- 

     Event_content = event_occ(_, _, _, _, _, _, List), 
   
     setof(Req, 
        ( member(instance_of(Instance, customer_requirements, Req), List), 
          exec(Instance/Process, 
               create(instance_of(Instance, customer_requirements, Req)))
        ), _list ). 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% construct issue occ 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

exec(Instance/Process, construct_issue(Issue, _, New_issue_content)) :-
   
    dyn(agenda(process(Instance, Process/_PID, Status, Priority, 
               Begin_time/End_time, _Time_cost, 
               (Provider/Provider_type, Receiver/Receiver_type), 
                _P_Trigger, _Precond, _Action, _Postcond))), 

     %%% get requirements and old solution from old issue 
   ( issue_occ(Instance, Issue, Status, Priority, Begin_time/End_time, 
               [solution(Provider, Requirements, 
                         _, Old_solution, _diff)])
    ; 
     %%% get basic solution from issue class template
     issue(Instance, Issue, Status, Priority, Begin_time/End_time, _, 
           [solution( Provider, Requirements, 
            Old_solution, _, _diff)] ), 
 
     %% get customer requirements 
     dyn(instance_of(Instance, customer_requirements, Requirements))
   ), % end ; 

    New_issue_content = 
    issue_occ(Instance, Issue, Status, Priority, Begin_time/End_time, 
              (Provider/Provider_type, Receiver/Receiver_type), 
              [solution(Provider, Requirements, 
                        Old_solution, _new_sol, _diff) ] ),

   write('------- this is the issue occ ----'),nl, 
   write(New_issue_content), nl. 


%%%%%%%%%%%%%%%%%% 
% This action fishes out the constraint and solve it. 
% If the constraint is true, return true; otherwise, falise. 

exec(_Instance/_Process, 
     get_cost_constraint(Sol, _Total, Result)) :- 

     member(Constraint, [less_than(A, B), 
                         greater_than(A, B), 
                         equal(A, B), 
                         greater_equal(A, B), 
                         less_equal(A, B)]), 
     member(Constraint, Sol), 

%    member(total_cost(Total), Sol), 

     (    Constraint, Result = true; 
       \+ Constraint, Result = false).      

/******* see library.pl 

less_than(A, B)     :- A < B.
equal(A, B)         :- A = B. 
greater_than(A, B)  :- A > B.
greater_equal(A, B) :- A >= B. 
less_equal(A, B)    :- A =< B. 

exec(_, calculate_total_cost(
     [allocate(process_x, _), allocate(io_x, _)], Total) ). 

*****************/ 

% Total_cost to start with is a variable, this action
% calculate the value of it. This action also allows
% the total cost to be unified with the constraint
% predicates, such as less_than/2. 

exec(_, calculate_total_cost(Sol, Total_cost ) ) :-

    member(total_cost(Total_cost), Sol), 

    setof(Cost,      
          [ member(allocate(B, _), Sol),
            instance_of(B, Board), 
            property(Board, cost, Cost) 
          ], 
          List), 
    
    sum_list(List, Total_cost). 

%%%%%%%%%%%%%%%%%%%%%%%   end of file %%%%%%%%%%%%%%%%%%%%    
    
