[m-rev.] diff: minor improvement to equality and comparison for arrays
Julien Fischer
jfischer at opturion.com
Wed Aug 15 09:45:30 AEST 2018
Minor improvement to equality and comparison for arrays.
library/array.m:
Use unsafe lookups in the implementation of equality and
comparison. In these cases the lookups are safe since
the necessary bounds checks are done by the caller.
Avoid unnecessary module qualification.
tests/hard_coded/Mmakefile:
tests/hard_coded/array_unify_compare.{m,exp}:
Add a systematic test for array equality and comparison.
Julien.
diff --git a/library/array.m b/library/array.m
index f02a9dd..fe07597 100644
--- a/library/array.m
+++ b/library/array.m
@@ -874,22 +874,22 @@ array_equal(Array1, Array2) :-
array.size(Array1, Size),
array.size(Array2, Size)
then
- array.equal_elements(0, Size, Array1, Array2)
+ equal_elements(0, Size, Array1, Array2)
else
fail
).
-:- pred array.equal_elements(int, int, array(T), array(T)).
-:- mode array.equal_elements(in, in, in, in) is semidet.
+:- pred equal_elements(int, int, array(T), array(T)).
+:- mode equal_elements(in, in, in, in) is semidet.
equal_elements(N, Size, Array1, Array2) :-
( if N = Size then
true
else
- array.lookup(Array1, N, Elem),
- array.lookup(Array2, N, Elem),
+ array.unsafe_lookup(Array1, N, Elem),
+ array.unsafe_lookup(Array2, N, Elem),
N1 = N + 1,
- array.equal_elements(N1, Size, Array1, Array2)
+ equal_elements(N1, Size, Array1, Array2)
).
array_compare(A1, A2) = C :-
@@ -907,7 +907,7 @@ array_compare(Result, Array1, Array2) :-
compare(SizeResult, Size1, Size2),
(
SizeResult = (=),
- array.compare_elements(0, Size1, Array1, Array2, Result)
+ compare_elements(0, Size1, Array1, Array2, Result)
;
( SizeResult = (<)
; SizeResult = (>)
@@ -922,13 +922,13 @@ compare_elements(N, Size, Array1, Array2, Result) :-
( if N = Size then
Result = (=)
else
- array.lookup(Array1, N, Elem1),
- array.lookup(Array2, N, Elem2),
+ array.unsafe_lookup(Array1, N, Elem1),
+ array.unsafe_lookup(Array2, N, Elem2),
compare(ElemResult, Elem1, Elem2),
(
ElemResult = (=),
N1 = N + 1,
- array.compare_elements(N1, Size, Array1, Array2, Result)
+ compare_elements(N1, Size, Array1, Array2, Result)
;
( ElemResult = (<)
; ElemResult = (>)
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index a418d8c..3880f06 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -16,6 +16,7 @@ ORDINARY_PROGS = \
array_all_tf \
array_gen \
array_sort \
+ array_unify_compare \
array_test \
array_test2 \
bag_various \
diff --git a/tests/hard_coded/array_unify_compare.exp b/tests/hard_coded/array_unify_compare.exp
index e69de29..348dc49 100644
--- a/tests/hard_coded/array_unify_compare.exp
+++ b/tests/hard_coded/array_unify_compare.exp
@@ -0,0 +1,51 @@
+unify(array([]), array([])) ==> true
+unify(array([]), array([1])) ==> false
+unify(array([]), array([1, 2])) ==> false
+unify(array([]), array([2, 1])) ==> false
+unify(array([]), array([2])) ==> false
+unify(array([1]), array([])) ==> false
+unify(array([1]), array([1])) ==> true
+unify(array([1]), array([1, 2])) ==> false
+unify(array([1]), array([2, 1])) ==> false
+unify(array([1]), array([2])) ==> false
+unify(array([1, 2]), array([])) ==> false
+unify(array([1, 2]), array([1])) ==> false
+unify(array([1, 2]), array([1, 2])) ==> true
+unify(array([1, 2]), array([2, 1])) ==> false
+unify(array([1, 2]), array([2])) ==> false
+unify(array([2, 1]), array([])) ==> false
+unify(array([2, 1]), array([1])) ==> false
+unify(array([2, 1]), array([1, 2])) ==> false
+unify(array([2, 1]), array([2, 1])) ==> true
+unify(array([2, 1]), array([2])) ==> false
+unify(array([2]), array([])) ==> false
+unify(array([2]), array([1])) ==> false
+unify(array([2]), array([1, 2])) ==> false
+unify(array([2]), array([2, 1])) ==> false
+unify(array([2]), array([2])) ==> true
+
+compare(array([]), array([])) ==> '='
+compare(array([]), array([1])) ==> '<'
+compare(array([]), array([1, 2])) ==> '<'
+compare(array([]), array([2, 1])) ==> '<'
+compare(array([]), array([2])) ==> '<'
+compare(array([1]), array([])) ==> '>'
+compare(array([1]), array([1])) ==> '='
+compare(array([1]), array([1, 2])) ==> '<'
+compare(array([1]), array([2, 1])) ==> '<'
+compare(array([1]), array([2])) ==> '<'
+compare(array([1, 2]), array([])) ==> '>'
+compare(array([1, 2]), array([1])) ==> '>'
+compare(array([1, 2]), array([1, 2])) ==> '='
+compare(array([1, 2]), array([2, 1])) ==> '<'
+compare(array([1, 2]), array([2])) ==> '>'
+compare(array([2, 1]), array([])) ==> '>'
+compare(array([2, 1]), array([1])) ==> '>'
+compare(array([2, 1]), array([1, 2])) ==> '>'
+compare(array([2, 1]), array([2, 1])) ==> '='
+compare(array([2, 1]), array([2])) ==> '>'
+compare(array([2]), array([])) ==> '>'
+compare(array([2]), array([1])) ==> '>'
+compare(array([2]), array([1, 2])) ==> '<'
+compare(array([2]), array([2, 1])) ==> '<'
+compare(array([2]), array([2])) ==> '='
diff --git a/tests/hard_coded/array_unify_compare.m b/tests/hard_coded/array_unify_compare.m
index e69de29..47b236d 100644
--- a/tests/hard_coded/array_unify_compare.m
+++ b/tests/hard_coded/array_unify_compare.m
@@ -0,0 +1,84 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+%
+% Test unification and comparison for arrays.
+%
+%---------------------------------------------------------------------------%
+
+:- module array_unify_compare.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module array.
+:- import_module list.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+ test_unify(test_arrays, test_arrays, !IO),
+ io.nl(!IO),
+ test_compare(test_arrays, test_arrays, !IO).
+
+:- pred test_unify(list(list(int))::in, list(list(int))::in,
+ io::di, io::uo) is det.
+
+test_unify([], _, !IO).
+test_unify([A | As], Bs, !IO) :-
+ do_test_unify(array(A), Bs, !IO),
+ test_unify(As, Bs, !IO).
+
+:- pred do_test_unify(array(int)::in, list(list(int))::in, io::di, io::uo) is det.
+
+do_test_unify(_, [], !IO).
+do_test_unify(ArrayA, [B | Bs], !IO) :-
+ ArrayB = array(B),
+ ( if ArrayA = ArrayB then
+ Result = "true"
+ else
+ Result = "false"
+ ),
+ io.format("unify(%s, %s) ==> %s\n",
+ [s(string(ArrayA)), s(string(ArrayB)), s(Result)], !IO),
+ do_test_unify(ArrayA, Bs, !IO).
+
+:- pred test_compare(list(list(int))::in, list(list(int))::in,
+ io::di, io::uo) is det.
+
+test_compare([], _, !IO).
+test_compare([A | As], Bs, !IO) :-
+ do_test_compare(array(A), Bs, !IO),
+ test_compare(As, Bs, !IO).
+
+:- pred do_test_compare(array(int)::in, list(list(int))::in, io::di, io::uo)
+ is det.
+
+do_test_compare(_, [], !IO).
+do_test_compare(ArrayA, [B | Bs], !IO) :-
+ ArrayB = array(B),
+ compare(Result, ArrayA, ArrayB),
+ io.format("compare(%s, %s) ==> %s\n",
+ [s(string(ArrayA)), s(string(ArrayB)), s(string(Result))], !IO),
+ do_test_compare(ArrayA, Bs, !IO).
+
+:- func test_arrays = list(list(int)).
+
+test_arrays = [
+ [],
+ [1],
+ [1, 2],
+ [2, 1],
+ [2]
+].
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
More information about the reviews
mailing list