Prolog如何将DCG规则转换为明确的条款?

时间:2015-12-08 15:49:42

标签: prolog dcg

我正在学习Definite Clause Grammar,但我有一些问题需要理解Prolog如何将DCG规则转化为明确的条款。 例如,这里有一个写成DCG的小语法:

s --> np, vp.

np --> det, n.

vp --> v, np.
vp --> v.

det --> [the].
det --> [a].

n --> [woman].
n --> [man].

v --> [kisses].

如果我提出查询:

?-listing(s).

它回答我:

s(A,C) :- 
     np(A,B),
     vp(B,C).

这是什么意思?为什么有两个论点?

此外,' C'这里的意思是:

det(A,B) :-
    'C'(A,the,B).

谢谢!

1 个答案:

答案 0 :(得分:5)

使用了一个名为差异列表的概念。让我们假设您要进行解析(您也可以使用这些谓词生成列表,但现在让我们忽略它。)

如果您解析列表,例如[the,man,kisses,the,woman]。您可以将此视为词汇,我借用"来自@Vikramnath Venkatasubramani的火车类比,所以归功于他/她。现在,如果我们拨打s([the,man,kisses,the,woman],C)C将返回[]

在每个谓词中会发生断开零,一个或多个货车的情况。所以它意味着:

s(A,C) :-
    np(A,B),
    vp(B,C).

np/2会断开货车[the,man],导致它仍然存储剩余的火车B=[kisses,the,woman]。现在,vp/2会断开所有剩余的货车,导致C=[],一列空车。

如何实施

让我们考虑部分语法的实现。

s(A,C) :-
    np(A,B),
    vp(B,C).

np(A,B) :-
    det(A,D),
    n(D,B).

vp(B,C) :-
    v(B,E),
    np(E,C).
vp(B,C) :-
    v(B,C).

det([the|W],W).
det([a|W],W).

n([woman|W],W).
n([man|W],W).

v([kisses|W],W).

如前所述,您致电np([the,man,kisses,the,woman],B),而np/2必须断开构成名词短语的货车:[the,man]

轮到他人np/2det/2

n/2。现在det/2会断开确定者的连接:the,而n/2会断开名词man的连接,以使其更明确:

np([the,man,kisses,the,woman],[kisses,the,woman]) :-
    det([the,man,kisses,the,woman],[man,kisses,the,woman]),
    n([man,kisses,the,woman],[kisses,the,woman]).

现在det/2不再重定向其职责,它实现为:

det([the|W],W).

现在我们进行模式匹配,这将基于:

det([the,man,kisses,the,woman],[man,kisses,the,woman]).

所以这意味着它已经断开了the

使用这种方法的优点是可以在恒定时间内完成断开连接。实际上,谓词并不知道列表的整个尾部。

此外,它允许断开事实中的多个单词。例如,您将名称添加为名词:

n([s,dallapalma|W],W).

在这种情况下n/2将同时断开两辆货车。其他谓词不需要知道这一点,例如s/2也不必决定它在np/2vp/2之间分割火车的时间点:它允许{{1}断开尽可能多的货车,np/2的目标是与列车的其余部分一起工作。