[m-rev.] For review: add array.binary_search
Ralph Becket
rafe at csse.unimelb.edu.au
Wed Jun 17 14:45:44 AEST 2009
Interdiff in response to verbal feedback in the office:
diff -u NEWS NEWS
--- NEWS 17 Jun 2009 04:18:22 -0000
+++ NEWS 17 Jun 2009 04:43:56 -0000
@@ -96,9 +96,12 @@
set.filter_map/3
* The following predicates have been added to the array modules:
+ array.binary_search/3
+ array.binary_search/4
+ array.approx_binary_search/3
+ array.approx_binary_search/4
array.fold/4
array.foldl2/6
- array.binary_search/3
version_array.foldl/4
* The following predicates have been added to the list module:
diff -u library/array.m library/array.m
--- library/array.m 17 Jun 2009 04:17:23 -0000
+++ library/array.m 17 Jun 2009 04:43:36 -0000
@@ -328,6 +328,9 @@
%:- mode array.fetch_items(array_ui, in, in) = out is det.
:- mode array.fetch_items(in, in, in) = out is det.
+ % XXX We prefer users to call the new array.binary_search predicate
+ % instead of array.bsearch, which may be deprecated in later releases.
+ %
% array.bsearch takes an array, an element to be matched and a comparison
% predicate and returns the position of the first occurrence in the array
% of an element which is equivalent to the given one in the ordering
@@ -342,6 +345,32 @@
%:- mode array.bsearch(array_ui, in, in(comparison_func)) = out is det.
:- mode array.bsearch(in, in, in(comparison_func)) = out is det.
+ % array.approx_binary_search(A, X, I) performs a binary search for an
+ % approximate match for X in array A, computing I as the result. More
+ % specifically, if the call succeeds, then either A ^ elem(I) = X or
+ % A ^ elem(I) @< X and either X @< A ^ elem(I + 1) or I is the last index
+ % in A.
+ %
+ % array.binary_search(A, X, I) performs a binary search for an
+ % exact match for X in array A (i.e., it succeeds iff X = A ^ elem(I)).
+ %
+ % A must be sorted into ascending order, but may contain duplicates
+ % (the ordering must be with respect to the supplied comparison predicate
+ % if one is supplied, otherwise with respect to the Mercury standard
+ % ordering).
+ %
+:- pred array.approx_binary_search(array(T), T, int).
+:- mode array.approx_binary_search(array_ui, in, out) is semidet.
+
+:- pred array.approx_binary_search(comparison_func(T), array(T), T, int).
+:- mode array.approx_binary_search(in, array_ui, in, out) is semidet.
+
+:- pred array.binary_search(array(T), T, int).
+:- mode array.binary_search(array_ui, in, out) is semidet.
+
+:- pred array.binary_search(comparison_func(T), array(T), T, int).
+:- mode array.binary_search(in, array_ui, in, out) is semidet.
+
% array.map(Closure, OldArray, NewArray) applies `Closure' to
% each of the elements of `OldArray' to create `NewArray'.
%
@@ -407,17 +436,6 @@
%:- mode array.foldr(func(in, di) = uo is det, array_ui, di) = uo is det.
:- mode array.foldr(func(in, di) = uo is det, in, di) = uo is det.
- % array.binary_search(A, X, I) performs a binary search for X in array A,
- % computing I as the result. More specifically, if the call succeeds, then
- % either A ^ elem(I) = X or I is the largest index of A such that
- % A ^ elem(I) @< X and either X @< A ^ elem(I + 1) or I is the last index
- % in A.
- %
- % A must be sorted into ascending order (but may contain duplicates).
- %
-:- pred array.binary_search(array(T), T, int).
-:- mode array.binary_search(array_ui, in, out) is semidet.
-
% array.random_permutation(A0, A, RS0, RS) permutes the elements in
% A0 given random seed RS0 and returns the permuted array in A
% and the next random seed in RS.
@@ -1488,20 +1506,30 @@
%------------------------------------------------------------------------------%
array.binary_search(A, X, I) :-
+ array.binary_search(ordering, A, X, I).
+
+array.binary_search(Cmp, A, X, I) :-
+ array.approx_binary_search(Cmp, A, X, I),
+ A ^ elem(I) = X.
+
+array.approx_binary_search(A, X, I) :-
+ array.approx_binary_search(ordering, A, X, I).
+
+array.approx_binary_search(Cmp, A, X, I) :-
Lo = 0,
Hi = array.size(A) - 1,
- binary_search_2(A, X, Lo, Hi, I).
+ approx_binary_search_2(Cmp, A, X, Lo, Hi, I).
-:- pred binary_search_2(array(T), T, int, int, int).
-:- mode binary_search_2(array_ui, in, in, in, out) is semidet.
+:- pred approx_binary_search_2(comparison_func(T), array(T), T, int, int, int).
+:- mode approx_binary_search_2(in, array_ui, in, in, in, out) is semidet.
-binary_search_2(A, X, Lo, Hi, I) :-
+approx_binary_search_2(Cmp, A, X, Lo, Hi, I) :-
Lo =< Hi,
Mid = (Lo + Hi) / 2,
- O = ordering(A ^ elem(Mid), X),
+ O = Cmp(A ^ elem(Mid), X),
(
O = (>),
- binary_search_2(A, X, Lo, Mid - 1, I)
+ approx_binary_search_2(Cmp, A, X, Lo, Mid - 1, I)
;
O = (=),
I = Mid
@@ -1510,7 +1538,7 @@
( if Mid < Hi, X @< A ^ elem(Mid + 1) then
I = Mid
else
- binary_search_2(A, X, Mid + 1, Hi, I)
+ approx_binary_search_2(Cmp, A, X, Mid + 1, Hi, I)
)
).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list