0

It is a water jug problem. The larger bucket holds 5, the smaller bucket holds 3. I want to get 4 in the larger bucket.

The problem is that when I run I cannot get any answer, it produces an error. It doesn't seem like an obvious error, the algorithm is simple and direct.

Could anyone help me to find what is wrong with it?

check_safe(X,Y):- X>=0,X=<3,Y>=0,Y=<5.

%empty the 3 bucket

move(state(X,Y),state(0,Y)):- X>0,check_safe(0,Y).

%empty the 5 bucket

move(state(X,Y),state(X,0)):- Y>0,check_safe(X,0).

%fill the 3 bucket

move(state(X,Y), state(3,Y)):- X<3, X>=0,check_safe(3,Y).

%fill the 5 bucket

move(state(X,Y),state(X,5)):- Y>=0, Y<5,check_safe(X,5).

%transfer from 3 to 5 until the larger bucket is full

move(state(X,Y),state(NewX,5)):- X+Y>= 5, X>0,Y>=0, NewX=X+Y-5,check_safe(NewX,5).

%transfer from 3 to 5 until the smaller bucket is empty

move(state(X,Y),state(0,NewY)):- X+Y<5, X>0,Y>=0, NewY=X+Y,check_safe(0,NewY).

%transfer from 5 to 3 until the smaller is full

move(state(X,Y),state(3,NewY)):- Y>0,X>=0,X+Y>=5, NewY=Y+X-3,check_safe(3,NewY).

%transfer from 5 to 3 until the larger is empty

move(state(X,Y),state(NewX,0)):-Y>0,X>=0, X+Y<5, NewX=Y+X,check_safe(NewX,0).


path(X,X,_,[X]).
path(X,Y,BeenStates,Path):-
    move(X,Somewhere),not(member(Somewhere,BeenStates)),
    path(Somewhere,Y,[Somewhere|BeenStates],Path2), Path = [X|Path2].


puzzle:- path(state(0,0),state(0,5),[state(0,0)],PathList),X>=0,X=<5,
    writeOut(PathList).

% Here's an easy little predicate for printing a list.
writeOut([]).
writeOut([H|T]):-write(H),nl, writeOut(T).
false
  • 10,264
  • 13
  • 101
  • 209
leaflyfly
  • 21
  • 1
  • 1
  • 2
  • 2
    @DanielLyons: the people who are actually using Prolog tend to hang out on mailing lists instead of here. On the SWI ML, interesting questions pop up every now and then. – Fred Foo Oct 04 '11 at 09:23

2 Answers2

5

You're not using "is" for the assignments.

Your puzzle\0 predicate has two unbound variables: X & Y.

And your path\4 predicates are faulty.

Try these:

path([state(X, 4)|Xs],[state(X, 4)|Xs]):- !.
path([X|Xs],Rs):-
    move(X,Y),not(member(Y,[X|Xs])),
    path([Y,X|Xs],Rs).

puzzle:- path([state(0,0)],PathList),
    write(PathList), nl, fail.

Below is my solution to this problem:

move(s(X,Y),s(Z,5)) :- Z is X - (5 - Y), Z >= 0.
move(s(X,Y),s(Z,0)) :- Z is X + Y, Z =< 3.
move(s(X,Y),s(3,Z)) :- Z is Y - (3 - X), Z >=0.
move(s(X,Y),s(0,Z)) :- Z is X + Y, Z =< 5.

move(s(0,Y),s(3,Y)).
move(s(X,0),s(X,5)).
move(s(X,Y),s(X,0)) :- Y > 0.
move(s(X,Y),s(0,Y)) :- X > 0.

moves(Xs) :- moves([s(0,0)],Xs).
moves([s(X0,Y0)|T], [s(X1,4),s(X0,Y0)|T])
    :- move(s(X0,Y0),s(X1,4)), !.
moves([s(X0,Y0)|T],Xs) :-
    move(s(X0,Y0),s(X1,Y1)), 
    not(member(s(X1,Y1),[s(X0,Y0)|T])),
    moves([s(X1,Y1),s(X0,Y0)|T],Xs).

