An useful Prolog extension: bestof/3

Bestof/3 is missing in all current Prolog implementations we know of. BinProlog's bestof/3 works like findall/3, but instead of accumulating alternative solutions, it selects successively the best one with respect to an arbitrary total order relation. If the test succeeds the new answer replaces the previous one. At the end, either the query has no answers, case in which bestof fails, or an answer is found such that it is better than every other answer with respect to the total order. The proposed syntax is

   ?-bestof(X,TotalOrder,Goal)

At the end, X is instantiated to the best answer. For example, the maximum of a list of integers can be defined simply as:

    max(Xs,X):-bestof(X,>,member(X,Xs)).

The following is an efficient implementation implementation using the blackboard.

% true if X is an answer of Generator such that
% X Rel Y for every other answer Y of Generator
bestof(X,Closure,Generator):-
  copy_term(X,Y),
  Closure=..L1,
  det_append(L1,[X,Y],L2),
  Test=..L2,
  bestof0(X,Y,Generator,Test).

bestof0(X,Y,Generator,Test):-
  inc_level(bestof,Level),
  Generator,
  update_bestof(Level,X,Y,Test),
  fail.
bestof0(X,_,_,_):-
  dec_level(bestof,Level),
  val(bestof,Level,X),
  rm(bestof,Level).

% uses Rel to compare New with so far the best answer
update_bestof(Level,New,Old,Test):-
  val(bestof,Level,Old),!,
  Test,
  bb_set(bestof,Level,New).
update_bestof(Level,New,_,_):-
  bb_let(bestof,Level,New).

% ensure correct implementation of embedded calls to bestof/3
inc_level(Obj,X1):-val(Obj,Obj,X),!,X1 is X+1,bb_set(Obj,Obj,X1).
inc_level(Obj,1):-bb_def(Obj,Obj,1).

dec_level(Obj,X):-val(Obj,Obj,X),X>0,X1 is X-1,bb_set(Obj,Obj,X1).

Note
that precomputation of Test in bestof/3 before calling the workhorse bestof0/4 is much more efficient than using some form of apply meta-predicate inside bestof0/4.