1:- module(rsasak_pddl_parser,[parseProblem/3,parseDomain/3]). 2
3:- style_check(-singleton). 4
5:- use_module(library(prolog_pack)). 6:- if( \+ prolog_pack:current_pack(planner_api)). 7:- dynamic user:file_search_path/2. 8:- multifile user:file_search_path/2. 9:- prolog_load_context(directory,Dir),
10 DirFor = planner,
11 (( \+ user:file_search_path(DirFor,Dir)) ->asserta(user:file_search_path(DirFor,Dir));true),
12 absolute_file_name('../..',Y,[relative_to(Dir),file_type(directory)]),
13 (( \+ user:file_search_path(pack,Y)) ->asserta(user:file_search_path(pack,Y));true). 14:- attach_packs. 15:- initialization(attach_packs). 16:- endif. 17
18
19:- if( \+ user:file_search_path(pddl,_) ). 20:- prolog_load_context(directory,Dir),
21 must((absolute_file_name('../pddl',Y,[relative_to(Dir),file_type(directory)]),
22 asserta(user:file_search_path(pddl,Y)))). 23:- endif. 24
25
26:- meta_predicate emptyOr(//,?,?). 27
54read_file(File, Words) :- seeing(Old), see(File), get_code(C), read_rest(C, Words), seen, see(Old).
55
57read_rest(-1,[]) :- !.
58
60read_rest(C,Words) :- ( C=32 ; C=10 ; C=9 ; C=13 ; C=92 ) , !,
61 get_code(C1),
62 read_rest(C1,Words).
63
65read_rest(C, [Char|Words]) :- ( C=40 ; C=41 ; C=44 ; C=45 ; C=46 ; C=63 ; C=58 ) , name(Char, [C]), !,
66 get_code(C1),
67 read_rest(C1, Words).
68
70read_rest(59, Words) :- get_code(Next), !,
71 read_comment(Next, Last),
72 read_rest(Last, Words).
73
75read_rest(C,[Word|Words]) :- read_word(C,Chars,Next),
76 name(Word,Chars),
77 read_rest(Next,Words).
78
80read_word(C,[],C) :- ( C=32 ; C=44 ; C=10 ; C=9 ; C=13 ;
81 C=46 ; C=63 ; C=40 ; C=41 ; C=58 ; C= -1 ) , !.
82
84read_word(C,[LC|Chars],Last) :- lower_case(C, LC),
85 get_code(Next),
86 read_word(Next,Chars,Last).
87
89lower_case(C,C) :- ( C < 65 ; C > 90 ) , !.
90lower_case(C,LC) :- LC is C + 32.
91
92
(10, 10) :- !.
95read_comment(-1, -1) :- !.
96read_comment(_, Last) :- get_code(Next),
97 read_comment(Next, Last).
98
100
108
109
110
137
138
141parseDomain(F, O):- parseDomain(F, O, _).
144parseDomain(File, Output, R) :-
145 read_file(File, List),
146 domainBNF(Output, List, R).
147
150
152:-op(300, fy, ?). 153
158domainBNF(domain(N, R, T, C, P, F, C, S))
159 --> ['(','define', '(','domain'], name(N), [')'],
160 (require_def(R) ; []),
161 (types_def(T) ; []), 162 (constants_def(C) ; []),
163 (predicates_def(P) ; []),
164 (functions_def(F) ; []), 166 zeroOrMore(structure_def, S),
167 [')'].
168
169require_def(R) --> ['(',':','requirements'], oneOrMore(require_key, R), [')'].
170require_key(strips) --> [':strips'].
171require_key(typing) --> [':typing'].
174require_key(equality) --> [':equality'].
175require_key('existential-preconditions') --> [':existential-preconditions'].
176require_key('universal-preconditions') --> [':universal-preconditions'].
177require_key('quantified-preconditions') --> [':quantified-preconditions'].
178require_key('conditional-effects') --> [':conditional-effects'].
179require_key(fluents) --> [':fluents'].
180require_key(adl) --> [':adl'].
181require_key('durative-actions') --> [':durative-actions'].
182require_key('derived-predicates') --> [':derived-predicates'].
183require_key('timed-initial-literals') --> [':timed-initial-literals'].
184require_key(preferences) --> [':preferences'].
185require_key(constraints) --> [':constraints'].
187require_key(R) --> [':', R].
188
189types_def(L) --> ['(',':',types], typed_list(name, L), [')'].
190constants_def(L) --> ['(',':',constants], typed_list(name, L), [')'].
191predicates_def(P) --> ['(',':',predicates], oneOrMore(atomic_formula_skeleton, P), [')'].
192
193atomic_formula_skeleton(F)
194 --> ['('], predicate(P), typed_list(variable, L), [')'], {F =.. [P|L]}.
195predicate(P) --> name(P).
196
197variable(V) --> ['?'], name(N), {V =.. [?, N]}.
198atomic_function_skeleton(f(S, L))
199 --> ['('], function_symbol(S), typed_list(variable, L), [')'].
200function_symbol(S) --> name(S).
201functions_def(F) --> ['(',':',functions], function_typed_list(atomic_function_skeleton, F), [')']. 203structure_def(A) --> action_def(A).
207typed_list(W, [G|Ns]) --> oneOrMore(W, N), ['-'], type(T), !, typed_list(W, Ns), {G =.. [T,N]}.
208typed_list(W, N) --> zeroOrMore(W, N).
209
210primitive_type(N) --> name(N).
211type(either(PT)) --> ['(',either], !, oneOrMore(primitive_type, PT), [')'].
212type(PT) --> primitive_type(PT).
213function_typed_list(W, [F|Ls])
214 --> oneOrMore(W, L), ['-'], !, function_type(T), function_typed_list(W, Ls), {F =.. [T|L]}. 215function_typed_list(W, L) --> zeroOrMore(W, L).
216
217function_type(number) --> [number].
218
219emptyOr(_) --> ['(',')'].
220emptyOr(W) --> W.
221
223action_def(action(S, L, Precon, Pos, Neg, Assign))
224 --> ['(',':',action], action_symbol(S),
225 [':',parameters,'('], typed_list(variable, L), [')'],
226 action_def_body(Precon, Pos, Neg, Assign),
227 [')'].
228action_symbol(N) --> name(N).
229action_def_body(P, Pos, Neg, Assign)
230 --> (([':',precondition], emptyOr(pre_GD(P))) ; []),
231 (([':',effect], emptyOr(effect(Pos, Neg, Assign))) ; []).
232pre_GD([F]) --> atomic_formula(term, F), !.
233pre_GD(P) --> pref_GD(P).
234pre_GD(P) --> ['(',and], pre_GD(P), [')'].
237pref_GD(P) --> gd(P).
238pref_name(N) --> name(N).
239gd(F) --> atomic_formula(term, F). 241gd(P) --> ['(',and], zeroOrMore(gd, P), [')'].
247gd(F) --> f_comp(F). 248f_comp(compare(C, E1, E2)) --> ['('], binary_comp(C), f_exp(E1), f_exp(E2), [')'].
249literal(T, F) --> atomic_formula(T, F).
250literal(T, not(F)) --> ['(',not], atomic_formula(T, F), [')'].
251atomic_formula(_, F) --> ['('], predicate(P), zeroOrMore(term, T), [')'], {F =.. [P|T]}. 252
253
254term(N) --> name(N).
255term(V) --> variable(V).
256f_exp(N) --> number(N).
257f_exp(op(O, E1, E2)) --> ['('],binary_op(O), f_exp(E1), f_exp(E2), [')'].
258f_exp('-'(E)) --> ['(','-'], f_exp(E), [')'].
259f_exp(H) --> f_head(H).
260f_head(F) --> ['('], function_symbol(S), zeroOrMore(term, T), [')'], { F =.. [S|T] }.
261f_head(S) --> function_symbol(S).
262binary_op(O) --> multi_op(O).
263binary_op(45) --> [45]. 264binary_op('/') --> ['/'].
265multi_op('*') --> ['*'].
266multi_op('+') --> ['+'].
267binary_comp('>') --> ['>'].
268binary_comp('<') --> ['<'].
269binary_comp('=') --> ['='].
270binary_comp('>=') --> ['>='].
271binary_comp('<=') --> ['<='].
272number(N) --> [N], {integer(N)}.
273number(N) --> [N], {float(N)}.
274effect(P, N, A) --> ['(',and], c_effect(P, N, A), [')'].
275effect(P, N, A) --> c_effect(P, N, A).
278c_effect(P, N, A) --> p_effect(P, N, A).
279p_effect([], [], []) --> [].
280p_effect(Ps, Ns, [F|As])
281 --> ['('], assign_op(O), f_head(H), f_exp(E), [')'], p_effect(Ps, Ns, As), {F =.. [O, H, E]}.
282p_effect(Ps, [F|Ns], As) --> ['(',not], atomic_formula(term,F), [')'], p_effect(Ps, Ns, As).
283p_effect([F|Ps], Ns, As) --> atomic_formula(term, F), p_effect(Ps, Ns, As).
287assign_op(assign) --> [assign].
288assign_op(scale_up) --> [scale_up].
289assign_op(scale_down) --> [scale_down].
290assign_op(increase) --> [increase].
291assign_op(decrease) --> [decrease].
292
293
296oneOrMore(W, [R|Rs], A, C) :- F =.. [W, R, A, B], F, (
297 oneOrMore(W, Rs, B, C) ;
298 (Rs = [] , C = B)
299 ).
301zeroOrMore(W, R) --> oneOrMore(W, R).
302zeroOrMore(_, []) --> [].
303
306name(N) --> [N], {integer(N), !, fail}.
307name(N) --> [N], {float(N), !, fail}.
308name(N) --> [N], {N=')', !, fail}.
309name(N) --> [N], {N='(', !, fail}.
310name(N) --> [N], {N='?', !, fail}.
311name(N) --> [N], {N='-', !, fail}.
312name(N) --> [N].
313
314
315
336:-catch(guitracer,E,writeq(E)),nl. 337
340parseProblem(F, O):-parseProblem(F, O, _).
341
344parseProblem(F, O, R) :-
345 read_file(F, L),
346 problem(O, L, R).
347
350
351
352
359problem(problem(Name, Domain, R, OD, I, G, _, MS, LS))
360 --> ['(',define,'(',problem,Name,')',
361 '(',':',domain, Domain,')'],
362 (require_def(R) ; []),
363 (object_declaration(OD) ; []),
364 init(I),
365 goal(G),
367 (metric_spec(MS) ; []),
368 (length_spec(LS) ; []),
369 [')'].
370
371object_declaration(L) --> ['(',':',objects], typed_list_as_list(name, L),[')'].
372
373typed_list_as_list(W, [G|Ns]) --> oneOrMore(W, N), ['-'], type(T), !, typed_list_as_list(W, Ns), {G =.. [T,N]}.
374typed_list_as_list(W, N) --> zeroOrMore(W, N).
375
376
377
378init(I) --> ['(',':',init], zeroOrMore(init_el, I), [')'].
379
380init_el(I) --> literal(name, I).
381init_el(set(H,N)) --> ['(','='], f_head(H), number(N), [')']. 382init_el(at(N, L)) --> ['(',at], number(N), literal(name, L), [')']. 383goal(G) --> ['(',':',goal], pre_GD(G),[')'].
385pref_con_GD(and(P)) --> ['(',and], zeroOrMore(pref_con_GD, P), [')'].
388pref_con_GD(P) --> con_GD(P).
389
390con_GD(and(L)) --> ['(',and], zeroOrMore(con_GD, L), [')'].
391con_GD(forall(L, P)) --> ['(',forall,'('], typed_list(variable, L),[')'], con_GD(P), [')'].
392con_GD(at_end(P)) --> ['(',at,end], gd(P), [')'].
393con_GD(always(P)) --> ['(',always], gd(P), [')'].
394con_GD(sometime(P)) --> ['(',sometime], gd(P), [')'].
395con_GD(within(N, P)) --> ['(',within], number(N), gd(P), [')'].
396
397con_GD(at_most_once(P)) --> ['(','at-most-once'], gd(P),[')'].
398con_GD(some_time_after(P1, P2)) --> ['(','sometime-after'], gd(P1), gd(P2), [')'].
399con_GD(some_time_before(P1, P2))--> ['(','sometime-before'], gd(P1), gd(P2), [')'].
400con_GD(always_within(N, P1, P2))--> ['(','always-within'], number(N), gd(P1), gd(P2), [')'].
401con_GD(hold_during(N1, N2, P)) --> ['(','hold-during'], number(N1), number(N2), gd(P), [')'].
402con_GD(hold_after(N, P)) --> ['(','hold-after'], number(N), gd(P),[')'].
403
404metric_spec(metric(O, E)) --> ['(',':',metric], optimization(O), metric_f_exp(E), [')'].
405
406optimization(minimize) --> [minimize].
407optimization(maximize) --> [maximize].
408
409metric_f_exp(E) --> ['('], binary_op(O), metric_f_exp(E1), metric_f_exp(E2), [')'], {E =..[O, E1, E2]}.
410metric_f_exp(multi_op(O,[E1|E]))--> ['('], multi_op(O), metric_f_exp(E1), oneOrMore(metric_f_exp, E), [')']. 411metric_f_exp(E) --> ['(','-'], metric_f_exp(E1), [')'], {E=..[-, E1]}.
412metric_f_exp(N) --> number(N).
413metric_f_exp(F) --> ['('], function_symbol(S), zeroOrMore(name, Ns), [')'], { F=..[S|Ns]}. 414metric_f_exp(function(S)) --> function_symbol(S).
415metric_f_exp(total_time) --> ['total-time'].
416metric_f_exp(is_violated(N)) --> ['(','is-violated'], pref_name(N), [')'].
417
419length_spec([]) --> [not_defined].