Files
mercury/tests/hard_coded/test_bag.m
Zoltan Somogyi 90462e8c36 Improve bag.m.
library/bag.m:
    The old implementations of bag.subtract, bag.least_upper_bound,
    bag.union, bag.intersect iterated over their second bag arguments,
    and did a logarithmic amount of work in each iteration. This is good
    if the second bag is small, but not if it is big. Keep those
    implementations as the implementation of bag.subtract_small,
    bag.least_upper_bound_small etc, and replace the implementation
    of bag.subtract etc with code that iterates over the assoc_list version
    of both bags. This does work that linear in total size of the two sets.

    Replace the implementation of bag.subset_compare with one
    that actually works.

    Replace the implementation of bag.is_subbag with one that
    does significantly less work.

    Group related predicates together.

    Improve the documentation of the exported predicates.

    Use a more descriptive and more consistent set of variable names.

tests/hard_coded/test_bag.{m,exp}:
    A new test case, to test the new algorithms in bag.m.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2015-09-02 05:57:46 +10:00

127 lines
4.0 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module test_bag.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module bag.
:- import_module list.
main(!IO) :-
Bag111 = bag.from_list([11, 12, 13]) : bag(int),
% Bag122 = bag.from_list([11, 12, 12, 13, 13]) : bag(int),
Bag212 = bag.from_list([11, 11, 12, 13, 13]) : bag(int),
% Bag221 = bag.from_list([11, 11, 12, 13, 13]) : bag(int),
Bag222 = bag.from_list([11, 11, 12, 12, 13, 13]) : bag(int),
BagS = bag.from_list([5, 5, 6]) : bag(int),
BagL = bag.from_list([25, 26, 26]) : bag(int),
BagSM = bag.from_list([5, 5, 6, 12]) : bag(int),
BagSL = bag.from_list([5, 5, 6, 25, 26, 26]) : bag(int),
BagML = bag.from_list([12, 25, 26, 26]) : bag(int),
BagSML = bag.from_list([5, 5, 6, 25, 12, 26, 26]) : bag(int),
AllBags = [Bag111, Bag212, Bag222,
BagS, BagL, BagSL, BagSM, BagML, BagSML],
test_bag_combinations_outer_loop(AllBags, AllBags, !IO).
:- pred test_bag_combinations_outer_loop(
list(bag(int))::in, list(bag(int))::in,
io::di, io::uo) is det.
test_bag_combinations_outer_loop([], _, !IO).
test_bag_combinations_outer_loop([OuterBag | OuterBags], InnerBags, !IO) :-
test_bag_combinations_inner_loop(OuterBag, InnerBags, !IO),
test_bag_combinations_outer_loop(OuterBags, InnerBags, !IO).
:- pred test_bag_combinations_inner_loop(bag(int)::in, list(bag(int))::in,
io::di, io::uo) is det.
test_bag_combinations_inner_loop(_OuterBag, [], !IO).
test_bag_combinations_inner_loop(OuterBag, [InnerBag | InnerBags], !IO) :-
test_bag_combination(OuterBag, InnerBag, !IO),
test_bag_combinations_inner_loop(OuterBag, InnerBags, !IO).
:- pred test_bag_combination(bag(int)::in, bag(int)::in,
io::di, io::uo) is det.
test_bag_combination(BagA, BagB, !IO) :-
bag.to_list(BagA, ListA),
bag.to_list(BagB, ListB),
io.write_string("-----------------------------------------", !IO),
io.nl(!IO),
io.write_string("BagA = ", !IO),
io.write(ListA, !IO),
io.nl(!IO),
io.write_string("BagB = ", !IO),
io.write(ListB, !IO),
io.nl(!IO),
bag.subtract(BagA, BagB, BagAmB),
bag.subtract_small(BagA, BagB, BagAmBS),
bag.to_list(BagAmB, ListAmB),
bag.to_list(BagAmBS, ListAmBS),
io.write_string("A subtract B: ", !IO),
io.write(ListAmB, !IO),
io.write_string(maybe_agree(ListAmB, ListAmBS), !IO),
io.nl(!IO),
bag.least_upper_bound(BagA, BagB, BagAlubB),
bag.least_upper_bound_small(BagA, BagB, BagAlubBS),
bag.to_list(BagAlubB, ListAlubB),
bag.to_list(BagAlubBS, ListAlubBS),
io.write_string("A least_upper_bound B: ", !IO),
io.write(ListAlubB, !IO),
io.write_string(maybe_agree(ListAlubB, ListAlubBS), !IO),
io.nl(!IO),
bag.union(BagA, BagB, BagAuB),
bag.union_small(BagA, BagB, BagAuBS),
bag.to_list(BagAuB, ListAuB),
bag.to_list(BagAuBS, ListAuBS),
io.write_string("A union B: ", !IO),
io.write(ListAuB, !IO),
io.write_string(maybe_agree(ListAuB, ListAuBS), !IO),
io.nl(!IO),
bag.intersect(BagA, BagB, BagAiB),
bag.intersect_small(BagA, BagB, BagAiBS),
bag.to_list(BagAiB, ListAiB),
bag.to_list(BagAiBS, ListAiBS),
io.write_string("A intersect B: ", !IO),
io.write(ListAiB, !IO),
io.write_string(maybe_agree(ListAiB, ListAiBS), !IO),
io.nl(!IO),
io.write_string("A ", !IO),
( if bag.subset_compare(CmpRes, BagA, BagB) then
io.write(CmpRes, !IO)
else
io.write_string("incomparable", !IO)
),
io.write_string(" B", !IO),
io.nl(!IO),
io.write_string("-----------------------------------------", !IO),
io.nl(!IO).
:- func maybe_agree(list(int), list(int)) = string.
maybe_agree(ListA, ListB) = Str :-
( if ListA = ListB then
Str = ""
else
Str = " disagree"
).