Can anyone find why I can't have any true answers with my 'go' at this code? For example, I write go(7,3,l)
and I suppose that it should move 3 litres of water to the second jug, but it is false according to prolog. What's wrong?
:- 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(7,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(init1(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.
The first thing you need to correct it's basic syntax: variables must begin with uppercase, so for instance you must change this rule
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.
to
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.
and
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).
to
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).
You should realize that N1 is valorized just in the first newstate/2 procedure: then correct the other instances of that rule.
Then you should remove the useless dynamic assertions: think about your actual assert/retractall usage: what you need is to change the state moving 'water' between 'jugs' at any step: so you should assert/retract state/5 while looping in go, from an initial state (assert this at start program), to a final acceptable state, to be tested in go to stop the cycle.
But this style based on state change leads to very difficult debugging. Try instead to remove altogheter the dynamic,assert/retractall, and pass around the state in your cycle.