Why Arguments are not sufficiently instantiated?

101 Views Asked by At

it is my implementation of finding minimum on list:

min(L, M) :- min(L, M, M).
min([], M, M).
min([Head|Tail], Acc, M) :- NewAcc is min(Acc, Head), min(Tail, NewAcc, M). 

min([1,2,3,4,5,6], 1).
true.

min([1,2,3,4,5,6], 2).
false.

min([1,2,3,4,5,6], X).
 is/2: Arguments are not sufficiently instantiated   

I cant understand why this error happened. Could you explain it to me ?

1

There are 1 best solutions below

0
On BEST ANSWER

When you query, min([1,2,3,4,5,6], X). you quickly get to NewAcc is min(Acc, Head) where Acc has no value (not instantiated). is/2 requires that all variables in the expression be bound so that it can evaluate the expression.

The problem is in your predicate clause:

min(L, M) :- min(L, M, M).

M is a variable in the query, min([1,2,3,4,5,6], X). which becomes Acc in the first clause of min/3. This implementation also doesn't match what you're really needing to do with the extra argument, which is to offer an initial candidate for minimum.

One classic way of doing this is to use the first element of the list as the minimum candidate:

min([H|T], Min) :-
    min(T, H, Min).

This also means min([], _) will fail, which is fine since an empty list doesn't have a minimum.