[m-rev.] New library module: table.m
Ralph Becket
rafe at cs.mu.OZ.AU
Tue Jan 21 18:26:01 AEDT 2003
Fergus Henderson, Tuesday, 21 January 2003:
> On 21-Jan-2003, Ralph Becket <rafe at cs.mu.OZ.AU> wrote:
> > Added a new library module, table.m, implementing 2d rectangular arrays.
>
> Hmm. Would it be better to name this `array2d', or `matrix',
> rather than `table'?
>
> I think I prefer the name `array2d'.
I thought about this one and ended up with `table'; `matrix' suggests
a numerical array to me. I'm happy to change if there's a majority
preference.
> > tests/hard_coded/test_table.m:
> > tests/hard_coded/test_table.exp:
> > tests/hard_coded/Mmakefile:
> > Test case added.
>
> The test case should IMHO also test that the implementation does bounds
> checking.
Done.
> > Index: library/table.m
> > + % table([[X11, ..., X1N], ..., [XM1, ..., XMN]]) constructs a table
> > + % of size M * N.
> ...
> > + % new(M, N, X) = table([[X11, ..., X1N], ..., [XM1, ..., XMN]])
> > + % where each XIJ = X.
> ...
> > + % table([[X11, ..., X1N], ..., [XM1, ..., XMN]]) ^ elem(I, J) = XIJ
> > + %
> > + % An exception is thrown unless 0 =< I < M, 0 =< J < N.
>
> Do table indexes start at zero, or at 1?
>
> The documentation for `elem' is contradictory on this point.
> The use of "X11, ..., X1N" in the documentation of `table',
> `new', and `elem' strongly suggests that indexes start at 1.
> And the definition of elem(I, J) = XIJ confirms it.
> But then the bit about when exceptions get thrown contradicts this.
You're right. Indices start at zero; I've changed the documentation.
> > + % table(Rows, Cols, Array)
> > + %
> > +:- type table(T) ---> table(int, int, array(T)).
>
> You should document here whether the table is stored in
> row-major or column-major order.
Done.
> > +table(Xss @ [Xs | _]) = T :-
> > +
> > + M = length(Xss),
> > + N = length(Xs),
> > + T = table(M, N, A @ array(condense(Xss))),
> > +
> > + ( size(A) \= M * N =>
> > + error("table.table/1: non-rectangular list of lists") ).
>
> The error condition might not get checked if this code is compiled
> with --no-fully-strict, which would contravene the documentation for
> this function. So either the code should be rewritten so that it
> only binds T in the case when size(A) = M * N, or you should add a comment
> here and also in the Mmakefile, where it passes `--strict-sequential',
> saying that this code relies on it. I recommend the former.
Fixed.
Here's the interdiff:
diff -u library/table.m library/table.m
--- library/table.m 21 Jan 2003 03:34:56 -0000
+++ library/table.m 21 Jan 2003 07:21:15 -0000
@@ -18,6 +18,10 @@
+ % A table 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 table(T).
:- inst table ---> table(ground, ground, array).
@@ -32,7 +36,7 @@
% table([[X11, ..., X1N], ..., [XM1, ..., XMN]]) constructs a table
- % of size M * N.
+ % of size M * N, with the special case that bounds(table([]), 0, 0).
%
% An exception is thrown if the sublists are not all the same length.
%
@@ -45,7 +49,9 @@
:- func new(int, int, T ) = table(T).
:- mode new(in, in, in) = table_uo is det.
- % table([[X11, ..., X1N], ..., [XM1, ..., XMN]]) ^ elem(I, J) = XIJ
+ % table([[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.
%
@@ -60,8 +66,9 @@
:- mode table_ui ^ unsafe_elem(in, in ) = out is det.
:- mode in ^ unsafe_elem(in, in ) = out is det.
- % ( table([[X11, ..., X1N], ..., [XM1, ..., XMN]]) ^ elem(I, J) := XIJ ) =
- % table([[X11, ..., X1N], ..., [..., XIJ, ...], ..., [XM1, ..., XMN]])
+ % ( 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.
%
@@ -111,21 +118,23 @@
table( [] ) = table(0, 0, make_empty_array).
-table(Xss @ [Xs | _]) = T :-
-
- M = length(Xss),
- N = length(Xs),
- T = table(M, N, A @ array(condense(Xss))),
-
- ( size(A) \= M * N =>
- error("table.table/1: non-rectangular list of lists") ).
+table(Xss @ [Xs | _]) =
+ ( if
+ M = length(Xss),
+ N = length(Xs),
+ all [Ys] ( member(Ys, Xss) => length(Ys) = N ),
+ then
+ table(M, N, array(condense(Xss)))
+ else
+ func_error("table.table/1: non-rectangular list of lists")
+ ).
%-----------------------------------------------------------------------------%
new(M, N, X) =
( if M >= 0, N >= 0
then table(M, N, array.init(M * N, X))
- else func_error("table.new: dimensions must be non-negative")
+ else func_error("table.new: bounds must be non-negative")
).
%-----------------------------------------------------------------------------%
diff -u tests/hard_coded/test_table.m tests/hard_coded/test_table.m
--- tests/hard_coded/test_table.m 21 Jan 2003 03:51:22 -0000
+++ tests/hard_coded/test_table.m 21 Jan 2003 07:01:27 -0000
@@ -14,14 +14,14 @@
-:- pred main(io::di, io::uo) is det.
+:- pred main(io::di, io::uo) is cc_multi.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module int, list, string, table, pprint.
+:- import_module int, list, string, table, pprint, exception.
%-----------------------------------------------------------------------------%
@@ -54,6 +54,22 @@
Zeroes = table.new(3, 3, 0),
write_table("Zeroes", Zeroes, !IO),
+
+ try((pred(X::out) is det :- X = Empty ^ elem( 0, 0)), Ea),
+ try((pred(X::out) is det :- X = Zeroes ^ elem(-1, 0)), Eb),
+ try((pred(X::out) is det :- X = Zeroes ^ elem( 0, -1)), Ec),
+ try((pred(X::out) is det :- X = Zeroes ^ elem(-1, -1)), Ed),
+ try((pred(X::out) is det :- X = Zeroes ^ elem( 3, 0)), Ee),
+ try((pred(X::out) is det :- X = Zeroes ^ elem( 0, 3)), Ef),
+ try((pred(X::out) is det :- X = Zeroes ^ elem( 3, 3)), Eg),
+
+ io.print(Ea, !IO), io.nl(!IO),
+ io.print(Eb, !IO), io.nl(!IO),
+ io.print(Ec, !IO), io.nl(!IO),
+ io.print(Ed, !IO), io.nl(!IO),
+ io.print(Ee, !IO), io.nl(!IO),
+ io.print(Ef, !IO), io.nl(!IO),
+ io.print(Eg, !IO), io.nl(!IO),
true.
Cheers,
Ralph
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list