[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