Search code examples
prologprolog-dif

Prolog order of query rules


Prolog Question: Just started learning prolog and this was on one of the practice quizzes we were given.

Given:

avenger(thor).
avenger(captainAmerica).
sibling(thor,loki).
asgardian(thor).
asgardian(X) :- sibling(Y,X),asgardian(Y).
train1(X,Y) :- avenger(X),!,avenger(Y).
train2(X,Y) :- avenger(X),X\=Y,avenger(Y). 

List all answers returned by the following queries.

train2(A, captainAmerica). %returns A=thor.
train2(captainAmerica, A). %returns false.

My question is about the second query. Why wouldn't this return A=thor. ? I messed around a bit and if i change train2 to

train2(X,Y) :- avenger(X),avenger(Y),X\=Y.

when i run the second query I get

A=thor. 

A quick explanation of why the order of the rules in the query matters here would be awesome. Thanks.


Solution

  • \= is a weird predicate... It says, "if the unification of the two arguments succeeds, fail; if the unification fails, succeed". So, as the unification of a free variable with an atom will always succeed, it fails.

    Once the Y has been unified with thor, the unification of captainAmerica with thor fails, so the X \= Y succeeds.

    Anyway, you should not use \= in this context. Instead, use dif/2. Try messing around with a predicate defined as:

    train3(X, Y) :-
        dif(X, Y),
        avenger(X),
        avenger(Y).
    

    Better than the other two in several ways. You can search SO for other questions with dif/2.