1
votes

I have this fact that returns the descendants but it only returns if "ascendente" is father/mother of "descendente". What am I doing wrong?

%descendenteDir(homem,mulher,filho)
descendenteDir('Tywin','Joanna','Ser Jaime').
descendenteDir('Tywin','Joanna','Cersei').
descendenteDir('Robert','Cersei','Joffrey').
descendenteDir('Robert','Cersei','Myrcella').
descendenteDir('Robert','Cersei','Tommen').
descendenteDir('Kevan','Dorna','Lancel').

descendente(Ascendente,Descendente):- descendenteDir(Ascendente,_,Descendente)
    ;descendenteDir(_,Ascendente,Descendente)
    ;descendenteDir(descendente(Ascendente,_),_,Descendente)
    ;   descendenteDir(_,descendente(Ascendente,_),Descendente).

1

1 Answers

1
votes

The descendente(Ascendente,_) part in the final rule is not quite right. It should be something like this:

descendente(Ascendente,Descendente):- descendenteDir(Ascendente,_,Descendente)
    ;descendenteDir(_,Ascendente,Descendente)
    ;descendenteDir(X,_,Descendente), descendente(Ascendente,X)
    ;descendenteDir(_,X,Descendente), descendente(Ascendente,X).

It's not the same as calling functions and getting returned values in languages like C++/Python/Java. In Prolog, you have a set of facts (the descendenteDir rules at the top), and some inference rules (the descendente rule). In the definition where you would use the rule recursively, you would have to provide a variable which would be bound to the values available (from the facts). That variable would later be used to infer the subsequent rules. Here X is that variable. Prolog will bind different values to it and try to infer the next part from the following clause.