可化約性與進階不可判定性

計算的自我複製(quine)

/ quine rhymes with 'mine' /

quine 是一個程式,執行時會原封不動地印出自己的原始碼,不讀取輸入、也不讀自己的檔案。乍看像個悖論:要印出自己的程式碼,程式就得包含自己的程式碼,而那又包含自己的程式碼,永無止境。然而每種通用語言裡都存在 quine。它們是遞迴定理俏皮而具體的一面:證明一個程式真的能取得並重現自己的描述。

破解這表面上無限退行的把戲,是把程式拆成兩個合作的部件:一塊資料,是程式文本的引號副本;一塊程式碼,把那塊資料印兩次,一次當作字串字面值、一次當作活的程式碼。資料描述程式碼;程式碼執行時重建資料。示意如下:令部件 B 是指令「印出底下這個字串,然後再把它當程式碼印一次」,令部件 A 是 B 的引號副本;執行 A 再執行 B,就重現了 A 再 B。沒有任何部件包含自己的無限副本;兩半各自描述對方,合起來閉合了迴圈。這招「由一個部件計算出整體的描述」,正是遞迴定理證明的引擎。

自我複製不只是奇趣。它是遞迴定理的形式核心(機器能取得自己的描述),並由此支撐起若干嚴肅現象:馮諾依曼研究的自我複製結構、電腦病毒的理論基礎(一個把自己複製進其他程式的程式),以及哥德爾不完備性核心的自指——其中一個邏輯語句實質上說「我不可被證明」。一點誠實的提醒:一個印出自己的 quine 並不是矛盾,也不違反任何極限;它完全可計算。極限只在「自指」與「要求判定自己的不可判定行為」結合時才出現,正如遞迴定理那些不可判定性證明所示。

一個由兩個合作半部組成的 quine:一個資料字串 s,存著程式的引號副本;以及一段程式碼,它 (1) 用 s 印出程式碼那一半,然後 (2) 把 s 本身適當加引號印出。執行它便發出相同的兩半,重現整份原始碼。沒有任何一半存著自己的無限副本;各自描述對方。

拆成「描述程式碼的資料」與「印出資料的程式碼」;合起來便印出整個程式。

從磁碟讀取自己的原始碼檔案「不」算 quine,也不是遞迴定理所提供的東西。真正的 quine 純粹由自己執行中的程式碼重建出自己的文本——這才是深刻之處。

又稱
self-reproducing programself-replicating programquine自我複製程式