Search code examples
prologtransitive-closure

Prolog query not terminating


This is a very basic query, but I'm new to prolog and have trouble finding why this query does not terminate:

% fact 
progeny(dexter, mark).
progeny(mark, bill).
progeny(bill, lisa).


% rule
progeny(X, Y) :- progeny(X, Z), progeny(Z, Y).

The query, progeny(dexter, X), gives mark, bill and lisa, but does not terminate.
Whereas the query, progeny(Y, lisa), gives bill and dexter and does not terminate (this query answer also misses mentioning mark).
It should be noted that I am using the same name for fact and rule to test for some values.
Any help or clarification for this problem would be much appreciated.


Solution

  • You can also use tabling. Read the docs I linked for background, explanations, details.

    To fix your program, you just add a table directive for your predicate progeny/2.

    :- table progeny/2.
    
    % fact
    progeny(dexter, mark).
    progeny(mark, bill).
    progeny(bill, lisa).
    
    
    % rule
    progeny(X, Y) :- progeny(X, Z), progeny(Z, Y).
    

    You should now get:

    ?- [progeny].
    true.
    
    ?- progeny(dexter, X).
    X = bill ;
    X = mark ;
    X = lisa. % query terminates
    
    ?- progeny(Y, lisa).
    Y = bill ;
    Y = dexter ;
    Y = mark. % no missing solutions, query terminates.