/* GPS utils in Picat. Here are predicates for a GPS (General Problem Solver) like planner, or perhaps it should be called a STRIPS like planner since it support more stuff than GPS originally did. - pre(L,Xs): preconditions All elements in Xs must be in the list L. This can be used in final/1. - pre_neg(L,Xs): negative preconditions None of the element is Xs must be in the list L. - del(L,Xs): delete clause Delete all elements in Xs from L - add(L,Xs): add clause Add all elements in Xs to L. Notes: - the calling programm must define these two predicates * action/4: for the planner module) * a final/1: for defining the goal state - this program use the ordset module so one have to ensure that the lists are sorted. In gps_*_plan this is done by creating Init as an ordset (with new_ordset/1). This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ module gps_utils. % import util. import planner. import ordset. % % precondition: all elements in Xs must be in L pre(L,Xs) => foreach(P in Xs) member(P, L) end. % pre(L,Xs) => subset(Xs,L). % negative preconditions pre_neg(L,Xs) => foreach(P in Xs) not member(P, L) end. final_check(L,Xs) => subset(Xs.new_ordset(),L). % % delete all occurrences of Xs (a list) in L % % del(L, X) = L2 => % L2 = L, % foreach(E in X) % L2 := delete_all(L2,E) % end. del(L,Xs) = subtract(L,Xs.new_ordset()). % % add elements of list Xs to L. % % add(L, Xs) = L2 => % L1 = L, % foreach(E in Xs) % if not member(E,L1) then % L1 := L1 ++ [E] % end % end, % L2 = L1. add(L,Xs) = union(L,Xs.new_ordset()). gps_best_plan(Init) => println(init_state=Init), best_plan(Init.new_ordset(), Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_best_plan(Init,Limit) => println(init_state=Init), best_plan(Init.new_ordset(), Limit, Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_plan(Init) => println(init_state=Init), plan(Init.new_ordset(), Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_plan(Init,Limit) => println(init_state=Init), plan(Init.new_ordset(), Limit,Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_best_plan_downward(Init) => println(init_state=Init), best_plan(Init.new_ordset(), Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_best_plan_downward(Init,Limit) => println(init_state=Init), best_plan(Init.new_ordset(), Limit,Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_best_plan_bb(Init) => println(init_state=Init), best_plan_bb(Init.new_ordset(), Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_best_plan_bb(Init,Limit) => println(init_state=Init), best_plan_bb(Init.new_ordset(), Limit,Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. gps_best_plan_unbounded(Init) => println(init_state=Init), best_plan_bb(Init.new_ordset(), Plan), foreach(Move in Plan) println(move=Move) end, println(len=Plan.length), nl. % % ensure that all goals in final2/1 are in the list L. % % final(L) => % final2(Final2), % pre(L,Final2), % writeln(final=L). %