
導(dǎo)語(yǔ)
“請(qǐng)不要閱讀這條消息”——哎呀,太晚了,你已經(jīng)讀了!恭喜你,你剛剛體驗(yàn)了自指悖論和愚人節(jié)惡作劇的完美結(jié)合。
愚人節(jié)讓你分不清真假,自指則是讓邏輯自己把自己繞暈。想想“這句話(huà)是假的”——如果它說(shuō)的是真的,那它就是假的;如果它是假的,那它就是真的。是不是感覺(jué)大腦已經(jīng)開(kāi)始藍(lán)屏重啟了?
這種邏輯短路的奇妙感覺(jué),正是愚人節(jié)和自指悖論共同的魅力所在。一個(gè)讓你笑著上當(dāng),一個(gè)讓你聰明地犯傻。下面,我們將一起探索這些能讓侯世達(dá)都稱(chēng)為“金帶”的腦筋急轉(zhuǎn)彎,看看它們?nèi)绾卧趶臄?shù)學(xué)到生命,從計(jì)算機(jī)到哲學(xué)的各個(gè)領(lǐng)域搗鬼。
準(zhǔn)備好讓你的大腦在“是”與“不是”之間愉快地彈跳了嗎?往下看,但別說(shuō)我沒(méi)警告你——雖然這警告本身可能也是個(gè)悖論!
PS:也歡迎你在文末分享你最?lèi)?ài)的自指悖論,用邏輯打個(gè)結(jié),點(diǎn)贊前三名贏取《復(fù)雜》書(shū)籍+知識(shí)卡~
張江 | 作者
自指——一條永恒的金帶
自指是一個(gè)非常古老的話(huà)題,它通常與古代奧義以及各種神秘哲學(xué)有關(guān)。例如佛教中所提倡的“觀身無(wú)常、觀心無(wú)我”,以及古希臘的“認(rèn)識(shí)你自己”,都在勸解人們能夠?qū)⑿闹堑挠^察箭頭指向自己。中國(guó)道家所倡導(dǎo)的“無(wú)”,正是一個(gè)最簡(jiǎn)單的一字悖論。

