Search code examples
prologdcg

extracting words from a prolog structure


i have been set a task of natural language parsing in Prolog. so far i have the program working to an extent. So far it will print sentence(noun_phrase(det(the), np2(noun(cat))), verb_phrase(verb(sat), pp(prep(on), noun_phrase(det(the), np2(noun(mat)))))) if i input a list of [the,cat,sat,on,the,mat], which is fine.

the next task i have to do is to extract the keywords from the sentence, ie extract the noun in the noun phrase, the verb in the verb phrase and the noun in the verb phrase, so i could return a list: [cat,sat,mat]. Could anybody give me a hand getting started because im very stuck with this. thanks!

my current code is:

sentence(S,sentence((NP), (VP))):-
   nl,
np(S, NP, R),
vp(R, VP, []),
write('sentence('), nl, write('   '), write((NP))
      ,nl,write('    '), write((VP)),nl,write('  ').

np([X | S], noun_phrase(det(X), NP2), R) :-
    det(X),
    np2(S, NP2, R).
np(S, NP, R) :-
    np2(S, NP, R).
np(S, np(NP, PP), R) :-
    append(X, Y, S), /* Changed here - otherwise possible endless recursion */
    pp(Y, PP, R),
    np(X, NP, []).

np2([X | R], np2(noun(X)), R) :-
    noun(X).
np2([X | S], np2(adj(X), NP), R) :-
    adj(X),
    np2(S, NP, R).

pp([X | S], pp(prep(X), NP), R):-
    prep(X),
    np(S, NP, R).

vp([X | R], verb_phrase(verb(X)), R) :- /* Changed here - added the third argument */
    verb(X).
vp([X | S], verb_phrase(verb(X), PP), R) :-
    verb(X),
    pp(S, PP, R).
vp([X | S], verb_phrase(verb(X), NP), R) :-
    verb(X),
    np(S, NP, R).


det(the).
det(with).
noun(cat).
noun(mat).
verb(sat).
prep(on).
adj(big).

Solution

  • Instead of multiple successive write/1 calls, consider using format/2. However, it is usually best to avoid side-effects, and instead to think in terms of relations. To describe the relation between your sentence structures and lists, consider using DCG notation:

    sentence(sentence(NP, VP)) -->
        np(NP),
        vp(VP).
    
    np(noun_phrase(det(D), np2(noun(N)))) --> [D, N].
    ... etc.
    

    and then using the program like ?- phrase(sentence(S), List).. You can then use the program in all directions and for example also check whether a given list corresponds to a sentence structure, which you cannot do so easily if you just write output to the screen.