Haskell和Lambda演算:实现Alpha同余(Alpha等价)

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的情况下,我猜

我正在Haskell中实现一个不纯的非类型lambda演算解释器

目前,我一直致力于实现“alpha同余”(在一些教科书中也称为“alpha等价”或“alpha相等”)。我想检查两个lambda表达式是否相等。例如,如果我在解释器中输入以下表达式,它将产生True(
\
用于指示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
???