Prolog and ancestor relationship

13,477

You can use an accumulator to adapt @Scott Hunter's solution :

mother(anna, fanny).
mother(daniel, fanny).
mother(celine, gertrude).
father(tim, bernd).
father(anna, ephraim).
father(daniel, ephraim).
father(celine, daniel).

ancestor(X, Y, Z) :- ancestor(X, Y, X, Z).
ancestor(X, Y, Acc, father(Acc)) :- father(X, Y).
ancestor(X, Y, Acc, mother(Acc)) :- mother(X, Y).
ancestor(X, Y, Acc, Result) :-
    father(X, Z),
    ancestor(Z, Y, father(Acc), Result).
ancestor(X, Y, Acc, Result) :-
    mother(X, Z),
    ancestor(Z, Y, mother(Acc), Result).

edit : as Scott Hunter showed in his edit, there's no need for an explicit accumulator here, since we can left the inner part of the term unbound easily at each iteration. His solution is therefore better !

Share:
13,477
user1164180
Author by

user1164180

Updated on June 04, 2022

Comments

  • user1164180
    user1164180 almost 2 years

    I have to write a small prolog program which checks if a given person is a ancestor of a second one. These are the facts and rules:

    mother(tim, anna).
    mother(anna, fanny).
    mother(daniel, fanny).
    mother(celine, gertrude).
    father(tim, bernd).
    father(anna, ephraim).
    father(daniel, ephraim).
    father(celine, daniel).
    
    parent(X,Y) :- mother(X,Y).
    parent(X,Y) :- father(X,Y).
    

    The test if a person is an ancestor of another person is easy:

    ancestor(X, Y) :- parent(X, Y).
    ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
    

    But now I have to write a method ancestor(X,Y,Z) which also prints out the relationship between two persons. It should look like this

    ?- ancestor(ephraim, tim, X).
    false.
    ?- ancestor(tim, ephraim, X).
    X = father(mother(tim)).
    

    And that is the problem: I have no clue how do to this.