%% Son Tran's translator program - b2s.pl %% %% input: a Prolog program representing an %% action theory in Language B %% output: a lp-program in Lparse/Smodels syntax %% which can be used for planning or RAC %% %% The b2s translator is currently capable of handling %% the following features: %% %% a. Dynamic Causal Laws of the form: %% causes(A,F,P) iff action A causes fluent literal F %% to be true if preconditions P hold. %% %& b. Static Causal Laws: %% caused(G,F) iff set of fluent literals G causes fluent %% literal F to be true. %% %% c. Executability conditions: %% executable(A,G) - A can be executed iff G holds %% %% d. Initial state: %% initially(F) iff fluent literal F holds in the initial state. %% %% e. Goal state: %% goal(F) iff fluent literal F holds in the final state. %% %% Notice that b2s will only work correctly if the following %% predicates are defined in the domain description input file: %% 1. fluent(F) iff F is a fluent. %% 2. action(A) iff A is an action. %% :- use_module(library(lists)). :- use_module(library(system)). unknown_predicate_handler(_,_,fail). %%% %%% Collecting the fluents and actions names %%% and repeating them in the output file %%% pr_generals(Id) :- findall(X, fluent(X), L), findall(Y, action(Y), L1), nl(Id), write(Id,'%%% Fluents %%%%'), nl(Id), nl(Id), pr_fluents(L,Id), nl(Id),nl(Id), write(Id,'%%% Actions %%%%'), nl(Id),nl(Id), pr_actions(L1,Id),nl(Id). pr_fluents([],Id) :- nl(Id),write(Id,'%%% End of Fluents %%%'),nl(Id). pr_fluents([X|Y],Id) :- write(Id,fluent(X)),write(Id,'.'),nl(Id), pr_fluents(Y,Id). pr_actions([],Id) :- nl(Id),write(Id,'%%% End of Actions %%%'),nl(Id). pr_actions([X|Y],Id) :- write(Id,action(X)),write(Id,'.'),nl(Id), pr_actions(Y,Id). %%% %%% Collecting static causal laws %%% and translating them into rules suitable for SMODELS %%% pr_static_causal(Id):- findall((X,Y),caused(X,Y),L), nl(Id), write(Id, '%%% Section: static causal laws %%%%'), nl(Id), pr_static_causal(L, Id). pr_static_causal([], Id):- nl(Id), write(Id, '%%% End section: static causal laws %%%%'), nl(Id). pr_static_causal([(L,C)|T], Id):- write(Id,'holds('), write(Id,L), write(Id,', T):- time(T), '), pr_causal_list(Id,C), nl(Id), pr_static_causal(T, Id). pr_causal_list(Id,[]):- write(Id, '.'). pr_causal_list(Id,[H|T]):- write(Id,'holds('), write(Id,H), write(Id,', T)'), length(T, N), (N > 0 -> write(Id,', ') | write(Id, '')), pr_causal_list(Id,T). %%% %%% Collecting dynamic causal laws %%% and translating them into rules suitable for SMODELS %%% pr_dynamic_causal(Id) :- findall((A,X,Y), causes(A,X,Y), Z), nl(Id), write(Id, '%%% Section: dynamic causal laws %%%%'), nl(Id), pr_dynamic_causal(Z, Id). pr_dynamic_causal([], Id):- nl(Id), write(Id, '%%% End section: dynamic causal laws %%%%'), nl(Id). pr_dynamic_causal([(A,L,C)|T], Id):- write(Id,'holds('), write(Id,L), write(Id,', T+1):- time(T), possible('), write(Id,A), write(Id,', T), '), write(Id,'occ('), write(Id,A), write(Id,',T)'), pr_condition_list(Id,C), nl(Id), pr_dynamic_causal(T, Id). pr_condition_list(Id,[]):- write(Id, '.'). pr_condition_list(Id,[H|T]):- write(Id,', holds('), write(Id,H), write(Id,', T)'), pr_condition_list(Id,T). %%% %%% Generating rules for each executability condition %%% %%% pr_impossible(Id):- nl(Id), nl(Id), write(Id, '%%% Section: Executability Conditions %%'), findall((X,Y), executable(X,Y), Z), nl(Id),nl(Id), pr_item_executable(Z,Id). pr_item_executable([],Id):- nl(Id), write(Id, '%%% End of section: Executability Conditions %%%%'), nl(Id). pr_item_executable([(A,L)|T],Id):- write(Id, 'possible('), write(Id, A), write(Id, ', T):- time(T)'), pr_condition_list(Id, L), nl(Id), pr_item_executable(T, Id). %%% %%% Generating initial rules for fluent literals %%% one rule per fluent literal %%% pr_initial(Id) :- findall(X, (fluent(X),is_inertial(X)), Z), % remove_dups(Z1, Z), nl(Id), write(Id, '%%% Section: initial conditions are exogenous %%%%'), nl(Id), pr_initial(Z, Id). pr_initial([], Id):- nl(Id), write(Id, '%%% End section: initial conditions are exogenous %%%%'), nl(Id). pr_initial([L|T], Id):- pri_line(L, Id), nl(Id), pri_line(neg(L), Id),nl(Id), pr_initial(T, Id). pri_line(H, Id):- fluent(H), add_time(H, '0', Id), write(Id, ' :- not '), add_time(neg(H), '0', Id), write(Id, '.'). pri_line(neg(H), Id):- fluent(H), add_time(neg(H),'0', Id), write(Id, ' :- not '), add_time(H, '0', Id), write(Id, '.'). %%% %%% Generating rules for 'actions are exogenous' %%% two rules for each action %%% pr_ex_action(Id):- findall(A, action(A), Z), nl(Id), write(Id, '%%% Section: actions are exogenous %%%%'), nl(Id), pr_ex_action(Z, Id). pr_ex_action([], Id):- nl(Id), write(Id, '%%% End of section: actions are exogenous %%%%'), nl(Id). pr_ex_action([A|T], Id):- add_time(A, 'T', Id), write(Id, ' :- time(T), not '), add_time(neg(A), 'T', Id), write(Id, '.'), nl(Id), add_time(neg(A), 'T', Id), write(Id, ' :- time(T), not '), add_time(A, 'T', Id), write(Id, '.'), nl(Id), pr_ex_action(T, Id). %%% %%% Generating rules for section 'no actions are executed at last time' %%% one per action %%% pr_no_action(Id):- findall(A, action(A), Z), nl(Id), nl(Id), write(Id, '%%% Section: no actions are executed at last time %%'), nl(Id),nl(Id), pr_no_action(Z, Id). pr_no_action([], Id):- nl(Id), write(Id, '%%% End of section: no actions are executed at last time %%%%'), nl(Id). pr_no_action([A|T], Id):- write(Id, ':- '), write(Id, 'occ('), write(Id, A),write(Id,',lasttime).'), nl(Id), pr_no_action(T, Id). %%% %%% Adding the two auxiliary predicates to the domain file %%% pr_auxiliary(Id):- nl(Id), write(Id, '%%% Auxiliary predicates '), nl(Id), nl(Id), write(Id, 'time(0..lasttime).'), nl(Id), write(Id, 'next(T,T1):- time(T), time(T1), T1 = T + 1.'), nl(Id), write(Id, '1 { occ(X,T): action(X) } 1 :- time(T), T < lasttime.'), nl(Id), write(Id, 'fliteral(L) :- fluent(L).'),nl(Id), write(Id, 'fliteral(neg(L)) :- fluent(L).'),nl(Id). %%% %%% Generating rules for each constraint %%% %%% pr_constraint(Id):- findall(X, constraint(X), Z), nl(Id), write(Id, '%%% Section: Constraints %%'), nl(Id), pr_constraint(Z,Id). pr_constraint([],Id):- nl(Id), write(Id, '%%% End of section: Constraints %%%%'), nl(Id). pr_constraint([A|T],Id):- write(Id, ':- time(T), '), add_time_list(A, 'T',Id), write(Id, '.'), nl(Id), pr_constraint(T,Id). %%% %%% Generating problem output file which includes %%% the initial situation %%% pr_initsit(Id) :- findall(I, initially(I), Z), nl(Id), write(Id, '%%% Initial Conditions %%%'), nl(Id), pr_initsituation(Z,Id). pr_initsituation([],Id):- nl(Id). pr_initsituation([G|T],Id) :- write(Id,'holds('), write(Id,G), write(Id,',0).'),nl(Id), pr_initsituation(T,Id). eq(X,X). neq(X,Y):- \+ eq(X,Y). %%% %%% for SICStus program %%% gen:- write(' Enter domain description file name: '), read(S), name(S,Chars), name(smo,Chars1), append(Chars,[46|Chars1],Chars2), name(S1,Chars2), absolute_file_name(S, Source), %%% get the source file name consult(Source), absolute_file_name(S1, FileDescr), %%% get the domain output file name write(' Generating .... '), open(FileDescr, write , X), write(X,'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'), nl(X), write(X,'%%%% Domain Description %%%%%'), nl(X), write(X,'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'), nl(X), pr_generals(X), pr_static_causal(X), pr_dynamic_causal(X), pr_impossible(X), pr_initsit(X), close(X).