提供两种有效的解析方式之一"通行权"在DCG中

时间:2018-03-14 04:55:12

标签: prolog dcg

我刚刚了解了DCG,并且非常享受我早期的探索。令人惊讶的是,您可以从一个非常简短的规范中获得多少。我已经碰到了一堵墙,我想象的是一个相当普遍的问题,并希望得到一些专家建议。 (或者甚至是新手的建议,考虑到我是一个完整的初学者。)

这是我的语法的玩具版本。为了纪念3/14,我已经专注于以馅饼为重点:

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

在这个语法中,我们担心数量,并且数量分配给名词或动词很重要。所以像#34;吃3个馅饼"有两个有效的解析,如下所示:

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

...我希望friends拥有qty(3)

是否有解决这些含糊之处的技术?

感谢您的时间!

1 个答案:

答案 0 :(得分:1)

你可以做很多事情。

最简单的可能是排除第一个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个馅饼"等