1
votes

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.

1
Do you know what = means in Prolog. See: Predicate =/2Guy Coder
Still I ask the same question: Do you know what = means in Prolog?Guy Coder
Yes I know what = means in prologIntellects
If you know what = means in Prolog then why did you change it?Guy Coder
What was the query that caused the error?Guy Coder

1 Answers

1
votes

Can't really see how this

changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).

would cause that error though.

_10148=<3
ERROR: Arguments are not sufficiently instantiated

For

changeState(s(A,B),s(C,D)) :- 
  B > 2, 
  D is B + ( (5 - A) mod 5), 
  valid(C,D).

when this is executed (called) the query is

changeState(s(0, 5), X)

A is bound to 0
B is bound to 5
X is bound to s(C,D)

then for

B > 2

the query is

5 > 2

which is true

then for

D is B + ( (5 - A) mod 5)

the query is

D is 5 + ( (5 - 0) mod 5)

D is bound to 5

then for

valid(C,D)

C is unbound
D is bound to 5

the query is

valid (<unbound>,5)

the only predicate to match is

valid(A,B) :- A =< 3, A >=0, B =< 5, B >= 0.

A is unbound
B is bound to 5

then for

A =< 3

since A is unbound the comparison =< gives the error because it needs both variables to be bound.

So back at this statement

changeState(s(A,B),s(C,D)) :- B > 2, D is B + ( (5 - A) mod 5), valid(C,D).

you need to bind C to a value.


If you use set up the trace with

?- visible(+all),leash(-all).

then enable tracing

?- trace.

and run your query you get

?- traverse(s(0,0), Sol, [s(0,0)]).
   Call: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Unify: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Call: (9) goal(s(0, 0))
   Unify: (9) goal(s(0, 0))
   Call: (10) 0+0=:=4
   Fail: (10) 0+0=:=4
   Fail: (9) goal(s(0, 0))   
   Redo: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Unify: (8) traverse(s(0, 0), _9866, [s(0, 0)])
   Call: (9) changeState(s(0, 0), _10092)
   Unify: (9) changeState(s(0, 0), s(3, 0))
   Exit: (9) changeState(s(0, 0), s(3, 0))
^  Call: (9) not(member(s(3, 0), [s(0, 0)]))
^  Unify: (9) not(user:member(s(3, 0), [s(0, 0)]))
^  Exit: (9) not(user:member(s(3, 0), [s(0, 0)]))
   Call: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Unify: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Call: (10) goal(s(3, 0))
   Unify: (10) goal(s(3, 0))
   Call: (11) 3+0=:=4
   Fail: (11) 3+0=:=4
   Fail: (10) goal(s(3, 0))   
   Redo: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Unify: (9) traverse(s(3, 0), _10116, [s(3, 0), s(0, 0)])
   Call: (10) changeState(s(3, 0), _10116)
   Unify: (10) changeState(s(3, 0), s(3, 5))
   Exit: (10) changeState(s(3, 0), s(3, 5))   
^  Call: (10) not(member(s(3, 5), [s(3, 0), s(0, 0)]))
^  Unify: (10) not(user:member(s(3, 5), [s(3, 0), s(0, 0)]))
^  Exit: (10) not(user:member(s(3, 5), [s(3, 0), s(0, 0)]))
   Call: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Unify: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Call: (11) goal(s(3, 5))
   Unify: (11) goal(s(3, 5))
   Call: (12) 3+5=:=4
   Fail: (12) 3+5=:=4
   Fail: (11) goal(s(3, 5))   
   Redo: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Unify: (10) traverse(s(3, 5), _10140, [s(3, 5), s(3, 0), s(0, 0)])
   Call: (11) changeState(s(3, 5), _10140)
   Unify: (11) changeState(s(3, 5), s(3, 0))
   Call: (12) 5>0
   Exit: (12) 5>0
   Call: (12) valid(3, 5)
   Unify: (12) valid(3, 5)
   Call: (13) 3=<3
   Exit: (13) 3=<3
   Call: (13) 3>=0
   Exit: (13) 3>=0
   Call: (13) 5=<5
   Exit: (13) 5=<5
   Call: (13) 5>=0
   Exit: (13) 5>=0
   Exit: (12) valid(3, 5)   
   Exit: (11) changeState(s(3, 5), s(3, 0))
