Prolog 给出两个有效解析中的一个;“通行权”;在DCG中

Prolog 给出两个有效解析中的一个;“通行权”;在DCG中,prolog,dcg,Prolog,Dcg,我刚刚了解了DCGs,并且非常喜欢我早期的探索。从一个非常简短的规范中可以得到多少,这是令人惊讶的。我碰到了一堵墙,我认为这是一个相当普遍的问题,我希望得到一些专家的建议。(甚至是新手建议,考虑到我是一个完全的新手。) 这是我语法的玩具版。为了纪念2014年3月3日,我把它做成了馅饼: sent(sent(VP, NP)) --> vp(VP), np(NP). vp(vp(V)) --> v(V). vp(vp(V, Qty)) --> v(V), qty(Qty). np(

我刚刚了解了DCGs,并且非常喜欢我早期的探索。从一个非常简短的规范中可以得到多少,这是令人惊讶的。我碰到了一堵墙,我认为这是一个相当普遍的问题,我希望得到一些专家的建议。(甚至是新手建议,考虑到我是一个完全的新手。)

这是我语法的玩具版。为了纪念2014年3月3日,我把它做成了馅饼:

sent(sent(VP, NP)) --> vp(VP), np(NP).
vp(vp(V)) --> v(V).
vp(vp(V, Qty)) --> v(V), qty(Qty).
np(np(Noun, Qty)) --> qty(Qty), n(Noun).
np(np(Noun)) --> n(Noun).

qty(qty(3)) --> ["3"].
v(v(eat)) --> ["eat"].
n(n(pie)) --> ["pies"].
在这个语法中,我们担心的是数量,它关系到数量分配给哪个词,名词还是动词。因此,像“Eat 3 pies”这样的句子有两种有效的语法分析,如下所示:

?- sent(X, ["eat", "3", "pies"], []).
X = sent(vp(v(eat)), np(n(pie), qty(3))) ;
X = sent(vp(v(eat), qty(3)), np(n(pie))) ;
在这种情况下,我总是希望动词“被授予”数量。那么,我的第一步是简单地删除允许数量在名词之前的规则。但在另一句话中,像这样的话

Bake 4 pies for 3 friends
。。。我想
朋友
有一个
数量(3)

有没有解决这些歧义的方法


谢谢你抽出时间

你可以做很多事情

最简单的可能是排除第一个np的情况
np/2

sent(sent(VP,NP)) --> vp(VP), np(NP), { NP \= np(_,_) }.
sent(sent(VP,NP,PP)) --> vp(VP), np(NP), pp(PP), { NP \= np(_,_) }.

vp(vp(V)) --> v(V).
vp(vp(V,Qty)) --> v(V), qty(Qty).

pp(pp(Prep,NP)) --> prep(Prep), np(NP).

np(np(Noun,Qty)) --> qty(Qty), n(Noun).
np(np(Noun)) --> n(Noun).

qty(qty(3)) --> ["3"].
qty(qty(4)) --> ["4"].

prep(for) --> ["for"].

v(v(bake)) --> ["bake"].
v(v(eat)) --> ["eat"].

n(n(pie)) --> ["pies"].
n(n(friend)) --> ["friends"].
这将产生:

| ?- sent(X,["eat","3","pies"],[]).
X = sent(vp(v(eat),qty(3)),np(n(pie))) ? ;
no
| ?- sent(X,["bake","4","pies","for","3","friends"],[]).
X = sent(vp(v(bake),qty(4)),np(n(pie)),pp(for,np(n(friend),qty(3)))) ? ;
no

但似乎很难从语言上证明这种设计。考虑“昨天吃了3个馅饼”,“吃晚餐3馅饼”,“吃1香肠,2胡萝卜,3馅饼”等等。哦,我每天都这样。我试图分析的句子的语料库受到了很强的限制,所以我可能永远不用担心你提到的那些例句类型。。。但从长远来看,我认为这将是一个更好的决定,因此我认为我将重新设计语法的语言学。很高兴知道使用原始prolog实现这种过滤器——这在某种程度上应该很方便。谢谢