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!
source to share
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
source to share