Files
mercury/tests/hard_coded/stable_sort.m
Zoltan Somogyi 2bd7c5ee3e Rename X's aux modules as X_helper_N in hard_coded.
tests/hard_coded/*.m:
    Rename modules as mentioned above.

    In a few cases, where the main module's name itself had a suffix,
    such as "_mod_a" or "_main", remove that suffix. This entails
    renaming the .exp file as well. (In some cases, this meant that
    the name of a helper module was "taken over" by the main module
    of the test case.)

    Update all references to the moved modules.

    General updates to programming style, such as

    - replacing DCG notation with state var notation
    - replacing (C->T;E) with (if C then T else E)
    - moving pred/func declarations to just before their code
    - replacing io.write/io.nl sequences with io.write_line
    - replacing io.print/io.nl sequences with io.print_line
    - fixing too-long lines
    - fixing grammar errors in comments

tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
    Update all references to the moved modules.

    Enable the constant_prop_int test case. The fact that it wasn't enabled
    before is probably an accident. (When constant_prop_int.m was created,
    the test case was added to a list in the Mmakefile, but that list
    was later removed due to never being referenced.)

tests/hard_coded/constant_prop_int.{m,exp}:
    Delete the calls to shift operations with negative shift amounts,
    since we have added a compile-time error for these since the test
    was originally created.
2023-06-16 08:33:22 +02:00

88 lines
2.6 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
%
% Test whether list.sort is stable.
%
%---------------------------------------------------------------------------%
:- module stable_sort.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module bool.
:- import_module int.
:- import_module list.
:- import_module random.
:- import_module random.sfc16.
main(!IO) :-
generate_random_list(List),
% io.write_line(List, !IO),
% io.write_line(sort(List) `with_type` list({int, int}), !IO),
is_sort_stable(List, Stable),
(
Stable = yes,
io.write_string("list.sort/3 appears stable\n", !IO)
;
Stable = no,
io.write_string("list.sort/3 is not stable\n", !IO)
).
:- pred generate_random_list(list({int, int})::out) is det.
generate_random_list(List) :-
RandomState0 = random.sfc16.init,
% We generate random integers from 0 to 9. The list length must be
% large enough to ensure that there are plenty of duplications,
% otherwise the test is trivial.
Count = 100,
generate_random_list_2(Count, [], List, RandomState0, _).
:- pred generate_random_list_2(int::in,
list({int, int})::in, list({int, int})::out,
RandomState::in, RandomState::out) is det <= random(RandomState).
generate_random_list_2(Count, List0, List, !RandomState) :-
( if Count > 0 then
uniform_int_in_range(0, 9, R1, !RandomState),
uniform_int_in_range(0, 9, R2, !RandomState),
generate_random_list_2(Count - 1, [{R1, R2} | List0], List,
!RandomState)
else
List = List0
).
:- pred is_sort_stable(list({int, int})::in, bool::out) is det.
is_sort_stable(Unsorted, Stable) :-
% If the sort is stable, then sorting on the second component
% followed by sorting on the first component *should* give a
% fully sorted result.
list.sort(compare_second, Unsorted, SortedOnSecond),
list.sort(compare_first, SortedOnSecond, SortedOnSecondThenFirst),
% Check whether the result is fully sorted.
list.sort(Unsorted, Sorted),
( if SortedOnSecondThenFirst = Sorted then
Stable = yes
else
Stable = no
).
:- pred compare_first({int, int}::in, {int, int}::in, comparison_result::out)
is det.
compare_first({A, _}, {B, _}, Res) :-
compare(Res, A, B).
:- pred compare_second({int, int}::in, {int, int}::in, comparison_result::out)
is det.
compare_second({_, A}, {_, B}, Res) :-
compare(Res, A, B).