There are a couple of fundamental issues.
One is in your problem lies in your representation of a list. Your predicates seem to assume that, for example, [3, [a,b,c]]
is represented as [3 | [a,b,c]]
but it is not. The list [3 | [a,b,c]]
is the list with 3
as the head, and [a,b,c]
as the rest of the list or the tail. In other words, [3 | [a,b,c]]
is [3, a, b, c]
.
And, so, your base case would be:
minway([[N,L]], N, L).
The second issue is in your other predicate clauses. There's no starting point for D
. In other words, it's never given a value to start with, so you get an instantiation error. You cannot compare N > D
if one of the variables doesn't have a value.
When doing a minimum or maximum from scratch, a common approach is to start by assuming the first element is the candidate result, and then replace it if you find a better one on each step of the recursion. It also means you need to carry with you the last candidate at each recursive call, so that adds extra arguments:
minway([[N,L]|T], D, R) :-
minway(T, N, L, D, R).
minway([], D, R, D, R). % At the end, so D, R is the answer
minway([[N,L]|T], Dm, Rm, D, R) :-
( N < Dm
-> minway(T, N, L, D, R) % N, L are new candidates if N < Dm
; minway(T, N, Dm, Rm, D, R) % Dm, Rm are still best candidate
).
In Prolog, you can simplify this a little since Prolog has a more general term comparison operator, @<
, @>
, etc, which is smart about comparing more complex terms. For example, [2, [d,e,f]] @< [3, [a,b,c]]
is true since 2 < 3
is true. We can then write:
minway([H|T], D, R) :-
minway(T, H, D, R).
minway([], [D, R], D, R).
minway([H|T], M, D, R) :-
( H @< M
-> minway(T, H, D, R)
; minway(T, M, D, R)
).