[m-rev.] New library module: table.m

Ralph Becket rafe at cs.mu.OZ.AU
Tue Jan 21 15:03:26 AEDT 2003


Estimated hours taken: 4
Branches: main

Added a new library module, table.m, implementing 2d rectangular arrays.

library/table.m:
	Added.

tests/hard_coded/test_table.m:
tests/hard_coded/test_table.exp:
tests/hard_coded/Mmakefile:
	Test case added.

Index: library/table.m
===================================================================
RCS file: library/table.m
diff -N library/table.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ library/table.m	21 Jan 2003 03:34:56 -0000
@@ -0,0 +1,188 @@
+%-----------------------------------------------------------------------------%
+% table.m
+% Ralph Becket <rafe at cs.mu.oz.au>
+% Wed Jan 15 15:17:11 EST 2003
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%
+% Two-dimensional rectangular (i.e. not ragged) array ADT.
+%
+% XXX The same caveats re: uniqueness of arrays apply to tables.
+%
+%-----------------------------------------------------------------------------%
+
+:- module table.
+
+:- interface.
+
+:- import_module int, array, list.
+
+
+
+:- type table(T).
+
+:- inst table ---> table(ground, ground, array).
+
+    % XXX These are work-arounds until we get nested uniqueness working.
+    %
+:- mode table_di == di(table).
+:- mode table_ui == in(table).
+:- mode table_uo == out(table).
+
+
+
+
+    % table([[X11, ..., X1N], ..., [XM1, ..., XMN]]) constructs a table
+    % of size M * N.
+    %
+    % An exception is thrown if the sublists are not all the same length.
+    %
+:- func table(list(list(T))) = table(T).
+:- mode table(in           ) = table_uo is det.
+
+    % new(M, N, X) = table([[X11, ..., X1N], ..., [XM1, ..., XMN]])
+    % where each XIJ = X.  An exception is thrown if M < 0 or N < 0.
+    %
+:- 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
+    %
+    % An exception is thrown unless 0 =< I < M, 0 =< J < N.
+    %
+:- func table(T) ^ elem(int, int) = T.
+:- mode table_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 table(T) ^ unsafe_elem(int, int) = T.
+:- 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]])
+    %
+    % An exception is thrown unless 0 =< I < M, 0 =< J < N.
+    %
+:- func ( table(T) ^ elem(int, int) := T  ) = table(T).
+:- mode ( table_di ^ elem(in,  in)  := in ) = table_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 ( table(T) ^ unsafe_elem(int, int) := T  ) = table(T).
+:- mode ( table_di ^ unsafe_elem(in,  in)  := in ) = table_uo is det.
+
+    % bounds(table([[X11, ..., X1N], ..., [XM1, ..., XMN]), M, N)
+    %
+:- pred bounds(table(T), int, int).
+:- mode bounds(table_ui, out, out) is det.
+:- mode bounds(in,       out, out) is det.
+
+    % in_bounds(table([[X11, ..., X1N], ..., [XM1, ..., XMN]), I, J)
+    % succeeds iff 0 =< I < M, 0 =< J < N.
+    %
+:- pred in_bounds(table(T), int, int).
+:- mode in_bounds(table_ui, in,  in ) is semidet.
+:- mode in_bounds(in,       in,  in ) is semidet.
+
+    % lists(table([[X11, ..., X1N], ..., [XM1, ..., XMN])) =
+    %     [[X11, ..., X1N], ..., [XM1, ..., XMN]]
+    %
+:- func lists(table(T)) = list(list(T)).
+:- mode lists(table_ui) = out is det.
+:- mode lists(in      ) = out is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module array, require, std_util.
+
+
+
+    % table(Rows, Cols, Array)
+    %
+:- type table(T) ---> table(int, int, array(T)).
+
+%-----------------------------------------------------------------------------%
+
+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") ).
+
+%-----------------------------------------------------------------------------%
+
+new(M, N, X) =
+    ( if   M >= 0, N >= 0
+      then table(M, N, array.init(M * N, X))
+      else func_error("table.new: bounds must be non-negative")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+bounds(table(M, N, _A), M, N).
+
+%-----------------------------------------------------------------------------%
+
+in_bounds(table(M, N, _A), I, J) :-
+    0 =< I, I < M,
+    0 =< J, J < N.
+
+%-----------------------------------------------------------------------------%
+
+T ^ elem(I, J) =
+    ( if   in_bounds(T, I, J)
+      then T ^ unsafe_elem(I, J)
+      else func_error("table.elem: indices out of bounds")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+table(_M, N, A) ^ unsafe_elem(I, J) = A ^ elem(I * N + J).
+
+%-----------------------------------------------------------------------------%
+
+( T ^ elem(I, J) := X ) =
+    ( if   in_bounds(T, I, J)
+      then T ^ unsafe_elem(I, J) := X
+      else func_error("table.'elem :=': indices out of bounds")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+( table(M, N, A) ^ unsafe_elem(I, J) := X ) = 
+    table(M, N, A ^ elem(I * N + J) := X).
+
+%-----------------------------------------------------------------------------%
+
+lists(table(M, N, A)) = lists_2((M * N) - 1, N - 1, N, A, [], []).
+
+
+:- func lists_2(int, int, int, array(T), list(T), list(list(T))) =
+            list(list(T)).
+:- mode lists_2(in,  in,  in,  array_ui, in,      in           ) = out is det.
+:- mode lists_2(in,  in,  in,  in,       in,      in           ) = out is det.
+
+lists_2(IJ, J, N, A, Xs, Xss) =
+    ( if 0 =< IJ then
+        ( if 0 =< J then
+            lists_2(IJ - 1, J - 1, N, A, [A ^ elem(IJ) | Xs], Xss       )
+          else
+            lists_2(IJ,     N - 1, N, A, [],                  [Xs | Xss])
+        )
+      else
+        [Xs | Xss]
+    ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.182
diff -u -r1.182 Mmakefile
--- tests/hard_coded/Mmakefile	17 Jan 2003 05:57:04 -0000	1.182
+++ tests/hard_coded/Mmakefile	21 Jan 2003 03:51:40 -0000
@@ -141,6 +141,7 @@
 	term_to_univ_test \
 	test_bitset \
 	test_imported_no_tag \
+	test_table \
 	tim_qual1 \
 	time_test \
 	tuple_test \
Index: tests/hard_coded/test_table.exp
===================================================================
RCS file: tests/hard_coded/test_table.exp
diff -N tests/hard_coded/test_table.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/test_table.exp	21 Jan 2003 03:51:54 -0000
@@ -0,0 +1,27 @@
+Empty =
+[[]]
+
+One =
+[[1]]
+One ^ elem(0, 0) = 1
+
+Two =
+[[1, 0]
+ [0, 2]]
+Two ^ elem(0, 0) = 1
+Two ^ elem(0, 1) = 0
+Two ^ elem(1, 0) = 0
+Two ^ elem(1, 1) = 2
+
+Two_a =
+[[1, 3]
+ [0, 2]]
+
+Two_b =
+[[1, 3]
+ [4, 2]]
+
+Zeroes =
+[[0, 0, 0]
+ [0, 0, 0]
+ [0, 0, 0]]
Index: tests/hard_coded/test_table.m
===================================================================
RCS file: tests/hard_coded/test_table.m
diff -N tests/hard_coded/test_table.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/test_table.m	21 Jan 2003 03:51:22 -0000
@@ -0,0 +1,86 @@
+%-----------------------------------------------------------------------------%
+% test_table.m
+% Ralph Becket <rafe at cs.mu.oz.au>
+% Tue Jan 21 12:38:05 EST 2003
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%
+%-----------------------------------------------------------------------------%
+
+:- module test_table.
+
+:- interface.
+
+:- import_module io.
+
+
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int, list, string, table, pprint.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+
+    Empty = table([]) `with_type` table(int),
+    write_table("Empty", Empty, !IO),
+    io.nl(!IO),
+
+    One   = table([[1]]),
+    write_table("One", One, !IO),
+    write_table_elem("One", One, 0, 0, !IO),
+    io.nl(!IO),
+
+    Two   = table([[1, 0], [0, 2]]),
+    write_table("Two", Two, !IO),
+    write_table_elem("Two", Two, 0, 0, !IO),
+    write_table_elem("Two", Two, 0, 1, !IO),
+    write_table_elem("Two", Two, 1, 0, !IO),
+    write_table_elem("Two", Two, 1, 1, !IO),
+    io.nl(!IO),
+
+    Two_a = Two ^ elem(0, 1) := 3,
+    write_table("Two_a", Two_a, !IO),
+    io.nl(!IO),
+
+    Two_b = Two_a ^ elem(1, 0) := 4,
+    write_table("Two_b", Two_b, !IO),
+    io.nl(!IO),
+
+    Zeroes = table.new(3, 3, 0),
+    write_table("Zeroes", Zeroes, !IO),
+
+    true.
+
+%-----------------------------------------------------------------------------%
+
+:- pred write_table(string, table(T), io, io).
+:- mode write_table(in,     table_ui, di, uo) is det.
+
+write_table(Name, Table, !IO) :-
+    io.format("%s =\n%s\n", [s(Name), s(string(Table))], !IO).
+
+%-----------------------------------------------------------------------------%
+
+:- pred write_table_elem(string, table(T), int, int, io, io).
+:- mode write_table_elem(in,     table_ui, in,  in,  di, uo) is det.
+
+write_table_elem(Name, Table, I, J, !IO) :-
+    io.format("%s ^ elem(%d, %d) = ", [s(Name), i(I), i(J)], !IO),
+    io.print(Table ^ elem(I, J), !IO),
+    io.nl(!IO).
+
+%-----------------------------------------------------------------------------%
+
+:- func string(table(T)) = string.
+:- mode string(table_ui) = out is det.
+
+string(T) = to_string(80, brackets(nest(1, separated(to_doc, line, lists(T))))).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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