So I am trying to solve the following problem using depth first search approach using prolog
Consider the following problem: Rowena has three unmarked glasses of different sizes: 3 ounces, 5 ounces, and 8 ounces. The largest glass is full. What can Rowena do to get 4 ounces of liquid into each of the larger two glasses?
I did the move states and everything and I used a version of depth first search found online and so far here is the code
%stack
empty_stack([]).
member_stack(E, S) :- member(E, S).
stack(E, S, [E|S]).
go(Start, Goal) :-
empty_stack(Empty_been_list),
stack(Start, Empty_been_list, Been_list),
path(Start, Goal, Been_list).
% path implements a depth first search in PROLOG
% Current state = goal, print out been list
path(Goal, Goal, Been_list) :-
reverse_print_stack(Been_list).
path(State, Goal, Been_list) :-
move(State, Next),
\+ (member_stack(Next, Been_list)),
stack(Next, Been_list, New_been_list),
path(Next, Goal, New_been_list), !.
reverse_print_stack(S) :-
empty_stack(S).
reverse_print_stack(S) :-
stack(E, Rest, S),
reverse_print_stack(Rest),
write(E), nl.
%move rule #1: Pour Large into Medium (L--> M)
%move(oldstate,newstate)
move([L, M, S], [NewLarge,NewMedium,S]) :-
L > 0, %We can't pour from large if Large is empty
M < 5, %We can't pour into the medium if medium is full
Diff is min(5 - M, L),
Diff > 0,
NewLarge is L - Diff, %calculate the new Large
NewMedium is M + Diff. %calculate the new Medium
% move rule #2: Pour Large into Small (L--> S)
move([L, M, S], [NewLarge,M,NewSmall]) :-
L > 0, %We can't pour from large if Large is empty
S < 3, %We can't pour into the small if small is full
Diff is min(5 - S, L),
Diff > 0,
NewLarge is L - Diff, %calculate the new Large
NewSmall is S + Diff. %calculate the new Small
% move rule #3: Pour Medium into Large (M--> L)
move([L, M, S], [NewLarge,NewMedium,S]) :-
L < 8, %We can't pour into the large if the large is full
M > 0, %We can't pour from Medium if medium is empty
Diff is min(8 - L, M),
Diff > 0,
NewMedium is M - Diff, %calculate the new Medium
NewLarge is L + Diff. %calculate the new Large
% move rule #4: Pour Medium into small (M--> S)
move([L, M, S], [L, NewMedium,NewSmall]) :-
M > 0, %We can't pour from Medium if Medium is empty
S < 3, %We can't pour into the small if small is full
Diff is min(5 - S, M),
Diff > 0,
NewMedium is M - Diff, %calculate the new Medium
NewSmall is S + Diff. %calculate the new Small
% move rule #5: Pour small into large (S--> L)
move([L, M, S], [NewLarge,M,NewSmall]) :-
L < 8, %We can't pour into the large if the large is full
S > 0, %We can't pour from Small if Small is empty
Diff is min(8 - L, S),
Diff > 0,
NewSmall is S - Diff, %calculate the new Small
NewLarge is L + Diff. %calculate the new Large
% move rule #6: Pour small into medium (S --> M)
move([L, M, S], [L,NewMedium,NewSmall]) :-
M < 5, %We can't pour into the large if the large is full
S > 0, %We can't pour from Medium if medium is empty
Diff is min(8 - M, S),
Diff > 0,
NewSmall is S - Diff, %calculate the new Small
NewMedium is M + Diff. %calculate the new Medium
Now it compiles and everthing but whenever I try to execute go([8,0,0],[4,4,0])
where [8,0,0]
is the initial state and [4,4,0]
is my goal state , I get an answer of no !! instead of a depth first search solution where it prints every state .. etc.
I tried to trace it and it told me there is an exception right away. Is there a way to fix this ?