在 DCG 中给出两个有效解析 "right of way" 之一
Giving one of two valid parses "right of way" in a 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"].
在这个语法中,我们担心的是数量,数量分配给哪个名词或动词很重要。所以像 "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))) ;
在这种情况下,我总是希望动词是 "awarded" 数量。那么,我的第一步是简单地删除允许数量在名词之前的规则。但是在像这样的另一句话中...
Bake 4 pies for 3 friends
...我希望 friends
有一个 qty(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
但似乎很难从语言上证明这种设计的合理性。考虑 "having eaten yesterday 3 pies"、"eat for dinner 3 pies"、"eat 1 sausage, 2 carrots, and 3 pies" 等
我刚刚了解了 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"].
在这个语法中,我们担心的是数量,数量分配给哪个名词或动词很重要。所以像 "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))) ;
在这种情况下,我总是希望动词是 "awarded" 数量。那么,我的第一步是简单地删除允许数量在名词之前的规则。但是在像这样的另一句话中...
Bake 4 pies for 3 friends
...我希望 friends
有一个 qty(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
但似乎很难从语言上证明这种设计的合理性。考虑 "having eaten yesterday 3 pies"、"eat for dinner 3 pies"、"eat 1 sausage, 2 carrots, and 3 pies" 等