I have 3 jugs of water problem to solve but with a little trick.I dont have to use an algorithm but to have a 'function' that allows to user to move litres from on jug to another with an initial and final state that its written also by him.
For example he writes initial(10,0,0,0,r) and the first state is 10 litres in first and zero in the other two, also he writes final(0,3,3,3,l) and the final state has 3 litres in the two smaller jugs and zero in the first one.
The 'moves' between the jugs happen when he writes go(7,3,r) where he moves 3 litres to the right (from right to left we have the jugs form bigger to smaller) from bigger to the second jug, -7 is the litres that are left and 3 are the litres to be moved and r is the direction-.
And i have written this prolog code but every go-state is false..Has anyone any idea why??
:- dynamic go/3.
:- dynamic cur_state/1,init/5.
:- dynamic end_state/1, final/5.
cur_state(State):-State = state(10,0,0,7,l).
end_state(State):-State = state(0,3,3,0,r).
pour(state(D1,D2,D3,N,l),move(D,C,r),state(D,C,D3,N,r)) :-
D is D1-N,
C is D2+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D,C,D3,N,l)) :-
D is D1-N,
C is D2.
pour(state(D1,D2,D3,N,l),move(D,C,r),state(D,D2,C,N,r)) :-
D is D1-N,
C is D3+N.
pour(state(D1,D2,D3,N,l),move(D,C,r),state(D1,D,C,N,r)) :-
D is D2-N,
C is D3+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D1,D,C,N,l)) :-
D is D2-N,
C is D1+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D1,D,c,N,l)) :-
D is D2-N,
C is D3.
pour(state(D1,D2,D3,N,l),move(D,C,r),state(C,D2,D,N,r)) :-
D is D3-N,
C is D1.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(D1,C,D,N,l)) :-
D is D3-N,
C is D2+N.
pour(state(D1,D2,D3,N,r),move(D,C,l),state(C,D2,D,N,l)) :-
D is D3-N,
C is D1+N.
carry(7,0).
carry(3,0).
carry(10,0).
carry(4,0).
carry(7,3).
legal(10,X,Y):-X+Y=<10.
legal(X,Y,Z):-X+Y+Z=<10.
legal(X,7,Y):-X+Y=<3.
legal(X,Y,3):-X+Y=<7.
newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
carry(M,C),
M=<7,C=<3,
D22 is D2+N,
D11 is D1-N,
D3 is D33,
N1 is N,
D2=<7,D1=<10,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
carry(M,C),
M=<10,C=<100,
D11 is D1-N,
D22 is D2,
D33 is D3,
D1=<10,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
carry(M,C),
M=<10,C<3,
D11 is D1-N,
D33 is D3+N,
D22 is D2,
D1=<10,D3=<3,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
carry(M,C),
M=<7,C=<3,
D22 is D2-N,
D33 is D1+N,
D11 is D1,
D2=<7,D1=<10,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
carry(M,C),
M=<7,C=0,
D22 is D2-N,
D33 is D3+N,
D11 is D1,
D2=<7,D3=<3,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
carry(M,C),
M=<7,C=<100,
D22 is D2-N,
D33 is D3,
D11 is D1,
D2=<7,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
carry(M,C),
M=<3,C=<7,
D22 is D2+N,
D33 is D3-N,
D11 is D1,
D3=<3,D2=<7,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,r),state(D11,D22,D33,N1,l)):-
carry(M,C),
M=<3,C=<100,
D11 is D1+N,
D33 is D3-N,
D22 is D2,
D3=<3,D1=<10,
legal(D1,D2,D3).
newstate(state(D1,D2,D3,N,l),state(D11,D22,D33,N1,r)):-
carry(M,C),
M=<3,C=<100,
D33 is D3-N,
D22 is D2,
D11 is D1,
D3=<3,
legal(D1,D2,D3).
eisodos(_):- cur_state(State),write(State),nl.
init(S1,S2,S3,S4,S5):-assert(cur_state(State):-State = state(S1,S2,S3,S4,S5)),write('Arxikh:'),
write(state(S1,S2,S3,S4,S5)),retractall(init(S1,S2,S3,S4,S5)),nl.
final(S1,S2,S3,S4,S5):-assert(end_state(State):-State = state(S1,S2,S3,S4,S5)),write('Telikh:'),
write(state(S1,S2,S3,S4,S5)),retractall(final(S1,S2,S3,S4,S5)),nl.
go(Move1,Move2,Move3):-cur_state(State),newstate(State,NextState),
pour(State,move(Move1,Move2,Move3), NextState),
retractall(cur_state(State):-State = state(_,_,_,_,_)),asserta(cur_state(NextState)),
((end_state(NextState),write('Bravo!!!!')) ;(write(' ---*Eiste sthn katastash --- :'),write(NextState))),nl.
It's hard to make sense of what you've written. If initial state is
ini(10,0,0,0,r)
, what are the last two arguments there? you only have three jugs don't you? Why final state isfin(0,3,3,3,r)
? What do the last3
andr
mean??You have three jugs, so your state just has three values in it:
s(A,B,C)
. You seem to want to have it dynamically redefined on the go. Fine. Yourgo(...)
predicate will callretract/assert
and will have to take care of the logic. If you want your user to be able to say "pour to the right" why do you insist on him to write also how much water is left in the jug??? That seems wrong, your system must calculate that value, and update your current dynamic database with it. Plus, "pour to the right" from where ?? Seems to me, yourgo(7,3,r)
says "pour from a '7'-jug the 3 liters of water into the jug to the right of it", but if so, why do you need to specify the amount at all?? Isn't it contrary to the usual specification of the jugs problem, where you do not have any ability to measure and are just instead given the jugs' capacities? Does it instead mean "pour all the water you can from a '7' jug into a '3' jug"? If so,r
has no function.So please clarify your problem. And lastly, what are your jugs' capacities?
EDIT: Well, after clarifications in the comments below about the rules, I would code this as follows:
Now what's left is to define
is_final_state
which will check thejug
facts, see if the end state is reached, print out the congratulatory message if it is, and returntrue
always. Or something like that. The sample run can be e.g.