直接在Prolog中对语法进行编码是一个非常繁琐的过程。是的,你可以做到这一点,但如果你刚刚开始学习Prolog,那么你并不处于最佳状态。事实上,科学花了很多年才提出了一个特别高效的编码–,并且当了解这种编码时,Prolog就诞生了!
你需要的是语法– definite clause grammarsdcg。不要试图在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)))) ...
请提供你想要实现的文法的一些编码(EBNF)或输入/输出的一些例子。顺便说一句:检查明文句法,他们会简化代码并避免很多样板 –