[mercury-users] det & cc_multi question
Ian MacLarty
maclarty at csse.unimelb.edu.au
Mon May 17 10:20:34 AEST 2010
On Sun, May 16, 2010 at 11:46 PM, Vladimir Gubarkov <xonixx at gmail.com> wrote:
> Hi Dear sirs
>
> let's look at code
>
>
> :- module tst2.
>
> :- interface.
>
> :- import_module io.
>
> :- pred main(io, io).
> :- mode main(di, uo) is det.
>
> :- implementation.
>
>
> :- import_module solutions, list, int.
>
> main -->
> {
> promise_equivalent_solutions [L] unsorted_solutions((pred(E::out) is
> nondet :-
> member(E, 1..20),
> E mod 3 = 0
> ), L)
> },
> print(L).
>
>
> Note, that without "promise_equivalent_solutions [L]" it gives
>
>
> $ mmc tst2
> tst2.m:008: In `main'(di, uo):
> tst2.m:008: error: determinism declaration not satisfied.
> tst2.m:008: Declared `det', inferred `multi'.
> tst2.m:017: call to `solutions.unsorted_solutions'((pred(out) is nondet),
> tst2.m:017: out) can succeed more than once.
> tst2.m:017: Error: call to predicate `solutions.unsorted_solutions'/2 with
> tst2.m:017: determinism `cc_multi' occurs in a context which requires all
> tst2.m:017: solutions.
>
>
> while compiling.
>
> I've read some documentation on cc_multi, and I seem to understand the
> meaning of cc_multi. It's used when we defining predicate as being multi,
> but using it in place where we nead only 1 solution (actually, anyone.. this
> is determined by compiler what solution to return taking in mind
> optimization concerns). What I can't understand is why should I explicitely
> convert it to det with "promise_equivalent_solutions [L]". Why compiler is
> not smart enough to make this automatically?
In general det is not the same as cc_multi, which is why the compiler
doesn't infer them the same automatically. det means that there is
exactly one solution to the procedure when it's inputs are bound.
cc_multi means that there are one or more solutions, but we only want
to pick one of them.
Consider the following example:
:- pred q is semidet.
q :-
p(X),
X > 2.
:- pred p(int::out) is multi.
p(1).
p(2).
p(3).
When you evaluate q it succeeds. Now say we changed the determinism
of p to cc_multi and used promise_equivalent_solutions to cast it to
det in the body of q:
:- pred q is semidet.
q :-
promise_equivalent_solutions [X] p(X),
X > 2.
:- pred p(int::out) is cc_multi.
p(1).
p(2).
p(3).
Now q fails, even though the program logic (the declarative semantics)
hasn't changed.
By requiring you to add the promise_equivalent_solutions the compiler
is forcing you to think about whether the solutions to p really are
equivalent. In this case they aren't and the
promise_equivalent_solutions is a bug.
I hope that helps.
Ian.
--------------------------------------------------------------------------
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