^  Call: (11) not(member(s(3, 0), [s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (11) not(user:member(s(3, 0), [s(3, 5), s(3, 0), s(0, 0)]))
^  Fail: (11) not(user:member(s(3, 0), [s(3, 5), s(3, 0), s(0, 0)]))
   Redo: (11) changeState(s(3, 5), _10140)
   Unify: (11) changeState(s(3, 5), s(0, 5))
   Call: (12) 3>0
   Exit: (12) 3>0
   Call: (12) valid(3, 5)
   Unify: (12) valid(3, 5)
   Call: (13) 3=<3
   Exit: (13) 3=<3
   Call: (13) 3>=0
   Exit: (13) 3>=0
   Call: (13) 5=<5
   Exit: (13) 5=<5
   Call: (13) 5>=0
   Exit: (13) 5>=0
   Exit: (12) valid(3, 5)
   Exit: (11) changeState(s(3, 5), s(0, 5))
^  Call: (11) not(member(s(0, 5), [s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (11) not(user:member(s(0, 5), [s(3, 5), s(3, 0), s(0, 0)]))
^  Exit: (11) not(user:member(s(0, 5), [s(3, 5), s(3, 0), s(0, 0)]))
   Call: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Unify: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Call: (12) goal(s(0, 5))
   Unify: (12) goal(s(0, 5))
   Call: (13) 0+5=:=4
   Fail: (13) 0+5=:=4
   Fail: (12) goal(s(0, 5))   
   Redo: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Unify: (11) traverse(s(0, 5), _10164, [s(0, 5), s(3, 5), s(3, 0), s(0, 0)])
   Call: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(3, 5))
   Exit: (12) changeState(s(0, 5), s(3, 5))
^  Call: (12) not(member(s(3, 5), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (12) not(user:member(s(3, 5), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Fail: (12) not(user:member(s(3, 5), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(0, 0))
   Call: (13) 5>0
   Exit: (13) 5>0
   Call: (13) valid(0, 5)
   Unify: (13) valid(0, 5)
   Call: (14) 0=<3
   Exit: (14) 0=<3
   Call: (14) 0>=0
   Exit: (14) 0>=0
   Call: (14) 5=<5
   Exit: (14) 5=<5
   Call: (14) 5>=0
   Exit: (14) 5>=0
   Exit: (13) valid(0, 5)
   Exit: (12) changeState(s(0, 5), s(0, 0))
^  Call: (12) not(member(s(0, 0), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Unify: (12) not(user:member(s(0, 0), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
^  Fail: (12) not(user:member(s(0, 0), [s(0, 5), s(3, 5), s(3, 0), s(0, 0)]))
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(0, 5))
   Call: (13) 0>0
   Fail: (13) 0>0
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(_10148, _10150))
   Call: (13) 5=<2
   Fail: (13) 5=<2
   Redo: (12) changeState(s(0, 5), _10164)
   Unify: (12) changeState(s(0, 5), s(_10148, _10150))
   Call: (13) 5>2
   Exit: (13) 5>2
   Call: (13) _10150 is 5+(5-0)mod 5
   Exit: (13) 5 is 5+(5-0)mod 5
   Call: (13) valid(_10148, 5)
   Unify: (13) valid(_10148, 5)
   Call: (14) _10148=<3
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [14] _11032=<3
ERROR:   [13] valid(_11058,5) at *.pl:10
ERROR:   [12] changeState(s(0,5),s(_11096,5)) at *.pl:17
ERROR:   [11] traverse(s(0,5),_11124,[s(0,5),...|...]) at *.pl:26
ERROR:   [10] traverse(s(3,5),_11176,[s(3,5),...|...]) at *.pl:28
ERROR:    [9] traverse(s(3,0),_11228,[s(3,0),...]) at *.pl:28
ERROR:    [8] traverse(s(0,0),_11280,[s(0,0)]) at *.pl:28
ERROR:    [7] <user>
   Exception: (14) _10148=<3 ? Unknown option (h for help)