1
votes

I am trying to see the possible situations for the following facts.

don likes cain
bob does not like don
cain does not like aron
nobody likes someone who does not like him
aron likes everyone who likes bob
don likes everyone bob likes
everybody likes somebody

I have just started learning prolog and I am trying to implement this in prolog and see how many possible situations arise. I scanned through few prolog threads here and I am also using the book "Learn prolog now" . So here is my best attempt to come up with the code.

likes(don, cain).
likes(aron,W):- likes(W,bob).
likes(don,M):- likes(bob,M).


(likes(aron,aron);likes(aron,bob));(likes(aron,cain);likes(aron,don)).

(likes(bob,aron);likes(bob,bob));(likes(bob,cain);likes(bob,don)).

(likes(cain,aron);likes(cain,bob));(likes(cain,cain);likes(cain,don)).

(likes(don,aron);likes(don,bob));(likes(don,cain);likes(don,don)).



not(likes(bob,don)).
not(likes(cain,aron)).

not(likes(Y,X)) :- not(likes(X,Y)).

When I run this in swipl compiler in Ubuntu Linux (which is in VirtualBox inside winxp), I get following errors

?- [test].
ERROR: /home/test.pl:11:
    '$record_clause'/2: No permission to modify static_procedure `(;)/2'
ERROR: /home/test.pl:13:
    '$record_clause'/2: No permission to modify static_procedure `(;)/2'
ERROR: /home/test.pl:15:
    '$record_clause'/2: No permission to modify static_procedure `(;)/2'
ERROR: /home/test.pl:17:
    '$record_clause'/2: No permission to modify static_procedure `(;)/2'
% test compiled 0.00 sec, 1,616 bytes
true.

So can you help me with this...... I have made use of not as a predicate here, some threads on the net seem to mention it.

1

1 Answers

1
votes

In Prolog we have a fairly natural representation of what's true, but when faced with negative information (say negation), we must adapt our intuition to the restricted computation model that Prolog offer.

In particular, Prolog semantic being based on closed world assumption, we could be tempted to omit as irrelevant proposition like bob does not like don, because this just states the absence of the positive clause 'bob likes don'. Such absence is indeed 'absorbed' in Prolog proof search, and formalized by a 'procedural' definition of not (the only available in Prolog, but with an operator less reminiscent of 'human' interpretation, i.e. \+ means not):

\+ X :- call(X), !, fail.
\+ X.

See this page for further explanation about.

All this introductory to say that I would introduce a not_like/2 to represent explicitly the 'negative' knowledge. Syntactically we get:

likes(don, cain).
not_likes(bob, don).
not_likes(cain, aron).
not_likes(X, Y) :- \+ likes(Y, X).
likes(aron, X) :- likes(X, bob).
likes(don, X) :- likes(bob, X).
likes(_, _).

Now those statements make sense? Prolog takes the viewpoint of a practical approach to logic programming, and it run queries against such knowledge, that make perfectly sense for some programming task...

edit suggested by comment, I think that instead of likes(_,_)., a better code for everybody likes somebody should be

likes(X, Y) :- \+ not_likes(X, Y).

This is justified by the last fact, but standalone it not allows to infer not_likes(cain, aron).