[mercury-users] newbie question on negation

Tomas By tomas at basun.net
Tue Sep 18 01:24:13 AEST 2012


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



More information about the users mailing list