views:

82

answers:

4

Hi,

in short: How to find min value in a list? (thanks for the advise kaarel)

long story:

I have created a weighted graph in amzi prolog and given 2 nodes, I am able to retrieve a list of paths. However, I need to find the minimum value in this path but am unable to traverse the list to do this. May I please seek your advise on how to determine the minimum value in the list?

my code currently looks like this:

arc(1,2). arc(2,3). arc(3,4). arc(3,5). arc(3,6). arc(2,5). arc(5,6). arc(2,6). path(X,Z,A) :- (arc(X,Y),path(Y,Z,A1),A is A1+1;arc(X,Z), A is 1).

thus, ' keying findall(Z,path(2,6,Z),L).' in listener allows me to attain a list [3,2,2,1]. I need to retrieve the minimum value from here and multiply it with an amount. Can someone please advise on how to retrieve the minimum value? thanks!

+2  A: 
andersoj
Thanks andersoj. I actually saw this code while searching online prior to submitting my qn here. Somehow, I did not understand it, now i do, thanks!
Roy
It's been years since I've thought in Prolog, but I suspect @mat has the readability edge on what I posted...
andersoj
The problem with your solution is also that you compare H and K twice, the min-function probably does not do that...
Kaarel
A: 

SWI-Prolog has min_list/2:

min_list(+List, -Min)
    True if Min is the smallest number in List.

Its definition is in library/lists.pl

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

min_list([], Min, Min).
min_list([H|T], Min0, Min) :-
    Min1 is min(H, Min0),
    min_list(T, Min1, Min).
Kaarel
+2  A: 

It is common to use a so-called "lagged argument" to benefit from first-argument indexing:

list_min([L|Ls], Min) :-
    list_min(Ls, L, Min).

list_min([], Min, Min).
list_min([L|Ls], Min0, Min) :-
    Min1 is min(L, Min0),
    list_min(Ls, Min1, Min).
mat
A: 

Hi everyone, thanks for the replies. been useful. I also experimented furthur and developed this answer:

min_list([X],X). % if list has only 1 element, it is the smallest. also, this is base case.

min_list([H|List],X) :- min_list(List,X1), (H =< X1,X is H; H > X1, X is X1).

%recursively call min_list with list and value, if H is less than X1, X1 is H,else it is the same.

Not sure how to gauge how good of an answer this is algorithmically yet, but it works! would appreciate any feedback nonetheless. thanks!

Roy