Prolog递归语法 [英] Prolog recursion grammar

查看:40
本文介绍了Prolog递归语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我在从 np2 循环回 noun_phrase 时遇到问题.我想知道是否有人可以帮助我循环回到 noun_phrase.这是一些代码:

noun_phrase([X|T],(det(X), NP2),Rem):-检测(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 的代码是错误的,因为我只是把它混在一起.

解决方案

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

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

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

<预>s(s(NP,VP)) --> np(NP), vp(VP).np(np(Det,N,Rel)) -->检测(检测),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)) --> [停止].det(det(a)) --> [a].n(n(程序)) --> [程序].tv(tv(writes)) --> [写].

如果要将字典表示为 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 = [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)))) ...

at the moment I am having a problem with looping back to noun_phrase from np2. I was wondering if someone can help me loop back to noun_phrase. Here is some code:

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

I want to loop from np2 back to noun_phrase. I think the code for np2 is wrong as I just hacked it together.

解决方案

Encoding a grammar directly in Prolog is a quite cumbersome process. Yes, you can do this, but if you just started to learn Prolog you are not in the best position. In fact, it took science many years to come up with a particularly efficient encoding – and when this encoding was understood, Prolog was born!

What you need are grammars – definite clause grammars . Don't try to understand their encoding in Prolog (now), simply get used to them with phrase/2!

Here is Program 3.11 from Prolog and Natural-Language Analysis by Fernando C. N. Pereira and Stuart M. Shieber. Pereira designed the very style of DCG rules we are using today. This book is one of the most undervalued Prologbooks. And it's free!

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

If you want to represent the dictionaries as Prolog facts, use in place of

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

rather

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

noun(program).

So, let's use it:

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

What a self-referential discourse! But now, all sentences by length which is a bit more edifying:

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

这篇关于Prolog递归语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