[mercury-users] Rewriting if-then-else as (CondGoal, ThenGoal; not(CondGoal), ElseGoal)
Daniel Patterson
lists.mercury at dbp.mm.st
Mon Sep 5 11:45:48 AEST 2011
Hi,
sorry if this is a really beginner question, but I have an example program (that solves the first of the project euler problems):
:- pred euler1(int::in,int::out) is det.
euler1(N,P) :-
Np = N mod 3, Nq = N mod 5,
( if
N =< 0
then
P = 0
else
(
if (Np = 0; Nq = 0)
then euler1(N-1,Ps), P = N + Ps
else euler1(N-1,P)
)
).
And I was trying to rewrite it without all the if-then-elses. My first attempt (just to get rid of the outermost one), said that it was inferred as nondet, not det. Code is:
:- pred euler1alt(int::in,int::out) is det.
euler1alt(N,P) :-
(
N =< 0, P = 0
;
not (N =< 0),
Np = N mod 3, Nq = N mod 5,
(if (Np = 0; Nq = 0)
then euler1alt(N-1,Ps), P = N + Ps
else euler1alt(N-1,P)
)
).
The error was:
one.m:025: Declared `det', inferred `nondet'.
one.m:029: Disjunction has multiple clauses with solutions.
one.m:029: call to `int.=<'(in, in) can fail.
one.m:031: Negated goal can succeed.
I'm not sure why this change meant that there were now many or no solutions, as it seemed analogous to the if-then-else used above. The error specifies that =< can fail, but I would have thought that was covered by the not (N =< 0) case in the switch.
What am I not understanding? I read the section on determinism and on goals (that talks about if-then-else having different semantics) in the reference manual, but I'm having a hard time figuring out how it is applying here, and how to fix the code!
Thanks in advance,
- An excited new user of Mercury.
--------------------------------------------------------------------------
mercury-users mailing list
Post messages to: mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions: mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the users
mailing list