目前我遇到了从noun_phrase
循环回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,_).
我想从np2
循环回noun_phrase
。我认为np2
的代码是错误的,因为我只是一起攻击它。
答案 0 :(得分:10)
直接在Prolog中编码语法是一个非常麻烦的过程。是的,你可以这样做,但如果你刚开始学习Prolog,你就不是最好的位置。事实上,科学花了很多年才提出一种特别有效的编码 - 当这种编码被理解时,Prolog就诞生了!
您需要的是语法 - definite clause grammars dcg。不要试图在Prolog(现在)中理解他们的编码,只需习惯phrase/2
!
以下是来自Prolog and Natural-Language Analysis的程序3.11 Fernando C. N. Pereira和Stuart M. Shieber。 Pereira设计了我们今天使用的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)))) ...