[m-rev.] for post-commit review: fix mantis bug #367
Peter Wang
novalazy at gmail.com
Fri Dec 5 16:11:09 AEDT 2014
On Wed, 03 Dec 2014 18:20:15 +1100 (EST), "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> Fix Mantis bug #367.
Please avoid using only a bug number for commit summary.
> diff --git a/library/array.m b/library/array.m
> index f9cba24..be7fb8b 100644
> --- a/library/array.m
> +++ b/library/array.m
...
> @@ -2135,8 +2153,32 @@ 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.
> + Lo = 0,
> + Hi = array.size(A) - 1,
> + binary_search_loop(Cmp, A, X, Lo, Hi, I).
> +
> +:- pred binary_search_loop(comparison_func(T)::in, array(T)::array_ui,
> + T::in, int::in, int::in, int::out) is semidet.
> +
> +binary_search_loop(Cmp, A, X, Lo, Hi, I) :-
> + % loop invariant: if X is anywhere in A[0] .. A[array.size(A)-1],
> + % then it is in A[Lo] .. A[Hi].
> + Lo =< Hi,
> + Mid = (Lo + Hi) / 2,
> + array.unsafe_lookup(A, Mid, MidX),
> + O = Cmp(MidX, X),
> + (
> + O = (>),
> + binary_search_loop(Cmp, A, X, Lo, Mid - 1, I)
> + ;
> + O = (=),
> + I = Mid % XXX repetitions
Did you mean to leave these in?
> -approx_binary_search_2(Cmp, A, X, Lo, Hi, I) :-
> +approx_binary_search_loop(Cmp, A, X, Lo, Hi, I) :-
> + % loop invariant: if X is anywhere in A[0] .. A[array.size(A)-1],
> + % then it is in A[Lo] .. A[Hi].
> Lo =< Hi,
> Mid = (Lo + Hi) / 2,
> - O = Cmp(A ^ elem(Mid), X),
> + array.unsafe_lookup(A, Mid, MidX),
> + O = Cmp(MidX, X),
> (
> O = (>),
> - approx_binary_search_2(Cmp, A, X, Lo, Mid - 1, I)
> + approx_binary_search_loop(Cmp, A, X, Lo, Mid - 1, I)
> ;
> O = (=),
> - I = Mid
> + I = Mid % XXX repetitions
> ;
> O = (<),
> - ( if ( Mid < Hi, X @< A ^ elem(Mid + 1) ; Mid = Hi ) then
> + ( if
> + (
> + Mid < Hi,
> + % Mid + 1 cannot exceed Hi, so the array access is safe.
> + array.unsafe_lookup(A, Mid + 1, MidP1X),
> + (<) = Cmp(X, MidP1X)
> + ;
> + Mid = Hi
> + )
> + then
> I = Mid
> - else
> - approx_binary_search_2(Cmp, A, X, Mid + 1, Hi, I)
> + else
> + approx_binary_search_loop(Cmp, A, X, Mid + 1, Hi, I)
> )
> ).
The unsafe_lookup goals could potentially be ordered before the bounds
checks. Do you want to want to fix it?
Thanks, Zoltan.
Peter
More information about the reviews
mailing list