Search code examples
recursionprologtransitive-closure

Writing prolog with recursive rules? "ERROR: Out of local stack"


Given facts such as:

  • Jake is smarter than Nik
  • Nik is smarter than Wes
  • Wes is smarter than Dik

Write a recursive program that will determine that Jake's is smarter than Dik's.

The solution that I have is:

smarter(jake, nik).
smarter(nik, wes).
smarter(wes, dik).
smarter(X, Y) :-
    smarter(X, Z),
    smarter(Z, Y).

The output:

?- smarter(jake, dik).
True

but when I swap it:

?- smarter(dik, jake)

The output will show "ERROR: Out of local stack" I need the output to show "False". How do I fix it?

Thanks


Solution

  • Your code can prove

            ?- smarter(jake, dik).
    

    because using X = jake, Y = dik it founds a Z=nik such that smarter(jake,nik) (this is a fact) and then smarter(nik,dik), (this is proved considering X1=nik, Y1=dik, Z1=wes).

    However, in order to prove

           ?- smarter(dik, jake).
    

    with X =dik, Y=jake, prolog needs a Z such that smarter(dik, Z). However, there is no fact smarter(dik, Z). Then, the rule is applied again ... and you have the loop.

    The idea to fix (at least this particular example) is to distinguish facts and rules:

    isSmarter(jake, nik).
    isSmarter(nik, wes).
    isSmarter(wes, dik).
    
    smarter(X, Y) :- isSmarter(X,Y).
    
    smarter(X, Y) :-
        isSmarter(X, Z),
        smarter(Z, Y).
    

    This should work.