Search code examples
prologdcg

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


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?


Solution

  • 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