Discontiguous predicate warning from GNU Prolog

Adam Straughan picture Adam Straughan · Sep 13, 2011 · Viewed 11.1k times · Source

For a lark I have started learning Prolog via http://www.learnprolognow.org/. My excuse is that I have only just started.

I am unsure of how the following (simple?) exercise should be written to work as expected. http://cs.union.edu/~striegnk/learn-prolog-now/html/node13.html#sec.l1.exercises

I can see that Gnu Prolog 1.4 ( http://www.gprolog.org/ ) is not happy that the 2nd predicate for wizard\1 is not next to the first one. I can re-order the program to make it work but then I end up with code which to my novice Prolog eye is less understandable than the one presented below.

Am I missing something obvious?

wiz.pl

wizard(ron).
hasWand(harry).
quidditchPlayer(harry).

wizard(X) :- hasBroom(X),hasWand(X).
hasBroom(X) :- quidditchPlayer(X).

consult wiz.pl

| ?- [wiz].
compiling D:/wiz.pl for byte code...
D:/wiz.pl:5: warning: discontiguous predicate wizard/1 - clause ignored
D:/wiz.pl compiled, 5 lines read - 632 bytes written, 24 ms

Answer

Fred Foo picture Fred Foo · Sep 13, 2011

Most Prologs want the clauses for any particular predicate to be listed together, unless you do some magic. I'm surprised Striegnitz and Bos ignore this. Change the program to

% all clauses for wizard/1
wizard(ron).
wizard(X) :- hasBroom(X),hasWand(X).

hasWand(harry).
quidditchPlayer(harry).
hasBroom(X) :- quidditchPlayer(X).

Note that I've kept the clauses for wizard/1 in the same order as in the original program. For simple knowledge bases such as this one, order doesn't matter much, but when implementing non-deterministic algorithms, clause order may determine the order in which solutions are generated.