[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