由簡入深,適時複習,溫故知新。 — housir
λ演算基於最簡單的定義函數的思想:
一爲函數抽象λx.E,由λ說明的x在函數體E中出現均爲形參變元。E是一個λ表達式。
一爲函數應用(λx.E)(a),即E中的x均由a置換變成E(a)。
接上一篇 博客 繼續寫點有關lambda演算的東西。
基本函數
- 基本的λ表達式
// 布爾類型
T = λx.λy.x // True
F = λx.λy.y // False
// 數字
0=λx.λy.y //與F的λ表達式相同
1=λx.λy.x y
2=λx.λy.x(x y)
n=λx.λy.x(x(…(x y)…) // λy.之後有n個x
- 基本操作函數
// 邏輯操作函數
not = λz.((z F) T)=λz.((zλx.λy.y)(λx.λy.x))
and = λa.λb.((a b)F) = λa.λb.((a b)λx.λy.y))
or = λa.λb.((a T)b) = λa.λb.((a λx.λy.x)b)
// 算術操作函數
+ = add = λx.λy.λa.λb.((x a)(y a)b)
* = multiply = λx.λy.λa.((x(y a)))
succ = λn.(λx.λy.n x(x y)) //後繼函數
zerop = λn.n(λx.F)T =λn.n(λz.λx.λy.y)(λx.λy.y) //判零函數
此外,還有sqr(冪運算)、identity(同一函數)、positive(取正整數)、neg(取負)、divide(除法)、subtract(-、減法),pred(前驅)等函數。
示例
下面介紹幾道有關lambda演算的題目,在實踐中理解lambda演算。
判零(zerop)
1.證明:zerop 1 = F
zerop 1
= (λn.n(λx.F)T ) 1
= 1 (λx.F)T β歸約[1/n]
= (λp.λq.pq) (λx.F)T
= (λq.(λx.F)q)T β歸約[(λx.F)/p]
= (λx.F)T β歸約[T/q] 或者η歸約
= F η歸約
2.證明:zerop 0 = T
zerop 0
= (λn.n(λx.F)T ) 0
= 0 (λx.F)T β歸約[0/n]
= (λp.λq.q) (λx.F)T
= (λq.q)T β歸約[(λx.F)/p]
= T β歸約[T/q]
加法(add)
核心的λ演算只有單目運算,例如:add 1它返回的結果是函數,再應用到後面的表達式上。這樣,1+2就寫add 1 2,add 1返回“加1函數”應用到2上當然就是3
1 add 2
= add 1 2
= (λx.λy.λa.λb.((x a)(y a)b)) 1 2
= (λy.λa.λb.((1 a)(y a)b)) 2 // β歸約[1/x]
= λa.λb.((1 a)(2 a)b) // β歸約[2/y]
= λa.λb.(( (λx.λy.x y) a )((λx.λy.x (x y)) a)b) // 1 2 展開
= λa.λb.((λy.a y) (λy.a (a y))b ) // β歸約[a/x]
= λa.λb.( (λy.a y)(a (a b)) ) // β歸約[b/y]
= λa.λb.(a (a (a b))) // β歸約[(a (a b))/y]
= 3
後繼(succ)
succ 1
= λn.(λx.λy.n x(x y)) 1
= λx.λy.1 x(x y) // β歸約[1/n]
= λx.λy. (λp.λq.p q) x (x y)
= λx.λy.(λq.x q)(x y) // β歸約[x/p]
= λx.λy.x(x y) // β歸約[(x y)/q]
= 2
Lambda演算能力還是比較強的,Church的理論證明,λ演算(核心λ演算)是個完備的系統,可以表示任何計算函數。初次接觸可能感覺陌生,一旦熟悉之後就會非常簡單。