2012-05-01 124 views
4

此刻我遇到问题从np2循环回noun_phrase。我想知道是否有人可以帮我循环回noun_phrase。下面是一些代码:序言递归语法

noun_phrase([X|T],(det(X), NP2),Rem):- 
    det(X), 
    np2(T,NP2,Rem). 

np2([H|T],np2(adj(H),Rest),NP) :- 
    adj(H), 
    np2(T,Rest,Rem), 
    noun_phrase(NP,Rem,_). 

我想从环回np2noun_phrase。我认为np2的代码是错误的,因为我只是将它们拼凑在一起。

+0

请提供你想要实现的文法的一些编码(EBNF)或输入/输出的一些例子。顺便说一句:检查明文句法,他们会简化代码并避免很多样板 –

回答

9

直接在Prolog中对语法进行编码是一个非常繁琐的过程。是的,你可以做到这一点,但如果你刚刚开始学习Prolog,那么你并不处于最佳状态。事实上,科学花了很多年才提出了一个特别高效的编码–,并且当了解这种编码时,Prolog就诞生了!

你需要的是语法– definite clause grammars。不要试图在Prolog(现在)中了解他们的编码,只需使用phrase/2就可以了!

这是程序3.11从Prolog and Natural-Language Analysis由 Fernando C. N. Pereira和Stuart M. Shieber。佩雷拉设计了我们今天使用的DCG规则的风格。这本书是最被低估的Prologbooks之一。它是免费的!

 
s(s(NP,VP)) --> np(NP), vp(VP). 

np(np(Det,N,Rel)) --> 
    det(Det), 
    n(N), 
    optrel(Rel). 
np(np(PN)) --> pn(PN). 

vp(vp(TV,NP)) --> tv(TV), np(NP). 
vp(vp(IV)) --> iv(IV). 

optrel(rel(epsilon)) --> []. 
optrel(rel(that,VP)) --> [that], vp(VP). 

pn(pn(terry)) --> [terry]. 
pn(pn(shrdlu)) --> [shrdlu]. 

iv(iv(halts)) --> [halts]. 

det(det(a)) --> [a]. 

n(n(program)) --> [program]. 

tv(tv(writes)) --> [writes]. 

如果你要代表词典作为Prolog的事实,代替

 
n(n(program)) --> [program]. 

 
n(n(W)) --> [W],{noun(W)}. 

noun(program). 

所以使用,让我们使用它:

?- phrase(s(P), Xs). 
P = s(np(det(a),n(program),rel(epsilon)),vp(tv(writes),np(det(a),n(program),rel(epsilon)))), 
Xs = [a,program,writes,a,program] ; 
P = s(np(det(a),n(program),rel(epsilon)),vp(tv(writes),np(det(a),n(program),rel(that,vp(tv(writes),np(det(a),n(program),rel(epsilon))))))), 
Xs = [a,program,writes,a,program,that,writes,a,program] ... 

什么是自我参照话语!但现在,所有的句子了长度是一个比较有启发性:

?- length(Xs, N), phrase(s(P), Xs). 
Xs = [terry,halts], 
N = 2, 
P = s(np(pn(terry)),vp(iv(halts))) ; 
Xs = [shrdlu,halts], 
N = 2, 
P = s(np(pn(shrdlu)),vp(iv(halts))) ; 
Xs = [a,program,halts], 
N = 3, 
P = s(np(det(a),n(program),rel(epsilon)),vp(iv(halts))) ; 
Xs = [terry,writes,terry], 
N = 3, 
P = s(np(pn(terry)),vp(tv(writes),np(pn(terry)))) ; 
Xs = [terry,writes,shrdlu], 
N = 3, 
P = s(np(pn(terry)),vp(tv(writes),np(pn(shrdlu)))) ; 
Xs = [shrdlu,writes,terry], 
N = 3, 
P = s(np(pn(shrdlu)),vp(tv(writes),np(pn(terry)))) ... 
+0

现在有没有办法从np2递归到名词短语呢?因为我知道这就是我所需要的全部工作。谢谢 – DorkMonstuh

+0

@JohnLam:你的程序有很多问题。最大的一个:你不使用DCG。此外,你不明白你想要什么。采取上述代码并根据需要进行修改。 – false

+0

我知道np2是错误的,我没有使用DCG。我想要的是在np2中,我想再次调用noun_phrase,所以我可以再次通过它。 – DorkMonstuh