2017-12-09 16 views
1

프롤로그에 문장 파서를 만들었습니다. 그것은 성공적으로 입력되는 문장 ... ?- sentence([input,sentence,here],Parse).프롤로그 문장 파서의 정보 처리

이 내가 문장을 구문 분석하는 데 사용하고 코드입니다 구문 분석 :

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, _). 

내가 언급해야을 출력 될 것이라고 : 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)))))).

미리 정의 된 어휘 사용 : det(a), adj(very), adj(young), noun(boy), verb(loves), det(a), adj(manual), noun(problem).

내가 원하는 것은 단어를 "주체, 동사 및 개체"인 세 가지 범주로 구분할 술어에 구문 분석 된 결과를 전달하는 것입니다.

(1) 제목에는 처음 두 개의 형용사와 명사가 있습니다.

(2) 동사는 "동사구"에서 동사를 보유합니다.

(3) 개체는 "동사구"에서 형용사와 명사를 보유합니다.

모든 결정자는 무시해야합니다.

예를 들어 출력에서 ​​형용사를 찾는 조건자를 원합니다.

나는이 작업을 시도하지만 아무 것도 작동시키지 않으려 고 많은 일을 시도했다. 어떤 도움을 많이 주시면 감사하겠습니다. 문법에서 몇 가지 문제가 있습니다

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

:

+0

좋아. 문장을 구문 분석하는 데 사용하는 코드를 추가했습니다. – Joseph

답변

2

나는 두 번째 시도를하고 있습니다.

출력은 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))))))이됩니다. [...] 내가 원하는 것은 이라는 단어를 "subject, verb, object"라는 세 가지 범주로 구분하는 술어에 구문 분석 된 출력을 전달하는 것입니다.

구조에서 단어 목록으로 매핑하는 것과 같은 절차를 작성할 수 있습니다.

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]). 

이 생성됩니다

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

DCG는 다음이 동작을 생성합니다. 세 번째 np 절이 직접 호출되므로 (사이에 입력을 소비하지 않음) 무한 루프를 의미합니다. 당신이 올린 문법은 당신의 산출물을 만들어 낼 수없는 것 같습니다 (아주 어리다). 어쨌든, 여기에 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] }. 

추가 : 당신이 변경 (예 : 형용사를) 처리하는 경우, 신속하게 허무하게 간단한 확실한 솔루션이 존재하고 논리를 추가하는 등의 일반적인 기술이있다 변수를 np으로 변경하십시오.

이 변수 ( X)이 인스턴스화되지 않습니다
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). 

, 그것은 단지 함께 의미하는 명사구의 부분을 연결하는 역할을한다.

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

다양한 추가 가능성이 있습니다. 좋은 책은 Gazdar & Mellish, 프롤로그에서 NLP 및 노르 빅, 인공 지능 프로그래밍패러다임 (당신이 말을하면 리스프)뿐만 아니라 페레이라 & Shieber, 프롤로그 및 자연 언어 분석 있습니다.

추가 # 2 : 질문을 다시 읽은 후 this other question, 나는 실제로 세 개의 별도 목록을 원한다는 것을 깨달았습니다. 문제 없어.

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). 

출력 :

| ?- 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)] ? 
이제

어쩌면 당신 논리 변수를 필요로하지 않지만, 한 어린 소년이 수행하는 수동 문제를 사랑한다 "와 같은, 당신은 더 복잡한 수식을 가질 수 반면 빨간 볼트와 흰 조각 ". 그런 다음 변수는 어떤 형용사가 명사를 수정하는지 추적합니다.

+0

구문 분석 된 값을 전달하여 'extractnounphrase (np (det (A), _)) : -'와 같은 별도의 조건자를 사용하여이 작업을 수행 할 수 있습니까? 우리가 따라갈 때 그것을하는 대신에. – Joseph

+0

글쎄, 당신이 현재 생산하고있는 결과물이 문법의 규칙과 동형이기 때문에 두 개의 파서가있는 것과 같습니다. DCG가 훨씬 좋습니다. –

+0

나는 사람들이 계속 말하기 때문에 DSG가 더 낫다는 것을 이해하지만, 나는 아직도 이것을 배우고있다. 당신이 저에게 해왔 던 방식으로 어떻게하는지 보여 줄 수 있는지 궁금합니다. – Joseph