自噬的蛇
一幅最能體現(xiàn)自指深邃含義的圖畫(huà)莫過(guò)于這條正在吞噬自己的蛇。此蛇作為一種圖騰曾廣泛出現(xiàn)在北歐神話(huà)、基督教神學(xué)、印度教和非洲宗教之中。這條蛇將自指那種深刻的自我毀滅性體現(xiàn)得淋漓盡致——我們可以想象一下當(dāng)它把自己吞噬完畢會(huì)產(chǎn)生怎樣怪異的情景。
將這種自我毀滅性的古代奧義應(yīng)用到現(xiàn)代科學(xué)中已經(jīng)產(chǎn)生了一系列深刻的結(jié)論。首先,在19世紀(jì)末,著名數(shù)學(xué)家康托爾(George Cantor)將“對(duì)角線(xiàn)刪除”法則應(yīng)用到集合論中,從而證明了實(shí)數(shù)的個(gè)數(shù)比自然數(shù)多。緊接著,羅素(Bertrand Russell)提出了著名的“羅素悖論”而摧毀了弗雷格(Gottlob Frege)的數(shù)學(xué)大廈。年僅25歲的哥德?tīng)枺↘urt G?del)巧妙地應(yīng)用同樣的破壞性自指一舉摧毀了數(shù)學(xué)大師希爾伯特(David Hilbert)的完備一致性的數(shù)學(xué)體系夢(mèng)想。圖靈(Alan Turing)則利用同樣的技巧進(jìn)一步發(fā)現(xiàn)任何超級(jí)計(jì)算機(jī)都不可能求解的圖靈停機(jī)問(wèn)題。
紐約時(shí)報(bào)曾將哥德?tīng)柌煌陚涠ɡ碓u(píng)價(jià)為20世紀(jì)最偉大的數(shù)學(xué)定理。自指可以用來(lái)構(gòu)造破壞性的悖論已經(jīng)是眾人皆知、司空見(jiàn)慣了。然而,這種認(rèn)識(shí)其實(shí)很片面。自指包含了比自指悖論更寬泛的內(nèi)容,因?yàn)樵谧灾复蠹彝ブ?,還包括另外一類(lèi)構(gòu)建性的成員。
1953年,正當(dāng)人們舉杯歡慶沃森和克里克發(fā)現(xiàn)了DNA雙螺旋結(jié)構(gòu),并從分子層面上解釋了生命的自我復(fù)制之謎的時(shí)候,另外一名偉大的美國(guó)匈牙利裔數(shù)學(xué)家:約翰.馮諾依曼(John von Neumann)正在獨(dú)立地思考著生命自我復(fù)制的邏輯基礎(chǔ)。然而,令人遺憾的是,那時(shí)的馮諾依曼已經(jīng)患上了癌癥,并于1957年的2月去世。于是,他的助手阿瑟.伯克斯Arthur Burks將他關(guān)于自復(fù)制自動(dòng)機(jī)理論的整理成書(shū)《Theory of Self-reproducing Automata》,并于1966年出版。
集智俱樂(lè)部資深粉絲“東方和尚”將全書(shū)第一部分翻譯成中文,張江做了詳細(xì)點(diǎn)評(píng)。我們將其整理成“馮·諾依曼自動(dòng)機(jī)器理論”系列文章。
與沃森.克里克不同的是,馮諾依曼要尋找的是生命自我復(fù)制的邏輯基礎(chǔ)而非物質(zhì)基礎(chǔ)。雖然馮諾依曼沒(méi)有明確指出,但是已經(jīng)暗含了這個(gè)自復(fù)制的邏輯基礎(chǔ)不是別的,正是一種自指結(jié)構(gòu)。也就是說(shuō),自指恰恰是生命實(shí)現(xiàn)自我復(fù)制的邏輯內(nèi)核。這也許會(huì)讓讀者感到困惑。不是說(shuō),自指都是用來(lái)構(gòu)造諸如哥德?tīng)柖ɡ?、羅素悖論之類(lèi)的破壞性武器嗎?實(shí)際上,還存在著另外一大類(lèi)自指,筆者稱(chēng)之為“建構(gòu)性的自指”,它不但不會(huì)引起破壞,反而能夠創(chuàng)造很多令人意想不到的驚奇結(jié)構(gòu)。至于自我繁殖的系統(tǒng)是如何令人意想不到的,請(qǐng)參考第4節(jié)的討論。
實(shí)際上,早在1938年,與哥德?tīng)柟餐於ㄟf歸函數(shù)論基礎(chǔ)的數(shù)學(xué)家克林尼(Stephen Kleene)就證明了遞歸函數(shù)論中的一個(gè)著名定理:遞歸定理(更精確地說(shuō),應(yīng)該叫Kleene第二遞歸定理)。根據(jù)它,人們可以很輕松地得到一個(gè)數(shù)學(xué)推論,系統(tǒng)的自我復(fù)制是可能的。
證明遞歸定理的核心技巧,是一個(gè)被稱(chēng)為“蒯(kuai3)恩”的特別技術(shù)。蒯恩(Willard.V. Quine)是美國(guó)的哲學(xué)家,終身致力于哲學(xué)、數(shù)理邏輯、集合論的研究。他創(chuàng)造了一種稱(chēng)之為蒯恩的方法,使得人們可以不通過(guò)使用“我”或者“這句話(huà)”等詞語(yǔ)就能創(chuàng)造出可以談?wù)撟陨淼木渥觼?lái)。
有趣的是,蒯恩構(gòu)造恰恰就是那條“黃金對(duì)角線(xiàn)”(這一方法正是當(dāng)年康托爾最早提出證明實(shí)數(shù)比自然數(shù)多的方法,也是哥德?tīng)柖ɡ順?gòu)造哥德?tīng)柧渥拥年P(guān)鍵技術(shù))。只不過(guò),康托爾、哥德?tīng)柕热说膶?duì)角線(xiàn)與蒯恩的對(duì)角線(xiàn)方法稍有不同。我們會(huì)在第6節(jié)中詳細(xì)地討論這些技術(shù)。
總而言之,從宗教到科學(xué),從悖論到自復(fù)制,自指是貫穿始終的主題。正如《哥德?tīng)枴釥?、巴赫》這本書(shū)指出的那樣,自指是一條永恒的金帶。

