1:-module(rsasak_forward_wa_star_h_add,[]).
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:- expects_dialect(sicstus).
27:-use_module(library(timeout)).
28:-use_module(library(lists)).
29:-use_module(library(rsasak_pddl_parser)).
52
53pairfrom([Element1|Set], Element1, Element2, Residue) :-
54 select_20_faster(Element2, Set, Residue).
55pairfrom([Head|Tail], Element1, Element2, [Head|Rest]) :-
56 pairfrom(Tail, Element1, Element2, Rest).
57
58
59
63
64select_20_faster(X, [X|R], R ).
65select_20_faster(X, [A,X|R], [A|R] ).
66select_20_faster(X, [A,B,X|R], [A,B|R] ).
67select_20_faster(X, [A,B,C|L], [A,B,C|R]) :-
68 select_20_faster(X, L, R).
69
77
79
83command_line:-
84 prolog_flag(argv, [D,P]),
85 solve_files(D, P),
86 halt.
87
88
89
94
130
132
134solve_files(DomainFile, ProblemFile):-
135 parseDomain(DomainFile, DD, _),
136 parseProblem(ProblemFile, PP, _),
137 term_to_ord_term(DD, D),
138 term_to_ord_term(PP, P),
139 reset_statistic,
140 !,
141 time_out(solve(D, P, S), 500000, _Result), 142 show_statistic(P, S),
143 !.
144
145
146
149solve(D, P, Solution):-
150 get_init(P, I), bb_put(initState, I),
151 get_goal(P, G), bb_put(goalState, G),
152 get_metric(P, M), bb_put(metric, M),
153 get_actions(D, A), bb_put(actions, A),
154 get_objects(P, O), bb_put(objects, O),
155 make_init_state(IS),
156 search(IS, G, Solution).
157
158
162term_to_ord_term([], []).
163term_to_ord_term(A, A):-atomic(A), !.
164term_to_ord_term([H|T], R):-
165 term_to_ord_term(H, OH),
166 term_to_ord_term(T, OT),
167 ord_add_element(OT, OH, R), !.
169term_to_ord_term(T, OT):-
170 T =.. [F,P], !,
171 term_to_ord_term(P, OP),
172 OT =..[F,OP].
173term_to_ord_term(T, OT):-
174 T =.. [F,P|Ps],
175 NT=.. [F|Ps],
176 term_to_ord_term(P, OP),
177 term_to_ord_term(NT, ONT),
178 ONT =.. [_|OPs],
179 OT =.. [F,OP|OPs], !.
180
181
182
186mysubset([], _).
187mysubset([X|R], S):- member(X, S), mysubset(R, S).
188
189
190
193get_actions( domain(_, _, _, _, _, _, _, A), A).
194get_problem_name( problem(N, _, _, _, _, _, _, _, _), N).
195get_init( problem(_, _, _, _, I, _, _, _, _), I).
196get_goal( problem(_, _, _, _, _, G, _, _, _), G).
197get_metric( problem(_, _, _, _, _, _, _, M, _), M).
198get_objects( problem(_, _, _, O, _, _, _, _, _), O).
199get_precondition( action(_, _, P, _, _, _), P).
200get_positiv_effect( action(_, _, _, PE, _, _), PE).
201get_negativ_effect( action(_, _, _, _, NE, _), NE).
202get_assign_effect( action(_, _, _, _, _, AE), AE).
203get_parameters( action(_, P, _, _, _, _), P).
204get_action_def( action(Name, Params, _, _, _, _), F):-
205 untype(Params, UP),
206 F =.. [Name|UP].
207
208
210get_action(A):-
211 get_action(A, _).
212get_action(A, ActionDef):-
213 bb_get(actions, As),
214 member(Afree, As),
215 copy_term_spec(Afree, A),
217 get_action_def(A, ActionDef).
218
219
220get_goal(G):-bb_get(goalState, G).
221get_init(I):-bb_get(initState, I).
222
224untype([], []).
225untype([H|T], [U|Us]):- compound(H), H =.. [_T, [U]], !, untype(T, Us).
226untype([H|T], [H|Us]):- untype(T, Us).
227
229setInit([], []).
230setInit([set(F, V)|Ls], S):-
231 F =.. A,
232 concat_atom(A, '-', CA),
233 bb_put(CA, V),
235 setInit(Ls, S), !.
236setInit([A|Ls], [A|Ss]):-
237 setInit(Ls, Ss).
238
240concat_atom([E1, E2], D, O):-
241 atom_concat(E1, D, Temp),
242 atom_concat(Temp, E2, O).
243concat_atom([H|T], D, O):-
244 concat_atom(T, D, Ts),
245 atom_concat(H, D, Temp),
246 atom_concat(Temp, Ts, O).
247
248
252copy_term_spec(A,B):- cp(A,[],B,_).
253
254cp(A,Vars,A,Vars):- atomic(A), A\= ?(_).
255cp(?(V),Vars,NV,NVars):- atomic(V), register_var(V,Vars,NV,NVars).
256cp(V,Vars,NV,NVars):- var(V),register_var(V,Vars,NV,NVars).
257
258cp(Term,Vars,NTerm,NVars):-
259 compound(Term),
260 Term \= ?(_),
261 Term=..[F|Args], 262 cp_args(Args,Vars,NArgs,NVars),
263 NTerm=..[F|NArgs]. 264cp_args([H|T],Vars,[NH|NT],NVars):- cp(H,Vars,NH,SVars),
265cp_args(T,SVars,NT,NVars).
266cp_args([],Vars,[],Vars).
267
270register_var(V,[X/H|T],N,[X/H|NT]):-
271 V\==X, 272 register_var(V,T,N,NT).
273register_var(V,[X/H|T],H,[X/H|T]):-
274 V==X. 275register_var(V,[],N,[V/N]).
276
277
278
281minOfList([X|Xs], Min):-
282 minOfList(Xs, X, Min).
283minOfList([], Min, Min).
284minOfList([X|Xs], Min0, Min):-
285 ( X @< Min0 -> Min1 = X ; Min1 = Min0 ),
286 minOfList(Xs, Min1, Min).
287
288
289
290reset_statistic:-
291 bb_put(stat_nodes, 0),
292 statistics(runtime, [T,_]),
293 bb_put(startTime, T).
294
295show_statistic:-
296 bb_get(stat_nodes, N),
297 bb_get(startTime, T0),
298 statistics(runtime, [T1,_]),
299 statistics(memory, [M, _]),
300 T is T1-T0,
301 format('~3d sec ~d nodes ~d bytes~n', [T, N, M]).
302
304show_statistic(P, S):-
305 ground(S),
306 get_problem_name(P, Name),
307 bb_get(stat_nodes, N),
308 bb_get(startTime, T0),
309 statistics(runtime, [T1,_]),
310 statistics(memory, [M, _]),
311 T is T1-T0,
312 length(S, L),
313 format('~a ~3d ~d ~d ~d', [Name,T, N, M, L]),
314 solution_to_lisp(S),
315 nl, !.
316show_statistic(_, _).
317
318solution_to_lisp([]).
319solution_to_lisp([H|T]):-
320 H =.. [F|P],
321 write(' ('),
322 write(F),
323 write_list(P),
324 write(')'),
325 solution_to_lisp(T).
326
327write_list([]).
328write_list([H|T]):-
329 write(' '), write(H),
330 write_list(T).
331
332
333stat_node:-
334 bb_get(stat_nodes, N),
335 NN is N+1,
336 bb_update(stat_nodes, _, NN).
337
338
339
340space(0):-!.
341space(I):-
342 write(' '),
343 NI is I-1,
344 space(NI).
345
346writel([]):-nl.
347writel([H|T]):-
348 write(H),nl,
349 writel(T).
350
351w(X):-
352 attvar(X),
353 354 get_attrs(X,Attrs),!,write(=(X,Attrs)).
355
356w(X):-
357 var(X),!,
358 write(X).
359
360w(X):-
361 atomic(X),!,
362 write(X).
363w([H|T]):-
364 write('['), !,
365 w_list([H|T]),
366 write(']').
367w(X):-
368 compound(X),!,
369 X=..[F|L],
370 write(F),write('('),
371 w_params(L),
372 write(')').
373w_params([H]):-
374 w(H).
375w_params([H,H2|T]):-
376 w(H),write(','),
377 w_params([H2|T]).
378w_list([H]):-
379 w(H), !.
380w_list([H|T]):-
381 w(H),
382 write(','),
383 w_list(T).
384
386state_record(S, PS, A, D, [S, PS, A, D]).
387
389solution(SR, V, L):-
390 solution(SR, V, [], L).
391solution(SR, _, L, L):-
392 state_record(_, nil, nil, _, SR), !.
393solution(SR, V, R, L):-
394 state_record(_, PS, AD, _, SR),
395 state_record(PS, _, _, _, Previous),
396 member(Previous, V),
397 solution(Previous, V, [AD|R], L).
398
399
400
403
404 make_mutex(M):-
405 bagof(R1, forbiden_pair(R1), MA),
406 bagof(R2, forbiden_pair(MA, R2), MB),
409 union(MA, MB, M0),
412 clear_mutex1(M0, M1),
413 clear_mutex2(M1, M2),
414 clear_duplicates(M2, M).
415 416
417clear_duplicates([], []).
418clear_duplicates([H|T], R):-
419 member(M, T),
420 identical_but_for_variables(H, M),
421 !,
422 clear_duplicates(T, R).
423clear_duplicates([H|T], [H|R]):-
424 clear_duplicates(T, R).
425
426forbiden_pair(R):-
427 get_action(A),
428 get_positiv_effect(A, PE),
429 get_negativ_effect(A, NE),
430 member(P, PE),
431 member(Q, NE),
432 copy_term_spec(P-Q, R).
433forbiden_pair(MA, NR):-
434 member(P-Q, MA),
435 get_action(A),
436 get_precondition(A, Precond),
437 get_positiv_effect(A, PE),
438 member(R, Precond),
439 member(P, PE),
440 copy_term_spec(R-Q, NR).
441
442clear_mutex1([], []):-!.
443clear_mutex1([PP-QQ|T], M):-
444 (P-Q = PP-QQ ; P-Q = QQ-PP),
445 get_init(I),
446 select_20_faster(P, I, R),
447 member(Q, R),
449 clear_mutex1(T, M), !.
450clear_mutex1([P-Q|R], [P-Q|M]):-
451 clear_mutex1(R, M).
452
453clear_mutex2(M0, M):-
454 (select_20_faster(P-Q, M0, R) ; select_20_faster(Q-P, M0, R)),
455 get_action(A, _Def), get_precondition(A, Precond), get_positiv_effect(A, PE), get_negativ_effect(A, NE),
456 select_20_faster(P, PE, RPE),
457 \+ member(Q, NE),
458 (
459 member(Q, RPE) 460 ;
461 all_not_in(Precond, P, Q, M0) 462 ),
464
465 clear_mutex2(R, M), !.
466clear_mutex2(M0, M0).
467
468all_not_in([], _, _, _).
469all_not_in([P|T], P, Q, M):-
470 all_not_in(T, P, Q, M).
471all_not_in([R|T], P, Q, M):-
472 \+ (member(R-Q, M) ; member(Q-R, M)),
473 474 all_not_in(T, P, Q, M).
475
476
477
479check_mutex(S):-
480 bb_get(mutex, M),
481 pairfrom(S, P, Q, _),
482 (member(P-Q, M) ; member(Q-P, M)),
484 !, fail.
485check_mutex(_).
486
487
488identical_but_for_variables(X, Y) :-
489 \+ \+ (
490 copy_term(X, Z),
491 numbervars(Z, 0, N),
492 numbervars(Y, 0, N),
493 Z = Y
494 ). 499:- expects_dialect(sicstus).
500:-use_module(library(ordsets)).
501:-use_module(library(heaps)).
502
504search(I, _, Solution):-
505 a_star(I, Solution, _).
506
507
509a_star(S, A, C):-
510 state_record(S, nil, nil, 0, SR),
511 list_to_heap([0-SR], PQ),
512 a_star(PQ, [], A, C).
513
514
516a_star(PQ, _, 'NO SOLUTION', _):-
517 empty_heap(PQ),!.
518a_star(PQ, V, Solution, C):-
519 get_from_heap(PQ, C, SR, _),
520 state_record(S, _, _, _, SR),
521 is_goal(S),
525 solution(SR, V, Solution).
526
527a_star(PQ, V, Solution, C):-
528 get_from_heap(PQ, _K, SR, RPQ),
529 ord_add_element(V, SR, NV),
530 (bagof(K-NS, next_node(SR, PQ, NV, K, NS), NextNodes) ; NextNodes=[]),
533
534 add_list_to_heap(RPQ, NextNodes, NPQ),
535
536 stat_node,
537 a_star(NPQ, NV, Solution, C).
538
540next_node(SR, Q, V, E, NewSR):-
541 state_record(S, _, _, D, SR),
542 step(S, A, NewS),
543 state_record(NewS, _, _, _, Temp),
544 \+ my_ord_member(NewS, V),
545 heap_to_list(Q, PQL),
546 \+ member(Temp, PQL),
547 h(S, H),
548 E is 5*H+D,
549 ND is D+1,
550 state_record(NewS, S, A, ND, NewSR).
551
553add_list_to_heap(OH, [], OH).
554add_list_to_heap(OH, [K-D|T], NH):-
555 add_to_heap(OH, K, D, H),
556 add_list_to_heap(H, T, NH).
557
558my_ord_member(S, [SR|_]):-
559 state_record(S2, _, _, _,SR),
560 repeating(S, S2),
561 !.
562my_ord_member(S, [_|T]):-
563 my_ord_member(S, T).
571
572:-use_module(library(ordsets)).
573
574make_init_state(I):-
575 get_init(I),
576 get_goal(G),
577 bb_put(fictiveGoal, G).
578
579
580make_solution(S, S).
581
582step(State, ActionDef, NewState):-
583 get_action(A, ActionDef),
584 get_precondition(A, P), mysubset(P, State), 585 get_negativ_effect(A, NE), ord_subtract(State, NE, State2),
586 get_positiv_effect(A, PE), ord_union(State2, PE, NewState).
587
588is_goal(S):-
589 get_goal(G),
590 ord_subset(G, S).
591
592repeating(S1, S2):-
593 S1 = S2.
594
598
599h(S, E):-h_add(S, E).
603
604h_0(_, 0).
605
606h_diff(S, E):-
607 bb_get(fictiveGoal, G),
608 ord_subtract(G, S, I),
609 length(I, E).
610
611h_add(S, E):-
612 bb_get(fictiveGoal, G),
613 relax(S, G, E).
615
616relax(_, [], 0):-!.
617relax(S, G, E):-
618 subtract(G, S, Delta),
619 setof(P, relax_step(S, P), RS),
620 ord_union([S|RS], NS),
621 relax(NS, Delta, NE),
622 length(Delta, LD),
623 E is LD+NE.
624
625relax_step(State, PE):-
626 get_action(A), get_precondition(A, P),
627 mysubset(P, State),
628 get_positiv_effect(A, PE).
629
630
631
632h_addb([], 0).
633h_addb([H|T], E):-
634 bb_get(predicatesPrices, Ps),
635 member(H-Price, Ps),
636 h(T, Sum),
637 E is Sum + Price.
638
639
641init_heuristics(_):-!.
642init_heuristics_addb(InitState):-
643 relax_addb(InitState, InitState, 0, Ps),
644 bb_put(predicatesPrices, Ps).
645
646relax_addb(_, [], _D, []):-!.
647relax_addb(S, Delta, D, Ps):-
648 mark_by(Delta, D, Marked),
649 setof(P, relax_step(S, P), PE),
650 ord_union([S|PE], NS),
651 ord_subtract(NS, S, NewDelta),
652 ND is D+1,
653 relax_addb(NS, NewDelta, ND, NewPs),
654 ord_union(NewPs, Marked, Ps).
655
656 mark_by([], _, []).
657 mark_by([H|T], D, [H-D|NT]):-
658 mark_by(T, D, NT).
659
660
661
662
675
676command_line_sas:-
677 prolog_flag(argv, [D,P]),!,
678 solve_files(D, P),
679 halt.
680
681command_line_sas:- test_blocks, test_all.
682
683slow_on('blocks-07-0.pddl').
684slow_on('blocks-08-0.pddl').
685slow_on('blocks-09-0.pddl').
686
687min_sas(A,B,A):-A =< B,!.
688min_sas(_,A,A).
689
690
691must_filematch(string(A),string(B)):-!.
692must_filematch(A,B):-must((filematch(A,B))).
693
694
695test_all:-test_all(7).
696
697test_all(N):-
698 must_filematch(('./test/?*?/domain*.pddl'),_),!,
699 (forall(must_filematch(('./test/?*?/domain*.pddl'),E),
700 once(test_domain(E,N)))).
701
702
703test_all(N):-
704 must_filematch(('./test/?*?/domain*.pddl'),_),!,
705 (forall(must_filematch(('./test/?*?/domain*.pddl'),E),
706 once(test_domain(E,N)))).
707
708test_all(N):- expand_file_name(('./test/?*?/domain*.pddl'),RList),RList\=[],!,reverse(RList,List),
709 forall(member(E,List),once(test_domain(E,N))).
710
712
713
714first_n_elements(ListR,Num,List):-length(ListR,PosNum),min_sas(PosNum,Num,MinNum),length(List,MinNum),append(List,_,ListR),!.
715
716test_domain(DP):- t_l:loading_files,!,must(load_domain(DP)).
717test_domain(DP):- test_domain(DP,12).
718
719test_domain(DP,Num):- \+ atom(DP),forall((filematch(DP,FOUND),exists_file(FOUND)),test_domain(FOUND,Num)),!.
720test_domain(DP,Num):- \+ exists_file(DP),!, forall(filematch(DP,MATCH),(exists_file(MATCH),test_domain(MATCH,Num))).
721test_domain(DP,Num):-
722 format('~q.~n',[test_domain(DP)]),
723 directory_file_path(D,_,DP),directory_files(D,RList),reverse(RList,ListR),
724 sort(ListR,ListS),length(ListR,PosNum),min_sas(PosNum,Num,MinNum),length(List,MinNum),append(List,_,ListS),!,
725 forall(member(T,List),ignore((directory_file_path(D,T,TP),exists_file(TP),not(same_file(DP,TP)),
726 solve_files(DP,TP)))).
727
728
742
743load_domain(DP):- \+ atom(DP),forall((filematch(DP,FOUND),exists_file(FOUND)),load_domain(FOUND)),!.
744load_domain(DP):- \+ exists_file(DP),!, forall(filematch(DP,MATCH),((exists_file(MATCH),load_domain(MATCH)))).
745load_domain(DP):-
746 format('~q.~n',[load_domain(DP)]),
747 directory_file_path(D,_,DP),directory_files(D,RList),
748 forall(member(T,RList),ignore((directory_file_path(D,T,TP),exists_file(TP),must(call(call,load_file,TP))))).
749
750
751:-export(z2p/2).
752z2p(A,A).
753
754save_type_named(Type,Named,O):- doall(retract((is_saved_type(Type,Named,_):-_))),nop(ain((is_saved_type(Type,Named,A):-z2p(O,A)))).
755save_sterm(O):-nop((gensym(sterm,Named),save_type_named(sterm,Named,O))).
756
757
758test_blocks:- solve_files(('./test/blocks/domain-blocks.pddl'),
759 ('./test/blocks/blocks-03-0.pddl')), fail.
760test_blocks:- fail, expand_file_name(('./test/blocks/domain*.pddl'),RList),reverse(RList,List),
761 forall(member(E,List),once(test_domain(E))).
762test_blocks:- expand_file_name(('./test/?*?/domain*.pddl'),RList),reverse(RList,List),
763 forall(member(E,List),once(test_domain(E))).
764test_blocks.
765
766
768:-thread_local(t_l:loading_files).
769:-thread_local(t_l:hyhtn_solve/1).
771
772
773
774:- flag(time_used,_,0).
775:- flag(time_used_other,_,0).
776
777probfreecell:- solve_files('../pddl/benchmarks/freecell/domain.pddl', '../pddl/benchmarks/freecell/probfreecell-9-5.pddl').