[m-rev.] for review: conversion from array/1 to array2d/1

Julien Fischer jfischer at opturion.com
Thu Nov 29 17:06:14 AEDT 2018


Hi,

Is anyone planning to reveiw this one?

Julien.

On Mon, 19 Nov 2018, Julien Fischer wrote:

>
> For review by anyone.
>
> Conversion from array/1 to array2d/1.
>
> Add a function that uses an array/1 value to construct an array2d/1 value
> without allocating new memory for the element storage or traversing the
> elements.
>
> library/array2d.m:
>     Add a function that creates an array2d/1 from an array/1 value
>
>     Fix minor documentation issues:
>     - re-order the declarations so that of from_lists/1 is directly below
>       that of array2d/1.
>
>    - s/a/an/ in a few spots.
>
>    - add missing apostrophes.
>
> NEWS:
>     Announce the new function.
>
> tests/hard_coded/Mmakefile:
> tests/hard_coded/array2d_from_array.{m,exp}:
>     Add a test case.
>
> Julien.
>
> diff --git a/NEWS b/NEWS
> index 88d36a7..8463bba 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -474,10 +474,11 @@ Changes to the Mercury standard library:
>     - least_index/1
>     - greatest_index/1
>
> -* The following predicates have been added to the array2d module:
> +* The following predicates and functions have been added to the array2d 
> module:
>
>     - is_empty/1
>     - fill/3
> +   - from_array/3
>
> * The following predicates have been added to the time module:
>
> diff --git a/library/array2d.m b/library/array2d.m
> index c84a081..61f9837 100644
> --- a/library/array2d.m
> +++ b/library/array2d.m
> @@ -25,7 +25,7 @@
>
> % ---------------------------------------------------------------------------%
>
> -    % A array2d is a two-dimensional array stored in row-major order
> +    % An array2d is a two-dimensional array stored in row-major order
>     %  (that is, the elements of the first row in left-to-right
>     %  order, followed by the elements of the second row and so forth.)
>     % 
> @@ -46,7 +46,7 @@
>  :- func init(int, int, T) = array2d(T).
>  :- mode init(in, in, in) = array2d_uo is det.
>
> -    % array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]]) constructs a array2d
> +    % array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]]) constructs an array2d
>     %  of size M * N, with the special case that bounds(array2d([]), 0, 0).
>     %
>     %  An exception is thrown if the sublists are not all the same length.
> @@ -54,6 +54,20 @@
>  :- func array2d(list(list(T))) = array2d(T).
>  :- mode array2d(in) = array2d_uo is det.
>
> +    % A synonym for the above.
> +    %
> +:- func from_lists(list(list(T))) = array2d(T).
> +:- mode from_lists(in) = array2d_uo is det.
> +
> +    % from_array(M, N, Array) constructs an array2d of size M * N whose
> +    % elements are taken from Array.  The elements in Array are added to
> +    % the array2d in row-major order (see above).
> +    % Throws an exception if M < or N < 0, or if the number of elements in
> +    % Array does not equal M * N.
> +    %
> +:- func from_array(int, int, array(T)) = array2d(T).
> +:- mode from_array(in, in, array_di) = array2d_uo is det.
> +
>     %  is_empty(Array):
>     %  True iff Array contains zero elements.
>     % 
> @@ -61,11 +75,6 @@
> % :- mode is_empty(array2d_ui) is semidet.
>  :- mode is_empty(in) is semidet.
>
> -    % A synonym for the above.
> -    %
> -: - func from_lists(list(list(T))) = array2d(T).
> -: - mode from_lists(in) = array2d_uo is det.
> -
>     %  bounds(array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]), M, N)
>     % 
> :- pred bounds(array2d(T), int, int).
> @@ -80,7 +89,7 @@
>  :- mode in_bounds(in,       in,  in ) is semidet.
>
>     %  array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]]) ^ elem(I, J) = X
> -    % where X is the J+1th element of the I+1th row (that is, indices
> +    % where X is the J+1'th element of the I+1'th row (that is, indices
>     %  start from zero.)
>     %
>     %  An exception is thrown unless 0 =< I < M, 0 =< J < N.
> @@ -175,11 +184,34 @@ array2d(Xss @ [Xs | _]) = T :-
>            else  func_error("array2d.array2d/1: non-rectangular list of
>            lists")
>         ) .
>
> +from_lists(Xss) = array2d(Xss).
> +
> +from_array(M, N, Array) = Array2d :-
> +    ( if
> +        M >= 0,
> +        N >= 0
> +    then
> +        array.size(Array, Size),
> +        compare(Result, Size, M * N),
> +        (
> +            Result = (=),
> +            Array2d = array2d(M, N, Array)
> +        ;
> +            Result = (>),
> +            error("array2d.from_array: too many elements")
> +        ;
> +            Result = (<),
> +            error("array2d.from_array: too few elements")
> +        )
> +    else
> +        error("array2d.from_array: bounds must be non-negative")
> +    ).
> +
> +%---------------------------------------------------------------------------%
> +
>  is_empty(array2d(_, _, A)) :-
>      array.is_empty(A).
>
> -from_lists(Xss) = array2d(Xss).
> -
> % ---------------------------------------------------------------------------%
>
> bounds(array2d(M, N, _A), M, N).
> diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
> index bbbbc97..dd39c13 100644
> --- a/tests/hard_coded/Mmakefile
> +++ b/tests/hard_coded/Mmakefile
> @@ -676,6 +676,7 @@ ifeq "$(findstring profdeep,$(GRADE))" ""
> 		 array_resize \
> 		 array_shrink \
> 		 array_swap \
> +		array2d_from_array \
> 		 allow_stubs \
> 		 arith_int16 \
> 		 arith_int32 \
> diff --git a/tests/hard_coded/array2d_from_array.exp 
> b/tests/hard_coded/array2d_from_array.exp
> index e69de29..511ecf9 100644
> --- a/tests/hard_coded/array2d_from_array.exp
> +++ b/tests/hard_coded/array2d_from_array.exp
> @@ -0,0 +1,45 @@
> +------FROM ARRAY------
> +Array = array([])
> +M = -1
> +N = -1
> +EXCEPTION: "array2d.from_array: bounds must be non-negative"
> +------FROM ARRAY------
> +Array = array([])
> +M = 0
> +N = -1
> +EXCEPTION: "array2d.from_array: bounds must be non-negative"
> +------FROM ARRAY------
> +Array = array([])
> +M = -1
> +N = 0
> +EXCEPTION: "array2d.from_array: bounds must be non-negative"
> +------FROM ARRAY------
> +Array = array([])
> +M = 2
> +N = 2
> +EXCEPTION: "array2d.from_array: too few elements"
> +------FROM ARRAY------
> +Array = array([1, 2, 3, 4, 5])
> +M = 2
> +N = 2
> +EXCEPTION: "array2d.from_array: too many elements"
> +------FROM ARRAY------
> +Array = array([])
> +M = 0
> +N = 0
> +Array2d = array2d(0, 0, array([]))
> +------FROM ARRAY------
> +Array = array([1])
> +M = 1
> +N = 1
> +Array2d = array2d(1, 1, array([1]))
> +------FROM ARRAY------
> +Array = array([1, 2, 3, 4])
> +M = 2
> +N = 2
> +Array2d = array2d(2, 2, array([1, 2, 3, 4]))
> +------FROM ARRAY------
> +Array = array([1, 2, 3, 4, 5, 6])
> +M = 2
> +N = 3
> +Array2d = array2d(2, 3, array([1, 2, 3, 4, 5, 6]))
> diff --git a/tests/hard_coded/array2d_from_array.m 
> b/tests/hard_coded/array2d_from_array.m
> index e69de29..219bb3c 100644
> --- a/tests/hard_coded/array2d_from_array.m
> +++ b/tests/hard_coded/array2d_from_array.m
> @@ -0,0 +1,56 @@
> +%---------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%---------------------------------------------------------------------------%
> +%
> +% Test array2d.from_array/3.
> +%
> +
> +:- module array2d_from_array.
> +:- interface.
> +
> +:- import_module io.
> +
> +:- pred main(io::di, io::uo) is cc_multi.
> +
> +%---------------------------------------------------------------------------%
> +%---------------------------------------------------------------------------%
> +
> +:- implementation.
> +
> +:- import_module array.
> +:- import_module array2d.
> +:- import_module exception.
> +:- import_module list.
> +
> +main(!IO) :-
> +    test_from_array([], -1, -1, !IO),
> +    test_from_array([], 0, -1, !IO),
> +    test_from_array([], -1, 0, !IO),
> +    test_from_array([], 2, 2, !IO),              % Too few elements.
> +    test_from_array([1, 2, 3, 4, 5], 2, 2, !IO), % Too many elements.
> +    test_from_array([], 0, 0, !IO),
> +    test_from_array([1], 1, 1, !IO),
> +    test_from_array([1, 2, 3, 4], 2, 2, !IO),
> +    test_from_array([1, 2, 3, 4, 5, 6], 2, 3, !IO).
> +
> +:- pred test_from_array(list(int)::in, int::in, int::in,
> +    io::di, io::uo) is cc_multi.
> +
> +test_from_array(Elems, M, N, !IO) :-
> +    io.write_string("------FROM ARRAY------\n", !IO),
> +    Array = array.from_list(Elems),
> +    io.write_string("Array = ", !IO),
> +    io.write_line(Array, !IO),
> +    io.write_string("M = ", !IO),
> +    io.write_line(M, !IO),
> +    io.write_string("N = ", !IO),
> +    io.write_line(N, !IO),
> +    ( try []
> +        Array2d = array2d.from_array(M, N, Array)
> +    then
> +        io.write_string("Array2d = ", !IO),
> +        io.write_line(Array2d, !IO)
> +    catch software_error(E) ->
> +        io.write_string("EXCEPTION: ", !IO),
> +        io.write_line(E, !IO)
> +    ).
>
>


More information about the reviews mailing list