01 - DFS Water Jug Problem Prolog
01 - DFS Water Jug Problem Prolog
Bb_planner.pl Program:
%% bb_planner.pl
%% 1) goal_state now called with the solution search.
%% (Previously goal was determined prior to search, which is
%% less flexible. Now it can search for several potential goals
%% within a single goal.
%% 2) equivalent_states is now only used by the loop checker, not
%% when testing for goals, so goal_state predicate needs to be
%% true for all acceptable goals.
%% Change: eliminated some retundant backtracking in the 'solution'
% predicate.
:- use_module( library(lists) ).
find_solution :-
initial_state( Initial ),
write( '== Starting Search ==' ), nl,
solution( [[Initial]], StateList ),
length( StateList, Len ),
Transitions is Len -1,
format( '~n** FOUND SOLUTION of length ~p **', [Transitions] ), nl,
showlist( StateList ), !.
%find_solution :-
% write( '!! FAILED: No plan reaches a goal !!' ), nl, fail.
solution( _, _ ) :- !,
write( '!! Cannot extend statelist !!' ), nl,
write( '!! FAILED: No plan reaches a goal !!' ), nl,
fail, !.
%% Check whether State (or some equivalent state) has already been
%% reached in any state list in StateLists.
already_reached( State, StateLists ) :-
member( StateList, StateLists ),
member( State1, StateList ),
equivalent_states( State, State1 ).
% initial_state( SomeState ).
% goal_state( AnotherState ).
% You can tell the planner that some state representations are equivalent.
% equivalent_states( S1, S2 ) :- conditions.
% If all distinct state expressions represent different states, just use:
% equivalent_states( S, S ).
% The equivalent_states predicate is only used when checking if a generated
% state is equivalent to an already reached state, when loopcheck is on.
% You must tell the planner whether to check for and discard repeated states.
% Specify one of:
% loopcheck(off).
% loopcheck(on).
% Eliminating loops can greatly prune the search space.
% But looking for loops can use a lot of processing time, and may not be
% worth doing (especailly if loops cannot occur!).
% To run each time file is loaded, add the following command to the
% the end of your program file.
% :- find_solution.
% This special SWISH comment adds the find_solution query to the examples
% menu under the console window. So you can use that instead when running
% in SWISH. (But you first need to define the initial state, goal state,
% transition relation etc., as explained above
/** <examples>
?- find_solution.
*/
Waterjug.pl Program:
:- include(bb_planner).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% bb_planner Example: A Measuring Jugs Problem
%% Changes: 1) Defined goal muliple possible goal_state options, which now
%% works because of update to bb_planner
%% 2) Simplified and added explanation to the pour/4 predicate.
%%%% Goal: Find a sequence of pouring actions by which you can measure out
%%% 4 litres of water into one of the jugs without spilling any.
% What if I want to share out the water equally between two people?
%%% The state transitions are "pour" operations, where the contents of
%%% one jug is poured into another jug up to the limit of the capacity
%%% of the recipient jug.
%%% There are six possible pour actions from one jug to another:
transition( [_, A1,B1,C], [pour_a_to_b, A2,B2,C] ) :- pour(A1,B1,A2,B2).
transition( [_, A1,B,C1], [pour_a_to_c, A2,B,C2] ) :- pour(A1,C1,A2,C2).
transition( [_, A1,B1,C], [pour_b_to_a, A2,B2,C] ) :- pour(B1,A1,B2,A2).
transition( [_, A,B1,C1], [pour_b_to_c, A,B2,C2] ) :- pour(B1,C1,B2,C2).
transition( [_, A1,B,C1], [pour_c_to_a, A2,B,C2] ) :- pour(C1,A1,C2,A2).
transition( [_, A,B1,C1], [pour_c_to_b, A,B2,C2] ) :- pour(C1,B1,C2,B2).
%% Define the other helper predicates that specify how bb_planner will operate:
legal_state( _ ). % All states that can be reached are legal
equivalent_states( X, X ). % Only identical states are equivalent.
loopcheck(on). % Don't allow search to go into a loop.
% This special comment adds the find_solution query to the examples menu
% under the console window.
/** <examples>
?- find_solution.
*/
Output: