mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-20 08:19:28 +00:00
Estimated hours taken: 1.5 Perform some minor simplifications in mode analysis, so as to provide more information to unique mode analysis. Previously unique_modes.m was reporting spurious errors for tests/hard_coded/bidirectional.m, because modes.m produced output containing a subgoal of the form `disj([Goal, conj([disj([])]])' instead of just `Goal', and the presence of a disjunction then caused unique mode analysis to make overly conservative assumptions. compiler/modes.m: Ensure that we do not produce singleton conjunctions or disjunctions. Also, if the result of mode checking a disjunct is a (nested) disjunction, then merge it with the containing disjunction. If the nested disjunction is the empty disjunction (fail), then this means it will be deleted. tests/hard_coded/Mmakefile: Re-enable the test case bidirectional.m, since the compiler now accepts it, due to the above change. tests/warnings/simple_code.m: tests/warnings/simple_code.exp: Update this test case, because the above change meant that the compiler no longer issues the warning about "this disjunct can never succeed" in cases like this -- mode analysis will already have optimized it away, before we even get to simplify.m (which handles those kinds of warnings). This warning is not as important as allowing bidirectional code.
101 lines
1.4 KiB
Mathematica
101 lines
1.4 KiB
Mathematica
:- module simple_code.
|
|
:- interface.
|
|
:- pred p(int::in, int::out) is erroneous.
|
|
:- implementation.
|
|
|
|
:- import_module require.
|
|
p -->
|
|
(
|
|
[]
|
|
;
|
|
{ error("foo") }
|
|
),
|
|
( { true } ->
|
|
{ Z = 2 }
|
|
;
|
|
{ Z = 3 }
|
|
),
|
|
( { X = 3, X = 2, Z = 2 } ->
|
|
[]
|
|
;
|
|
[]
|
|
),
|
|
( { \+ true } ->
|
|
[]
|
|
;
|
|
[]
|
|
),
|
|
( { \+ det_pred } ->
|
|
[]
|
|
;
|
|
[]
|
|
),
|
|
( { \+ fail_pred } ->
|
|
[]
|
|
;
|
|
[]
|
|
),
|
|
{ \+ fail },
|
|
{ obsolete },
|
|
( { error("blah") } ->
|
|
[]
|
|
;
|
|
[]
|
|
).
|
|
|
|
:- pred det_pred is det.
|
|
|
|
det_pred.
|
|
|
|
:- pred fail_pred is failure.
|
|
|
|
fail_pred :- fail.
|
|
|
|
:- pred obsolete is det.
|
|
:- pragma obsolete(obsolete/0).
|
|
|
|
obsolete.
|
|
|
|
% This should give a warning about the second disjunct never succeeding.
|
|
% XXX Currently it doesn't, because mode analysis simplifies away the
|
|
% whole disjunction.
|
|
:- pred r(int, int).
|
|
:- mode r(in(bound(1)), out(bound(42))) is det.
|
|
|
|
r(1, 42).
|
|
r(2, 21).
|
|
|
|
% This should not give a warning, because the second disjunct can
|
|
% succeed in the first mode.
|
|
:- pred q(int, int).
|
|
:- mode q(in, out) is semidet.
|
|
:- mode q(in(bound(1)), out(bound(42))) is det.
|
|
|
|
q(1, 42).
|
|
q(2, 21).
|
|
|
|
:- type node ---> a ; b ; c.
|
|
|
|
:- pred parent(node, node).
|
|
:- mode parent(in, out).
|
|
:- mode parent(out, in).
|
|
parent(a, b).
|
|
parent(b, c).
|
|
parent(a, c).
|
|
|
|
:- pred node(node).
|
|
:- mode node(out).
|
|
node(a).
|
|
node(b).
|
|
node(c).
|
|
|
|
:- pred anc(node, node).
|
|
:- mode anc(in, out).
|
|
:- mode anc(out, in).
|
|
anc(X, X) :-
|
|
node(X).
|
|
anc(X, Z) :-
|
|
parent(X, Y),
|
|
anc(Y, Z).
|
|
|