段落是句子的序列。
段落表示理论
一阶逻辑中的量化标准方法仅局限于单个句子,但是有的量词的范围是可以扩大到两个以上的句子.
看下面的例子:
(54)a. Angus owns a dog. It bit Irene.
b.∃x.(dog(x) &own(Angus, x)&bite(x, Irene))
段落表示理论(Discourse RepresentationTheory,DRT)的目标是提供一种方法处理这个和看上去是段落的特征的其他语义现象。
DRS(discourse representation structure,DRS)段落表示结构
如图所示:
为了处理DRS计算,我们需要将其转换成线性格式。
其中,DRS是由一个段落指称链表和一个DRS条件链表组成的配对:
([x, y],[angus(x), dog(y),own(x,y)])
在NLTK中建立DRS对象:
>>>dp= nltk.DrtParser() >>>drs1 = dp.parse('([x,y],[angus(x), dog(y),own(x,y)])') >>>print drs1 ([x,y],[angus(x), dog(y),own(x,y)])
可以查看可视化效果:
>>>drs1.draw()
每一个DRS都可以转化为一阶逻辑公式:
>>>print drs1.fol() exists xy.((angus(x) &dog(y)) &own(x,y))
DRT表达式有DRS连接运算符,用+表示。
>>>drs2 = dp.parse('([x],[walk(x)]) + ([y], [run(y)])') >>>print drs2 (([x],[walk(x)]) + ([y],[run(y)])) >>>print drs2.simplify() ([x,y],[walk(x), run(y)])
一个DRS内嵌入另一个DRS。这是全称量词被处理的方式。
>>>drs3 = dp.parse('([],[(([x], [dog(x)]) -> ([y],[ankle(y), bite(x, y)]))])') >>>print drs3.fol() all x.(dog(x)-> exists y.(ankle(y) &bite(x,y)))
如果DRS包含PRO(x)形式的条件,方法resolve_anaphora()将其替换为x=[...]形式的条件,其中[...]是一个可能的先行词链表。
>>>drs4 = dp.parse('([x,y],[angus(x), dog(y),own(x,y)])') >>>drs5 = dp.parse('([u,z], [PRO(u), irene(z), bite(u, z)])') >>>drs6 = drs4 + drs5 >>>print drs6.simplify() ([x,y,u,z],[angus(x), dog(y),own(x,y), PRO(u),irene(z), bite(u,z)]) >>>print drs6.simplify().resolve_anaphora() ([x,y,u,z],[angus(x), dog(y),own(x,y), (u = [x,y,z]), irene(z), bite(u,z)])
DRS的处理与处理λ抽象的现有机制是兼容的。
Det[NUM=sg,SEM=<\P Q.([x],[])+ P(x)+ Q(x)>]-> 'a' Det[NUM=sg,SEM=<\P Q.exists x.(P(x)&Q(x))>]-> 'a'
例如,a dog:
(NP[NUM='sg', SEM=<\Q.(([x],[dog(x)])+ Q(x))>] (Det[NUM'sg', SEM=<\PQ.((([x],[])+ P(x))+ Q(x))>]a) (Nom[NUM='sg', SEM=<\x.([],[dog(x)])>] (N[NUM='sg', SEM=<\x.([],[dog(x)])>]dog)))))
我们可以使用DRT解析方式来解析句子:
>>>from nltk import load_parser >>>parser= load_parser('grammars/book_grammars/drt.fcfg', logic_parser=nltk.DrtParser()) >>>trees = parser.nbest_parse('Angus ownsa dog'.split()) >>>print trees[0].node['sem'].simplify() ([x,z2],[Angus(x), dog(z2),own(x,z2)])
段落处理
段落是一个句子的序列,s1,s2,s3…段落线是读法的序列s1-ri,…sn-f。
>>>dt =nltk.DiscourseTester(['A student dances','Every student is a person']) >>>dt.readings() s0readings: s0-r0: exists x.(student(x)&dance(x)) s1readings: s1-r0: all x.(student(x)-> person(x))
我们可以随时添加句子和删除句子,设置consistchk=True可以检查每个可接收的读法序列来检查模块的一致性:
>>>dt.add_sentence('No person dances',consistchk=True) Inconsistent discoursed0['s0-r0', 's1-r0', 's2-r0']: s0-r0: exists x.(student(x)&dance(x)) s1-r0: all x.(student(x) -> person(x)) s2-r0: -exists x.(person(x)&dance(x)) >>>dt.retract_sentence('No person dances',verbose=True) Current sentences are s0: A student dances s1: Every student is a person
我们使用informchk=True检查新的句子φ是否对当前的段落有信息量。
>>>dt.add_sentence('A person dances',informchk=True) Sentence'A persondances'under reading 'exists x.(person(x)&dance(x))': Not informative relative to thread 'd0'