Next: , Previous: array, Up: Top


2 array2d

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 2003, 2005-2007, 2011-2012 The University of Melbourne.
     % This file may only be copied under the terms of the GNU Library General
     % Public License - see the file COPYING.LIB in the Mercury distribution.
     %--------------------------------------------------%
     %
     % 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.
     
     %--------------------------------------------------%
     
         % A 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 ---> 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 a 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.
     
         % array2d([[X11, ..., X1N], ..., [XM1, ..., XMN]]) ^ elem(I, J) = X
         % where X is the J+1th element of the I+1th 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.
     
         % 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.
     
         % 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.
     
     %--------------------------------------------------%
     %--------------------------------------------------%