If you turn tracing on you can see what's wrong with your script.
1 ?- trace.
true.
Original version:
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
Output:
[trace] 2 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G4129) ? creep
Call: (7) _G4129=<5 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (7) _G4129=<5 ? creep
You're trying to compare an unistantiated variable with 5. Solution: swap lines in the script so that the variable is instantiated before the comparison.
/** Version 1 */
min([], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
Output:
[trace] 5 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G517) ? creep
Call: (7) min([3, 7, 6], _G517) ? creep
Call: (8) min([7, 6], _G517) ? creep
Call: (9) min([6], _G517) ? creep
Call: (10) min([], _G517) ? creep
Exit: (10) min([], _G517) ? creep
Call: (10) _G517=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G517=<6 ?
[trace] 102 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G3067) ? creep
Call: (7) min([3, 7, 6], _G3067) ? creep
Call: (8) min([7, 6], _G3067) ? creep
Call: (9) min([6], _G3067) ? creep
Call: (10) min([], _G3067) ? creep
Exit: (10) min([], _G3067) ? creep
Call: (10) _G3067=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G3067=<6 ?
This way the script goes a bit further but when computing the minimum of the tail it reaches a comparison with an unistantiated variable again. Solution: change min([], Result).
to min([Result], Result)
.
/** version 2 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
Output:
[trace] 8 ?- min([5,3,7,6],3).
Call: (6) min([5, 3, 7, 6], 3) ? creep
Call: (7) min([3, 7, 6], 3) ? creep
Call: (8) min([7, 6], 3) ? creep
Call: (9) min([6], 3) ? creep
Call: (10) min([], 3) ? creep
Fail: (10) min([], 3) ? creep
Fail: (9) min([6], 3) ? creep
Fail: (8) min([7, 6], 3) ? creep
Fail: (7) min([3, 7, 6], 3) ? creep
Fail: (6) min([5, 3, 7, 6], 3) ? creep
false.
The program now only returns false. This is because you only consider the case the minimum of the tail is smaller than or equal than the head. This program will only return a correct result when the input list is sorted decreasingly (so that the minimum of the tail is smaller than the head, recursively).
[trace] 10 ?- min([5,4,3,2],X).
Call: (6) min([5, 4, 3, 2], _G2469) ? creep
Call: (7) min([4, 3, 2], _G2469) ? creep
Call: (8) min([3, 2], _G2469) ? creep
Call: (9) min([2], _G2469) ? creep
Exit: (9) min([2], 2) ? creep
Call: (9) 2=<3 ? creep
Exit: (9) 2=<3 ? creep
Exit: (8) min([3, 2], 2) ? creep
Call: (8) 2=<4 ? creep
Exit: (8) 2=<4 ? creep
Exit: (7) min([4, 3, 2], 2) ? creep
Call: (7) 2=<5 ? creep
Exit: (7) 2=<5 ? creep
Exit: (6) min([5, 4, 3, 2], 2) ? creep
X = 2 .
So you need to take care of the case when the minimum of the tail is strictly greater than the head by adding the clause:
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
And here's the final version:
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
(turn tracing off with nodebug.
)