我知道为什么重命名变量以避免捕获很重要,但是在下面的示例中,我不明白为什么它不会发生。
(λf.λx.f(fx))(λf.λx.fx)
显然减少到
λx.(λf.λx.fx)((λf.λx.fx)x)
但是不应该在x
或(λf.λx.f(fx))
中重命名(λf.λx.f(fx))
吗?他们不是指不同的x
吗?
答案 0 :(得分:1)
避免捕获是为了避免捕获免费变量。 “捕获”绑定变量不会带来太大的伤害:在
λx.(λf.λx.fx)((λf.λx.fx)x)
x
的两种用法确实是不同的变量,但这已经在术语中进行了编码:通常,子术语中的新抽象将“覆盖”其他最外层抽象的绑定。 / strong>这完全是由于lambda项的求值方式所致:如果对同一个变量进行了新的抽象,那么旧的抽象将最终在具有新抽象的子项中失去作用,并且该变量与仅受外部抽象约束的变量相比,受内部抽象约束的变量实际上是不同的变量。
您可以尝试以下方法:如果将λx.(λf.λx.fx)((λf.λx.fx)x)
应用于某个术语N
,则根据beta减少的定义,该术语将减少为(λf.λx.fx)((λf.λx.fx)x)[N/x]
,即获得的术语用x
替换(λf.λx.fx)((λf.λx.fx)x)
中N
中x
的每次出现(!)(根据定义,替换仅对自由变量起作用)。该术语x
中唯一的自由出现是最后一个。两个子项(λf.λx.fx)
中的其他两个λx
受它们各自的x
约束。因此,将由N
替换的唯一(λx.(λf.λx.fx)((λf.λx.fx)x))N
是最后一个,因此(λf.λx.fx)((λf.λx.fx)N)
将减少为x
-子项中的(λf.λx.fx)
x
保持不变。
因此受内部抽象限制的x
和该术语末尾的$env:username
确实是属于不同抽象的不同变量。因此,在应用程序中不重命名它们是没有问题的。
话虽这么说,有时进行此类重命名对于提高可读性有时很有用。所产生的术语将与直接替换而不重命名所获得的术语完全一致。