?- moves(Xs), write(Xs), nl, fail.

I get these solutions:

[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(3,5),s(3,0),s(0,0)]
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,2),s(0,5),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(0,0)]
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,5),s(0,5),s(0,0)]

Obviously the second to last, being the shortest, is the best.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

**

Water Jug Problem:

**

%database
    visited_state(integer,integer).

%predicates
    state(integer,integer).

%clauses
    state(2,0).

state(X,Y):- X < 4,
    not(visited_state(4,Y)),
    assert(visited_state(X,Y)),
    write("Fill the 4-Gallon Jug: (",X,",",Y,") --> (", 4,",",Y,")\n"),
    state(4,Y).

state(X,Y):- Y < 3,
    not(visited_state(X,3)),
    assert(visited_state(X,Y)),
    write("Fill the 3-Gallon Jug: (", X,",",Y,") --> (", X,",",3,")\n"),
    state(X,3).

state(X,Y):- X > 0,
    not(visited_state(0,Y)),
    assert(visited_state(X,Y)),
    write("Empty the 4-Gallon jug on ground: (", X,",",Y,") --> (", 0,",",Y,")\n"),
    state(0,Y).

state(X,Y):- Y > 0,
    not(visited_state(X,0)),
    assert(visited_state(X,0)),
    write("Empty the 3-Gallon jug on ground: (", X,",",Y,") --> (", X,",",0,")\n"),
    state(X,0).

state(X,Y):- X + Y >= 4,
    Y > 0,
    NEW_Y = Y - (4 - X),
    not(visited_state(4,NEW_Y)),
    assert(visited_state(X,Y)),
    write("Pour water from 3-Gallon jug to 4-gallon until it is full: (", X,",",Y,") --> (", 4,",",NEW_Y,")\n"),
    state(4,NEW_Y).


state(X,Y):- X + Y >=3,
    X > 0,
    NEW_X = X - (3 - Y),
    not(visited_state(X,3)),
    assert(visited_state(X,Y)),
    write("Pour water from 4-Gallon jug to 3-gallon until it is full: (", X,",",Y,") --> (", NEW_X,",",3,")\n"),
    state(NEW_X,3).

state(X,Y):- X + Y>=4,
    Y > 0,
    NEW_X = X + Y,
    not(visited_state(NEW_X,0)),
    assert(visited_state(X,Y)),
    write("Pour all the water from 3-Gallon jug to 4-gallon: (", X,",",Y,") --> (", NEW_X,",",0,")\n"),
    state(NEW_X,0).

state(X,Y):- X+Y >=3,
    X > 0,
    NEW_Y = X + Y,
    not(visited_state(0,NEW_Y)),
    assert(visited_state(X,Y)),
    write("Pour all the water from 4-Gallon jug to 3-gallon: (", X,",",Y,") --> (", 0,",",NEW_Y,")\n"),
    state(0,NEW_Y).

state(0,2):- not(visited_state(2,0)),
    assert(visited_state(0,2)),
    write("Pour 2 gallons from 3-Gallon jug to 4-gallon: (", 0,",",2,") --> (", 2,",",0,")\n"),
    state(2,0).

state(2,Y):- not(visited_state(0,Y)),
    assert(visited_state(2,Y)),
    write("Empty 2 gallons from 4-Gallon jug on the ground: (", 2,",",Y,") --> (", 0,",",Y,")\n"),
    state(0,Y).

goal:-
makewindow(1,2,3,"4-3 Water Jug Problem",0,0,25,80),
state(0,0).

**

> Output:
state(2,5).

**
Hack3r
  • 1
  • 1
  • 2
  • You should be more specific. The question was `Could anyone help me to find what is wrong with it?`, so if you are bringing a possible solution, the user will not understand what was wrong. – David García Bodego Oct 16 '19 at 07:11
  • Actually, dude this is the code for water jug problem which I did recently.And I thought it might be helpful... – Hack3r Oct 16 '19 at 07:14
  • OK, so please, on the top of the post, place your answer...`"I just receive/solve this problem and the proved answer is..."` – David García Bodego Oct 16 '19 at 07:17