Reciprocal Prolog referencing rules in a family tree

I've seen various implementations of family trees in Prolog, but I haven't found one that does what I would like to do, which is to define a child and a parent by referencing each other. I want to do this because sometimes I have the fact that someone is someone's child, other times I have the fact that someone is someone's parent. From any of these facts, I would like to know who are the parents and who are the children.

My attempt at coding is as follows: -

parent(mary, fred).
child(john, peter).
child(paul, peter).

parent(P, C).
parent(P, C) :- child(C, P).
child (C, P).
child(C, P) :- parent(P, C).

      

It seems to be working fine, except that it will keep giving duplicate results over and over. For example: -

[3]  ?- parent(peter, X).
true ;
X = john ;
X = paul ;
true ;
X = john ;
X = paul ;
true 

      

Is there a way to make it stop after giving me the full set of results once?

More generally, such a definition is strange, what should you do (due to mutual recursion)? I want you to have data about the reported parents or children and how to infer the "opposite" relationship from them.

Thank!

+3


source to share


1 answer


The problem with your program is that you are concatenating predicates. parent / 2 and child / 2 are facts, you shouldn't specify a rule like the one already defined in your program.

Rename the rules and everything will work. Also, the base clause in your rules should add a condition that matches the fact, something like this:

parent(mary, fred).
child(john, peter).
child(paul, peter).

isparent(P, C):- parent(P, C).
isparent(P, C):- child(C, P).

ischild(C, P):- child(C, P).
ischild(C, P) :- parent(P, C).

      



Now the request:

?- isparent(peter, X).
X = john
X = paul

      

Also, don't use the padding rule in your state, which is not necessary, and you will avoid recursion

+2


source







All Articles