Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Existential quantification in Prolog facts

I am doing my first steps in Prolog (swi-prolog) and cannot solve the following problem: How can I include existentially quantified rules to my facts; specifically, how can I include the sentence "Everybody is a friend of somebody" \forall x \exists y friend(x,y)as a fact? Every question I found so far was only about queries not facts. Thank you!

like image 724
huxley Avatar asked May 05 '17 19:05

huxley


1 Answers

In the example you gave, you are actually quantifying over variables not rules. With this in mind, consider the following example:

friend_of(a,b).

friend(X) :-
   friend_of(X,Y).

The variables in the rule are universally quantified, so you can write the rule as a logic formula like so:

XY (friend(X)friend_of(X,Y))

Since the variable Y does not occur in the head of the rule, its universal quantifier can be moved into the body of the rule as existential quantifier:

X (friend(X) ← ∃Y friend_of(X,Y))

Now this formula reads as: Forall X friend(X) is true if there exists a Y such that friend_of(X,Y) is true. This seems to be pretty close to what you wanted.

If you consider facts on the other hand, they are used to state that something is the case. The fact friend_of/2 in the above example is just the short way of writing

friend_of(a,b) :- true.

However, there are no variables here, so there's nothing to quantify over.

EDIT: Concerning the case in your comments, I would note that predicates constitute relations. Relations are not neccessarily symmetric, that is the reason why I named the relation friend_of/2. That is, friend_of(a,b) does not neccessarily mean friend_of(b,a). Relations are also not neccessarily reflexive. It is debatable whether the relation friend is reflexive or not. However, it certainly is a possible reading. With that in mind and the given examples in your comment, let's assume that you have some facts that describe a, b and c as persons, like so:

person(a).
person(b).
person(c).

Then you can describe a reflexive relation friends/2 like so:

friends(a,b) :- false.   % example from your comment
friends(a,c) :- false.   % example from your comment
friends(X,X) :-          % the relation is reflexive
   person(X).            % among people

The rule expressing reflexivity basically states, that everybody is friends with at least him/herself. From this rule your requirement Everybody is a friend of someone directly follows. If you query this relation you get the desired result:

   ?- friends(a,X).
X = a

The most general query also yields results for every person, although no actual friendships between two different people are stated:

   ?- friends(X,Y).
X = Y = a ? ;
X = Y = b ? ;
X = Y = c

Note that the facts person/1 are neccessary to restrict the answers to actual people. If you query friends/2 with some non-person:

   ?- friends(cos(0),X).
no

If you try to define reflexivity without such a goal:

friend(X,X).

your definition will be too general:

   ?- friends(a,X).           % desired result
X = a
   ?- friends(cos(0),X).      % undesired result
X = cos(0)

And the most general query will not produce any actual people:

   ?- friends(X,Y).
X = Y
like image 172
tas Avatar answered Oct 20 '22 08:10

tas