[mercury-users] Simple problem with switch
Peter Ross
petdr at miscrit.be
Tue Oct 3 23:36:57 AEDT 2000
On Fri, Sep 22, 2000 at 05:16:04PM +0200, Renaud Paquay wrote:
>
> With the following simple source code, I get these errors:
>
> ex_worksheet_parse.m:085: In `tata(in, out)':
> ex_worksheet_parse.m:085: error: determinism declaration not satisfied.
> ex_worksheet_parse.m:085: Declared `det', inferred `nondet'.
> ex_worksheet_parse.m:090: The switch on T does not cover
> ex_worksheet_parse:a/0 and/or ex_worksheet_parse:b/0.
> ex_worksheet_parse.m:088: The switch on T does not cover
> ex_worksheet_parse:c/0 and/or ex_worksheet_parse:d/0.
> ex_worksheet_parse.m:090: Disjunction has multiple clauses with solutions.
>
>
> Why does "tutu/1" compile and not "tata/2"?
>
> As in tata/2, I often need to apply the same predicates on different
> subsets of a enumerated type, but I never managed to make
> it compile without explicitely extending the switch on one level,
> thus repeating the same code for different values.
>
> Has anybody a simple practical solution to this, wihtout
> using if-then-else, neither intermediate predicate(s)?
>
>
> Renaud Paquay
> Mission Critical
>
>
> :- type toto ---> a; b; c; d.
>
> :- pred tutu(toto::in) is det.
> tutu(T):-
> (
> (T = a; T = b),
> true
> ;
> T = c,
> true
> ;
> T = d,
> true
> ).
The calls to true can be removed to give you
:- pred tutu(toto::in) is det.
tutu(T):-
(
(T = a; T = b)
;
T = c
;
T = d
).
which is trivally equivalent to the following the only difference is the
bracketing.
:- pred tutu(toto::in) is det.
tutu(T):-
(
T = a
;
T = b
;
T = c
;
T = d
).
Hence you have a switch covering all possible cases.
>
> :- pred tata(toto::in, int::out) is det.
> tata(T, I):-
> (
> (T = a; T = b),
> I = 0
> ;
> T = c,
> I = 1
> ;
> T = d,
> I = 2
> ).
Here you cannot remove the call to I=0 so you are left with a nested
switch which the compiler sees as the follows
(
... % point A
;
T = c,
...
;
...
T = d
)
This switch doesn't cover all the possible alternatives so it cannot be
deterministic hence introducing the nondeterminism.
:- pred tata(toto::in, int::out) is det.
tata(T, I):-
P = (pred(X::out) is det :- X = 0),
(
T = a,
P(I)
;
T = b,
P(I)
;
T = c,
I = 1
;
T = d,
I = 2
).
You can make the switch deterministic and avoid introducing an auxilary
predicate by using a lambda expression instead for the common code
between the a and b arms of the switch. I don't know if this qualifies
as a simple or practical solution, but you may find it useful.
Pete
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list