Arguments are not sufficiently instantiated prolog

317 Views Asked by At

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

There are 1 best solutions below

0
On BEST ANSWER

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)