Solving Water Jug Problems in Prolog

i’m trying to solve 2-water jug problem in swi-prolog by implementing this pseudocode:

x, y is current volume of jug X, Y
Vx, Vy is capacity of jug X, Y
and z is the goal volume of liquid

while (x != z and y != z):
  if y == 0:
    y = Vy
  if x == Vx:
    x = 0
  if y != 0 and x < Vx:
    k = min(y, Vx - x)
    x = x + k
    y = y - k

Here is my Prolog code:

jugY(Y, Vy, Yc) :- (   Y =:= 0
            ->  Yc is Vy; % Yc is the new volume of jug Y
                Yc is Y
            ).

jugX(X, Vx, Xc) :- (   X =:= Vx 
            ->  Xc is 0; % Xc is the new volume of jug X
                Xc is X
            ).

pouring(Y, X, Vx, K, Xc, Yc) :- (   Y =\= 0, X < Vx
                                ->  K is min(Y, Vx - X)
                                , 	Xc is X + K
                                , 	Yc is Y - K
                                ).

do(Vy, Vx, Y, X, Yc, Xc, K) :-
    jugY(Y, Vy, Yc);
    jugX(X, Vx, Xc);
    pouring(Yc, Xc, Vx, K, Xc1, Yc1).

loop(Vy, Vx, Y, X, Z, Yc, Xc, K) :- 
    (   X =\= Z, Y =\= Z	),
    jugY(Y, Vy, Yc);
    jugX(X, Vx, Xc);
    pouring(Yc, Xc, Vx, K, Xc1, Yc1),
    loop(Vy, Vx, Y, X, Z, Yc, Xc, K).

My 3 conditions work fine. Now i’m stucking at creating the while loop.
This is my query:

?- do(5, 3, 0, 0, Yc, Xc, K).

The predicate do i created to test 1 iteration of the loop. In this predicate, 2 first conditions are executed successfully. But at predicate pouring,i got this error:

Arguments are not sufficiently instantiated
In:
   [2] _1450=\=0
   [1] pouring(_1506,_1508,3,_1512,_1514,_1516) at  line 11

I tried to write the value of Yc and Xc, and it works fine. I don’t know why that error keeps happen.
Can you guys tell me how to fix this error and how to implement this while loop in Prolog.
Thank you so much. :smiley:

This is cross-posted on StackOverflow.

Do you know what the semicolon means? You write your commas (the conjunction) at the beginning of the lines (to make them more obvious I assume?) but you hide the semicolon (the disjunction) at the end of the line, sticking to the last subgoal. You are also wrapping conjunctions in unnecessary parentheses. This suggests to me that you might be not aware of the meaning or the precedence of these control structures.

I get “singleton variable” warnings when I compile your code. It might be that figuring out what causes those warnings will lead you to discover the problem on your own.

Sorry for reposting it. I just found out about this site after posting in StackOverFlow, so i thought this site would be better to post my question in.

Sorry, this is my first time coding Prolog.
I thought “;” can be used as If in other programming language so i use that as if.

While reposting is fine, one should also note all the cross-postings to avoid confusion.

Don’t worry about it, you are not the first person to not mention a cross posting and will not be the last. This happens about once a month on average.

2 Likes

You could use is as if but if it doesn’t work as if you will get unexpected results.

1 Like

Hi, thanks to @TessellatingHeckler on StackOverflow. I solve the problem.
And thanks everyone for helping me.

And then you removed it from StackOverflow- why?

The code for the question and answer are still on StackOverflow but you need enough rep (10,000 I beleive) to gain the privilege to see the deleted Q&A.

No I don’t plan on posting it here, he deleted it for a reason and I see no reason to undo that at present.