Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swi-prolog negation

I've had a hard time searching for clear answers on negation in Prolog, so I apologize if this is an obvious question:

I'm trying to write a simple code that will logically say that "X and Y love each other if X likes Y and only Y." My .pl code looks something like this:

likes(mary,john).
likes(mary,chad).
likes(john,mary).

loves(X,Y):- likes(X,Y), \+likes(X,Z).

I then run my program and simply ask:

?- loves(X,Y).

but it always comes out false. By my logic, it ought to come back saying 'X=john, Y=mary'.

I've tried a few combinations of separating the negation with cuts, trying multiple lines for defining "loves"... I'm probably missing a major principle of negation, or maybe there's even an easier way to implement what I'm trying to do here. Please let me know if you can help!

I'm using SWI-Prolog (swipl) from the Debian Software Manager, if that helps at all, though I doubt this will make much difference.

like image 309
bjscollura Avatar asked Nov 15 '12 05:11

bjscollura


1 Answers

Your problem is that Z it's not bound when your rule calls for \+likes(X,Z), then at least there will always be Z=Y that invalidates loves/2. I mean, since likes(X,Y) is true, surely will be true likes(X,Z).

Change it this way:

loves(X,Y):- likes(X,Y), \+ (( likes(X,Z), Z \= Y )).

and you'll get

?- loves(X,Y).
X = john,
Y = mary.
like image 186
CapelliC Avatar answered Sep 19 '22 01:09

CapelliC