[m-rev.] diff: standard library additions
Julien Fischer
jfischer at opturion.com
Mon Dec 16 16:11:21 AEDT 2013
Branches: master
-------------------
Add some more standard library procedures.
library/bimap.m:
Add a predicate for testing semantic equality of bimaps.
library/assoc_list.m:
Add fold_values with two or three accumulator arguments.
library/int.m:
Add fold_{up,down} with three accumulator arguments.
library/map.m:
library/tree234.m;
Add foldl_values with two or three accumulator arguments.
NEWS:
Announce the above additions.
Reformat the existing changes to the pqueue module slightly
Julien.
diff --git a/NEWS b/NEWS
index 496c14e..79bc885 100644
--- a/NEWS
+++ b/NEWS
@@ -15,8 +15,8 @@ Changes to the Mercury standard library:
* We have added the following predicates to the array and version_array
modules: is_empty/1, all_true/2 and all_false/2.
-* We have added the following functions to the map module: det_min_key/1
- and det_max_key/1.
+* We have added the following predicates and functions to the map module:
+ det_min_key/1, det_max_key/1, foldl2_values/6 and foldl3_values/8.
* We have added the following predicates to the list module: foldr2/6 and
foldr3/8.
@@ -24,14 +24,18 @@ Changes to the Mercury standard library:
* We have added the following predicates to the bag module: foldl/4 and
foldl2/6.
-* We have added the following predicate to the assoc_list module:
- foldl2_values/6.
+* We have added the following predicates to the assoc_list module:
+ foldl2_values/6 and foldl3_values/8.
-* We have added the following predicates to the pqueue module:
- is_empty/1, peek/3, peek_key/2, peek_value/2, det_peek/3 and merge/3.
- We have also added the following functions to the pqueue module:
+* We have added the following predicates and functions to the pqueue module:
+ is_empty/1, peek/3, peek_key/2, peek_value/2, det_peek/3, merge/3,
det_peek_key/1 and det_peek_value/1.
+* We have added the predicate bimap.equal/2.
+
+* We have added the following predicates to the int module: fold_up3/9 and
+ fold_down3/9.
+
Changes to the extras distribution:
* We've added a library that provides support for accessing the function
diff --git a/library/assoc_list.m b/library/assoc_list.m
index 63d0e40..7c9813a 100644
--- a/library/assoc_list.m
+++ b/library/assoc_list.m
@@ -199,6 +199,27 @@
in, out, in, out) is multi.
:- mode assoc_list.foldl2_values(pred(in, in, out, in, out) is nondet, in,
in, out, in, out) is nondet.
+
+ % As above, but with three accumulators.
+ %
+:- pred assoc_list.foldl3_values(pred(V, A, A, B, B, C, C), assoc_list(K, V),
+ A, A, B, B, C, C).
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, in, out) is det,
+ in, in, out, in, out, in, out) is det.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, mdi, muo) is det,
+ in, in, out, in, out, mdi, muo) is det.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, di, uo) is det,
+ in, in, out, in, out, di, uo) is det.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, in, out) is semidet,
+ in, in, out, in, out, in, out) is semidet.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, mdi, muo) is semidet,
+ in, in, out, in, out, mdi, muo) is semidet.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, di, uo) is semidet,
+ in, in, out, in, out, di, uo) is semidet.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, in, out) is multi,
+ in, in, out, in, out, in, out) is multi.
+:- mode assoc_list.foldl3_values(pred(in, in, out, in, out, in, out) is nondet,
+ in, in, out, in, out, in, out) is nondet.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -392,6 +413,12 @@ assoc_list.foldl2_values(P, [KV | KVs], !Acc1, !Acc2) :-
P(V, !Acc1, !Acc2),
assoc_list.foldl2_values(P, KVs, !Acc1, !Acc2).
+assoc_list.foldl3_values(_, [], !Acc1, !Acc2, !Acc3).
+assoc_list.foldl3_values(P, [KV | KVs], !Acc1, !Acc2, !Acc3) :-
+ KV = _K - V,
+ P(V, !Acc1, !Acc2, !Acc3),
+ assoc_list.foldl3_values(P, KVs, !Acc1, !Acc2, !Acc3).
+
%-----------------------------------------------------------------------------%
:- end_module assoc_list.
%-----------------------------------------------------------------------------%
diff --git a/library/bimap.m b/library/bimap.m
index 4fd8a5b..c52b203 100644
--- a/library/bimap.m
+++ b/library/bimap.m
@@ -46,6 +46,15 @@
%
:- pred bimap.is_empty(bimap(K, V)::in) is semidet.
+ % True if both bimaps have the same set of key-value pairs, regardless of
+ % how the bimaps were constructed.
+ %
+ % Unifying bimaps does not work as one might expect because the internal
+ % structures of two bimaps that contain the same set of key-value pairs
+ % may be different.
+ %
+:- pred bimap.equal(bimap(K, V)::in, bimap(K, V)::in) is semidet.
+
% Search the bimap. The first mode searches for a value given a key
% and the second mode searches for a key given a value.
%
@@ -358,6 +367,11 @@ bimap.singleton(K, V) = B:-
bimap.is_empty(bimap(Forward, _)) :-
map.is_empty(Forward). % by inference == map.is_empty(Reverse).
+bimap.equal(BMA, BMB) :-
+ BMA = bimap(ForwardA, _ReverseA),
+ BMB = bimap(ForwardB, _ReverseB),
+ map.equal(ForwardA, ForwardB).
+
bimap.search(bimap(Forward, Reverse), K, V) :-
map.search(Forward, K, V),
map.search(Reverse, V, K).
diff --git a/library/int.m b/library/int.m
index 2530b70..3a86657 100644
--- a/library/int.m
+++ b/library/int.m
@@ -349,6 +349,60 @@
in, out, in, out) is nondet.
:- mode int.fold_down2(pred(in, in, out, mdi, muo) is nondet, in, in,
in, out, mdi, muo) is nondet.
+
+ % fold_up3(F, Low, High, !Acc1, Acc2, !Acc3) <=>
+ % list.foldl3(F, Low .. High, !Acc1, !Acc2, !Acc3)
+ %
+ % NOTE: fold_up3/9 is undefined if High = int.max_int.
+ %
+:- pred int.fold_up3(pred(int, T, T, U, U, V, V), int, int, T, T, U, U, V, V).
+:- mode int.fold_up3(pred(in, in, out, in, out, in, out) is det,
+ in, in, in, out, in, out, in, out) is det.
+:- mode int.fold_up3(pred(in, in, out, in, out, mdi, muo) is det,
+ in, in, in, out, in, out, mdi, muo) is det.
+:- mode int.fold_up3(pred(in, in, out, in, out, di, uo) is det,
+ in, in, in, out, in, out, di, uo) is det.
+:- mode int.fold_up3(pred(in, in, out, di, uo, di, uo) is det,
+ in, in, in, out, di, uo, di, uo) is det.
+:- mode int.fold_up3(pred(in, in, out, in, out, array_di, array_uo) is det,
+ in, in, in, out, in, out, array_di, array_uo) is det.
+:- mode int.fold_up3(pred(in, in, out, in, out, in, out) is semidet,
+ in, in, in, out, in, out, in, out) is semidet.
+:- mode int.fold_up3(pred(in, in, out, in, out, mdi, muo) is semidet,
+ in, in, in, out, in, out, mdi, muo) is semidet.
+:- mode int.fold_up3(pred(in, in, out, in, out, di, uo) is semidet,
+ in, in, in, out, in, out, di, uo) is semidet.
+:- mode int.fold_up3(pred(in, in, out, in, out, in, out) is nondet,
+ in, in, in, out, in, out, in, out) is nondet.
+:- mode int.fold_up3(pred(in, in, out, in, out, mdi, muo) is nondet,
+ in, in, in, out, in, out, mdi, muo) is nondet.
+
+ % fold_up3(F, Low, High, !Acc1, Acc2, !Acc3) <=>
+ % list.foldr3(F, Low .. High, !Acc1, !Acc2, !Acc3)
+ %
+ % NOTE: fold_down3/9 is undefined if Low = int.min_int.
+ %
+:- pred int.fold_down3(pred(int, T, T, U, U, V, V), int, int, T, T, U, U, V, V).
+:- mode int.fold_down3(pred(in, in, out, in, out, in, out) is det,
+ in, in, in, out, in, out, in, out) is det.
+:- mode int.fold_down3(pred(in, in, out, in, out, mdi, muo) is det,
+ in, in, in, out, in, out, mdi, muo) is det.
+:- mode int.fold_down3(pred(in, in, out, in, out, di, uo) is det,
+ in, in, in, out, in, out, di, uo) is det.
+:- mode int.fold_down3(pred(in, in, out, di, uo, di, uo) is det,
+ in, in, in, out, di, uo, di, uo) is det.
+:- mode int.fold_down3(pred(in, in, out, in, out, array_di, array_uo) is det,
+ in, in, in, out, in, out, array_di, array_uo) is det.
+:- mode int.fold_down3(pred(in, in, out, in, out, in, out) is semidet,
+ in, in, in, out, in, out, in, out) is semidet.
+:- mode int.fold_down3(pred(in, in, out, in, out, mdi, muo) is semidet,
+ in, in, in, out, in, out, mdi, muo) is semidet.
+:- mode int.fold_down3(pred(in, in, out, in, out, di, uo) is semidet,
+ in, in, in, out, in, out, di, uo) is semidet.
+:- mode int.fold_down3(pred(in, in, out, in, out, in, out) is nondet,
+ in, in, in, out, in, out, in, out) is nondet.
+:- mode int.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):
%
@@ -831,6 +885,12 @@ int.fold_up2(P, Lo, Hi, !A, !B) :-
else true
).
+int.fold_up3(P, Lo, Hi, !A, !B, !C) :-
+ ( if Lo =< Hi
+ then P(Lo, !A, !B, !C), int.fold_up3(P, Lo + 1, Hi, !A, !B, !C)
+ else true
+ ).
+
%-----------------------------------------------------------------------------%
int.fold_down(P, Lo, Hi, !A) :-
@@ -848,6 +908,14 @@ int.fold_down2(P, Lo, Hi, !A, !B) :-
else true
).
+int.fold_down3(P, Lo, Hi, !A, !B, !C) :-
+ ( if Lo =< Hi
+ then P(Hi, !A, !B, !C), int.fold_down3(P, Lo, Hi - 1, !A, !B, !C)
+ else true
+ ).
+
+%-----------------------------------------------------------------------------%
+
nondet_int_in_range(Lo, Hi, I) :-
% Leave a choice point only if there is at least one solution
% to find on backtracking.
diff --git a/library/map.m b/library/map.m
index 24d225c..3bd416e 100644
--- a/library/map.m
+++ b/library/map.m
@@ -456,6 +456,51 @@
:- mode map.foldl_values(pred(in, mdi, muo) is cc_multi, in, mdi, muo)
is cc_multi.
+ % As above, but with two accumulators.
+ %
+:- pred map.foldl2_values(pred(V, A, A, B, B), map(K, V), A, A, B, B).
+:- mode map.foldl2_values(pred(in, in, out, in, out) is det, in,
+ in, out, in, out) is det.
+:- mode map.foldl2_values(pred(in, in, out, mdi, muo) is det, in,
+ in, out, mdi, muo) is det.
+:- mode map.foldl2_values(pred(in, in, out, di, uo) is det, in,
+ in, out, di, uo) is det.
+:- mode map.foldl2_values(pred(in, in, out, in, out) is semidet, in,
+ in, out, in, out) is semidet.
+:- mode map.foldl2_values(pred(in, in, out, mdi, muo) is semidet, in,
+ in, out, mdi, muo) is semidet.
+:- mode map.foldl2_values(pred(in, in, out, di, uo) is semidet, in,
+ in, out, di, uo) is semidet.
+:- mode map.foldl2_values(pred(in, in, out, in, out) is cc_multi, in,
+ in, out, in, out) is cc_multi.
+:- mode map.foldl2_values(pred(in, in, out, mdi, muo) is cc_multi, in,
+ in, out, mdi, muo) is cc_multi.
+:- mode map.foldl2_values(pred(in, in, out, di, uo) is cc_multi, in,
+ in, out, di, uo) is cc_multi.
+
+ % As above, but with three accumulators.
+ %
+:- pred map.foldl3_values(pred(V, A, A, B, B, C, C), map(K, V),
+ A, A, B, B, C, C).
+:- mode map.foldl3_values(pred(in, in, out, in, out, in, out) is det, in,
+ in, out, in, out, in, out) is det.
+:- mode map.foldl3_values(pred(in, in, out, in, out, mdi, muo) is det, in,
+ in, out, in, out, mdi, muo) is det.
+:- mode map.foldl3_values(pred(in, in, out, in, out, di, uo) is det, in,
+ in, out, in, out, di, uo) is det.
+:- mode map.foldl3_values(pred(in, in, out, in, out, in, out) is semidet, in,
+ in, out, in, out, in, out) is semidet.
+:- mode map.foldl3_values(pred(in, in, out, in, out, mdi, muo) is semidet, in,
+ in, out, in, out, mdi, muo) is semidet.
+:- mode map.foldl3_values(pred(in, in, out, in, out, di, uo) is semidet, in,
+ in, out, in, out, di, uo) is semidet.
+:- mode map.foldl3_values(pred(in, in, out, in, out, in, out) is cc_multi, in,
+ in, out, in, out, in, out) is cc_multi.
+:- mode map.foldl3_values(pred(in, in, out, in, out, mdi, muo) is cc_multi, in,
+ in, out, in, out, mdi, muo) is cc_multi.
+:- mode map.foldl3_values(pred(in, in, out, in, out, di, uo) is cc_multi, in,
+ in, out, in, out, di, uo) is cc_multi.
+
:- func map.foldr(func(K, V, A) = A, map(K, V), A) = A.
:- pred map.foldr(pred(K, V, A, A), map(K, V), A, A).
:- mode map.foldr(pred(in, in, in, out) is det, in, in, out) is det.
@@ -1263,6 +1308,12 @@ map.foldl4(Pred, Map, !A, !B, !C, !D) :-
map.foldl_values(Pred, Map, !A) :-
tree234.foldl_values(Pred, Map, !A).
+map.foldl2_values(Pred, Map, !A, !B) :-
+ tree234.foldl2_values(Pred, Map, !A, !B).
+
+map.foldl3_values(Pred, Map, !A, !B, !C) :-
+ tree234.foldl3_values(Pred, Map, !A, !B, !C).
+
map.foldr(F, M, A) = B :-
P = (pred(W::in, X::in, Y::in, Z::out) is det :- Z = F(W, X, Y) ),
map.foldr(P, M, A, B).
diff --git a/library/tree234.m b/library/tree234.m
index 7aa6efd..01422fc 100644
--- a/library/tree234.m
+++ b/library/tree234.m
@@ -300,6 +300,47 @@
:- mode tree234.foldl_values(pred(in, mdi, muo) is cc_multi, in, mdi, muo)
is cc_multi.
+:- pred tree234.foldl2_values(pred(V, A, A, B, B), tree234(K, V), A, A, B, B).
+:- mode tree234.foldl2_values(pred(in, in, out, in, out) is det, in,
+ in, out, in, out) is det.
+:- mode tree234.foldl2_values(pred(in, in, out, mdi, muo) is det, in,
+ in, out, mdi, muo) is det.
+:- mode tree234.foldl2_values(pred(in, in, out, di, uo) is det, in,
+ in, out, di, uo) is det.
+:- mode tree234.foldl2_values(pred(in, in, out, in, out) is semidet, in,
+ in, out, in, out) is semidet.
+:- mode tree234.foldl2_values(pred(in, in, out, mdi, muo) is semidet, in,
+ in, out, mdi, muo) is semidet.
+:- mode tree234.foldl2_values(pred(in, in, out, di, uo) is semidet, in,
+ in, out, di, uo) is semidet.
+:- mode tree234.foldl2_values(pred(in, in, out, in, out) is cc_multi, in,
+ in, out, in, out) is cc_multi.
+:- mode tree234.foldl2_values(pred(in, in, out, mdi, muo) is cc_multi, in,
+ in, out, mdi, muo) is cc_multi.
+:- mode tree234.foldl2_values(pred(in, in, out, di, uo) is cc_multi, in,
+ in, out, di, uo) is cc_multi.
+
+:- pred tree234.foldl3_values(pred(V, A, A, B, B, C, C), tree234(K, V),
+ A, A, B, B, C, C).
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, in, out) is det,
+ in, in, out, in, out, in, out) is det.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, mdi, muo) is det,
+ in, in, out, in, out, mdi, muo) is det.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, di, uo) is det,
+ in, in, out, in, out, di, uo) is det.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, in, out) is semidet,
+ in, in, out, in, out, in, out) is semidet.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, mdi, muo) is semidet,
+ in, in, out, in, out, mdi, muo) is semidet.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, di, uo) is semidet,
+ in, in, out, in, out, di, uo) is semidet.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, in, out) is cc_multi,
+ in, in, out, in, out, in, out) is cc_multi.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, mdi, muo) is cc_multi,
+ in, in, out, in, out, mdi, muo) is cc_multi.
+:- mode tree234.foldl3_values(pred(in, in, out, in, out, di, uo) is cc_multi,
+ in, in, out, in, out, di, uo) is cc_multi.
+
:- func tree234.foldr(func(K, V, A) = A, tree234(K, V), A) = A.
:- pred tree234.foldr(pred(K, V, A, A), tree234(K, V), A, A).
@@ -3831,6 +3872,48 @@ tree234.foldl_values(Pred, four(_K0, V0, _K1, V1, _K2, V2, T0, T1, T2, T3),
Pred(V2, !A),
tree234.foldl_values(Pred, T3, !A).
+tree234.foldl2_values(_Pred, empty, !A, !B).
+tree234.foldl2_values(Pred, two(_K, V, T0, T1), !A, !B) :-
+ tree234.foldl2_values(Pred, T0, !A, !B),
+ Pred(V, !A, !B),
+ tree234.foldl2_values(Pred, T1, !A, !B).
+tree234.foldl2_values(Pred, three(_K0, V0, _K1, V1, T0, T1, T2), !A, !B) :-
+ tree234.foldl2_values(Pred, T0, !A, !B),
+ Pred(V0, !A, !B),
+ tree234.foldl2_values(Pred, T1, !A, !B),
+ Pred(V1, !A, !B),
+ tree234.foldl2_values(Pred, T2, !A, !B).
+tree234.foldl2_values(Pred, four(_K0, V0, _K1, V1, _K2, V2, T0, T1, T2, T3),
+ !A, !B) :-
+ tree234.foldl2_values(Pred, T0, !A, !B),
+ Pred(V0, !A, !B),
+ tree234.foldl2_values(Pred, T1, !A, !B),
+ Pred(V1, !A, !B),
+ tree234.foldl2_values(Pred, T2, !A, !B),
+ Pred(V2, !A, !B),
+ tree234.foldl2_values(Pred, T3, !A, !B).
+
+tree234.foldl3_values(_Pred, empty, !A, !B, !C).
+tree234.foldl3_values(Pred, two(_K, V, T0, T1), !A, !B, !C) :-
+ tree234.foldl3_values(Pred, T0, !A, !B, !C),
+ Pred(V, !A, !B, !C),
+ tree234.foldl3_values(Pred, T1, !A, !B, !C).
+tree234.foldl3_values(Pred, three(_K0, V0, _K1, V1, T0, T1, T2), !A, !B, !C) :-
+ tree234.foldl3_values(Pred, T0, !A, !B, !C),
+ Pred(V0, !A, !B, !C),
+ tree234.foldl3_values(Pred, T1, !A, !B, !C),
+ Pred(V1, !A, !B, !C),
+ tree234.foldl3_values(Pred, T2, !A, !B, !C).
+tree234.foldl3_values(Pred, four(_K0, V0, _K1, V1, _K2, V2, T0, T1, T2, T3),
+ !A, !B, !C) :-
+ tree234.foldl3_values(Pred, T0, !A, !B, !C),
+ Pred(V0, !A, !B, !C),
+ tree234.foldl3_values(Pred, T1, !A, !B, !C),
+ Pred(V1, !A, !B, !C),
+ tree234.foldl3_values(Pred, T2, !A, !B, !C),
+ Pred(V2, !A, !B, !C),
+ tree234.foldl3_values(Pred, T3, !A, !B, !C).
+
%------------------------------------------------------------------------------%
tree234.foldr(F, T, A) = B :-
More information about the reviews
mailing list