2017-12-09 1 views
1

Ich habe einen Satz Parser in Prolog erstellt. Es analysiert erfolgreich Sätze, die mit eingegeben werden ... ?- sentence([input,sentence,here],Parse).Umgang mit Informationen aus einem Prolog Satz Parser

Dies ist der Code, den ich mit dem Satz zu analysieren:

np([X|T],np(det(X),NP2),Rem):- /* Det NP2 */ 
    det(X), 
    np2(T,NP2,Rem). 
np(Sentence,Parse,Rem):- np2(Sentence,Parse,Rem). /* NP2 */ 
np(Sentence,np(NP,PP),Rem):- /* NP PP */ 
    np(Sentence,NP,Rem1), 
    pp(Rem1,PP,Rem). 

np2([H|T],np2(noun(H)),T):- noun(H). /* Noun */ 
np2([H|T],np2(adj(H),Rest),Rem):- adj(H),np2(T,Rest,Rem). 

pp([H|T],pp(prep(H),Parse),Rem):- /* PP NP */ 
    prep(H), 
    np(T,Parse,Rem). 

vp([H| []], vp(verb(H))):- /* Verb */ 
    verb(H). 

vp([H|T], vp(verb(H), Rem)):- /* VP PP */ 
    vp(H, Rem), 
    pp(T, Rem, _). 

vp([H|T], vp(verb(H), Rem)):- /* Verb NP */ 
    verb(H), 
    np(T, Rem, _). 

sollte ich erwähnen, dass die Ausgabe wäre: sentence(np(det(a), np2(adj(very), np2(adj(young), np2(noun(boy))))), vp(verb(loves), np(det(a), np2(adj(manual), np2(noun(problem)))))).

Verwenden des vordefinierten Vokabulars: det(a), adj(very), adj(young), noun(boy), verb(loves), det(a), adj(manual), noun(problem).

Was ich tun möchte, ist die übergebene Ausgabe an Prädikate übergeben, die die Wörter in drei verschiedene Kategorien trennen würde, die "Subjekt, Verb und Objekt" sind.

(1) Das Subjekt wird die ersten zwei Adjektive und dann ein Nomen halten.

(2) Das Verb wird das Verb von der "Verbalphrase" halten.

(3) Und das Objekt wird die Adjektive und Substantive in der "Verbalphrase" enthalten.

Alle Bestimmungsfaktoren sollten ignoriert werden.

Zum Beispiel möchte ich ein Prädikat, das nach Adjektiven in der Ausgabe suchen würde.

Ich habe versucht viele Dinge zu versuchen und dies funktioniert, aber keine Arbeit. Jede Hilfe wird sehr geschätzt.

+0

Ok. Ich habe den Code hinzugefügt, den ich verwende, um den Satz zu analysieren. – Joseph

Antwort

2

Ich mache einen zweiten Versuch, dann.

der Ausgang wäre: sentence(np(det(a), np2(adj(very), np2(adj(young), np2(noun(boy))))), vp(verb(loves), np(det(a), np2(adj(manual), np2(noun(problem)))))). [...] Was ich tun möchte, ist übergeben Sie die geparste Ausgabe zu Prädikaten, die die Wörter in drei verschiedene Kategorien trennen würde, die "Subjekt, Verb und Objekt" sind.

Sie können Verfahren wie diese schreiben, die von Ihren Strukturen auf Wortlisten abbilden.

handle_sent(sentence(NP1,vp(V,NP2)),Subj,Verb,Obj) :- 
    handle_np(NP1,Subj), handle_verb(V,Verb), handle_np(NP2,Obj). 

handle_verb(verb(V),[V]). 

handle_np(np(_,np2(adj(A),np2(noun(N)))),[A,N]). 
handle_np(np(_,np2(adj(A1),np2(adj(A2),np2(noun(N))))),[A1,A2,N]). 

Dies erzeugt:

?- handle_sent(...,Subj,Verb,Obj). 
Subj = [very,young,boy] 
Verb = [loves] 
Obj = [manual,problem] 
1

Die DCG erzeugt unter dieses Verhalten:

?- s(Sem,[a,young,boy,loves,a,manual,problem],[]). 
Sem = [noun(boy),verb(loves),noun(problem)] 

Es gibt einige Probleme in der Grammatik. Ihre dritte np-Klausel ruft sich direkt auf (keine Eingabe dazwischen), was Endlosschleife bedeutet. Die von dir gepostete Grammatik scheint nicht in der Lage zu sein, deine Ausgabe zu produzieren (sehr jung). Wie auch immer, hier ist die DCG:

s(Sem) --> 
    np(Sem1), vp(Sem2), { append(Sem1,Sem2,Sem) }. 

