General
Material
Lecture 1
Lecture 2
Lecture 3
Lecture 4
Lecture 5

Recursion: the effects of changing the order of clauses and goals

In today's lecture, we saw the following definition of ancestor_of/2".

ancestor_of(X,Y) :- parent_of(X,Y).
ancestor_of(X,Y) :- parent_of(X,Z),
                    ancestor_of(Z,Y).
(Download the knowledge base.)

What if we had defined this predicate as

ancestor_of(X,Y) :- ancestor_of(Z,Y),
                    parent_of(X,Z).
ancestor_of(X,Y) :- parent_of(X,Y).
(Download knowledge base.)

or as
ancestor_of(X,Y) :- parent_of(X,Y).
ancestor_of(X,Y) :- ancestor_of(Z,Y),
                    parent_of(X,Z).
(Download knowledge base.)

or as
ancestor_of(X,Y) :- parent_of(X,Z),
                    ancestor_of(Z,Y).
ancestor_of(X,Y) :- parent_of(X,Y).
(Download knowledge base.)

From a purely logical point of view, all of these definitions should be equivalent. After all, logically X and Y is equivalent to Y and X. The way that Prolog treats them differs, though. Ask some queries to all of the different knowledge bases and see how Prologs reactions differ. Ask queries where Prolog should answer yes, queries where it should answer no and queries which involve variables.

Try to understand why Prolog behaves in the ways it does. Do traces and draw the search trees that correspond to the different queries.

If Prolog does not come back with an answer, it has probably gone off into an endless loop. Stop it by pressing Ctrl-c. Then type a to abort.

Back to the practical session of day2.