Trying to write a program that solves this problem:
"You are given two jugs, a 5-gallon one and a 3-gallon one. Neither of them has any measuring markers on it. There is a tap that can be used to fill the jugs with water. The goal is to obtain exactly 4 gallons of water." This is the code I currently have:
%(WaterInThree, WaterInFive)
s(A,B).
initial(s(0,0)).
goal(s(A,B)):- A + B =:= 4.
valid(A,B) :- A =< 3, A >=0, B =< 5, B >= 0.
changeState(s(0,B),s(3,B)).
changeState(s(A,0),s(A,5)).
changeState(s(A,B),s(A,0)) :- B > 0, valid(A,B).
changeState(s(A,B),s(0,B)) :- A > 0, valid(A,B).
changeState(s(A,B),s(C,D)) :- B =< 2, D is A + B, C is B - A, valid(C,D).
changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).
changeState(s(A,B),s(3,D)) :- B =< 3, D is B - (3 - A), valid(A,D).
changeState(s(A,B),s(C,D)) :- B =:= 5, C is A + B, D is A - B, valid(C,D).
traverse(StartNode,Sol,_) :- goal(StartNode), Sol = [StartNode].
traverse(StartNode,Sol,Visit) :- changeState(StartNode, NextNode),
not(member(NextNode, Visit)),
traverse(NextNode, PartialSol, [NextNode|Visit]),
Sol = [StartNode | PartialSol].
When I execute this code, I get these errors:
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [13] _11226=<3
ERROR: [12] valid(_11252,5+(5-3))
ERROR: [11] changeState(s(3,5),s(_11302,5+ ...))
ERROR: [10] traverse(s(3,5),_11336,[s(3,5),...|...])
ERROR: [9] traverse(s(3,0),_11388,[s(3,0),...])
ERROR: [8] traverse(s(0,0),_11440,[s(0,0)])
ERROR: [7] <user>
Not really sure what the issue is, I've been trying to fix this for hours on end and can't figure out what's wrong. Can't even properly test if the changeState predicates I've created even work because of this so it's extremely frustrating. Would appreciate any help!
EDIT I've narrowed it down to the this line causing the error:
changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).
Can't really see how this would cause that error though.
For
when this is executed (called) the query is
then for
the query is
which is true
then for
the query is
then for
the query is
the only predicate to match is
then for
since A is unbound the comparison
=<
gives the error because it needs both variables to be bound.So back at this statement
you need to bind
C
to a value.If you use set up the trace with
then enable tracing
and run your query you get