4

目前我在循环回noun_phrasefrom时遇到问题np2。我想知道是否有人可以帮助我循环回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,_).

我想从np2back 循环到noun_phrase. 我认为代码np2是错误的,因为我只是一起破解了它。

4

1 回答 1

9

直接在 Prolog 中编码语法是一个相当繁琐的过程。是的,你可以这样做,但如果你刚开始学习 Prolog,你并不是处于最佳位置。事实上,科学花了很多年才想出一种特别有效的编码——当这种编码被理解时,Prolog 就诞生了!

你需要的是语法——定句语法 。不要试图理解它们在 Prolog 中的编码(现在),只需使用phrase/2!

这是Fernando CN Pereira 和 Stuart M. Shieber的Prolog 和自然语言分析中的程序 3.11 。Pereira 设计了我们今天使用的 DCG 规则的风格。这本书是最被低估的 Prologbook 之一。而且它是免费的!

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

np(np(Det,N,Rel)) -->
   检测(检测),
   n(N),
   optrel(相对)。
np(np(PN))-> pn(PN)。

副总裁(副总裁(电视,NP))->电视(电视),NP(NP)。
vp(vp(IV)) --> iv(IV)。

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

pn(pn(terry)) --> [特里]。
pn(pn(shrdlu)) --> [shrdlu]。

iv(iv(halts)) --> [暂停]。

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

n(n(程序))-> [程序]。

电视(电视(写入))-> [写入]。

如果要将字典表示为 Prolog 事实,请使用

n(n(程序))-> [程序]。

相当

n(n(W)) --> [W],{名词(W)}。

名词(程序)。

所以,让我们使用它:

?-短语(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] ...

多么自我指涉的话语啊!但是现在,所有句子的长度都更有启发性:

?-长度(Xs,N),短语(s(P),Xs)。
Xs = [特里,暂停],
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 = [特里,写,特里],
N = 3,
P = s(np(pn(terry)),vp(tv(writes),np(pn(terry))));
Xs = [特里,写,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))))...
于 2012-05-01T17:27:22.047 回答