mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
216 lines
4.8 KiB
Mathematica
216 lines
4.8 KiB
Mathematica
%
|
|
% Test the require tail recursion pragma with the
|
|
% --no-warn-non-tail-recursion option. These tests do not raise an error,
|
|
% the tests that do raise errors are in invalid/
|
|
%
|
|
|
|
:- module require_tailrec_2.
|
|
|
|
:- interface.
|
|
|
|
:- import_module bool.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
|
|
:- pred foldl1(pred(X, A, A), list(X), A, A).
|
|
:- mode foldl1(pred(in, in, out) is det, in, in, out) is det.
|
|
|
|
:- pred foldl2(pred(X, A, A), list(X), A, A).
|
|
:- mode foldl2(pred(in, in, out) is det, in, in, out) is det.
|
|
|
|
:- pred foldl3(pred(X, A, A), list(X), A, A).
|
|
:- mode foldl3(pred(in, in, out) is det, in, in, out) is det.
|
|
|
|
:- pred foldl4(pred(X, A, A), list(X), A, A).
|
|
:- mode foldl4(pred(in, in, out) is det, in, in, out) is det.
|
|
|
|
:- pred map1(pred(X, Y), list(X), list(Y)).
|
|
:- mode map1(pred(in, out) is det, in, out) is det.
|
|
|
|
:- pred map2(pred(X, Y), list(X), list(Y)).
|
|
:- mode map2(pred(in, out) is det, in, out) is det.
|
|
|
|
:- func even1(int) = bool.
|
|
:- func odd1(int) = bool.
|
|
|
|
:- func even2(int) = bool.
|
|
:- func odd2(int) = bool.
|
|
|
|
:- func even3(int) = bool.
|
|
:- func odd3(int) = bool.
|
|
|
|
:- func even4(int) = bool.
|
|
:- func odd4(int) = bool.
|
|
|
|
:- func even5(int) = bool.
|
|
:- func odd5(int) = bool.
|
|
|
|
:- func even6(int) = bool.
|
|
:- func odd6(int) = bool.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred qsortapp(list(int)::in, list(int)::out) is det.
|
|
|
|
:- pred qsortapp_2(list(int)::in, list(int)::out) is det.
|
|
|
|
:- implementation.
|
|
|
|
% self tail recursive code with no pragma.
|
|
foldl1(_, [], !Acc).
|
|
foldl1(P, [X | Xs], !Acc) :-
|
|
P(X, !Acc),
|
|
foldl1(P, Xs, !Acc).
|
|
|
|
% self tail recursive code with none pragma.
|
|
:- pragma require_tail_recursion(foldl2/4, [none]).
|
|
foldl2(_, [], !Acc).
|
|
foldl2(P, [X | Xs], !Acc) :-
|
|
P(X, !Acc),
|
|
foldl2(P, Xs, !Acc).
|
|
|
|
% self tail recursive code with self pragma.
|
|
:- pragma require_tail_recursion(foldl3/4, [self_recursion_only]).
|
|
foldl3(_, [], !Acc).
|
|
foldl3(P, [X | Xs], !Acc) :-
|
|
P(X, !Acc),
|
|
foldl3(P, Xs, !Acc).
|
|
|
|
% self tail recursive code with mutual pragma.
|
|
:- pragma require_tail_recursion(foldl4/4, [self_or_mutual_recursion]).
|
|
foldl4(_, [], !Acc).
|
|
foldl4(P, [X | Xs], !Acc) :-
|
|
P(X, !Acc),
|
|
foldl4(P, Xs, !Acc).
|
|
|
|
% Self non-tail recursive code with no pragma
|
|
map1(_, [], []).
|
|
map1(P, [X | Xs], [Y | Ys]) :-
|
|
P(X, Y),
|
|
map1(P, Xs, Ys).
|
|
|
|
% Self non-tail recursive code with none pragma
|
|
:- pragma require_tail_recursion(map2/3, [none]).
|
|
map2(_, [], []).
|
|
map2(P, [X | Xs], [Y | Ys]) :-
|
|
P(X, Y),
|
|
map2(P, Xs, Ys).
|
|
|
|
% Mutual tail recursion with no pragma.
|
|
even1(N) =
|
|
( if N = 0 then
|
|
yes
|
|
else
|
|
odd1(N - 1)
|
|
).
|
|
odd1(N) =
|
|
( if N = 0 then
|
|
no
|
|
else
|
|
even1(N - 1)
|
|
).
|
|
|
|
% Mutual tail recursion with none pragma.
|
|
:- pragma require_tail_recursion(even2/1, [none]).
|
|
even2(N) =
|
|
( if N = 0 then
|
|
yes
|
|
else
|
|
odd2(N - 1)
|
|
).
|
|
:- pragma require_tail_recursion(odd2/1, [none]).
|
|
odd2(N) =
|
|
( if N = 0 then
|
|
no
|
|
else
|
|
even2(N - 1)
|
|
).
|
|
|
|
% Mutual tail recursion with none pragma.
|
|
:- pragma require_tail_recursion(even3/1, [self_or_mutual_recursion]).
|
|
even3(N) =
|
|
( if N = 0 then
|
|
yes
|
|
else
|
|
odd3(N - 1)
|
|
).
|
|
odd3(N) =
|
|
( if N = 0 then
|
|
no
|
|
else
|
|
even3(N - 1)
|
|
).
|
|
|
|
even4(N) =
|
|
( if N = 0 then
|
|
yes
|
|
else
|
|
bool.not(odd4(N))
|
|
).
|
|
odd4(N) =
|
|
( if N = 0 then
|
|
no
|
|
else
|
|
bool.not(even4(N))
|
|
).
|
|
|
|
:- pragma require_tail_recursion(even5/1, [none]).
|
|
even5(N) =
|
|
( if N = 0 then
|
|
yes
|
|
else
|
|
bool.not(odd5(N))
|
|
).
|
|
odd5(N) =
|
|
( if N = 0 then
|
|
no
|
|
else
|
|
bool.not(even5(N))
|
|
).
|
|
|
|
:- pragma require_tail_recursion(even6/1, [self_recursion_only]).
|
|
even6(N) =
|
|
( if N = 0 then
|
|
yes
|
|
else
|
|
bool.not(odd6(N - 1))
|
|
).
|
|
:- pragma require_tail_recursion(odd6/1, [self_recursion_only]).
|
|
odd6(N) =
|
|
( if N = 0 then
|
|
no
|
|
else
|
|
bool.not(even6(N - 1))
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pragma require_tail_recursion(qsortapp/2, [none]).
|
|
|
|
qsortapp([], []).
|
|
qsortapp([Pivot | T], List) :-
|
|
partition(Pivot, T, [], Left0, [], Right0),
|
|
qsortapp(Left0, Left),
|
|
qsortapp(Right0, Right),
|
|
append(Left, [Pivot | Right], List).
|
|
|
|
qsortapp_2([], []).
|
|
qsortapp_2([Pivot | T], List) :-
|
|
partition(Pivot, T, [], Left0, [], Right0),
|
|
qsortapp_2(Left0, Left),
|
|
qsortapp_2(Right0, Right),
|
|
append(Left, [Pivot | Right], List).
|
|
|
|
:- pred partition(int::in, list(int)::in, list(int)::in, list(int)::out,
|
|
list(int)::in, list(int)::out) is det.
|
|
:- pragma require_tail_recursion(partition/6).
|
|
|
|
partition(_Pivot, [], Left, Left, Right, Right).
|
|
partition(Pivot, [H | T], Left0, Left, Right0, Right) :-
|
|
( if H < Pivot then
|
|
partition(Pivot, T, [H | Left0], Left, Right0, Right)
|
|
else
|
|
partition(Pivot, T, Left0, Left, [H | Right0], Right)
|
|
).
|
|
|