Lambda 演算 beta 归约具体步骤及原因

Lambda calculus beta reduction specific steps and why

来自我最近读的一本书:

第一个:

.(..)()((.)) 此时,最外层的 lambda 绑定是不可约的,因为它没有可应用的参数。剩下的就是一次一层地进入术语,直到我们找到可以简化的东西。

下一个:

.(.)((.)) 我们可以将 lambda 绑定应用于 argument 。我们一直在寻找可以申请的条款。接下来我们可以应用的是 lambda 绑定到 lambda 项 ((.)).

我不明白。在第一节中,它说 </code> 没有适用的参数,我大概可以理解,但是在下一节中我认为 <code>z 可以绑定到 ((.)) 因为如你所见,.(.)</code> 的主体显然有一个可以绑定的 <code>z 参数。但是书中只是忽略了头部</code>,直接将<code>n绑定到((.))。我的意思是 . 没有 n 参数,为什么要绑定它?

有人可以向我解释一下吗?

Lambda 表示法解析起来有点奇怪。 IMO Haskell 语法更清晰:

\z -> (\m -> \n -> m) z ((\p -> p) z)

或者,更明确

\z -> (
        (
           ( \m -> (\n -> m) )
           z
        )
        ( (\p -> p) z )
      )

第一个缩减步骤是

\z -> (
        (
           (\n -> z)
        )
        ( (\p -> p) z )
      )

\z -> (
        (\n -> z)
        ( (\p -> p) z )
      )

那么您确实可以绑定 ((\p -> p) z) – 不是绑定到 z,而是绑定到 n! (虽然实际上根本没有使用。)

\z -> (
        (z)
      )

或简单地 \z -> z。所以,我们 仍然 有那个 z lambda,正如书中所说,它是不可修正的。我们就是没有别的了!


...我不确定这是否真的是您的问题。如果是:为什么我们不 首先 看看我们是否可以减少 ((\p -> p) z),那么答案是,我认为,lambda 演算本身根本没有定义它(它只是定义了您 可以 应用什么转换,而不是您 应该 应用的顺序。实际上我不确定关于这一点,如果我错了请纠正我)。在像 Scheme 这样的严格语言中,你确实会首先减少 ((\p -> p) z); Haskell 不会那样做,因为没有必要。无论哪种方式,这都无关紧要,因为无论如何结果都会被丢弃。

   ( \z -> (\n -> z) ((\p -> p) z) )
≡  ( \z -> (\n -> z) z )
≡  ( \z -> (\n -> z) foo )
≡  ( \z -> z )

关键是n从来没有在抽象中使用过。 n 仍然绑定到 ((λp.p)z),但立即被丢弃。

λz.(λm.λn.m)(z)((λp.p)z) = λz.(λn.z)((λp.p)z)  Replacing m with z
                         = λz.z                Replacing n with ((λp.p)z)

使用正常的顺序评估,你可以在两个 beta 减少中得到答案

// beta reduction 1
λz.(<b>λm.</b>λn.<b>m</b>)(<b>z</b>)((λp.p)z) →β (λn.m) [m := z]
λz.(<del>λm.</del>λn.<b>z</b>)<del>(z)</del>((λp.p)z)

// beta reduction 2
λz.(<b>λn.</b>z)(<b>(λp.p)z</b>)       →β z      [n := ((λp.p)z)]
λz.<del>(λn.</del>z<del>)((λp.p)z)</del>

// result
λz.z

第二次归约可能看起来很棘手,因为 n 绑定到 ((λp.p)z) 但表达式只是 z,所以 n 被丢弃了。


使用applicative order evaluation,多了一步

// beta reduction 1
λz.(λm.λn.m)(z)((<b>λp.p</b>)<b>z</b>) →β p      [p := z]
λz.(λm.λn.m)(z)(<del>(λp.</del><b>z</b><del>)z</del>)

// beta reduction 2
λz.(<b>λm.</b>λn.<b>m</b>)(<b>z</b>)(z)       →β (λn.m) [m := z]
λz.(<del>λm.</del>λn.<b>z</b>)<del>(z)</del>(z)

// beta reduction 3
λz.(<b>λn.</b>z)(<b>z</b>)             →β z      [n := z]
λz.<del>(λn.</del>z<del>)(z)</del>

// result
λz.z

在这种情况下,无论我们使用普通顺序评估还是应用顺序评估,结果都是一样的。不同的评估策略有时会评估出不同的结果。

重要说明,在应用 λz 之前,我们在上面完成的减少步骤不会发生 (取决于实施)。在您提供的示例代码中,从未应用 λz,因此简化 λz 的术语只是为了练习,在这种情况下。

我们所做的只是证明 lambda 等效性(在两种不同的评估策略下)

λz.(λm.λn.m)(z)((λp.p)z) <=> λz.z