%Start:Start node, goal_node:Goal node, Solution:path,L:cost
bestfirst(Start,goal_node,Solution,L) :-
	expand([],l(Start,0),_,yes,Solution).

%expand(path_to_the_tree,Tree_to_search,expanded_tree,solved,path)
%create the path if you have reached the goal node
expand(P,l(N,_),_,yes,[N|P]) :- goal(N).

%generate successors and expand them
expand(P,l(N,G),Tree1,Solved,Sol) :-
%puts all successors in list Succ
	(bagof(M/C,((s(N,M,C);s(M,N,C)),not(member(M,P))),Succ),!,
%make list of search leaves ordered by their values
	succlist(G,Succ,Ts),
%finds the values of the leaves
	bestf(Ts,F1),
	expand(P,t(N,F1,Ts),Tree1,Solved,Sol)
	;
	Solved = never
).

expand(P,t(N,F,[T|Ts]),Tree1,Solved,Sol):-
	bestf(Ts,F),
	expand([N|P],T,T1,Solved1,Sol),
	continue(P,t(N,F,[T1|Ts]),Tree1,Solved1,Solved,Sol).

expand(_,t(_,_,[]),_,never,_):-!.

continue(_,_,_,yes,yes,Sol).

continue(P,t(N,F,[T1|Ts]),Tree1,no,Solved,Sol):-
	insert(T1,Ts,NTs),
	bestf(NTs,F1),
	expand(P,t(N,F1,NTs),Tree1,Solved,Sol).

continue(P,t(N,F,[_|Ts]),Tree1,never,Solved,Sol):-
	bestf(Ts,F1),
	expand(P,t(N,F1,Ts),Tree1,Solved,Sol).

succlist(_,[],[]).

succlist(G0,[N/C|NCs],Ts):-
	G is G0+C,
	F is G,
	succlist(G0,NCs,Ts1),
	insert(l(N,F),Ts1,Ts).

insert(T,Ts,[T|Ts]):-
	f(T,F),bestf(Ts,F1),
	F=<F1,!.

insert(T,[T1|Ts],[T1,Ts1]):-
	insert(T,Ts,Ts1).

f(l(_,F),F).
f(t(_,F,_),F).

bestf([T|_],F):-
	f(T,F).
bestf([],_):- fail.

min(X,Y,X):-
	X =< Y,!.

min(X,Y,Y).

s(a,b,120).
s(b,e,141).
%goal(e).
