以拉丁文大学导论为例,考虑以下句子:
the sailor gives the girl money
Run Code Online (Sandbox Code Playgroud)
我们可以使用DCG在Prolog中处理这个问题,这个规则非常优雅:
sentence(s(NP, VP)) --> noun_phrase(NP), verb_phrase(VP).
noun_phrase(Noun) --> det, noun(Noun).
noun_phrase(Noun) --> noun(Noun).
verb_phrase(vp(Verb, DO, IO)) --> verb(Verb), noun_phrase(IO), noun_phrase(DO).
det --> [the].
noun(X) --> [X], { member(X, [sailor, girl, money]) }.
verb(gives) --> [gives].
Run Code Online (Sandbox Code Playgroud)
我们看到这有效:
?- phrase(sentence(S), [the,sailor,gives,the,girl,money]).
S = s(sailor, vp(gives, money, girl)) ;
Run Code Online (Sandbox Code Playgroud)
在我看来,DCG真的是为处理字序语言而优化的.我完全失去了如何处理这个拉丁语的句子:
nauta dat pecuniam puellae
Run Code Online (Sandbox Code Playgroud)
这意味着同样的事情(水手给女孩钱),但是单词顺序是完全免费的:所有这些排列也意味着完全相同的事情:
nauta dat puellae pecuniam
nauta puellae pecuniam dat
puellae pecuniam dat nauta
puellae pecuniam nauta dat
dat pecuniam nauta puellae
Run Code Online (Sandbox Code Playgroud)
我发生的第一件事就是枚举排列:
sentence(s(NP, VP)) --> noun_phrase(NP), verb_phrase(VP).
sentence(s(NP, VP)) --> verb_phrase(VP), noun_phrase(NP).
Run Code Online (Sandbox Code Playgroud)
但这不行,因为虽然nauta属于主语名词短语,puellae属于对象,但是名词短语从属于动词,但可以在它之前.我想知道我是否应该通过首先构建某种属性列表来接近它:
?- attributed([nauta,dat,pecuniam,puellae], Attributed)
Attributed = [noun(nauta,nom), verb(do,3,s), noun(pecunia,acc), noun(puella,dat)]
Run Code Online (Sandbox Code Playgroud)
这看起来似乎是必要的(我没有看到一个好方法),但从语法上来说,它正在我的盘子上推动食物.也许我可以编写一个带有某种可怕的非DCG装置的解析器,如下所示:
parse(s(NounPhrase, VerbPhrase), Attributed) :-
parse(subject_noun_phrase(NounPhrase, Attributed)),
parse(verb_phrase(VerbPhrase, Attributed)).
parse(subject_noun_phrase(Noun), Attributed) :-
member(noun(Noun,nom), Attributed).
parse(object_noun_phrase(Noun), Attributed) :-
member(noun(Noun,acc), Attributed)
Run Code Online (Sandbox Code Playgroud)
这似乎可行,但只要我没有递归; 一旦我引入了一个从属条款,我就会以不健康的方式重用主题.
我只是没有看到如何从非单词序列句子到解析树.有没有一本书可以讨论这个问题?谢谢.