這個系列有個顯著的特點,那就是標題越來越長。忽然發現今天是讀書節,讀書節多讀書。
==下面是沒有意義的一段話
我是一個喜歡從學習知識中獲得樂趣並樂於分享這種樂趣的人。我認為大部分知識只要花點時間都是能學會的。幾年前,我迷上微分幾何。我對每個朋友說這東西很有意思花點時間精力就能學會。他們回答說唉沒時間時間不知去哪兒了。後來,我迷上量子力學。我對每個朋友說這東西值得一學,只要花點時間精力。他們回答說唉煩心事太多沒精力去學。再後來,我迷上程式語言。我對每個朋友說只要使勁擠點時間就能掌握這個。他們回答說唉渾渾噩噩不知道一直在忙什麼沒時間唉。現在,他們都結婚了,我依然單身。
==然後,本文開始
不動點
唉,又是一個數學概念, 又是沒有實際意義的一節。 但是作為遞迴相關的常識,還是得提一下。 話說回來,把這玩意兒當作常識,我大概是價值觀扭曲,重要性排行顛倒吧。 據說很多研究程式語言,研究偏微分方程的人都這樣。
然後,一個——呃——東西$x$被稱為函數$f$的不動點,如果它滿足下麵條件: \[ (f \; x) = x \]
不動點和遞迴有什麼關係呢? $({Y} \; f)$不僅是關於輔助函數$f$的遞迴函式,同時也是$f$的不動點。 證明如下: \begin{eqnarray*} ({Y} \; f) &=& (\lambda x.(\lambda v.(v \; v) \; \lambda f.(x \; (f \; f))) \; f) \\ &=& (\lambda x.(\lambda v.(v \; v) \; \lambda p.(x \; (p \; p))) \; f) \\ &=& (\lambda v.(v \; v) \; \lambda p.(f \; (p \; p))) \\ &=& (\lambda p.(f \; (p \; p)) \; \lambda p.(f \; (p \; p))) \\ &=& (f \; (\lambda p.(f \; (p \; p)) \; \lambda p.(f \; (p \; p)))) \\ &=& (f \; (\lambda v.(v \; v) \; \lambda p.(f \; (p \; p)))) \\ &=& (f \; (\lambda x.(\lambda v.(v \; v) \; \lambda p.(x \; (p \; p))) \; f)) \\ &=& (f \; ({Y} \; f)) \end{eqnarray*} 由於遞迴函式肯定能寫成$({Y} \; f)$的形式(參見之前mkdouble的構造方法),遞迴函式必定是某個函數$f$的不動點。
加入fix運算式
用Y組合子構造遞迴函式總歸太麻煩。 所以需要能直接構造遞迴函式的運算式。 先來看這個運算式需要哪些元素。 首先,遞迴函式要調用自己,需要一個指向自己的變數,記為$X_1$。 其次,遞迴函式有個參數,記為$X_2$。 最後,遞迴函式的函數體,記為$M$。 構造遞迴函式其實是尋找不動點的過程,所以這個運算式叫fix運算式(不動點叫fixed point)。 fix運算式長這個樣: \[ ({fix} \; X_1 \; X_2 \; M) \] 加入fix運算式最簡單的方法是定義為宏: \[ ({fix} \; X_1 \; X_2 \; M) = ({Y} \; \lambda X_1.\lambda X_2.M) \] 但是這樣做又重新引入了Y組合子。 這次採用另一種方法,不定義宏,而是把fix運算式加入文法: \begin{eqnarray*} M, N, L &=& ... \\ &|& ({fix} \; X_1 \; X_2 \; M) \end{eqnarray*}
現在考察fix運算式的求值過程。 fix運算式的求值結果是個函數,參數是$X_2$: \[ eval(({fix} \; X_1 \; X_2 \; M)) = \lambda X_2.? \] 最適合放在問號處的函數體的是$M$,但是$M$包含了自由變數$X_1$,使用$M$之前得先想方法除掉$X_1$。 $X_1$代表遞迴函式本身,也就是$({fix} \; X_1 \; X_2 \; M)$。 為了去掉$M$中的自由變數$X_1$,將$X_1$替換為遞迴函式$({fix} \; X_1 \; X_2 \; M)$。 綜上,fix運算式的求值過程為: \[ eval(({fix} \; X_1 \; X_2 \; M)) = \lambda X_2.M[X_1 \leftarrow ({fix} \; X_1 \; X_2 \; M)] \] 代碼:
加入了新文法,要添加相應的替換過程(這個替換過程和$\lambda X.M$的替換過程類似,但是麻煩了點): \begin{eqnarray*} ({fix} \; X_1 \; X_2 \; M)[X_1 \leftarrow N] &=& ({fix} \; X_1 \; X_2 \; M) \\ ({fix} \; X_1 \; X_2 \; M)[X_2 \leftarrow N] &=& ({fix} \; X_1 \; X_2 \; M) \\ ({fix} \; X_1 \; X_2 \; M)[X_3 \leftarrow N] &=& ({fix} \; X_4 \; X_5 \; M[X_2 \leftarrow X_5][X_1 \leftarrow X_4][X_3 \leftarrow N]) \\ &其中&X_3 \neq X_1, X_3 \neq X_2, \\ &&X_4 \notin FV(N), X_4 \notin FV(M)\backslash\{X_1\}, \\ &&X_5 \notin FV(N), X_5 \notin FV(M)\backslash\{X_2\} \end{eqnarray*} 代碼:
本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/project/