prologprolog-diffailure-slice

Why does Prolog crash in this simple example?


likes(tom,jerry).
likes(mary,john).
likes(mary,mary).
likes(tom,mouse).
likes(jerry,jerry).
likes(jerry,cheese).
likes(mary,fruit).
likes(john,book).
likes(mary,book).
likes(tom,john).

likes(john,X):-likes(X,john), X\=john.

Hi there, above is a very simple prolog file, with some facts and only one rule: John likes anyone who likes him. But after loading this file and ask Prolog the following query:

likes(john,X).

The program crashes. The reason is somehow prolog gets stuck at likes(john,john) even though the rule states that X\=john.

Any advice?


Solution

  • Ironically, given the site we're on, you're getting a stack overflow.

    It does this because of the order of execution that prolog uses, it's going to go into an infinite recursion at likes(X,john) in your rule, it activates the rule again - not a fact - never getting to the X\=john bit.

    One way to fix this is to have your rule named differently from your fact like this:

    kindoflikes(tom,jerry).
    kindoflikes(mary,john).
    kindoflikes(mary,mary).
    kindoflikes(tom,mouse).
    kindoflikes(jerry,jerry).
    kindoflikes(jerry,cheese).
    kindoflikes(mary,fruit).
    kindoflikes(john,book).
    kindoflikes(mary,book).
    kindoflikes(tom,john).
    
    likes(Y,X):- kindoflikes(X,Y), X\=Y.
    likex(Y,X):- kindoflikes(Y,X), X\=Y.
    

    Note the reversal of X and Y in the kindoflikes in the two rule definitions. So you get:

    ?- likes(john,X).
    X = mary ;
    X = tom ;
    X = book.
    

    But you're not locked into finding what john likes, and you can do:

    ?- likes(jerry,X).
    X = tom ;
    X = cheese.