Files
mercury/tests/general/complex_failure.m
Zoltan Somogyi 33eb3028f5 Clean up the tests in half the test directories.
tests/accumulator/*.m:
tests/analysis_*/*.m:
tests/benchmarks*/*.m:
tests/debugger*/*.{m,exp,inp}:
tests/declarative_debugger*/*.{m,exp,inp}:
tests/dppd*/*.m:
tests/exceptions*/*.m:
tests/general*/*.m:
tests/grade_subdirs*/*.m:
tests/hard_coded*/*.m:
    Make these tests use four-space indentation, and ensure that
    each module is imported on its own line. (I intend to use the latter
    to figure out which subdirectories' tests can be executed in parallel.)

    These changes usually move code to different lines. For the debugger tests,
    specify the new line numbers in .inp files and expect them in .exp files.
2015-02-14 20:14:03 +11:00

132 lines
2.4 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
%
% This test case exercises the code generator's handling of if-then-elses
% whose conditions include nondet disjunctions, looking for problems caused
% by the disjunction's clobbering some of the same redoip/redofr slots used
% for the soft cut in the if-then-else.
:- module complex_failure.
:- interface.
:- import_module io.
:- pred main(io__state::di, io__state::uo) is det.
:- implementation.
:- import_module int.
:- import_module list.
:- import_module solutions.
main -->
{ solutions(p1, Xs1) },
print_list(Xs1),
{ solutions(p2, Xs2) },
print_list(Xs2),
{ solutions(p3, Xs3) },
print_list(Xs3).
:- pred p1(int::out) is nondet.
p1(X) :-
p(1, X).
:- pred p2(int::out) is nondet.
p2(X) :-
p(2, X).
:- pred p3(int::out) is nondet.
p3(X) :-
p(3, X).
:- pred p(int::in, int::out) is nondet.
p(A, X) :-
% The first if-then-else can hijack the redoip/redofr slots
% of p's frame.
( if
some [B] ( q(A, B) ; r(A, B) )
then
C = B * 10
% s(B, C)
else
C = A * 10
% s(A, C)
),
% The second if-then-else cannot hijack the redoip/redofr slots
% of p's frame, since this may not be (and usually won't be)
% on top when execution gets here.
( if
some [D] ( q(C, D) ; r(C, D) )
then
s(D, X)
else
s(C, X)
).
:- pred q(int::in, int::out) is nondet.
q(1, 15).
q(1, 16).
q(2, 25).
q(2, 26).
q(3, 35).
q(150, 660).
q(161, 661).
q(281, 662).
:- pred r(int::in, int::out) is nondet.
r(1, 18).
r(1, 19).
r(2, 28).
r(2, 29).
r(3, 38).
r(260, 690).
r(370, 698).
:- pred s(int::in, int::out) is nondet.
s(F, G) :-
F < 695,
(
G = 10 * F
;
G = 10 * F + 1
).
:- pred print_list(list(int), io__state, io__state).
:- mode print_list(in, di, uo) is det.
print_list(Xs) -->
(
{ Xs = [] }
->
io__write_string("[]\n")
;
io__write_string("["),
print_list_2(Xs),
io__write_string("]\n")
).
:- pred print_list_2(list(int), io__state, io__state).
:- mode print_list_2(in, di, uo) is det.
print_list_2([]) --> [].
print_list_2([X | Xs]) -->
io__write_int(X),
(
{ Xs = [] }
->
[]
;
io__write_string(", "),
print_list_2(Xs)
).