在Prolog中创建能够解析树的DCG

问题描述

我必须在Prolog中创建具有以下功能的DCG:

  1. 处理主题/对象的区别
  2. 单/复数区别
  3. 能够生成分析树
  4. 使用单独的词典

这是给定的词典:

lex(the,det,_).
lex(a,singular).
lex(man,n,singular).
lex(men,plural).
lex(woman,singular).
lex(women,plural).
lex(apple,singular).
lex(apples,plural).
lex(pear,singular).
lex(pears,plural).

lex(eat,v,plural).
lex(eats,singular).
lex(kNow,plural).
lex(kNows,singular).

lex(i,pronoun,singular,subject).
lex(we,plural,subject).
lex(me,object).
lex(us,object).
lex(you,_,_).
lex(he,subject).
lex(she,subject).
lex(him,object).
lex(her,object).
lex(they,subject).
lex(them,object).
lex(it,_).

这是我的代码

s(s(NP,VP)) --> np(NP,X,subject),vp(VP,X).

np(np(DET,N),_) --> det(DET,X),n(N,X).
np(np(PRO),Y) --> pro(PRO,Y).

vp(vp(V,NP),X) --> v(V,np(NP,object).
vp(vp(V),X).

det(det(DET),X) --> [DET],{lex(DET,X)}.

n(n(N),X) --> [N],{lex(N,X)}.

pro(pro(PRO),Y) --> [PRO],{lex(PRO,pro,Y)}.

v(v(V),X) --> [V],{lex(V,X)}.

当我输入时:

s(X,[the,man,eats,the,apple],[]).

我应该得到:

X = s(np(det(the,singular),n(man,subject)),vp(v(eats,np(det(the,n(apple,object))))

但是我得到了:

X = s(np(det(the),n(man)),vp(v(eats),np(det(the),n(apple)))) 

而且我不确定为什么它没有输出完整的内容

解决方法

像这样呼叫DCG

PhotoImage

在许多资料中仍然讲授某种“旧样式”,但是更“现代”的方法是使用rule(Args,List,Rest) 代替:

phrase/[2,3]

在需要完整解析的常见情况下,采用两个参数的形式可以避免将其余部分指定为?- phrase(s(Tree),[the,man,eats,the,apple]). Tree = s(np(det(the),n(man)),vp(v(eats),np(det(the),n(apple)))) ; false. ?- phrase(s(Tree),apple],Rest). Tree = s(np(det(the),n(apple)))),Rest = [] ; Tree = s(np(det(the),vp(v(eats))),Rest = [the,apple] ; false. 。您还可以将DCG规则的参数与要解析的列表分开。因此,在[]调用中,phrase为语法树采用一个参数,就像在其定义中一样。

对于您的问题,好处是Prolog是一种非常容易测试的语言。如果某些大问题(例如分析整个句子)出了问题,我们可以解决问题并测试较小的部分,例如分析名词短语或仅分析名词。

因此,将主题分解为越来越小的部分:

s

您想将名词短语解析为?- phrase(np(Tree,Number,Role),man]). Tree = np(det(the),Number = singular ; false. ?- phrase(det(Tree,[the]). Tree = det(the). ?- phrase(n(Tree,Number),[man]). Tree = n(man),Number = singular. ,但是从np(det(the,singular),n(man,singular,subject))det获得的实际树已经缺少了一些额外的参数。您需要调整这些:

n

有了这个你得到:

det(det(DET,Number) --> [DET],{lex(DET,det,Number)}.

n(n(N,_Role),Number) --> [N],{lex(N,n,Number)}.

整个句子的解析现在是:

?- phrase(det(Tree,[the]).
Tree = det(the,Role).

?- phrase(n(Tree,[man]).
Tree = n(man,_2114),Number = singular.

?- phrase(np(Tree,man]).
Tree = np(det(the,_2178)),Number = singular ;
false.

现在有关于确定词和名词的额外参数。缺少的是对动词和名词短语执行相同的操作,以便正确地绑定“角色”(主题或对象)。