Files
mercury/tests/hard_coded/tl_backjump_test.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

121 lines
3.5 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
%
% Test for thread-local backjumping.
%
%---------------------------------------------------------------------------%
:- module tl_backjump_test.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.
:- implementation.
:- import_module backjump.
:- import_module list.
:- import_module solutions.
:- import_module string.
:- import_module thread.
:- import_module thread.semaphore.
main(!IO) :-
( if can_spawn then
semaphore.init(1, Sem, !IO),
thread.spawn(run_problem(Sem, 2), !IO),
thread.spawn(run_problem(Sem, 3), !IO)
else
io.write_string("spawn/3 not supported in this grade", !IO)
).
:- type thread_id == int.
:- pred run_problem(semaphore::in, thread_id::in, io::di, io::uo) is cc_multi.
run_problem(Sem, TId0, !IO) :-
cc_multi_equal(TId0, TId), % Make sure we are cc_multi.
solutions(problem(Sem, TId), Sols),
(
Sols = [],
locked_write_string(Sem,
format("(TID: #%d) No solutions!\n", [i(TId)]),
!IO)
;
Sols = [_ | _],
wait(Sem, !IO),
io.format("(TID: #%d) Solutions:\n", [i(TId)], !IO),
WriteSoln =
( pred(Sol::in, !.IO::di, !:IO::uo) is det :-
io.format("(TID: #%d) ", [i(TId)], !IO),
io.write(Sol, !IO)
),
io.write_list(Sols, ",\n", WriteSoln, !IO),
io.nl(!IO),
signal(Sem, !IO)
).
:- pred problem(semaphore::in, thread_id::in, {int, int, int}::out) is nondet.
problem(Sem, TId, {A, B, C}) :-
promise_pure (
impure label(Sem, TId, "A", [1, 2], A, PA),
impure label(Sem, TId, "B", [1, 2], B, PB),
impure label(Sem, TId, "C", [1, 2, 3], C, PC),
impure check(Sem, TId, A, B, C, PA, PB, PC)
).
:- impure pred label(semaphore::in, thread_id::in, string::in,
list(int)::in, int::out, choice_id::out) is nondet.
label(Sem, TId, Name, [N | _], N, P) :-
impure get_choice_id(P),
trace [io(!IO)] (
locked_write_string(Sem, format("(TID: #%d) label %s = %d, (%d)\n",
[i(TId), s(Name), i(N), i(to_int(P))]), !IO),
true
).
label(Sem, TId, Name, [_ | Ns], N, P) :-
impure label(Sem, TId, Name, Ns, N, P).
:- impure pred check(semaphore::in, thread_id::in, int::in, int::in, int::in,
choice_id::in, choice_id::in, choice_id::in) is semidet.
check(Sem, TId, A, B, C, PA, PB, PC) :-
( if is_nogood(A, B, C, PA, PB, PC, P) then
trace [io(!IO)] (
locked_write_string(Sem,
format("(TID: #%d) backjump (%d)\n", [i(TId), i(to_int(P))]),
!IO)
),
impure backjump(P)
else
is_solution(A, B, C),
trace [io(!IO)] (
locked_write_string(Sem, format("(TID: #%d) solution %d, %d, %d\n",
[i(TId), i(A), i(B), i(C)]), !IO)
)
).
:- pred is_nogood(int::in, int::in, int::in, choice_id::in, choice_id::in,
choice_id::in, choice_id::out) is semidet.
is_nogood(1, 1, 2, _, _, P, P).
is_nogood(1, 2, 1, P, _, _, P).
is_nogood(2, 1, 2, _, P, _, P).
:- pred is_solution(int::in, int::in, int::in) is semidet.
is_solution(1, 1, 3).
is_solution(2, 1, 1).
is_solution(2, 2, 2).
:- pred locked_write_string(semaphore::in, string::in, io::di, io::uo) is det.
locked_write_string(Sem, String, !IO) :-
wait(Sem, !IO),
write_string(String, !IO),
signal(Sem, !IO).