mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
Replace __ with . as the module qualifier symbol. Replace references to io.state with just io. Replace DCGs with state variables. Replace (C->T;E) syntax for if-then-elses with (if C then T else E) syntax. Replace if-then-elses with switches when possible and where this does not affect what is being tested. Replace separate pred and mode declarations with predmode declarations. Put predicate and function declarations just before the definition of the predicate or function. Delete unneeded module qualifications on predicate and function declarations and definitions. Update .exp files (and if needed, .inp files) for the line number changes that result from the above. For tests that have more than one .exp file and where one of those files is affected by the above, add a section to the source file header that says which .exp file is for what grade, with XXXs for the (as yet) unknown parts.
143 lines
2.9 KiB
Mathematica
143 lines
2.9 KiB
Mathematica
% vim: ts=4 sw=4 et ft=mercury
|
|
%
|
|
% This test case tests the handling of impure functions as attributes of user
|
|
% events.
|
|
%
|
|
% In this test case, the impure function, safe_counter, records the number of
|
|
% "safe" tests so far. Unfortunately, we cannot make safe_counter a zero arity
|
|
% function, since any mention of such a function is automatically converted by
|
|
% the compiler into an *invocation* of that function. This made sense when all
|
|
% functions were pure, but doesn't make sense anymore.
|
|
|
|
:- module synth_attr_impure.
|
|
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is cc_multi.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module int.
|
|
:- import_module require.
|
|
|
|
:- type listint == list(int).
|
|
|
|
main(!IO) :-
|
|
data(Data),
|
|
( if queen(Data, Out) then
|
|
print_list(Out, !IO)
|
|
else
|
|
io.write_string("No solution\n", !IO)
|
|
).
|
|
|
|
:- pred data(list(int)::out) is det.
|
|
|
|
data([1, 2, 3, 4, 5]).
|
|
|
|
:- pred queen(list(int)::in, list(int)::out) is nondet.
|
|
|
|
queen(Data, Out) :-
|
|
qperm(Data, Out),
|
|
event safe_test(Out, testlen(10), safe_counter),
|
|
safe(Out).
|
|
|
|
:- pragma foreign_decl("C",
|
|
"
|
|
extern int safe_counter;
|
|
").
|
|
|
|
:- pragma foreign_code("C",
|
|
"
|
|
int safe_counter = 0;
|
|
").
|
|
|
|
:- impure func safe_counter(list(int)) = int.
|
|
|
|
:- pragma foreign_proc("C",
|
|
safe_counter(_Out::in) = (Seq::out),
|
|
[will_not_call_mercury],
|
|
"
|
|
Seq = safe_counter++;
|
|
").
|
|
|
|
:- func testlen(int, list(int)) = int.
|
|
|
|
testlen(Min, L) = N :-
|
|
list.length(L, N0),
|
|
( if N0 >= Min then
|
|
N = N0
|
|
else
|
|
error("testlen: N < Min")
|
|
).
|
|
|
|
:- pred qperm(list(T)::in, list(T)::out) is nondet.
|
|
|
|
qperm([], []).
|
|
qperm(L, K) :-
|
|
L = [_ | _],
|
|
qdelete(U, L, Z),
|
|
K = [U | V],
|
|
qperm(Z, V).
|
|
|
|
:- pred qdelete(T::out, list(T)::in, list(T)::out) is nondet.
|
|
|
|
qdelete(A, [A | L], L).
|
|
qdelete(X, [A | Z], [A | R]) :-
|
|
qdelete(X, Z, R).
|
|
|
|
:- pred safe(list(int)::in) is semidet.
|
|
|
|
safe([]).
|
|
safe([N | L]) :-
|
|
nodiag(N, 1, L),
|
|
safe(L).
|
|
|
|
:- pred nodiag(int::in, int::in, list(int)::in) is semidet.
|
|
|
|
nodiag(_, _, []).
|
|
nodiag(B, D, [N | L]) :-
|
|
NmB = N - B,
|
|
BmN = B - N,
|
|
( if D = NmB then
|
|
event nodiag_fail("N - B", B, N, list.length, list.sort,
|
|
[N | L]),
|
|
fail
|
|
else if D = BmN then
|
|
event nodiag_fail("B - N", B, N, list.length, list.sort,
|
|
[N | L]),
|
|
fail
|
|
else
|
|
true
|
|
),
|
|
D1 = D + 1,
|
|
nodiag(B, D1, L).
|
|
|
|
:- pred print_list(list(int)::in, io::di, io::uo) is det.
|
|
|
|
print_list(Xs, !IO) :-
|
|
(
|
|
Xs = [],
|
|
io.write_string("[]\n", !IO)
|
|
;
|
|
Xs = [_ | _],
|
|
io.write_string("[", !IO),
|
|
print_list_2(Xs, !IO),
|
|
io.write_string("]\n", !IO)
|
|
).
|
|
|
|
:- pred print_list_2(list(int)::in, io::di, io::uo) is det.
|
|
|
|
print_list_2([], !IO).
|
|
print_list_2([X | Xs], !IO) :-
|
|
io.write_int(X, !IO),
|
|
(
|
|
Xs = []
|
|
;
|
|
Xs = [_ | _],
|
|
io.write_string(", ", !IO),
|
|
print_list_2(Xs, !IO)
|
|
).
|