1
votes

I have the typical relationship example.

m(thomas).
m(leon).
w(nina).
born(thomas, nina, leon).

born(Father, Mother, Child) :- born(Mother, Father, Child).
father(Father, Child) :- born(Father, Mother, Child), m(Father).
mother(Mother, Child) :- born(Father, Mother, Child), w(Mother).
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).

When I ask after parent, only the father will be listed:

?- parent(X, leon).
X = thomas ;
X = thomas ;
.....

I want both parents:

?- parent(X, leon).
X = thomas ;
X = nina ;

What can I do?

Edit: problem:

My problem wasn't the or because it normally gives back both statements.

The problem was that born/3, in the code above, is a loop. I tried to make the mother and father exchange able against each other.

Edit: fix:

I got two answers on this from ChristianF and CapelliC. They both helped me to understand the what was wrong with my statement.

My own solution:

m(thomas).
m(leon).
w(nina).
b(thomas, nina, leon).

born(Father, Mother, Child)
    :- (m(Father), w(Mother), b(Father, Mother, Child)); b(Mother, Father, Child).
father(Father, Child) :- born(Father,_, Child), m(Father).
mother(Mother, Child) :- born(_, Mother, Child), w(Mother).
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).
3
born(Father, Mother, Child) :- born(Mother, Father, Child). is a lot of trouble. One thing that would help is to establish a convention for born/3 facts in which the father or the mother is always listed first. - lurker
you really should always include in your questions the output that you get, and explain why it isn't what you wanted. I'm sure it's somewhere in the "Help Center" (i.e. FAQ). You have included the explanation, but not the output itself. - Will Ness
@mbratch : That is a solution but something i can't do. I need the father and mother to be change able against each other. - Spenhouet
@WillNess : ? You didn't even read the last sentence. You allways shoud read everything before you answer! I'm sure it's somewhere in the "Help Center" (i.e. FAQ). - Spenhouet
the key piece of information that's missing is the verbatim copy of the transcript of your attempt. Better to include raw evidence; even full verbal description is second best option - and when you don't understand something fully (since you ask about it), chances are you don't know what about it can be safely ignored, when you describe it. :) - Will Ness

3 Answers

2
votes

You have a 'loop' in your rules. Remove born/3 rule, and you'll get

?- parent(P,leon).
P = thomas ;
P = nina.

edit since you need that a parent could stay in first or second 'position' irrespective of gender, I would suggest

father(Father, Child) :-
   m(Father), (born(Father, _, Child) ; born(_, Father, Child)).

I moved the gender test before the born/3 query, seems more efficient to avoid to repeat the query...

1
votes

The problem is that there are infinitely many ways to show born for the father since there is an infinite recursion.

m(thomas).                                                                  
m(leon).                                                                    
w(nina).                                                                    

born(thomas, nina, leon).                                                   

born_sym(Father, Mother, Child) :- born(Father, Mother, Child).             
born_sym(Father, Mother, Child) :- born(Mother, Father, Child).             

father(Father, Child) :- born_sym(Father, Mother, Child), m(Father).        
mother(Mother, Child) :- born_sym(Father, Mother, Child), w(Mother).        
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).    
0
votes

another fix is using cut in fact to avoid an infinite recursion:

m(thomas).
m(leon).
w(nina).

born(thomas, nina, leon) :- !.
born(Father, Mother, Child) :- born(Mother, Father, Child).

father(Father, Child) :- born(Father, Mother, Child), m(Father).
mother(Mother, Child) :- born(Father, Mother, Child), w(Mother).
parent(Parent, Child) :- father(Parent, Child); mother(Parent, Child).

Just another manner to fix infinite recursion, maybe not a good style :)