Search code examples
prologdcg

Having trouble understanding Prolog DCG


enter image description here

enter image description here

This is a new following up question of https://stackoverflow.com/questions/34170191/confused-about-how-to-use-in-prolog?noredirect=1#comment56112107_34170191

I tried to make the code in 9.7 more powerful. So I decide to add a new grammar

every,man,that,a,woman,loves,dance

the answer should be

all(man(X)&exists(woman(Y)&loves(Y, X)))->dance(1)))

at least I believe it is the answer.

I tried some approach but it does not work. This is my final Wrong solution:

rel_clasue(X,P1,P3)-->[that],determiner(X,P1,P2,P3),noun(X,P1),trans_verb(X,P2,?).

? means that I do not know what to write. and I believe I has other bugs too. Rest code are exactly as book above. of course I add "dance" part

Can some one help me fix it or write a correct one?


Solution

  • Looking at rel_clause//3 it looks like you basically have two rules: an empty base case and another case that accepts a verb phrase. So it works when you give it [that,loves,a,woman] for instance:

    ?- phrase(rel_clause(X, P1, Y), [that,loves,a,woman]).
    Y = P1&exists(_G1990, woman(_G1990)&loves(X, _G1990))
    

    But it doesn't work when you give it a more complex phrase:

    ?- phrase(rel_clause(X, P1, Y), [that,a,woman,loves]).
    false.
    

    So I think you need to add a rule to rel_clause//3 to handle that. It seems clear to me that [that,a,woman,loves] and [that,loves,a,woman] is really just inverting the relationship, and in the former case we actually get a transitive verb without a noun following it to be the direct object. In other words [that,a,woman,loves] is somehow like man(M) & (exists(woman(W)) & loves(W, M) where [that,loves,a,woman] is more like man(M) & (exists(woman(W)) & loves(M, W), where the M and W are swapped in the love/2 structure.

    I venture this as a guess:

    rel_clause(X, P1, (P1&P3)) -->
        [that], noun_phrase(Y, P2, P3), trans_verb(Y, X, P2).
    

    This seems to produce the parse we want:

    ?- phrase(sentence(X), [every,man,that,a,woman,loves,lives]).
    X = all(_1, man(_1)&exists(_2, woman(_2)&loves(_2, _1))->lives(_1)) ;
    

    Apart from that, dance should be dances and you will need to make an intransitive verb rule for that:

    intrans_verb(X, dances(X)) --> [dances].