Why do I need to duplicate my Prolog predicates in order to make my program work?

67 views Asked by At

I am using SICStus Prolog 4.0.8 to write a program that parses a sentence in English and returns the syntactic tree, as well as a yes/no on whether the sentence is correct according to the programmed grammar. Here is an example (sentence is Larry and Carol meet their older neighbors Paul and Lillian):

s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).

If I run the code like this, it complains that np2/3 is not defined, but if I put the numbers before the brackets, then it complains np/3 is not defined. My only solution is to put both predicates in, like this:

s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
np1(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np2(np2(D, A, N)) --> det(D), adj(A), cn(N).
vp1(vp1(V, A)) --> tv(V), app(A).

Then it compiles and executes successfully. What's the cause of this behavior?

1

There are 1 answers

4
slago On BEST ANSWER

In the first version of your code, the clause

np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).

defines the predicate np/3 (and calls the predicate pn/3). However, the clause

app(app(N1, N2)) --> np2(N1), np1(N2).

calls predicates np2/3 and np1/3, which are not defined. That's the cause of the runtime error.

In the second version of your code, the predicates np2/3 and np1/3 are also defined and, therefore, there is no error.

What's the problem? I think you are confusing np/3 and pn/3 (which are predicates) with np1/3 and np2/3 (which are terms representing syntax tree nodes).


np( np1(N1, C, N2) ) --> pn(N1), conj(C), pn(N2).
^    ^                   ^
|    |                   |
|    |                   +--- predicate being called (must be defined)
|    |
|    +----------------------- term representing a syntax tree node (this is not a predicate) 
|
+---------------------------- predicate being defined