[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