0
votes
male(jerry).
male(stuart).
male(warren).
male(peter).

female(kather).
female(maryalice).
female(ann).

brother(jerry,stuart).
brother(jerry,kather).
brother(peter, warren).

sister(ann, maryalice).
sister(kather,jerry).

parent_of(warren,jerry).
parent_of(maryalice,jerry).

I was given the facts above and I need to define a rule using the predicate parent_of. Yes, it is the same predicate as the above facts defined by parent_of.

Assume I have a sibling(X, Y) rule that will return all the correct sibling pairs.

I write my parent_of(X, Y) rule as parent_of(X, Y) :- parent_of(X, A), sibling(A, Y).

However, this implementation will lead me to an infinity loop.

Is there a way to define the rule parent_of(X, Y) such that it will return

(warren, jerry), 
(warren, stuart), 
(warren, kather), 
(maryalice, jerry), 
(maryalice, stuart), 
(maryalice, kather)

I also tried

parent_of(X, Y) :- 
    parent_of(X, jerry), 
    brother(jerry, Y).

I can get the correct answers by this way but it ended up in "Out of local stack" error. Besides that, I don't think the rule is fine as I hard coded it.

I have seen suggestions like change the rule name to something else such as another_parent_of(X, Y). It does solve the problem, but it is a requirement for me to define it using the same predicate.

Any help is greatly appreciated.

EDITED

The intention of this exercise is to write rules such that you can complete this family tree, though only minimal facts are given. As you can see, it only states that Warren is the father of Jerry, and from brother and sister facts, we know Jerry is the brother of Stuart and Kather. So I will have a rule, parent_of(X, Y) to deduce Warren is also the father of Stuart and Kather, though this was not stated in the facts above.

The main concern is how can I write my parent_of(X, Y) rule to avoid it getting into infinite loop.

2

2 Answers

1
votes

I do not understand why you need to use parent_of in the definition of sibling. Why you no just write:

sibling(X, Y) :-
    parent_of(Parent, X),
    parent_of(Parent, Y).

I also don't understand the logic of the facts that you are given. You have male and female, but you also have brother and sister; why not define brother and sister in terms of "brother is a male sibling" and "sister is a female sibling"? I already show above how to define "siblings have same parent".

Anyway, this is really old tired question, it is very amazing how many times "Prolog family tree" has been regurgitated.

the cow the old cow she is dead
it sleeps well the horned head
we poor lads tis our turn now
to hear such tunes as killed the cow
0
votes

I cannot see a way to directly solve your problem. But if your Prolog offers tabling, here is an easy way:

:- use_module(library(tabling)). ... :- table parent_of/2. parent_of(warren,jerry). parent_of(maryalice,jerry). parent_of(X, Y) :- parent_of(X, A), sibling(A, Y). ... ?- parent_of(X,Y). X = warren, Y = stuart ; X = warren, Y = jerry ; X = warren, Y = kather ; X = maryalice, Y = stuart ; X = maryalice, Y = jerry ; X = maryalice, Y = kather.