我正在尝试定义单词“are”的 Lambda 演算表示,它是此 ccg 的等式谓词:
ccg = '''
# CCG grammar
# complete the lexical entries with their categories and semantics
:- S, NP, N
logicians => NP { \\x. LOGICIANS(x) }
logicians => N { \\x. LOGICIANS(x) }
linguists => NP { \\x. LINGUISTS(x) }
linguists => N { \\x. LINGUISTS(x) }
engineers => NP { \\x. ENGINEERS(x) }
engineers => N { \\x. ENGINEERS(x) }
non => NP/N { \\N x. ~N(x) }
are => (S\\NP)/NP {\\x y.are(x,y)}
all => NP/N { \\P Q. all x. (P(x) -> Q(x)) }
no => NP/N { \\P Q. all x. (P(x) -> ~Q(x)) }
some => NP/N { \\N V. exists x. (N(x) & V(x)) }
'''
通过这个 ccg,我想解析诸如“所有逻辑学家都是语言学家”之类的句子。然而,我发现很难找到“are”这个词的正确表示。例如,我尝试将“are”定义为:
are => (S\\NP)/NP {\\X x.X(\y.are(x,y))}
不幸的是,这导致了错误的语义解释:
S {are(\x.LINGUISTS(x),\Q.all x.(LOGICIANS(x) -> Q(x)))}
接下来,我尝试将其定义为:
are => (S\\NP)/NP { \\X Y. all y. (X(y) <-> Y(y)) }
但是后来我得到了以下错误,因为 y 被解释为变量
LogicalExpressionException Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/nltk/sem/logic.py in parse(self, data, signature)
153 try:
--> 154 result = self.process_next_expression(None)
155 if self.inRange(0):
24 frames
LogicalExpressionException: 'y' is an illegal predicate name. Individual variables may not be used as predicates.
The above exception was the direct cause of the following exception:
LogicalExpressionException Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/nltk/sem/logic.py in parse(self, data, signature)
157 except LogicalExpressionException as e:
158 msg = "{}\n{}\n{}^".format(e, data, " " * mapping[e.index - 1])
--> 159 raise LogicalExpressionException(None, msg) from e
160
161 if self.type_check:
LogicalExpressionException: 'y' is an illegal predicate name. Individual variables may not be used as predicates.
all y.(LINGUISTS(y) <-> all x.(LOGICIANS(x) -> y(x)))
我无法更改语法本身(S、NP、N 规则),所以我感觉自己陷入了困境。有什么方法可以定义 ccg 的 Lambda 演算中的等式关系吗?
你的语法问题很早就开始了。
您不需要为每个谓词“逻辑学家”、“语言学家”等提供两个不同的定义,以使它们在句子的不同句法位置上发挥作用。它们是 NP——接受个体并返回 true 或 false 的函数。类别
N
与此行为不匹配。所以这些定义应该消失,只保留带有 NP
的定义。
正如您正确 lambda 定义的那样,量词是连续与右侧的两个谓词 (NP) 组合形成句子 (S) 的函数。所以他们的类别一定是
(S/NP)/NP
。
由于“非”使一个 NP 成为另一个 NP,因此其类型必须是
NP/NP
。
现在我们想要
are
的行为是
all(logicians)(are(linguists))
> all(logicians)(linguists)
即当与谓词结合时,它只返回该谓词本身。所以
are
是谓词上的 identify 函数:\\P.P
。
从语法上来说,它与一个 NP 结合产生另一个 NP,所以它的类别是
NP/NP
。
are => NP/NP {\\P.P}
现在我们得到了所需的减少行为:
all(logicians)(are(linguists))
( (S/NP)/NP )( NP )(NP/NP( NP ))
= (\\P Q. all x. (P(x) -> Q(x))(\\x. Logician(x))(\\P.P(\\x. Linguist(x)))
( (S/NP)/NP )( NP )( NP ))
= (\\P Q. all x. (P(x) -> Q(x))(\\x. Logician(x))(\\x. Linguist(x))
( (S/NP) )( NP ))
= (\\ Q. all x. ((\\x. Logician(x))(x) -> Q(x))(\\x. Linguist(x))
( (S/NP) )( NP ))
= (\\ Q. all x. (Logician(x) -> Q(x))(\\x. Linguist(x))
( S )
= all x. (Logician(x) -> (\\x. Linguist(x))(x)
S
= all x. (Logician(x) -> Linguist(x))