[mercury-users] newbie question on negation

Prashanth prash.n.rao at gmail.com
Tue Sep 18 04:50:14 AEST 2012


Thank you, Tomas. I realize I had made a mistake in the mode declaration 
of isentity/1. Your example of for printing predicate names was helpful too.

On 17/09/12 17:24, Tomas By wrote:
> This works:
>
> ---------- begin ----------
> :- module kb0.
>
> :- interface.
>
> :- import_module io.
>
> :- pred main(io::di,io::uo) is det.
>
> :- implementation.
> :- import_module solutions.
>
> :- type entity ---> joe ; moe ; larry.
>
> :- pred happy(entity::out) is multi.
> happy(joe).
> happy(larry).
>
> :- pred isentity(entity::out) is multi.
> isentity(joe).
> isentity(moe).
> isentity(larry).
>
> :- pred unhappy(entity::out) is nondet.
> unhappy(E) :-
>    isentity(E),
>    not happy(E).
>
> main(!IO) :-
>    solutions(unhappy,Xs),
>    io.write_list(Xs,"\n",io.print,!IO),
>    io.nl(!IO).
> ---------- end ----------
>
> Your isentity/1 below is written to test, not generate.
>
> /Tomas
>
>
>
> On Mon, September 17, 2012 17:10, Prashanth wrote:
>> Hi Richard,
>> I added the two predicates, accordingly. However, I get compilation
>> errors.
>> Here is the updated code
>> %%%%%% START %%%%%
>> :- module kb0.
>>
>> :- interface.
>>
>> :- import_module io.
>>
>> :- pred main(io, io).
>> :- mode main(di, uo) is det.
>>
>> :- implementation.
>> :- import_module solutions.
>>
>> :- type entity == string.
>> :- func j = entity.
>>      j = "joe".
>> :- func m = entity.
>>      m = "moe".
>> :- func l = entity.
>>      l = "larry".
>>
>> :- pred happy(entity).
>> :- mode happy(out) is multi.
>> happy(E) :-
>>       E = j;
>>       E = l.
>>
>> :- pred isentity(entity).
>> :- mode isentity(in) is semidet.
>> isentity(E) :-
>>       E=j; E=m; E=l.
>>
>> :- pred unhappy(entity).
>> :- mode unhappy(out) is multi.
>> unhappy(E) :-
>>       isentity(E),      % line 35
>>       not happy(E).  % line 36
>>
>> main(!IO) :-
>>       solutions(unhappy, Xs),
>>       io.write_list(Xs, "\n",  io.write_string, !IO),
>>       io.nl(!IO).
>> %%%%%% STOP %%%%%
>>
>> and the error messages:
>> kb0.m:036: In clause for `unhappy(out)':
>> kb0.m:036:   mode error in conjunction. The next 2 error messages indicate
>> kb0.m:036:   possible causes of this error.
>> kb0.m:035:   In clause for `unhappy(out)':
>> kb0.m:035:   in argument 1 of call to predicate `kb0.isentity'/1:
>> kb0.m:035:   mode error: variable `E' has instantiatedness `free',
>> kb0.m:035:   expected instantiatedness was `ground'.
>> kb0.m:036:   In clause for `unhappy(out)':
>> kb0.m:036:   in argument 1 of call to predicate `kb0.happy'/1:
>> kb0.m:036:   scope error: attempt to bind a non-local variable inside a
>> kb0.m:036:   negation.
>> kb0.m:036:   Variable `E' has instantiatedness `free',
>> kb0.m:036:   expected instantiatedness was `ground'.
>> kb0.m:036:   A negation is only allowed to bind variables which are local
>> to
>> kb0.m:036:   the negation, i.e. those which are implicitly existentially
>> kb0.m:036:   quantified inside the scope of the negation.
>>
>> (Sorry about the excessive verbosity, but I don't know if would have
>> been easy to understand these error messages without the corresponding
>> code.)
>>
>> I don't see why it complains about a `free' `E' when it gets bound in
>> the previous line.
>>
>> I am using strings because it is easier for me to print. I don't know if
>> it's possible to print names of predicates.
>> BTW, Curly is Curly Joe. ;-) I tend to think of him as just Joe.
>>
>> On 17/09/12 00:15, Richard O'Keefe wrote:
>>> On 17/09/2012, at 12:26 AM, Prashanth wrote:
>>>
>>> The fundamental issue with negation is that many data structures have
>>> infinitely many instances, so that if p(X) has finitely many solutions
>>> not p(X) will have infinitely many.
>>>
>>>> Given that I don't want to write "unhappy(E) :- m.", my questions are:
>>>> 1. How do I get it to print ONE entity that is not happy? I tried "not
>>>> happy(X), io.write_string(X, !IO)" but on further reading, discovered
>>>> how the Goal for the "not" becomes part of an "if then else", and that
>>>> the scope of X does not extend to the else.
>>> You have got to generate values for X explicitly and then test them.
>>>
>>> :- pred clown(entity).
>>> :- mode clown(out) is multi.
>>>
>>> clown(E) :- E = "j" ; E = "m" ; E = "l".
>>>
>>> :- pred unhappy_clown(entity).
>>> :- mode unhappy_clown(out) is multi.
>>>
>>> unhappy_clown(E) :- clown(E), not happy(E).
>>>
>>> (Seeing "moe" and "larry" I was expecting "curly", not "joe".)
>>>
>>>> 2. How do I get it to print ALL entities that is not happy?
>>> You really do NOT want to be defining entities to be strings,
>>> because presumably the strings "", "a", "aa", "aaa", "aaaa", ...
>>> are not happy.
>>>
>>> As a rule of thumb, if there a small finite set of values
>>> you are interested in, do not use strings for that.
>>>
>>>
>>> --------------------------------------------------------------------------
>>> 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
>>> --------------------------------------------------------------------------
>> --------------------------------------------------------------------------
>> 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
>> --------------------------------------------------------------------------
>>
>
> --------------------------------------------------------------------------
> 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
> --------------------------------------------------------------------------

--------------------------------------------------------------------------
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