|Bad Rule Names||Infinite Recursion Errors|
Never give a fact and a rule the same name.
I wanted to do something like this.
noun(man). noun(woman). prn(it).
noun(X) :- prn(X).That is, I wanted PROLOG to treat pronouns just like nouns. If X is a pronoun, then for our purposes X is a noun. This generated some weird compile errors. The following code accomplishes the same thing without the errors:
n(man). n(woman). prn(it).noun(X) :- prn(X). noun(X) :- n(X).Infinite Recursion Problems -- Instruction Order Still Matters
Because PROLOG is theoretically a nonprocedural language, programmers can be lulled into thinking that the order in which statements are given doesn't matter. Indeed, if f1(X) is true and f2(X) is true, then the order in which f1 and f2 are called makes no logical difference. However, nonprocedural PROLOG is always being implemented on very procedural machines. The sequence of instructions can make the difference between a perfect program and one that is no good at all.
This came to my attention dealing with the following problem. I wanted a recursively defined noun phrase -- a noun preceded by any number of determiners. With all this in mind, compare the following two code fragments.
nounp(X) :-noun(X). nounp(X) :-append(A,B,X),det(A),nounp(B). /*good recursive definition*/nounp(X) :-noun(X). nounp(X) :-det(A),nounp(B),append(A,B,X)./*ERROR - infinte recursion*/In the first example, the program splits up the phrase (X), then tries to find a determiner that matches the first piece (A) and another noun phrase that matches the second piece (B). When nounp is called recursively, it gets called with a smaller list every time.
In the second example, the program picks a determiner from its list, then calls nounp. B has not yet been bound, so on my system it assumed the value of X. Naturally enough, this results from infinite recursion.
Avoid these two errors, and you will be well on your way to good PROLOG programming.
Back to the Outline