《哥德?tīng)?、艾舍爾、巴赫》的原?左,20 周年)和中譯本(右)
集智俱樂(lè)部曾于2018年4月18日邀請(qǐng)侯世達(dá)(DouglasRichard Hofstadter)來(lái)到北京線(xiàn)下和杭州線(xiàn)下做分享交流:
https://pattern.swarma.org/study_group_issue/383
深刻的影響了很多集智社區(qū)的成員,包括集智俱樂(lè)部的創(chuàng)始人,北京師范大學(xué)的教授張江,推薦張江教授對(duì)《GEB》的解讀視頻:https://campus.swarma.org/course/51
語(yǔ)言中的自指
提到自指,很多讀者馬上就會(huì)聯(lián)系到那句臭名昭著的悖論句子:
這句話(huà)是錯(cuò)的
這句話(huà)之所以讓人討厭,是因?yàn)槟銦o(wú)論從正面(即假設(shè)它是對(duì)的),還是從反面(即假設(shè)它是錯(cuò)的),都會(huì)得出相反的結(jié)論。因此,這句話(huà)既不對(duì)也不錯(cuò)。
然而,這句“說(shuō)謊者悖論”僅僅是廣大自指語(yǔ)句家庭中的成員之一,有很多語(yǔ)言是自指的,但卻是無(wú)害的甚至是有益的。比如下面的句子:
這句話(huà)是對(duì)的
這句話(huà)就是一個(gè)既可以是對(duì)又可以是錯(cuò)的句子。你可以非常虔誠(chéng)地承認(rèn)這句話(huà)所論述的內(nèi)容是對(duì)的,然后,再看它的內(nèi)容,它正在陳述:它自己是對(duì)的。于是你初期的假設(shè)被證實(shí)了。另一方面,當(dāng)你假設(shè)它是錯(cuò)誤的時(shí)候,你就會(huì)知道它的語(yǔ)義“這句話(huà)對(duì)”是錯(cuò)誤的,于是你就真的得到了這句話(huà)就是錯(cuò)誤的結(jié)論。也就是說(shuō)這句話(huà)的對(duì)錯(cuò)完全取決于你的假設(shè)。
當(dāng)然,還有一些更好玩的自指句子,如:
這句話(huà)有2個(gè)‘這’字,2個(gè)‘句’字,2個(gè)‘話(huà)’字,2個(gè)‘有’字,7個(gè)‘2’字,11個(gè)‘個(gè)’字,11個(gè)‘字’字,2個(gè)‘7’字,3個(gè)‘11’字,2個(gè)‘3’字
這被稱(chēng)為自描述語(yǔ)句,也就是說(shuō)這個(gè)句子正在描述自己的“分子”構(gòu)成。當(dāng)你嘗試獨(dú)立寫(xiě)下這樣一個(gè)自描述語(yǔ)句的時(shí)候就會(huì)發(fā)現(xiàn),你其實(shí)并沒(méi)有創(chuàng)造這句話(huà),而是這句話(huà)正在“迫使”你寫(xiě)出它自己。這是因?yàn)椋凑者@個(gè)句子的邏輯一旦你開(kāi)始寫(xiě)下第一個(gè)字,你就必須按照已出現(xiàn)的字的情況而自動(dòng)補(bǔ)全后面的句子。同時(shí),這個(gè)語(yǔ)句還具有了不起的自我修復(fù)性。你不妨將該句子中的某一個(gè)漢字刪掉(例如你刪除第一個(gè)‘2’字),就會(huì)很快發(fā)現(xiàn)該句子中的一部分出現(xiàn)問(wèn)題了,即“7個(gè)‘2’字”是錯(cuò)誤的。因此,你會(huì)根據(jù)句子整體的意思指導(dǎo)而發(fā)現(xiàn)你少了一個(gè)‘2’字。
因此,自指不都是破壞性的,更多的自指是無(wú)害的,而且可以給我們帶來(lái)一定的“驚奇性”。這種驚奇性的來(lái)源主要是自指語(yǔ)句中包含的無(wú)窮遞歸,因?yàn)樗梢詣?chuàng)造無(wú)限的虛擬層次。
虛擬層次是一個(gè)我們司空見(jiàn)慣的概念,例如故事中的故事,電影中的電影,夢(mèng)境中的夢(mèng)境等等(電影《盜夢(mèng)空間》(Inception)就是對(duì)夢(mèng)中夢(mèng)層次的一個(gè)非常好的展示)。在上一章中,我們已經(jīng)領(lǐng)略了程序是可以通過(guò)模擬而產(chǎn)生多個(gè)虛擬層次的。在語(yǔ)言中,我們不妨將引號(hào)看作是標(biāo)識(shí)一個(gè)新的虛擬層次出現(xiàn)的符號(hào)。這樣,下面這句話(huà):
“明天會(huì)下雨”是錯(cuò)的
就包含了兩個(gè)層次,更深一層的句子是“明天會(huì)下雨”,而上面一層則是“‘明天會(huì)下雨’是錯(cuò)的”。當(dāng)然,我們通過(guò)不斷地加引號(hào)就能創(chuàng)造出各種復(fù)雜的嵌套結(jié)構(gòu)。
另外,人們發(fā)明了一類(lèi)代詞可以指代不同的句子。例如“這句話(huà)”,“那句話(huà)”。這些代詞就仿佛是一個(gè)指針會(huì)將一個(gè)句子整體放到一個(gè)引號(hào)中而實(shí)現(xiàn)多個(gè)層次的嵌套。例如下面兩句話(huà):
下面的句子是對(duì)的
明天會(huì)下雨
在第一句話(huà)中出現(xiàn)了一個(gè)指代詞“下面的句子”,它是一個(gè)指針指向了“明天會(huì)下雨”這句話(huà),于是我們觀察者作為一個(gè)解讀器就會(huì)將這兩句話(huà)解釋為:
“明天會(huì)下雨”是對(duì)的
也就是說(shuō),我們照指代詞的意思將“明天會(huì)下雨”這句話(huà)加上了引號(hào)放到了第一句中的“下面的句子”那個(gè)指代詞之中了。于是,指代詞創(chuàng)造了包含了兩個(gè)虛擬層次的句子。
按照同樣的邏輯,當(dāng)我們遇到了指代詞“這句話(huà)”的時(shí)候會(huì)發(fā)生什么呢?我們將會(huì)得到一個(gè)包含無(wú)窮虛擬層次的語(yǔ)句。例如我們將自指語(yǔ)句“這句話(huà)是錯(cuò)的”按照代詞的法則展開(kāi)就會(huì)得到:
““““…………”是錯(cuò)的”是錯(cuò)的”…………”是錯(cuò)的”是錯(cuò)的
我們看到,只要“這句話(huà)”這個(gè)指代詞一出現(xiàn),我們就能夠得到無(wú)窮。因此,自指語(yǔ)句往往都與無(wú)窮虛擬層次有關(guān)。注意,我這里用的詞語(yǔ)是“往往”,而不是“一定”。之所以這樣說(shuō),是因?yàn)榈拇_存在著一種構(gòu)造自指語(yǔ)句的方法,讓我們繞過(guò)無(wú)窮。這種方法就是大名鼎鼎的蒯恩法。
在討論蒯恩之前,讓我們先來(lái)領(lǐng)教句子中的動(dòng)詞(動(dòng)詞短語(yǔ))。大部分動(dòng)詞是與我們讀句子的觀察者無(wú)關(guān)的,例如:
小明起床了
這個(gè)句子表達(dá)了小明這個(gè)人物正在做的一個(gè)動(dòng)作是起床了。其中“起床了”就是一個(gè)動(dòng)詞。當(dāng)然,有很多動(dòng)詞不僅可以描述一個(gè)人或者事物,還可以去描述句子,例如:
“小明起床了”包含5個(gè)字
這里面的“包含5個(gè)字”就是一個(gè)描述句子“小明起床了”的動(dòng)詞。還有一些句子包含了動(dòng)詞,而這個(gè)動(dòng)詞是使役我們讀這個(gè)句子的觀察者做出某種動(dòng)作的:
刪除“小明起床了”中的第一個(gè)字
這個(gè)“刪除第一個(gè)字”的動(dòng)作就是使役讀句子的觀察者做出的,于是,我們按照這個(gè)句子的說(shuō)法進(jìn)行操作,就會(huì)得到一個(gè)新句子:
明起床了
我們可以再做稍微復(fù)雜一點(diǎn)的操作,例如:
把“小明起床了”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
按照這個(gè)句子所描述的復(fù)雜操作(你最好拿來(lái)一個(gè)草稿紙,自己在紙上寫(xiě)一寫(xiě)),我們就可以得到:
小“小明起床了”明起床了
好,既然你已經(jīng)熟悉了這個(gè)復(fù)雜的操作,那么讓我們來(lái)看下面一個(gè)古怪的句子:
把“把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
如果按照這個(gè)句子指示的操作你會(huì)得到什么?讓我們來(lái)做一做。按照這個(gè)句子的要求,我們可以把引號(hào)之中的句子施行下面的三步操作:第一步,把第一個(gè)字,也就是“把”放在左引號(hào)前面,這樣就得到的新句子中的第一個(gè)字:“把”;第二步,將后面的字放在右引號(hào)后面,這樣新句子就會(huì)以“中的第一個(gè)字放到……字不變”為結(jié)尾;第三步,保持引號(hào)和其中的字不變,于是新句子的中間會(huì)有一個(gè)引號(hào),并且引號(hào)的中間就會(huì)是“把中的第一個(gè)字放到……”。于是,我們得到的新句子就是:
把“把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
請(qǐng)注意,這個(gè)新句子和原句子是一模一樣的!事實(shí)上,原句子使役我們觀察者完成了一次對(duì)自己的拷貝!這個(gè)句子其實(shí)就是大名鼎鼎的蒯恩了!
也許,你已經(jīng)有些糊涂了,讓我們?cè)俸煤每纯淳烤关岫魇窃趺床僮鞯?。首先,我們定義了一種具有動(dòng)詞的句子,也就是:
把“X”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
我們不妨將這個(gè)句子記為,其中的就是一個(gè)空穴,可以往其中添放任何一個(gè)句子。例如,如果我們讓=“小明起床了”,那么原句子就成為了一個(gè)完整的句子:
把“小明起床了”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
按照的意思對(duì)進(jìn)行操作就得到了新句子:
小“小明起床了”明起床了
在這個(gè)例子中,顯然與沒(méi)有什么關(guān)系。
進(jìn)一步,如果去除句子中的空穴,我們可以得到:
把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
它也是一個(gè)句子(盡管它不完整),我們記它為。最關(guān)鍵的時(shí)刻來(lái)臨了:我們讓并代入之中會(huì)怎樣?也就是將除去空穴的句子部分放到這個(gè)句子的空穴之中:
把“把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
我們不妨把這個(gè)句子記做,因?yàn)槲覀儼芽昭〒Q成了殘句子。之后,我們?cè)侔凑者@個(gè)句子所給出的使役動(dòng)詞進(jìn)行操作,就能得到新句子,也就是:
把“把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變
令人驚奇的是,經(jīng)過(guò)動(dòng)詞操作之后創(chuàng)造的句子與原來(lái)的句子竟然是一模一樣的!所以句子利用使役動(dòng)詞完成了“自復(fù)制”過(guò)程,也就是。
我們把這種技巧稱(chēng)之為蒯恩以紀(jì)念它的發(fā)現(xiàn)者美國(guó)哲學(xué)家W.V. Quine。你會(huì)看到,這種技巧可以讓我們不用“這句話(huà)”指代詞就能夠造出自指語(yǔ)句,比如下面這個(gè)句子:
把“把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變得到的句子是假的”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變得到的句子是假的
注意,這個(gè)句子與前面的句子稍有不同,這就是在后面加上了一個(gè)判斷“得到的句子是假的”。我們不妨記“得到的句子是假的”,并且把:
把“X”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變得到的句子是假的
這句話(huà)記為,其中符號(hào)表示將兩個(gè)句子粘合在一起形成新的句子,于是就是:
把“把中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變得到的句子是假的”中的第一個(gè)字放到左引號(hào)前面,其余的字放到右引號(hào)后面,并保持引號(hào)及其中的字不變得到的句子是假的
我們可以驗(yàn)證,經(jīng)過(guò)句子所描述的操作之后得到的句子跟是一模一樣的。所以這句話(huà)就相當(dāng)于:“這句話(huà)是假的”。我們沒(méi)使用“這句話(huà)”指代詞就實(shí)現(xiàn)了自指。
有關(guān)更多的語(yǔ)言中的蒯恩操作的討論請(qǐng)參看《哥德?tīng)枴釥?、巴赫——集異璧之大成》一?shū)的對(duì)話(huà)《G弦上的詠嘆調(diào)》,以及《Diagonalization and Self-Reference》一書(shū)。
也許你會(huì)覺(jué)得我們?cè)谕媾Z(yǔ)言游戲,然而,這種語(yǔ)言技術(shù)卻在數(shù)學(xué)和計(jì)算機(jī)中起到了非常大的作用,因?yàn)樨岫骶渥忧∏【褪亲詮?fù)制機(jī)器的邏輯基礎(chǔ),也是Godel定理證明過(guò)程中的關(guān)鍵一步。下面,我們分別對(duì)建構(gòu)性自指和破壞性自指進(jìn)行詳細(xì)地介紹。
建構(gòu)性的自指
雖然提起自指,人們很容易想到自指悖輪。但是,人們不熟悉的是另外一大類(lèi)無(wú)害的自指,它們通常直接應(yīng)用蒯恩技術(shù),而實(shí)現(xiàn)某些意想不到的結(jié)構(gòu)或者功能。下面,讓我們先從一種最簡(jiǎn)單的建構(gòu)性自指:自打印程序說(shuō)起。
所謂的程序自打印就是指一個(gè)程序能夠在不讀取外部文件的條件下把自己的源代碼打印出來(lái)。首先,我們要先領(lǐng)教一下,一個(gè)自我打印的程序是多么不可能的!我們知道,要寫(xiě)一個(gè)程序打印出“helloworld!”字樣是非常容易的,例如:
Print(‘helloworld!’)
注意在這個(gè)程序中,字符串都用單引號(hào)括起來(lái)。那么,我們能不能寫(xiě)一個(gè)程序,把這個(gè)打印“helloworld!”程序的源代碼打印出來(lái)呢?這也是可以辦到的,例如下面的程序:
Print(‘Print(\’helloworld!\’)’)
注意,這里面的“\’”會(huì)被編譯器解釋為一個(gè)字符串,這個(gè)字符串中就有一個(gè)字符:“ ` ”。采用這個(gè)技巧,我們就可以解決如何在一個(gè)引號(hào)之中再輸入一個(gè)引號(hào)的問(wèn)題了。所以,我們可以很輕松地打印出這個(gè)能夠打印”helloworld!”程序的程序源代碼出來(lái)。但是很顯然這個(gè)程序并不能打印出它自己,也許你會(huì)想到能不能打印出上面的程序源代碼出來(lái)?當(dāng)然可以!
Print(‘Print(\’Print(\\\’helloworld!\\\’)\’)’)
其中\(zhòng)\就表示包含一個(gè)字符“\”的字符串變量,這樣Print(‘\\’)就會(huì)打印出一個(gè)字符“\”,而Print(‘\\\’’)就會(huì)打印出字符串“\’”出來(lái)。所以,引號(hào)里面可以放入任意層次的引號(hào)。
但是這個(gè)程序仍然不能打印自己!你很快發(fā)現(xiàn),我們?nèi)祟?lèi)是寫(xiě)不出這種能夠打印自己的程序的,因?yàn)樗藷o(wú)窮遞歸。不過(guò),通過(guò)蒯恩技巧,實(shí)際上我們完全可以寫(xiě)出來(lái)一個(gè)自打印程序,如下:
S(x){ q=’S(x){\\n q=\\\’\’+q+\’\\\’;\\n Print(\\\’\’+p(q)+\’\\\’);\\n}’; Print(‘S(x){\n q=\’’+q+’\’;\n Print(\’’+p(q)+’\’);\n}’); }
源代碼1:自打印程序源代碼
這里面的“\n”表示換行符,即如果執(zhí)行Print(‘A\nB’),則程序會(huì)輸出下面的字符串:
A B
“+”表示將兩個(gè)字符串進(jìn)行串聯(lián)形成一個(gè)新的字符串,例如A=’123’,B=’456’,則A+B=’123456’。
這個(gè)自打印程序調(diào)用了一個(gè)簡(jiǎn)單的解碼函數(shù),的作用是將字符串變換成更淺一層次的字符串。例如,如果是“\\\’\\’\\n\\”,那么這個(gè)函數(shù)就會(huì)計(jì)算輸出“\’’\n\”。也就是說(shuō)完成了一組映射:它把“\\”映射成“\”,把“\’”映射成“’”,而把“\n”映射成回車(chē)符。顯然是可以寫(xiě)出來(lái)的。我們知道,由引號(hào)的引用可以形成更加深層次的虛擬世界(參見(jiàn)上一小節(jié))。所以的作用就是讓字符串彈出一層虛擬世界。由于的作用很簡(jiǎn)單,我們假設(shè)它是一個(gè)系統(tǒng)自帶的函數(shù),因此就不在源代碼1中給出的實(shí)現(xiàn)代碼了。
S(x)這個(gè)程序中包含了過(guò)多的“\”和“’”符號(hào),這就導(dǎo)致我們理解源代碼1稍顯困難,下面我們將把該程序表示成下面的圖,從而讓讀者看得更清晰一些:

自打印程序源代碼中的引號(hào)層次示意
如上圖,這個(gè)自打印程序中的引號(hào)全部用方框來(lái)替代。這樣第一層引號(hào)’…’就對(duì)應(yīng)了第一層的方框,引號(hào)中的引號(hào),即“\’…\’”就對(duì)應(yīng)了框中的一個(gè)框。這樣,由于程序中出現(xiàn)最多的層次是四層引號(hào),即“\\\’”,所以上圖中就出現(xiàn)了第四層框。
另外,我們還觀察到,這個(gè)程序包含了兩個(gè)大框,即“q=”后面的黃框和“Print()”之中的那個(gè)藍(lán)框。這兩個(gè)框的結(jié)構(gòu)是完全一樣的,只不過(guò)黃框比藍(lán)框多了一個(gè)虛擬層次,這反映在所有的藍(lán)色框中的最深一層框都再加上一層框就得到了黃色框。
更有趣的是,整個(gè)程序S(x)實(shí)際上和這兩個(gè)框是相似的,因此這個(gè)程序本身就是一個(gè)分形結(jié)構(gòu)。在傳統(tǒng)的分形結(jié)構(gòu)中,每一個(gè)部分都會(huì)包括無(wú)窮多的細(xì)節(jié)。但是,在這個(gè)自打印程序中,雖然有嵌套的分形結(jié)構(gòu),但是卻沒(méi)有達(dá)到無(wú)窮,最深的引號(hào)也僅僅有4層。
讓我們來(lái)分析一下這個(gè)程序是如何運(yùn)作的。首先,看程序的最后一行,即Print(‘S(x){\nq=\’’+q+’\’;\nPrint(\’’+p(q)+’\’);\n}’);這句話(huà)的作用是讓程序在屏幕上打印出一個(gè)字符串。注意觀察,這個(gè)被打印出的字符串其實(shí)是由“+”號(hào)被分割成了5個(gè)部分,第一部分是“S(x){\nq=\’”,第二個(gè)部分是q這個(gè)字符串的原封不動(dòng)的拷貝,第三部分是字符串:“\’;\nPrint(\’”,第四部分是函數(shù)作用到上面的結(jié)果即;第五部分還是一個(gè)字符串:“\’);\n}”。然后當(dāng)我們把q字符串的數(shù)值代入第二部分和第四部分,并進(jìn)行運(yùn)算之后,就得到了和源程序一模一樣的結(jié)果。你不妨在計(jì)算機(jī)上運(yùn)行這段程序,就會(huì)發(fā)現(xiàn)這段程序會(huì)在屏幕上赤裸裸地把自己的源代碼打印出來(lái)。
我們不妨把這段程序的5個(gè)部分進(jìn)行歸并,寫(xiě)成由下面的三部分構(gòu)成的:,其中Copy就是5部分中的第二部分,即相當(dāng)于一個(gè)拷貝字符串的程序,你輸入 給Copy什么字符串,Copy就會(huì)把那個(gè)字符串再原封不動(dòng)地吐出來(lái);Popup這部分就是原來(lái)的5部分中的第四部分,即函數(shù),它的作用相當(dāng)于一個(gè)彈出操作,也就是為輸入的字符 串脫去一層引號(hào)。如果輸入的字符串原來(lái)是在第層虛擬世界,則Popup的作用就是讓字符串跳到第層;最后Control這部分就相當(dāng)于原來(lái)的第1、3、5這三部分以及最一開(kāi)始的語(yǔ)句Print的總合,它的作用就相當(dāng)于是為Copy和Popup制造出來(lái)的字符添加適當(dāng)?shù)倪B接詞,使得最后的字符串能夠拼接成與原來(lái)的程序一模一樣的源程序,并將其打印到屏幕上。所以這句“Print(‘S(x){\nq=\’’+q+’\’;\nPrint(\’’+p(q)+’\’);\n}’);”就可以改寫(xiě)成。其中“о”表示將不同的程序連接為一體。
如果我們把一個(gè)計(jì)算機(jī)程序的描述(或者稱(chēng)源代碼)寫(xiě)為,則自打印程序的第一條賦值語(yǔ)句就相當(dāng)于給賦予了,即這三個(gè)程序連在一起的源代碼。最后我們可以將自打印程序簡(jiǎn)寫(xiě)為:
S(x){ q= λ (Copyo Popupo Control) (Copyo Popupo Control)(q); }
源代碼2:自打印程序的源碼縮寫(xiě)
我們可以進(jìn)一步地把它簡(jiǎn)寫(xiě)為:,其中表示()這三個(gè)程序的聯(lián)合程序,而則表示聯(lián)合程序的源代碼。這個(gè)程序的作用是輸出一個(gè)特殊的字符串“”即程序調(diào)用自己的代碼x的源程序,我們稱(chēng)這個(gè)為蒯恩函數(shù)。
那么,自打印程序不是別的,正是將蒯恩函數(shù)自己的源代碼再喂給它自己,這樣就產(chǎn)生了""的效果。等式左邊是對(duì)的計(jì)算,是一個(gè)動(dòng)作,它的結(jié)果產(chǎn)生了等式右邊的字符串"",而這個(gè)字符串恰恰就是作用于的源代碼。我們看到,第2節(jié)中的蒯恩方法與這里的是一模一樣的。仔細(xì)想想不難發(fā)現(xiàn),其實(shí)自打印程序的邏輯與蒯恩語(yǔ)句的邏輯是相通的。因此,自指恰恰就隱藏在了這段自打印程序之中了。
我們只要對(duì)這個(gè)自打印程序稍加更改就能創(chuàng)造出自我復(fù)制的程序出來(lái)。首先,我們要說(shuō)明程序的自我復(fù)制究竟是什么意思。假設(shè)內(nèi)存中漂浮著很多大大小小的程序,某一個(gè)程序P能夠自我復(fù)制是指,當(dāng)CPU執(zhí)行到程序P的時(shí)候,P就會(huì)命令CPU執(zhí)行一系列的操作使得它自己的一份拷貝會(huì)出現(xiàn)在內(nèi)存中。但是,需要強(qiáng)調(diào)的是P不能夠從硬盤(pán)上讀取文件,否則自我復(fù)制將變得異常簡(jiǎn)單,只要把硬盤(pán)上的源程序再調(diào)用到內(nèi)存中就行了。乍一看,這似乎與自打印程序一樣不可能實(shí)現(xiàn)。但是利用與自打印程序同樣的蒯恩技巧,我們依然可以很輕松地構(gòu)造出自復(fù)制的程序出來(lái)。
我們只需要把自打印程序()中的改成Construct就可以了。這里的Construct是一個(gè)函數(shù),你輸入給Construct一段程序的源代碼,它就能把所對(duì)應(yīng)的程序編譯出來(lái)并駐留在內(nèi)存中。這樣,程序就可以完成自復(fù)制功能。
進(jìn)一步,利用同樣的邏輯,我們也能夠制造出可以復(fù)制自身的真實(shí)機(jī)器。只要讓Construct代表從給定機(jī)器的描述而構(gòu)造出實(shí)際機(jī)器就行了。在馮諾依曼的著作《自復(fù)制自動(dòng)機(jī)理論(Theory of Self-reproducing Automata)》一書(shū)中,作者試圖構(gòu)建的自復(fù)制自動(dòng)機(jī)就包括了這四個(gè)部分。即自復(fù)制機(jī)器是由一個(gè)通用拷貝機(jī)(Copy)、一個(gè)通用構(gòu)造機(jī)(Construct)和一個(gè)控制器(Control)以及所有這三臺(tái)機(jī)器的描述即源代碼構(gòu)成的。
在此小節(jié)中,我們用自打印程序和自復(fù)制程序?yàn)槔齺?lái)說(shuō)明了建構(gòu)型的自指。然而,建構(gòu)性的自指實(shí)際上不僅僅是這兩種,它還會(huì)有各種各樣的用途。
如果想更系統(tǒng)的了解層級(jí)與自指,推薦張江老師的復(fù)雜性思維的課程:
https://campus.swarma.org/course/1128
未完待續(xù):
http://wiki.swarma.net/index.php/%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E8%A7%82%E5%AF%9F%E8%80%85(5)%E2%80%94%E2%80%94%E8%87%AA%E6%8C%87(或點(diǎn)擊閱讀原文)
互動(dòng)有獎(jiǎng)
既然你已經(jīng)深入了自指悖論的兔子洞,現(xiàn)在輪到你來(lái)展示才華了!在評(píng)論區(qū)分享你遇到過(guò)的最有趣、最腦洞大開(kāi)或最讓人抓狂的自指悖論例子??梢允悄阍谏钪杏龅降?,也可以是你自己創(chuàng)造的腦筋急轉(zhuǎn)彎!
獎(jiǎng)品公告
點(diǎn)贊數(shù)前三名的悖論將獲得:
《復(fù)雜》精裝圖書(shū)一本
限量版《復(fù)雜》知識(shí)卡一套
參與規(guī)則
在評(píng)論區(qū)分享一個(gè)自指悖論的例子
可以給其他人的悖論點(diǎn)贊(請(qǐng)注意:系統(tǒng)可能會(huì)自動(dòng)忽略沒(méi)有先點(diǎn)贊本文的評(píng)論... 或者這句話(huà)本身就是個(gè)悖論?)
截止時(shí)間:4月8日晚上8點(diǎn)
獲獎(jiǎng)名單將在4月10日公布
靈感提示(感謝社區(qū)成員韓司陽(yáng)提供的靈感):


因果涌現(xiàn)讀書(shū)會(huì)第六季
在霓虹燈的閃爍、蟻群的精密協(xié)作、人類(lèi)意識(shí)的誕生中,隱藏著微觀與宏觀之間深刻的因果關(guān)聯(lián)——這些看似簡(jiǎn)單的個(gè)體行為,如何跨越尺度,涌現(xiàn)出令人驚嘆的復(fù)雜現(xiàn)象?因果涌現(xiàn)理論為我們揭示了答案:復(fù)雜系統(tǒng)的宏觀特征無(wú)法通過(guò)微觀元素的簡(jiǎn)單疊加解釋?zhuān)窃从诙喑叨葎?dòng)態(tài)交互中涌現(xiàn)的因果結(jié)構(gòu)。從奇異值分解(SVD)驅(qū)動(dòng)的動(dòng)態(tài)可逆性分析,到因果抽象與信息分解的量化工具,研究者們正逐步構(gòu)建起一套跨越數(shù)學(xué)、物理與信息科學(xué)的理論框架,試圖解碼復(fù)雜系統(tǒng)的“涌現(xiàn)密碼”。
為了系統(tǒng)梳理因果涌現(xiàn)最新進(jìn)展,北京師范大學(xué)系統(tǒng)科學(xué)學(xué)院教授、集智俱樂(lè)部創(chuàng)始人張江老師領(lǐng)銜發(fā)起,組織對(duì)本話(huà)題感興趣的朋友,深入研讀相關(guān)文獻(xiàn),激發(fā)科研靈感。
讀書(shū)會(huì)將從2025年3月16日開(kāi)始,每周日早9:00-11:00,持續(xù)時(shí)間預(yù)計(jì)10周左右。每周進(jìn)行線(xiàn)上會(huì)議,與主講人等社區(qū)成員當(dāng)面交流,之后可以獲得視頻回放持續(xù)學(xué)習(xí)。誠(chéng)摯邀請(qǐng)領(lǐng)域內(nèi)研究者、尋求跨領(lǐng)域融合的研究者加入,共同探討。
詳情請(qǐng)見(jiàn):
1.
2.
3.
4.
5.
6.
熱門(mén)跟貼