Reputation: 875
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
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
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