Lambda Calculus:捕获的递归定义避免替换

时间:2017-10-29 13:18:20

标签: lambda-calculus

我花了几周时间编写了无类型lambda演算的实现。

我相信在这样做的过程中,我可能已经为捕获避免替换制定了一个递归定义(即它使用替换作为alpha转换的一种形式),这非常适合维基百科上给出的替换定义。

如果有人可以为我验证它的正确性,我真的很感激,如果它是正确的,解释为什么很少使用这个定义,因为我发现它非常清晰和简单。

维基百科的定义:

x[x := N] ≡ N  
y[x := N] ≡ y, if x ≠ y  
(M1 M2)[x := N] ≡ (M1[x := N]) (M2[x := N])  
(λx.M)[x := N] ≡ λx.M  
(λy.M)[x := N] ≡ λy.(M[x := N]), if x ≠ y, provided y ∉ FV(N)  

我强制执行捕获避免的附加定义:

(λy.M)[x := N] ≡ λy'.(M'[x := N]), if x ≠ y and y ∈ FV(N)

其中

y' ∉ (FV(N) ∪ FV(M))  
M' ≡ M[y:=y']

1 个答案:

答案 0 :(得分:0)

你的规则是正确的。

它不经常使用,因为它需要跟踪自由变量。这是非常违反直觉的,因为我们都认为名称永远不会重要,而在这个实现中,名称起着核心作用。

您尚未展示您的操作语义。如果您这样做,您会看到应用规则需要知道x是否N捕获了(λx.M) N。如果是这样,则需要触发alpha重命名。

这里的问题是基本的一个表达式有太多(无限)表示。解决这个问题的一种典型方法是通过de Bruijin索引,或称为本地无名的混合方式。

https://en.wikipedia.org/wiki/De_Bruijn_index

https://www.chargueraud.org/research/2009/ln/main.pdf

主要思想是相同的:两者都取一个绑定表达式的商,这样一个表达式只有一个规范形式。