[mercury-users] Passing a multi-mode higher order predicate

Julien Fischer juliensf at csse.unimelb.edu.au
Mon Feb 6 19:03:39 AEDT 2012

On Sun, 5 Feb 2012, Jeff Thompson wrote:

> On 2/5/2012 7:52 AM, Julien Fischer wrote:
>> Hi,
>> On Sat, 4 Feb 2012, Jeff Thompson wrote:
>>> Hello again.  In the program below, the compiler gives the following error 
>>> due to "test(list.member)".
>>> test.m:010: In clause for `main(di, uo)':
>>> test.m:010:   in argument 1 of call to predicate `test.test'/1:
>>> test.m:010:   mode error: variable `V_6' has instantiatedness `free',
>>> test.m:010:   expected instantiatedness was `(pred((ground >> ground), 
>>> (ground
>>> test.m:010: >> ground)) is semidet)'.
>>> The predicate list.member exists with the correct mode, so why does the 
>>> compiler say the argument is free?
>> In general, the current Mercury implementation. does *not* support
>> creating higher-order terms from multi-moded predicates.   See the
>> ``Creating higher-order terms'' of the reference manual (section 8.1).
>> (There is an exception to this in the case where the are some curried
>> higher-order arguments, but that does not apply here.)   The compiler
>> usually generates a more useful error message for this; I'm not sure
>> why it doesn't in this case.
> Thanks for the clarification.  I see that in the language reference manual 
> now. I came across this because I am trying to convert a code base of Prolog 
> to Mercury which deeply uses bagof in multiple modes. My example comes from 
> the following use case where Prolog can easily handle the following code 
> whether X is var or nonvar:
> test(X, Bag) :- bagof(X, member(X, [1, 2]), Bag).
> If X is ground, then it uses list.member(int::in, list(int)::in).  But if it 
> is nonvar, then it uses list.member(int::out, list(int)::in).   I cannot 
> figure out an efficient way to duplicate bagof,

What do you mean by duplicate bagof?  Do you mean implement it in
Mecury?  What was wrong with the implementation you had that used

> much less the case where there are multiple modes. I know Mercury
> disputes the soundness of the semantics of bagof, but is there a paper
> which describes how to achieve the same multi-mode behavior?

Can't you just use mode-specific clauses?

Either with test/2, for example

    test(X::in, Bag::out) :- ...
    test(X::out, Bag::in) :- ...

or with bagof/3 itself, for example

    bagof(X::in, Pred::in(pred(in, in) is semidet), Bag::out) :- ...
    bagof(X::out, Pred::in(pred(out, in) is nondet), Bag::in) :- ...

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