'Arguments are not sufficiently instantiated'

87 Views Asked by At

The problem I'm trying to solve is finding how many of different types of coins is needed to pay for a given sum, if any solutions exist.

Here's my knowledge base:

    payment(0, _).
    payment(Total, [coin(AmountNeeded,ValueOfCoin,AmountAvailable)|Tail]) :-
      AmountNeeded in 0..AmountAvailable,
      Total #= SubTotal + ValueOfCoin*AmountNeeded,
      payment(SubTotal, Tail).

When I do the query

payment(25, [coin(Ones,1,11),coin(Fives,5,4),coin(Tens,10,3),coin(Twenties,20,2)]).

I get an answer:

    Fives in 3..4,
    _3198#=5*Fives,
    _3198 in 15..20,
    Ones+_3198#=25,
    Ones in 5..10

And so on, but when I add label to the query, like this

payment(25, [coin(Ones,1,11),coin(Fives,5,4),coin(Tens,10,3),coin(Twenties,20,2)]), 
label([Ones, Fives, Tens, Twenties]).

I get an error saying 'Arguments are not sufficiently instantiated'. From what I've found this means that there are still unbound variables. The way I understand my code it should recrusively unfold like this:

payment(25, [coin(Ones,1,11),coin(Fives,5,4),coin(Tens,10,3),coin(Twenties,20,2)]).
\/
Ones in 0..11
25 #= SubTotal' + 1*Ones
Fives in 0..4
(25-1*Ones) #= SubTotal'' + 5*Fives
Tens in 0..3
(25-1*Ones-5*Fives) #= SubTotal''' + 10*Tens
Twenties in 0..2
(25-1*Ones-5*Fives-10*Tens) #= SubTotal'''' + 20*Twenties

So I think it's at this point that it breaks down, since the SubTotal'''' variable is not assigned in the end. But how do I deal with this? Am I missing some base case? The code works for a single coin, but with more than one coin there's always one variable left unassigned.

0

There are 0 best solutions below