# [mercury-users] Switches and "subswitches"

Ondrej Bojar oboj7042 at ss1000.ms.mff.cuni.cz
Sun Sep 30 22:31:04 AEST 2001

```Hi. It's me again.

As time passes, my own general answer to such a  general question would
be: split the two intended modes. Write two separate decision trees.
Forget much of declarative writing and write straightforward code.

Would there be still a better solution?

Thanks, Andrew.

On Sun, 30 Sep 2001, Ondrej Bojar wrote:

> Hello.
>
> I quite often face a problem with switches and "subswitches". (I hope
> you'll find switches and subswitches in the following code, I'm really
> unable to describe the notion in English.)
>
> I want to write code like this: (line numbers supplied)
>
> 15 :- type type_a ---> a_a; a_b; a_c.
> 16 :- type type_b ---> b_a; b_b.
> 17
> 18 :- type type_c ---> c_a_a; c_anything_b; c_b_a; c_c_anything.
> 19
> 20 % the two_to_and_from_one is to convert information supplied
> 21 % in headvar 1 and headvar2 to headvar3 and back again.
> 22 :- pred two_to_and_from_one(type_a, type_b, type_c).
> 23 :- mode two_to_and_from_one(in, in, out) is det.
> 24 :- mode two_to_and_from_one(out, out, in) is multi.
> 25
> 26 % of course the real conversion is a bit more complicated
> 27 % usually I do some calls *after* the unifications
> 28 two_to_and_from_one(a_a, b_a, c_a_a).
> 29 two_to_and_from_one(a_b, b_a, c_b_a).
> 30 two_to_and_from_one(a_c, B, c_c_anything) :-
> 31   B = b_a; B = b_b.
> 32 two_to_and_from_one(A, b_b, c_anything_b) :-
> 33   A = a_a ; A = a_b.
>
>
> ...And now the error message
>
> testswitches.m:023: In `two_to_and_from_one(in, in, out)':
> testswitches.m:023:   error: determinism declaration not satisfied.
> testswitches.m:023:   Declared `det', inferred `nondet'.
> testswitches.m:028:   In argument 2 of clause head:
> testswitches.m:028:   unification of `HeadVar__2' and `testswitches:b_a'
> can fail.
> testswitches.m:029:   In argument 2 of clause head:
> testswitches.m:029:   unification of `HeadVar__2' and `testswitches:b_a'
> can fail.
> testswitches.m:032:   In argument 2 of clause head:
> testswitches.m:032:   unification of `HeadVar__2' and `testswitches:b_b'
> can fail.
> testswitches.m:033:   The switch on A does not cover testswitches:a_c/0.
> testswitches.m:028:   Disjunction has multiple clauses with solutions.
>
>
> I suppose, Mercury is not able to find out that for example the case of
> input variables a_a, b_b is covered with the last clause. And Mercury
> tries to get the answer in the first clause already. A solution would be
> to parse the input variables in exact order, as a decision tree: (the
> switches and subswitches notion)
>
> if A = a_a
>   then
>     if B = b_b
>     then C = c_anything_b
>     else C = c_a_a
>   else
>     ...
>
> But this solution will lead to I-dont-know-what code when the other mode
> of the predicate is to be build.
>
> Another solution would be to list all possible cases one by one:
>
> two_to_and_from_one(a_a, b_a, c_a_a).
> two_to_and_from_one(a_a, b_b, c_anything_b).
>
> But this solution is not too "typing-efficient" and is absolutely useless
> when string or int comes as the input variable type... (Which is my case.)
>
> Is there a better way of writing such code?
>
> (In the example above, the c_anything_b and c_c_anything combination is
> deliberate. Sometimes, only the first input is important, sometimes only
> the other is.)
>
> What also fails is using negation:
>
> two_to_and_from_one(A, b_b, c_anything_b) :-
>   A \= a_c.
>
> This leads to a mixed-mode error, as Mercury is (naturally) not able to
> find all possilbe values for A different from a_c when building mode (out,
> out, in).
>
>
> It might happen, that I even forget some cases when writing the code... I
> love Mercury for showing me mistakes like that, but here the situation is
> a bit too complicated, so Mercury can't explain what did I wrong...
>
> Thanks for any tips on rewriting the code.
>
> Andrew.
>
>
> --------------------------------------------------------------------------
> mercury-users mailing list
> post:  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
> --------------------------------------------------------------------------
>

--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au