Haskell和Lambda演算:实现Alpha同余(Alpha等价)
我正在Haskell中实现一个不纯的非类型lambda演算解释器 目前,我一直致力于实现“alpha同余”(在一些教科书中也称为“alpha等价”或“alpha相等”)。我想检查两个lambda表达式是否相等。例如,如果我在解释器中输入以下表达式,它将产生True(Haskell和Lambda演算:实现Alpha同余(Alpha等价),haskell,lambda-calculus,Haskell,Lambda Calculus,我正在Haskell中实现一个不纯的非类型lambda演算解释器 目前,我一直致力于实现“alpha同余”(在一些教科书中也称为“alpha等价”或“alpha相等”)。我想检查两个lambda表达式是否相等。例如,如果我在解释器中输入以下表达式,它将产生True(\用于指示lambda符号): 问题在于理解以下lambda表达式是否被视为alpha等效: >\x.xy == \y.yx ??? >\x.yxy == \z.wzw ??? 在\x.xy==\y.yx的情况下,我猜
\
用于指示lambda符号):
问题在于理解以下lambda表达式是否被视为alpha等效:
>\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中,我同样会猜测答案是真的。这是因为\x.yxy=>\a.yay
和\z.wzw=>\a.waw
是相等的
问题是,我的教科书中的所有定义都指出,只有绑定变量的名称需要更改,才能将两个lambda表达式视为相等。它没有提到表达式中需要统一重命名的自由变量。因此,即使y
和w
在lambda表达式中都位于正确的位置,程序如何“知道”第一个y
代表第一个w
,第二个y
代表第二个w
。我需要在实现中对此保持一致
简而言之,我将如何实现函数的无错误版本?我需要遵循哪些确切的规则才能使其正常工作
我更愿意在不使用de Bruijn指数的情况下这样做。你误解了:不同的自由变量不是阿尔法等价的。所以y/=x
,和\w.wy/=\w.wx
,和\x.xy/=\y.yx
。类似地,\x.yxy/=\z.wzw
,因为y/=w
您的书中没有提到允许统一重命名自由变量,因为它们不允许统一重命名
(这样想:如果我还没有告诉你not
和id
的定义,你会认为\x.not x
和\x.id x
是等价的吗?我当然希望不是!)它们不是等价的。让我们看一下\x.xy
。您可以根据自己的意愿在此处重命名x
,并始终获得相同的结果,但您不能随意重命名y
,因为它不受lambda抽象的限制。这同样适用于\y.yx
,但这次是x
未绑定,因此无法重命名。这意味着您不能重命名它们以使一致性\x.xy==\y.yx
为真。请参见>了解更多详细信息。更具体地说,\x.xy
可以重写为\a.ay
,\y.yx
可以重写为\a.ax
,那么很明显,\a.ay/=\a.ax
。这正是丹尼尔所说的。当您将x
视为自由变量时,它不是“任何”x
。谢谢!这两条评论都消除了混乱。难怪我的程序不起作用!
>\x.xy == \y.yx
???
>\x.yxy == \z.wzw
???