Search code examples
prologdcg

Some doubts about how work this DCG grammar for subset of natural language in Prolog


I am studying DCG grammar for natural language processing using Prolog and I have some doubts about if I have understand it correctly or if I am missing something.

This is my DCG grammar:

sentence2(VP) --> noun_phrase2(Actor),
              verb_phrase2(Actor, VP).

/* A noun phrase is a proper name of a person (that is unified in the Name variable) */
noun_phrase2(Name) --> properName(Name).

/* A verb_phrase can be an intransitive verb */
verb_phrase2(Actor, VP) --> intrans_verb(Actor, VP).

/* A verb_phrase can be a transitive verb followed by an object complement
verb_phrase2(Somebody, VP) --> trans_verb(Somebody, Something, VP),
                               noun_phrase2(Something).

/* The meaning of a proper name john is john
   The meaning of a proper name mary is mary */
properName(john) --> [john].
properName(mary) --> [mary].

intrans_verb(Actor, paints(Actor)) --> [paints].

trans_verb(Somebody, Something, likes(Somebody, Something)) --> [likes].

So this grammar can accept phrase like: [john, paints] that have the meaning: paints(john)

I would see if my idea about how I reach this meaning is correct.

So I think that this is what happen when I execute the following query:

?- sentence2(Meaning, [john, paints], []).
Meaning = paints(john) 

[john paints] it is my final sentence that I have to evaluate and say if it belong to my language or not.

A sentence have to be formed in the following way:

sentence2(VP) --> noun_phrase2(Actor),
                  verb_phrase2(Actor, VP).

(by something that is noun phrase followed by something that is a verb phrase.

A noun phrase is composed in this way:

noun_phrase2(Name) --> properName(Name).

so a noun phrase is a proper name

The meaning of a proper name is simple because by this line:

properName(john) --> [john].

I am simply say that the john is a proper name and I am adding a parameter to the DCG grammar that specify its meaning. So: the semantic meaning of the proper name john is john

So, as the meaning of a noun phrase is the same meaning of the proper name (because the variables Name unify)

So in the previous case the meaning ot the noun_phrase2 predicate is john and the first evalutation step of my original sentence is end.

Now I have to evaluate that the second part is a verbal phrase by the predicate: verb_phrase2(Actor, VP)

A verbal phrase could be, as in this case, an intransitive verb:

verb_phrase2(Actor, VP) --> intrans_verb(Actor, VP).

An intransitive verb is definied in this way:

intrans_verb(Actor, paints(Actor)) --> [paints].

So the word paints is an intransitive verb and it's meaning is paints(Actor) where Actor is a variable that dependnds from the context (in this case Actor rappresent who do the action, who paints)

So, it do backtrack to verb_phrase2(Actor, VP) to verify verb_phrase2(Actor, VP)

Now Actor still remain a not yet unified variable and its meaning is VP = paints(Actor)

So, it is verified that paints is an intransitive verb and its meaning is paints(Actor)

So execute backtrack to the original sentence2(VP) predicate where I have just verified the noun_phrase2(Actor) predicate and in which Actor = john

So I have something like this situation:

sentence2(VP) --> noun_phrase2(john),
                  verb_phrase2(john, paints(john)).

So the final VP is unified to paints(john)

Is it my reasoning correct or am I missing something? Is it a good way to reasoning in Prolog way?


Solution

  • please ask a specific, short question. Include relevant code without excessive comments.

    Here's how.


    Given the DCG rules

    sentence2(VP) --> noun_phrase2(Actor),verb_phrase2(Actor, VP).
    noun_phrase2(Name) --> properName(Name).
    verb_phrase2(Actor, VP) --> intrans_verb(Actor, VP).
    verb_phrase2(Somebody, VP) --> trans_verb(Somebody, Something, VP),
                                     noun_phrase2(Something).
    properName(john) --> [john].
    properName(mary) --> [mary].
    intrans_verb(Actor, paints(Actor)) --> [paints].
    trans_verb(Somebody, Something, likes(Somebody, Something)) --> [likes].
    

    how does the following achieve its result?

    ?- sentence2(Meaning, [john, paints], []).
    Meaning = paints(john) 
    

    Answer:

    The above rules are equivalent to

    sentence2(VP, L, Z):- noun_phrase2(Actor, L, L2), 
                          verb_phrase2(Actor, VP, L2, Z).
    noun_phrase2(Name, L, Z):- properName(Name, L, Z).    
    verb_phrase2(Actor, VP, L, Z):- intrans_verb(Actor, VP, L, Z). 
    verb_phrase2(Somebody, VP, L, Z):- trans_verb(Somebody, Something, VP, L, L2),
                                       noun_phrase2(Something, L2, Z).    
    properName(john, L, Z):- 
        L = [john | Z].         %// 'john' is present in the input stream
    properName(mary, L, Z):- 
        L = [mary | Z].         %// 'mary' is present in the input stream
    /* an alternative definition 
    properName(X) --> [X], { member(X, [john, mary]) }.
       %% would be translated as
    properName(X, L, Z):- L = [X | Z], member(X, [john, mary]). 
    */    
    intrans_verb(Actor, paints(Actor), L, Z):- 
        L = [paints | Z].       %// 'paints' is present in the input stream    
    trans_verb(Somebody, Something, likes(Somebody, Something), L, Z):-
        L = [likes | Z].        %// 'likes' is present in the input stream
    

    In particular,

    ?- sentence2(Meaning, [john, paints], []).    
    
    ?- noun_phrase2(Actor, [john, paints], L2),                    
       verb_phrase2(Actor, Meaning, L2, []).
    
      ?- noun_phrase2(Actor, [john, paints], L2).
      ?- properName(Actor, [john, paints], L2).   
      ?- properName(john, [john, paints], L2).            { Actor=john }
      !- [john, paints] = [john | [paints]]               { L2=[paints] }
    
      ?- verb_phrase2(john, Meaning, [paints], []).
      ?- intrans_verb(john, Meaning, [paints], []).
      ?- intrans_verb(john, paints(john), [paints], []).  { Meaning=paints(john) }
      !- [paints] = [paints | []]
    
    !-