If the user has defined the above procedures they can be given to the following general problem solver. It takes six arguments and produces a result which is the goal state if one is found and otherwise the value FALSE.
The first argument is a representation of the initial state. The second is a representation of the goal to be achieved. The next four arguments are procedures, which are the users versions of the four procedures listed above: the goal recogniser, the procedure for generating new states from old ones, the state equivalence recogniser, and the procedure to insert a new state into a list of states.
Here is one of many ways to define such a problem solver:
define solve_problem
(initial, current_goal, isgoal, nextstates, samestate, insert)
-> result;
lvars
initial, ;;; the initial state
current_goal, ;;; the second argument for isgoal
;;; four procedures defining the problem and a strategy
procedure (isgoal, nextstates, samestate, insert),
result;
lvars
alternatives = [^initial], ;;; the list of alternative states
history = [] ; ;;; the list of previous states
vars current_state, rest; ;;; use "vars" for pattern variables
repeat
if null(alternatives) then
;;; failed
false -> result;
return();
else
alternatives --> [?current_state ??rest];
rest -> alternatives;
;;; Check if current_state is a goal state
if isgoal(current_state, current_goal) then
;;; problem solved
current_state -> result;
return();
else
;;; Keep a history list, avoid circles
[ ^current_state ^^history ] -> history;
;;; generate successor states to current_state
lvars states;
nextstates(current_state) -> states;
;;; put all the "new" states onto the alternatives list
lvars state;
for state in states do
unless is_in_list(state, history, samestate) then
insert(state, alternatives) -> alternatives
endunless;
endfor;
;;; now go back to the beginning of the repeat loop
endif
endif
endrepeat
enddefine;