[m-rev.] for review: add the predicate int.all_true_in_range/3

Julien Fischer jfischer at opturion.com
Fri Jan 23 13:41:58 AEDT 2015


For review by anyone.

I am chiefly looking for feedback on the name of the new predicate.

Julien.

----------

Add the predicate int.all_true_in_range/3.

Add the predicate all_true_in_range/3 where

    all_true_in_range(P, Low, High) <=>
        list.all_true(P, Low .. High)

except that it avoids construction of the list 'Low..High'.

library/int.m:
     Add the above predicate.

     s/Lo to Hi/Low to High/ in the description of the predicate
     nondet_int_in_range/3.  We use the latter form when describing the fold
     predicates in the section above.

NEWS:
     Announce the new predicate.

     Adjust an existing entry.

tests/hard_coded/Mmakefile:
tests/hard_coded/int_range_ops.{m,exp}:
     Test the new predicate and also test the predicate 
nondet_int_in_range/3
     since none of the existing tests covered that.

diff --git a/NEWS b/NEWS
index 97ec632..9e29c31 100644
--- a/NEWS
+++ b/NEWS
@@ -124,7 +124,8 @@ Changes to the Mercury standard library:

     - fold2_maybe/6

-* The following predicates and functions have been added to the calendar module
+* The following predicates and functions have been added to the calendar
+  module:

     - int_to_month/2
     - det_int_to_month/1
@@ -138,6 +139,10 @@ Changes to the Mercury standard library:
    queue ADT.  This is a blend between a priority queue and a map.  This was
    contributed by Matthias Güdemann.

+* We have added the following predicate to the int module:
+
+  - all_true_in_range/3
+
  Changes to the Mercury compiler:

  * We have enabled stricter checking of non-ground final insts to reject more
diff --git a/library/int.m b/library/int.m
index 532617e..b4477e9 100644
--- a/library/int.m
+++ b/library/int.m
@@ -404,12 +404,20 @@
  :- mode fold_down3(pred(in, in, out, in, out, mdi, muo) is nondet,
      in, in, in, out, in, out, mdi, muo) is nondet.

-    % nondet_int_in_range(Lo, Hi, I):
+    % nondet_int_in_range(Low, High, I):
      %
-    % On successive successes, set I to every integer from Lo to Hi.
+    % On successive successes, set I to every integer from Low to High.
      %
  :- pred nondet_int_in_range(int::in, int::in, int::out) is nondet.

+    % all_true_in_range(P, Low, High):
+    % True iff P is true for every integer in Low to High.
+    %
+    % NOTE: all_true_in_range/3 is undefined if High = max_int.
+    %
+:- pred all_true_in_range(pred(int)::in(pred(in) is semidet),
+    int::in, int::in) is semidet.
+
      % Convert an int to a pretty_printer.doc for formatting.
      %
  :- func int_to_doc(int) = pretty_printer.doc.
@@ -932,6 +940,16 @@ nondet_int_in_range(Lo, Hi, I) :-

  %---------------------------------------------------------------------------%

+all_true_in_range(P, Lo, Hi) :-
+    ( if Lo =< Hi then
+        P(Lo),
+        all_true_in_range(P, Lo + 1, Hi)
+    else
+        true
+    ).
+
+%---------------------------------------------------------------------------%
+
  int_to_doc(X) = str(string.int_to_string(X)).

  %---------------------------------------------------------------------------%
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 73a2d31..75014f1 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -172,6 +172,7 @@ ORDINARY_PROGS=	\
  	intermod_pragma_clause \
  	intermod_type_qual \
  	intermod_unused_args \
+	int_range_ops \
  	java_rtti_bug \
  	join_list \
  	lco_double \
diff --git a/tests/hard_coded/int_range_ops.exp b/tests/hard_coded/int_range_ops.exp
new file mode 100644
index 0000000..cdc44fb
--- /dev/null
+++ b/tests/hard_coded/int_range_ops.exp
@@ -0,0 +1,8 @@
+solutions(nondet_int_in_range(1, 0)) = []
+solutions(nondet_int_in_range(1, 1)) = [0, 1]
+solutions(nondet_int_in_range(1, 10)) = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+all_true_in_range(int.even, 1, 0): true
+all_true_in_range(int.even, 1, 1): false
+all_true_in_range(int.odd, 1, 1): true
+all_true_in_range(LessThan10, 1, 5): true
+all_true_in_range(LessThan10, 8, 11): false
diff --git a/tests/hard_coded/int_range_ops.m b/tests/hard_coded/int_range_ops.m
new file mode 100644
index 0000000..99f4d81
--- /dev/null
+++ b/tests/hard_coded/int_range_ops.m
@@ -0,0 +1,68 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+
+% Test predicates from the int module that operate over int ranges.
+% The fold ops are tested separately in int_fold_up_down.m.
+
+:- module int_range_ops.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int.
+:- import_module list.
+:- import_module solutions.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+
+    % Test nondet_int_in_range/3.
+    solutions(nondet_int_in_range(10, 0), EmptyRangeResult),
+    io.write_string("solutions(nondet_int_in_range(1, 0)) = ", !IO),
+    io.print_line(EmptyRangeResult, !IO),
+    solutions(nondet_int_in_range(0, 1), SingletonRangeResult),
+    io.write_string("solutions(nondet_int_in_range(1, 1)) = ", !IO),
+    io.print_line(SingletonRangeResult, !IO),
+    solutions(nondet_int_in_range(1, 10), ManyRangeResult),
+    io.write_string("solutions(nondet_int_in_range(1, 10)) = ", !IO),
+    io.print_line(ManyRangeResult, !IO),
+
+    % Test all_true_in_range/3.
+    io.write_string("all_true_in_range(int.even, 1, 0): ", !IO),
+    ( if all_true_in_range(int.even, 1, 0)
+    then io.print_line("true", !IO)
+    else io.print_line("false", !IO)
+    ),
+    io.write_string("all_true_in_range(int.even, 1, 1): ", !IO),
+    ( if all_true_in_range(int.even, 1, 1)
+    then io.print_line("true", !IO)
+    else io.print_line("false", !IO)
+    ),
+    io.write_string("all_true_in_range(int.odd, 1, 1): ", !IO),
+    ( if all_true_in_range(int.odd, 1, 1)
+    then io.print_line("true", !IO)
+    else io.print_line("false", !IO)
+    ),
+    LessThan10 = (pred(I::in) is semidet :- I < 10),
+    io.write_string("all_true_in_range(LessThan10, 1, 5): ", !IO),
+    ( if all_true_in_range(LessThan10, 1, 5)
+    then io.print_line("true", !IO)
+    else io.print_line("false", !IO)
+    ),
+    io.write_string("all_true_in_range(LessThan10, 8, 11): ", !IO),
+    ( if all_true_in_range(LessThan10, 8, 11)
+    then io.print_line("true", !IO)
+    else io.print_line("false", !IO)
+    ).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%


More information about the reviews mailing list