lambda演算
简单起见,全部采用f(2,3)而不是(f 2 3)的形式
BNF范式
<expr> ::= <identifier>
<expr> ::= lambda <identifier-list>. <expr>
<expr> ::= (<expr> <expr>)
lambda可以视作匿名函数,如
(lambda x y.x + y)
如何调用上述函数?
((lambda x y.x + y) 2 3)
可以通过语法糖的方式得到命名函数
let add = (lambda x y. x + y)
add(2,3)
阿尔法规约和贝塔规约
Alpha转换公理:例如,“lambda x y.x + y”转换为“lambda a b.a + b”。换句话说,函数的参数起什么名字没有关系,可以随意替换,只要函数体里面对参数的使用的地方也同时注意相应替换掉就是了。
Beta转换公理:例如,“(lambda x y. x + y) 2 3”转换为“2 + 3”。这个就更简单了,也就是说,当把一个lambda函数用到参数身上时,只需用实际的参数来替换掉其函数体中的相应变量即可。
Y-combinator
简单起见,考虑没有终止条件的递归求阶乘函数factorial
伪代码
factorial (n)
return n * factorial(n - 1);
翻译成lambda,可以发现匿名函数中无法调用自己
lambda n.n * <???>(n - 1)
为了解决这个问题,考虑加一个参数,并采用语法糖
let factorial = lambda f n.n * f(f,n - 1)
factorial(factorial,5)
一个重要性质:函数即数据
现在引入不动点的概念
假设,我们已经构造出了一个完美的factorial,它可以以常规的方式递归自己(实际上lambda系统中无法定义出此函数)
let perfect_factorial = lambda n.n * perfect_factorial(n - 1)
此外,定义出F函数,一个伪递归
let F = lambda f n.n * f(n - 1)
我们可以先给出F的f参数(perfect_factorial),得到一个新的lambda函数
let new_F = lambda n.n * perfect_factorial(n - 1)
那么,可以发现,new_F 和 perfect_factorial 没有区别,二者等价,即
F(perfect_factorial) = perfect_factorial
那么对于P来说,perfect_factorial就是它的不动点
直观的说如果f(x) = x,x就是f的不动点
通过不动点的概念,我们可以推理出,对于任意的伪递归F
let F = lambda f n.n * f(n - 1)
必然存在一个完美的f,使得F(f) = f
假设存在一个神奇的Y-combinator,当它作用于伪递归F时,可以求出P对应的完美的函数f
即Y(F) = f,结合上文中的F(f) = f,我们可以得到
Y(F) = f = F(f) = F(Y(F))
即Y(F) = F(Y(F))
如何求出这个神奇的Y?显然构造可得
let Y = lambda F.
let self_f = lambda self.F(self(self))
return self_f(self_f)
我们将伪递归F带入演算:
let F = lambda f n.n * f(n - 1)
let self_f = lambda self.F(self(self))
= lambda self.(lambda f n.n * f(n - 1))(self(self))
= lambda self.lambda n.n * self(self)(n - 1)
self_f(self_f) = (lambda self.lambda n.n * self(self)(n - 1))(lambda self.lambda n.n * self(self)(n - 1))
= lambda n.n * ((lambda self.lambda n.n * self(self)(n - 1)))(((lambda self.lambda n.n * self(self)(n - 1))))(n - 1)
可以看到最终得到的lambda函数仅需要一个参数n
通过增加一个间接层,就可以实现自然的递归
丘奇数
丘奇数都是带两个参数的函数,具体的思路是定义z = 0,然后将s(z)得到z的后继
0 是 lambda s z . z
1 是 lambda s z . s(z)
2 是 lambda s z . s(s(z))
对于 2 + 3 = 5, 我们只需要通过阿尔法和贝塔规约把s(s(z))中的z换为s(s(s(z)))即可
let add = λx y s z.x(s,y(s,z))
let two = λs z.s(s(z))
let three = λs z.s(s(s(z)))
add(two,three)
= (λx y s z.x(s,y(s,z))) (λs z.s(s(z)),λs z.s(s(s(z))))
= (λs z.(λs z.s(s(z)))(s,(λs z.s(s(s(z))))(s,z)))
= (λs z.(λs z.s(s(z)))(s,s(s(s(z)))))
= (λs z.(λs z.s(s(z)))(s,s(s(s(z)))))
= λs z.s(s(s(s(s(z)))))
布尔表达式
let TRUE = lambda x y . x
let FALSE = lambda x y . y
let BoolAnd = lambda x y . x y FALSE
let BoolOr = lambda x y. x TRUE y
let BoolNot = lambda x . x FALSE TRUE
let IfThenElse = lambda cond true_expr false_expr . cond true_expr false_expr
来个栗子false BoolOr true
(lambda x y. x TRUE y) (lambda x y . y) (lambda x y . x)
= (lambda x y . y) TRUE (lambda x y . x)
= (lambda x y . x)
= TRUE
本文来自博客园,作者:XDU18清欢,转载请注明原文链接:https://www.cnblogs.com/XDU-mzb/p/16215144.html