:-use_module(library(lists)). :-use_module(library(ordsets)). :-[swicomp, parseProblem, parseDomain]. parsePDDL(DomainFile, ProblemFile):- % Parse the PDDL files into appropriate structures D,P parseDomainOrdered(DomainFile, D), parseProblemOrdered(ProblemFile, P), !, print('Parsing of domain and problem files complete.\n'), % Reset global variables that hold information about objects, % the initial state, the goal, and the available actions using D,P get_domain_name(D, DN), bb_put(domainName, DN), get_problem_name(P, PN), bb_put(problemName, PN), get_init(P, I), bb_put(initState, I), get_goal(P, G), bb_put(goalState, G), get_actions(D, A), bb_put(actions, A), get_objects(P, O), bb_put(objects, O), print('Global variables initialized.\n\n'). parseDomainOrdered(DomainFile, D):- parseDomain(DomainFile, DTemp), DTemp = domain(A1, A2, A3, A4, A5, A6, A7, ActionDefs), orderActionDefs(ActionDefs, OrderedActionDefs), D = domain(A1, A2, A3, A4, A5, A6, A7, OrderedActionDefs). orderActionDefs([],[]). orderActionDefs(ActionDefs,OrderedActionDefs):- ActionDefs = [ActionDef | RestOfActionDefs], ActionDef = action(Name, Params, Preconds, PosEff, NegEff, AssignEff), list_to_ord_set(Preconds, OrdPreconds), list_to_ord_set(PosEff, OrdPosEff), list_to_ord_set(NegEff, OrdNegEff), list_to_ord_set(AssignEff, OrdAssignEff), OrderedActionDef = action(Name, Params, OrdPreconds, OrdPosEff, OrdNegEff, OrdAssignEff), orderActionDefs(RestOfActionDefs, OrderedRestOfActionDefs), OrderedActionDefs = [OrderedActionDef | OrderedRestOfActionDefs]. parseProblemOrdered(ProblemFile, P):- parseProblem(ProblemFile, PTemp), PTemp = problem(Name, DomName, A1, Objects, Init, Goal, A2, A3, A4), list_to_ord_set(Objects, OrdObjects), list_to_ord_set(Init, OrdInit), list_to_ord_set(Goal, OrdGoal), P = problem(Name, DomName, A1, OrdObjects, OrdInit, OrdGoal, A2, A3, A4). show_information:- % Use the global variables to print useful information get_objects(Objects), get_goal(Goal), get_init(InitialState), get_actions(ActionSchemas), print('Objects in the domain: \n'), print(Objects), nl,nl, print('Initial State: \n'), print(InitialState), nl,nl, print('Goal State: \n'), print(Goal), nl,nl, print('Action schemas: \n'), print(ActionSchemas), nl,nl, flush_output. get_goal(G):- bb_get(goalState, G). get_init(I):- bb_get(initState, I). get_actions(A):- bb_get(actions, A). get_objects(O):- bb_get(objects, O). get_problem_name(Name):- bb_get(problemName, Name). get_domain_name(Name):- bb_get(domainName, Name). satisfies_goal(S):- get_goal(G), ord_subset(G, S). progress(State, GroundAction, NewState):- get_action(ActionSchema, GroundAction), get_precondition(ActionSchema, P), % The preconditions of the action should be satisfied in State mysubset(P, State), get_negativ_effect(ActionSchema, NE), ord_subtract(State, NE, State2), get_positiv_effect(ActionSchema, PE), ord_union(State2, PE, NewState). h(S,E):- bb_get(goalState, G), ord_subtract(G,S,T), length(T,E). % mysubset(+Subset, +Set) % It is similar to subset/2. Subset can include free variables that are % grounded with atoms of Set. mysubset([], _). mysubset([X|R], S):- member(X, S), mysubset(R, S). % Collection of shortcut functions. % get(+Structure, -Parameter) get_actions( domain(_, _, _, _, _, _, _, A), A). get_domain_name( domain(N, _, _, _, _, _, _, _), N). get_problem_name( problem(N, _, _, _, _, _, _, _, _), N). get_init( problem(_, _, _, _, I, _, _, _, _), I). get_goal( problem(_, _, _, _, _, G, _, _, _), G). get_metric( problem(_, _, _, _, _, _, _, M, _), M). get_objects( problem(_, _, _, O, _, _, _, _, _), O). get_precondition( action(_, _, P, _, _, _), P). get_positiv_effect( action(_, _, _, PE, _, _), PE). get_negativ_effect( action(_, _, _, _, NE, _), NE). get_assign_effect( action(_, _, _, _, _, AE), AE). get_parameters( action(_, P, _, _, _, _), P). get_action_def( action(Name, Params, _, _, _, _), F):- untype(Params, UP), F =.. [Name|UP]. % get_action(-Action, -ActionDef) get_action(A):- get_action(A, _). get_action(A, ActionDef):- bb_get(actions, As), member(Afree, As), copy_term_spec(Afree, A), % A =.. [_, Name, Params|_], get_action_def(A, ActionDef). %untype(LitOfParams, UntyperList). untype([], []). untype([H|T], [U|Us]):- compound(H), H =.. [_T, [U]], !, untype(T, Us). untype([H|T], [H|Us]):- untype(T, Us). %setInit(+Init, -State) setInit([], []). setInit([set(F, V)|Ls], S):- F =.. A, concat_atom(A, '-', CA), bb_put(CA, V), % write(CA),write(' '), write(V), nl, setInit(Ls, S), !. setInit([A|Ls], [A|Ss]):- setInit(Ls, Ss). % concat_atom(+List, +Delimiter, -ConcatenateAtom) concat_atom([E1, E2], D, O):- atom_concat(E1, D, Temp), atom_concat(Temp, E2, O). concat_atom([H|T], D, O):- concat_atom(T, D, Ts), atom_concat(H, D, Temp), atom_concat(Temp, Ts, O). % Special version of copy_term. variable x represented as ?(x) % All occurs of ?(x) are replaced with real prolog variables. % Modified version of code published by Bartak: http://kti.mff.cuni.cz/~bartak/prolog/data_struct.html copy_term_spec(A,B):- cp(A,[],B,_). cp(A,Vars,A,Vars):- atomic(A), A\= ?(_). cp(?(V),Vars,NV,NVars):- atomic(V), register_var(V,Vars,NV,NVars). cp(V,Vars,NV,NVars):- var(V),register_var(V,Vars,NV,NVars). cp(Term,Vars,NTerm,NVars):- compound(Term), Term \= ?(_), Term=..[F|Args], % decompose term cp_args(Args,Vars,NArgs,NVars), NTerm=..[F|NArgs]. % construct copy term cp_args([H|T],Vars,[NH|NT],NVars):- cp(H,Vars,NH,SVars), cp_args(T,SVars,NT,NVars). cp_args([],Vars,[],Vars). % During copying one has to remeber copies of variables which can be used further during copying. % Therefore the register of variable copies is maintained. register_var(V,[X/H|T],N,[X/H|NT]):- V\==X, % different variables register_var(V,T,N,NT). register_var(V,[X/H|T],H,[X/H|T]):- V==X. % same variables register_var(V,[],N,[V/N]). %minOfList(+List, -MaxiamlItem) %Find minimum value of the list minOfList([X|Xs], Min):- minOfList(Xs, X, Min). minOfList([], Min, Min). minOfList([X|Xs], Min0, Min):- ( X @< Min0 -> Min1 = X ; Min1 = Min0 ), minOfList(Xs, Min1, Min). reset_statistic:- bb_put(stat_nodes, 0), statistics(runtime, [T,_]), bb_put(startTime, T). show_statistic:- bb_get(stat_nodes, N), bb_get(startTime, T0), statistics(runtime, [T1,_]), statistics(memory, [M, _]), T is T1-T0, format('~3d sec ~d nodes ~d bytes~n', [T, N, M]),nl. %show_statistic(+Problem, +Solution). show_statistic(S):- ground(S), get_domain_name(DomainName), get_problem_name(ProblemName), bb_get(stat_nodes, N), bb_get(startTime, T0), statistics(runtime, [T1,_]), %statistics(memory, [M, _]), T is T1-T0, length(S, L), %format('~a ~3d ~d ~d ~d', [Name,T, N, M, L]),nl, format('Domain name: ~a \n',[DomainName]), format('Problem name: ~a \n',[ProblemName]), format('Time: ~3d sec\n',[T]), format('Search length: ~d nodes\n',[N]), %format('Memory use: ~3d KBytes\n', [M]), format('Solution length: ~d actions\n', [L]), print('Solution: '), solution_to_lisp(S), nl, !. show_statistic(_, _). solution_to_lisp([]). solution_to_lisp([H|T]):- H =.. [F|P], write(' ('), write(F), write_list(P), write(')'), solution_to_lisp(T). write_list([]). write_list([H|T]):- write(' '), write(H), write_list(T). stat_node:- bb_get(stat_nodes, N), NN is N+1, bb_update(stat_nodes, _, NN). space(0):-!. space(I):- write(' '), NI is I-1, space(NI). writel([]):-nl. writel([H|T]):- write(H),nl, writel(T). w(X):- var(X), domain(X, D, F),!, write(X=D-F). w(X):- var(X),!, write(X). w(X):- atomic(X),!, write(X). w([H|T]):- write('['), !, w_list([H|T]), write(']'). w(X):- compound(X),!, X=..[F|L], write(F),write('('), w_params(L), write(')'). w_params([H]):- w(H). w_params([H,H2|T]):- w(H),write(','), w_params([H2|T]). w_list([H]):- w(H), !. w_list([H|T]):- w(H), write(','), w_list(T). %state_record(State, PreviousState, Action, Deep, StateRecord) state_record(S, PS, A, D, [S, PS, A, D]). %solution(+StateRecord, +Visited, -ListOfActions) solution(SR, V, L):- solution(SR, V, [], L). solution(SR, _, L, L):- state_record(_, nil, nil, _, SR), !. solution(SR, V, R, L):- state_record(_, PS, AD, _, SR), state_record(PS, _, _, _, Previous), member(Previous, V), solution(Previous, V, [AD|R], L).