Search code examples
prologshortest-pathgnu-prolog

Prolog find minimum in list error


Im trying to make my code work, but somehow I got stuck on a problem, Im very newbie to prolog. This is my code.

    dist(valmiera, riga, 107).
%dist(riga, valmiera, 107).
dist(cesis, riga, 70).
dist(valmiera, rujiena,  50).
dist(rujiena, valka, 30).
dist(valmiera, strenci, 200).
dist(strenci, valka, 30).
dist(valmiera, cesis, 40).
dist(liepaja, saldus, 100).
dist(saldus, riga, 200).
dist(liepaja, jelgava, 270).
dist(jelgava, riga, 50).

path(A,B,C,[A,B]):- dist(A,B,C).
path(A,B,D,[A|As]):- dist(A,W,C), path(W,B,E,As), D is C+E.
%, findMin(YList, E), path(A,B,X,E),!.
shortestPath(A,B,X,E):-findall(Y,path(A,B,S,Y),YList), findMin(YList, E), path(A,B,X,E),!.


findMin([],fail).
findMin([H],E):-E=H,!.
findMin([H,V],E):-H<V, E=H,!; V<H, E=V, !; H=:=V, E=H, !.
findMin([H|T],E):-findMin(T,U), H<U, E=H,!;findMin(T,U), U<H, E=U,!;findMin(T,U), U=:=H, E=U,!.

but when I call findMin() I get this error

uncaught exception: error(type_error(evaluable,'.'/2),(<)/2)

I'm realy stuck and don't know what to do. Any help will be appreciated.

Applications purpose is get shortest path by calling shortestPath(), paths are in dist (a,b,distance)


Solution

  • The exception is because the terms you are trying to compare are lists.

    [liepaja,saldus,riga]<[liepaja,jelgava,riga] ?
    

    An expression:

    Term1 < Term2 
    

    succeeds if

    eval(Term1) < eval(Term2)
    

    So, Term1 and Term2 have to be evaluable terms (e.g., (1+1)<(2+2)).

    Try to change the shortestPath/4 body:

    shortestPath(A,B,X,E):-
       findall(couple(W,P),path(A,B,W,P),WP_List),
       findMin(WP_List, couple(Weight,ShortestPath)),...
    

    In this way you have a list of couple(Weight,Path) and in findMin you can get the Weight per Path.