has_descendant(?ancestor, ?descendant) :-
has_child(?ancestor, ?child),
has_descendant(?child, ?descendant).
Here, the assumption is that you have explicit `has_child` facts (expressing vertices in a graph, essentially), and the above rule gives you paths of arbitrary length.In SQL, given a table has_child(parent, child), it is not clear to me how you can get all descendants of a given person, or all ancestors.
Other people talk about recursive extensions to SQL, maybe that provides a way.