np(Sem) --> 
    [W], { det(W) }, 
    np2(Sem). 
np(Sem) --> 
    np2(Sem). 
np(Sem) --> 
    np2(Sem1), 
    pp(Sem2), { append(Sem1,Sem2,Sem) }. 

np2([noun(W)]) --> 
    [W], { noun(W) }. 
np2(Sem) --> 
    [W], { adj(W) }, 
    np2(Sem). 

pp(Sem) --> 
    [W], { prep(W) }, 
    np(Sem). 

vp([verb(W)]) --> 
    [W], { verb(W) }. 
vp(Sem) --> 
    [W], { verb(W) }, 
    np(Sem0), { Sem = [verb(W)|Sem0] }. 
vp(Sem) --> 
    [W], { verb(W) }, 
    pp(Sem0), { Sem = [verb(W)|Sem0] }. 

Zusatz: wenn Sie Änderung (zB Adjektive) zu handhaben wollen, dann gibt es einfache offensichtliche Lösungen, die schnell unpraktisch geworden, und dann gibt es allgemeinere Techniken, wie eine logische Hinzufügen Variable zum np.

np(X,Sem) --> 
    [W], { det(W) }, 
    np2(X,Sem). 
np(X,Sem) --> 
    np2(X,Sem). 
np(X,Sem) --> 
    np2(X,Sem1), 
    pp(Sem2), { append(Sem1,Sem2,Sem) }. 

np2(X,[noun(X,W)]) --> 
    [W], { noun(W) }. 
np2(X,[adj(X,W)|Sem]) --> 
    [W], { adj(W) }, 
    np2(X,Sem). 

Diese Variablen (X) niemals instanziiert, es dient nur die Teile der Nominalphrase miteinander zu verbinden bedeuten.

?- s(Sem,[a,young,boy,loves,a,manual,problem],[]). 
Sem = [adj(_A,young),noun(_A,boy),verb(loves),adj(_B,manual),noun(_B,problem)] 

Es gibt verschiedene zusätzliche Möglichkeiten. Gute Bücher sind Gazdars & Mellish, NLP in Prolog und Norvig, Paradigmen der AI-Programmierung (wenn Sie sprechen Lisp) sowie Pereira & Shieber, Prolog und in natürlicher Sprache Analyse.

Zusatz # 2: nach dem Lesen Ihrer Frage noch einmal und this other question, erkannte ich, dass Sie eigentlich wollen drei separate Listen. Kein Problem.

s(L1,L2,L3) --> 
    np(_,L1), vp(L2,L3). 

np(X,L) --> 
    [W], { det(W) }, 
    np2(X,L). 
np(X,L) --> 
    np2(X,L). 
np(X,L) --> 
    np2(X,L), 
    pp(_). 

np2(X,[noun(X,W)]) --> 
    [W], { noun(W) }. 
np2(X,[adj(X,W)|L]) --> 
    [W], { adj(W) }, 
    np2(X,L). 

pp(L) --> 
    [W], { prep(W) }, 
    np(_,L). 

vp([verb(W)],[]) --> 
    [W], { verb(W) }. 
vp([verb(W)],L) --> 
    [W], { verb(W) }, 
    np(_,L). 
vp([verb(W)],L) --> 
    [W], { verb(W) }, 
    pp(L). 

Ausgang:

| ?- s(L1,L2,L3,[a,young,boy,loves,a,manual,problem],[]). 
L1 = [adj(_A,young),noun(_A,boy)], 
L2 = [verb(loves)], 
L3 = [adj(_B,manual),noun(_B,problem)] ? 

Nun, vielleicht brauchen Sie nicht die logischen Variablen, aber eine der anderen Seite könnte man kompliziertere Modifikatoren haben, wie „ein kleiner Junge ein manuelles Problem liebt Beteiligung rote Schrauben und weiße Würfel ". Dann würden die Variablen verfolgen, welches Adjektiv das Substantiv modifiziert.

+0

Könnte ich dies tun, indem ich separate Prädikate wie 'extractnounphrase (np (det (A), _)): -' benutze, indem ich den geparsten Wert an sie übergebe? Anstatt es so zu machen, wie wir es machen. – Joseph

+0

Nun, es wäre wie zwei Parser, da die Ausgabe, die Sie gerade produzieren, isomorph zu den Regeln Ihrer Grammatik ist. DCG ist viel besser. –

+0

Ich verstehe, dass DSG besser ist (weil die Leute mir das immer wieder sagen), aber das muss ich noch lernen. Ich habe mich gefragt, ob du mir zeigen könntest, wie ich es mache, so wie ich es gemacht habe. – Joseph

Verwandte Themen