理解Redex中的lambda替换

理解Redex中的lambda替换,lambda,racket,substitution,redex,Lambda,Racket,Substitution,Redex,假设我在Redex中定义了以下内容: (define-language L [e ::= (λ x e) (e e) x] [x ::= variable-not-otherwise-mentioned] #:binding-forms (λ x e #:refers-to x)) 现在,我认为表达式(λy x)x意味着: 将x中出现的y(上述表达式中的内括号)替换为x(外括号)。既然x中没有y,答案应该是x。然后(λyx)xy应返回xy。但是: (defaul

假设我在Redex中定义了以下内容:

(define-language L
    [e ::= (λ x e) (e e) x]
    [x ::= variable-not-otherwise-mentioned]
    #:binding-forms
    (λ x e #:refers-to x))
现在,我认为表达式
(λy x)x
意味着:

x
中出现的
y
(上述表达式中的内括号)替换为
x
(外括号)。既然
x
中没有
y
,答案应该是
x
。然后
(λyx)xy
应返回
xy
。但是:

(default-language L)
(term (substitute (λ y x) x y))
'(λ y«0» y)
为什么它返回一个函数?那么
y
是什么意思?我是否误解了术语(替代品)

我也不明白这个结果:

(term (substitute (λ y x) x true))
'(λ y«1» true)

有人能帮我破译一下吗?我对Racket/Redex不太熟悉。

y«0»
y«1»
简单地说,虽然变量名为
y
,但它与传入的变量不同。
#:reference
标志用于使表单尊重捕获,避免替换

总的来说,我们的想法是,这个项目的结果应该是什么:

((lambda (x) (lambda (y) x))
 y)
该程序的评估结果是
4
还是
3
?如果我们使用简单的替换,那么我们可以说程序简化为:

(lambda (y) y)
这就是身份函数。如果我们将y绑定到5,并将结果称为:

(let* ([y 5]
       [f ((lambda (x) (lambda (y) x))
            y)])
  (f 6))
在这里,我们希望结果是
5
,即使我们将
6
传递到
f
。这是因为结果中的
y
指向
let*
中的第一个
y
。如果在DrRacket中使用鼠标
y
,可以看到这一点

为了避免这种情况,它不是简单地将表达式中的所有
x
s替换为
y
s,而是将所有绑定重命名为新名称,因此您可以得到:

(lambda (y«0») y)
现在很明显,这个表达式中的两个
y
s是不同的