找lambda演算的感覺
初看,感覺因符號系統不熟悉,導致完全沒感覺,所以先改寫成自己稍微熟悉的符號。
λx.x+2
改寫規則1:在此式中,將λ后的符號,在.后的符號找到,改寫為( ),且將λx.刪除。
λx.x+2改寫為( )+2。
(λx.x+2)3
改寫規則2:在此式中,將左括號刪除,右括號改寫為|。
(λx.x+2)3改寫為( )+2|3。
多個參數,左結合。
λx.λy.x-y改寫為λy.( )-y|改寫為( )-( )||
至此,λ演算就可以改寫為較為熟悉的形式了。
上面的例子其實非常不好,因為lambda演算的規則和中綴法是沖突的,反而誤導了初學者。
(λx. x x)(λz.u) → (λz.u) (λz.u)
在這個例子中,為何不是歸約為x (λz.u)呢?
這就用到beta規約的規則:
(λx.M)N → M[x/N] 如果N中所有變量的自由出現都在M[x/N]中保持自由出現
這句話用了條件狀語后置,上例中不能用x代入到x中,就是因為,x在x中不是自由出現,而是綁定。
看到別人的評論,mark一下。
在wiki中lambda calculus的Formal definition一節中,有這樣的描述:“The body of an abstraction extends as far right as possible”,也就是說λx.ab 等價于 λx.(ab),而不是(λx.a) b。
所謂的“左結合”法則,指的是應用(application),而非抽象(abstraction): M N P 等價于 (M N) P。
終于把lambda演算梳理清楚了,感覺lambda演算本身的邏輯還是很棒的,但是符號還是有很大的問題,是理解lambda演算最大的障礙。
沒錯說的就是括號,在lambda演算中,括號至少起了兩個作用,
1.對語句做劃分;
2.beta規則本身的一部分:被右括號分隔開的表達式E)x是代入,被左括號分隔開的表達式E(x則不是代入。
按照語言學的觀點,括號即用于劃分語法結構,又用于做論元標記了。
所幸沒有決定優先級的作用,但也正因為沒有優先級,lambda演算的規約過程和結果都不是唯一的。
接下來嘗試用lambda演算構造一下集合論。
抽象一個音系,輔音集C、復輔音集CC、元音集V、復元音集VV,允許的組合方式{V,CV,CCV,CVV,CCVV,CVC,CCVC,CVCC,CCVCC...}
看怎么把lambda表達式映射到這個集合中去。
然后大概想了下lambda演算到底是什么,元素、映射,映射分為按規則的映射,比如fx,也就是施用型表達式APPLY,(為了方便自己理解,自己先命名為內涵映射),和按象的映射,比如\x.x,也就是抽象型表達式ABSTRACTION,(為了方便自己理解,自己先命名為外延映射)。
其他的論域理論、施用型的左結合、抽象型的右結合、beta變換,都可以看作是一種論元標記規則,不是最重要的。改變這些規則會產生lambda演算的新的表達形式,以后可以嘗試。
這塊的想法也可以在圖靈機和lambda演算的等價性證明中看看是否可靠。
2016年01月03日開始構造集合論
首先觀察布爾函數的構造方法
已知T,F,AND分別定義為
λxy.x
λxy.y
λab.abF
求相應的OR,NOT的lambda編碼
發現小規律
通過擺弄AND T T,AND T F,AND F T,AND F F發現,AND是個框架,最后實質上參與運算的是T和F;
所以就先看看T和F的運算規律,有:
- TTT → T
- TTF → T
- TFT → F
- TFF → F
- FFT → T
- FFF → F
- FTT → T
- FTF → F
差不多可以認為有個天生的λabc.abc這樣一個布爾函數。
AND T T的可能形式:
- TTT → T
- FTT → T
- TTF → T
AND T F和AND F T的可能形式:
- TFT → F
- TFF → F
- FTF → F
AND F F的可能形式:
- FFF → F
- TFF → F
- FTF → F
然后怎么把AND的形式從中抓出來呢?
巧的是AND T F和AND F T的返回值都是F,都在TFT,TFF,FTF中,那么只需看TFT,TFF,FTF中的對稱性。
結果:TFF和FTF這一對滿足對1,2位的交換對稱,TFT和FTF滿足F,T的置換對稱。
這樣,就可以推測出AND的四種形式:
- λab.abF
- λab.baF
- λab.aba
- λab.bab
將以上四種形式代入AND T T和AND F F檢驗,全部滿足。這四種形式也說明了AND滿足交換律的性質。
至此,就基本掌握了尋找OR,NOT的lambda編碼的一些方法。
用同樣的方法得到OR的四種形式:
- λab.aTb
- λab.bTa
- λab.aab
- λab.bba
NOT只有一種形式: λab.abT。
接下來構造IFTHENELSE
因為返回值不在T,F中,就要用到另一種性質了:
- TT → RT
- TF → RF
- FF → I
- FT → I
其中RX是replace,將無論什么東西都替換為X,形式為λa.b(b為自由出現)。I是不變操作,無論什么東西都變為它本身,形式為λa.a。
嘗試后,不行,再接著減少數量,用F,T的性質。發現IFTHENELSE形式很簡潔漂亮:
λpmn.pmn
有(λpmn.pmn)TMN → M,(λpmn.pmn)FMN → N
然后搞自然數這塊
已知Church數的形式,以及后繼運算SUCC的形式。
- λnfx.f(nfx)
考慮前繼PRED,加PLUS,乘MULT,乘方EXP的形式。
通過觀察發現后繼的原理:
- λnfx.f(nfx) n用于帶入Church數,和布爾函數的做法沒分別;
- λnfx.f(nfx) fx用于替換參數的λfx頭部,這一點和布爾系統有區別,布爾系統的返回值的λ頭部用的是參數自己的λ頭部;
- λnfx.f(nfx) f用于增加返回值的f數量,完成“后繼”的功能。
考慮PLUS的形式:
連續兩次SUCC:
- (λnfx.f(nfx))((λnfx,f(bfx))n)
抽象一下就是f(fx),易知對n后繼m次(也就是n+m)就是$$SUCC^m n$$。
接著抽象,(λfx.f^m x) SUCC n,發現前面的λfx.f^m x就是Church數m,這里我們也就開始理解Church數的意義了,其實就是個遞歸函數,對吧?
接著抽象,就得到PLUS的一種形式:
- λmn.m SUCC n
但是,這種形式展開寫肯定很麻煩,要簡潔,只能到更底層中去。已經知道λnfx.f(nfx)中的f主要完成增加f的后繼功能,直接增加這里的f:
- λnfx.f^m (nfx)
抽象一下:
- λnfx.(λx.f^m x)(nfx)
搞成Church數:
- λnfx.(λfx.f^m x)f(nfx)
把其中的Church數m抽象出來:
- λmnfx.mf(nfx)
PLUS就搞好了
考慮MULT的形式:
先把m + n改寫成n + n,因為乘肯定是一堆相同的數相加:
- λnfx.nf(nfx)
遞歸的形式已經顯而易見了,那么,m個n連加:
- λnfx.(nf)^m x
抽象:
- λnfx.(λf.f^m x)(nf)
把x的帶入換到內層,不過分吧?
- λnf.(λfx.f^m x)(nf)
是啊,就是為了構造Church數,把所有的遞歸都換成Church數:
- λmnf.m(nf)
MULT也搞好了
考慮EXP的形式:
把m * n改寫成n * n:
- λnf.n(nf)
嗯,還是熟悉的味道,搞成遞歸:
- λnf.n^m f
抽象:
- λnf.(λfx.f^m x) nf
Church數代入:
- λmnf.mnf
反思,構造完這些函數,自然從函數怎么構造、怎么工作,開始想參數(TRUE,FALSE,Church數)是怎么構造的、怎么工作的。
可以說,Church數天生就是為了構造PLUS,MULT,EXP而構造的,PLUS,MULT,EXP本身就是一層一層遞歸的關系,所以將Church數構造為“將x在f中遞歸n次”再合適不過。
時隔一年,2016年12月23日
繼續考慮如何給lambda演算設計語音方案。現在覺得搞語音方案的一個阻礙是括號,這個不用多說了,口語要表達括號、語法層次,一直是個老難題。
假如定義一個表達式K,使得 KABC = A(BC),那么可以用 K 表達 A(BCD) 嗎?
也是可以的: KKKABCD = K(KA)BCD = (KA)(BC)D = KA(BC)D = A(BCD)。
只要擺脫括號的束縛,就可以進一步和語音的單向線性結構對應上了。但K的表達式是什么呢?
還是統協體告訴我這就是組合子邏輯SKI基中的B組合子。