理解Redex中的lambda替换
假设我在Redex中定义了以下内容:理解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
(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是不同的