forumulator
forumulator

Reputation: 875

Extending Prolog predicates

I have prolog predicates male, female, parent, as follows:

parent(bob, rick).
parent(jane, rick).
parent(rick, alice).
parent(betsy, alice).
male(rick).
female(jane).

Now, one way to infer incomplete gender info is to see if one parent is male, then the other has to be a female and vice versa, so I tried to extend female:

female(X) :- parent(X, Y), parent(Z, Y), male(Z).

Thus, my final female predicate is:

female(jane).
female(X) :- parent(X, Y), parent(Z, Y), male(Z).

However, when I try:

?- female(jane).
true ;
false.

?- female(betsy).
true ;
false.

Why's the false coming up there? Further problems are arising when I try to do a similar thing for male, because that's leading to an infinite recursion.

Upvotes: 2

Views: 299

Answers (2)

forumulator
forumulator

Reputation: 875

In case this helps anybody, I want to further add that in such a situation, if I also wanted to extend male similarly, it leads to an infinite recursion because male references female and female references male.

To avoid this, it is better to separate the facts and rules, like so:

male(rick).
is_male(X) :- male(X).
is_male(X) :- parent(X, Y), parent(Z, Y), X \== Z, female(Z).

female(jane).
is_female(X) :- female(X).
is_female(X) :- parent(X, Y), parent(Z, Y), X \== Z, male(Z).

(This is only appropriate here because further levels of recursion would not yield any extra info, which may not be true for other situations).

Upvotes: 0

tas
tas

Reputation: 8140

Let's look at what happens if you query female/1:

?- female(jane).

Prolog tries to prove the predicate by trying all facts and rules you have written for it. First the fact female(jane). matches successfully and Prolog tells you:

?- female(jane).
true 

After you hit the ;-key Prolog looks for further solutions:

?- female(jane).
true ;

There are no more facts for female/1 but a rule, so Prolog tries to prove the rule by proving its goals in the order you have written them. The X in the head of the rule is unified with jane. The first goal parent(jane,Y) succeeds for Y=rick. Then Prolog is trying to prove parent(Z,rick) which succeeds for Z=bob. Now Prolog tries to prove male(bob) but fails since your facts do not include male(bob). So Prolog backtracks to the previous goal parent(Z,rick) and finds a second solution Z=jane (after all your rule does not specify that X and Z have to be different). However, the goal male(jane) fails. Prolog is backtracking to the previous goal but does not find any more solutions to parent(Z,rick) so it backtracks further to the first goal parent(jane,Y). Since there are no more solutions to that either Prolog tells you:

?- female(jane).
true ;
false

To further illustrate how this works, I suggest you add a fact:

male(bob).

Now the query yields:

?- female(jane).
true ;
true ;
false.

Now follow the reasoning described above: The first true is because of the fact female(jane). The second true you get because the rule succeeds since Prolog can prove male(bob) now. And the false you get because there are no more solutions.

The answers to your second query can be explained the same way: You get the answer true because male(rick) can be proved in the rule. The false tells you there are no more solutions.

Upvotes: 3

Related Questions