[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