Next: , Previous: array, Up: Top   [Contents]

## 2 array2d

```%--------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%--------------------------------------------------%
% Copyright (C) 2003, 2005-2007, 2011-2012 The University of Melbourne.
% Copyright (C) 2013-2018 The Mercury team.
%--------------------------------------------------%
%
% File: array2d.m.
% Author: Ralph Becket <rafe@cs.mu.oz.au>.
% Stability: medium-low.
%
% Two-dimensional rectangular (i.e. not ragged) array ADT.
%
% XXX The same caveats re: uniqueness of arrays apply to array2ds.
%
%--------------------------------------------------%
%--------------------------------------------------%

:- module array2d.
:- interface.

:- import_module array.
:- import_module list.

%--------------------------------------------------%

% 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.)
%
:- type array2d(T).

:- inst array2d for array2d/1
--->    array2d(ground, ground, array).

% XXX These are work-arounds until we get nested uniqueness working.
%
:- mode array2d_di == di(array2d).
:- mode array2d_ui == in(array2d).
:- mode array2d_uo == out(array2d).

% init(M, N, X) = array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]])
% where each XIJ = X.  An exception is thrown if M < 0 or N < 0.
%
:- func init(int, int, T) = array2d(T).
:- mode init(in, in, in) = array2d_uo is det.

% 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.
%
:- 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 where the
% elements are taken from Array in row-major order, i.e. the element at row
% I column J is taken from Array at index (I * N + J). Indices start from
% zero. Throws an exception if M < 0 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.
%
:- pred is_empty(array2d(T)).
%:- mode is_empty(array2d_ui) is semidet.
:- mode is_empty(in) is semidet.

% bounds(array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]), M, N)
%
:- pred bounds(array2d(T), int, int).
%:- mode bounds(array2d_ui, out, out) is det.
:- mode bounds(in,       out, out) is det.

% in_bounds(array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]), I, J)
% succeeds iff 0 =< I < M, 0 =< J < N.
%
:- pred in_bounds(array2d(T), int, int).
%:- mode in_bounds(array2d_ui, in,  in ) is semidet.
:- mode in_bounds(in,       in,  in ) is semidet.

% array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]]) ^ elem(I, J) = X
% 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.
%
:- func array2d(T) ^ elem(int, int) = T.
%:- mode array2d_ui ^ elem(in,  in ) = out is det.
:- mode in       ^ elem(in,  in ) = out is det.

% T ^ unsafe_elem(I, J) is the same as T ^ elem(I, J) except that
% behaviour is undefined if not in_bounds(T, I, J).
%
:- func array2d(T) ^ unsafe_elem(int, int) = T.
%:- mode array2d_ui ^ unsafe_elem(in,  in ) = out is det.
:- mode in       ^ unsafe_elem(in,  in ) = out is det.

% ( T0 ^ elem(I, J) := X ) = T
% where T ^ elem(II, JJ) = X                 if I = II, J = JJ
% and   T ^ elem(II, JJ) = T0 ^ elem(II, JJ) otherwise.
%
% An exception is thrown unless 0 =< I < M, 0 =< J < N.
%
:- func ( array2d(T) ^ elem(int, int) := T  ) = array2d(T).
:- mode ( array2d_di ^ elem(in,  in)  := in ) = array2d_uo is det.

% Pred version of the above.
%
:- pred set(int, int, T,  array2d(T), array2d(T)).
:- mode set(in,  in,  in, array2d_di, array2d_uo) is det.

% T ^ unsafe_elem(I, J) := X is the same as T ^ elem(I, J) := X except
% that behaviour is undefined if not in_bounds(T, I, J).
%
:- func ( array2d(T) ^ unsafe_elem(int, int) := T  ) = array2d(T).
:- mode ( array2d_di ^ unsafe_elem(in,  in)  := in ) = array2d_uo is det.

% Pred version of the above.
%
:- pred unsafe_set(int, int, T,  array2d(T), array2d(T)).
:- mode unsafe_set(in,  in,  in, array2d_di, array2d_uo) is det.

% lists(array2d([[X11, ..., X1N], ..., [XM1, ..., XMN])) =
%     [[X11, ..., X1N], ..., [XM1, ..., XMN]]
%
:- func lists(array2d(T)) = list(list(T)).
%:- mode lists(array2d_ui) = out is det.
:- mode lists(in        ) = out is det.

% fill(Item, !Array2d):
% Sets every element of the array to Item.
%
:- pred fill(T::in, array2d(T)::array2d_di, array2d(T)::array2d_uo) is det.

%--------------------------------------------------%
%--------------------------------------------------%

```

Next: , Previous: array, Up: Top   [Contents]