我在Haskell中实现了一个不纯的无类型lambda-calculus解释器。
我目前仍然坚持实施“alpha-conruence”(在某些教科书中也称为“alpha-equivalence”或“alpha-equality”)。我希望能够检查两个lambda表达式是否相等或相等。例如,如果我在解释器中输入以下表达式,它应该产生True(\
用于表示lambda符号):
>\x.x == \y.y
True
问题在于理解以下lambda表达式是否被视为alpha-equivalent:
>\x.xy == \y.yx
???
>\x.yxy == \z.wzw
???
在\x.xy == \y.yx
的情况下,我猜答案是True
。这是因为\x.xy => \z.zy
和\y.yx => \z.zy
以及两者的右侧相等(其中符号=>
用于表示减少α)。
在\x.yxy == \z.wzw
的cae中我也会猜到答案是True
。这是因为\x.yxy => \a.yay
和\z.wzw => \a.waw
(我认为)相等。
问题是我的所有教科书的定义都指出只需要更改绑定变量的名称,以使两个lambda表达式被认为是相等的。它没有说明需要统一重命名的表达式中的 free 变量。因此,即使y
和w
都在lambda表达式中的正确位置,程序如何“知道”第一个y
代表第一个w
和第二个y
代表第二个w
。我需要在实现中保持一致。
简而言之,我将如何实现函数isAlphaCongruent
的无错误版本?为了实现此目的,我需要遵循哪些完全规则?
我更愿意在不使用de Bruijn指数的情况下这样做。
答案 0 :(得分:11)
您误解:不同的自由变量不是alpha等价物。所以y /= x
,\w.wy /= \w.wx
和\x.xy /= \y.yx
。同样,\x.yxy /= \z.wzw
因为y /= w
。
您的书中没有说明允许统一重命名自由变量,因为不允许统一重命名它们。
(想一想:如果我还没有告诉你not
和id
的定义,你会期望\x. not x
和\x. id x
是等价的?我当然希望不会!)