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