我們清楚,dna能進行自我複製,是因為dna中編碼了複製自己的**,實際上這種自我複製的機制並不簡單,而且非常迷人。侯世達在其大作《geb》中花了一章來講述dna的自複製機制。他指出,自複製的dna和自指的句子有著某種相似性,而且都與人的自我意識相似。自我意識實際上就是一種自指的現象。
接下來我們從自指的句子說起。什麼是自指的句子,舉例來說:
「本句子雖然很長,但是毫無意義。」
上面這句話就是自指的句子,它說的是某句話冗長而空洞,而那句話恰好是它自身。這麼來看自指的句子很容易構造,以「本句話」開頭就行;這樣我們還能輕鬆的構造出一篇自指的文章,只要文中有「本文」兩個字就行。簡單嗎?至少表面如此。自指類似於乙個迴圈,這種結構的自指實際上把大量的工作交給處於迴圈中的讀者,它靠乙個「本」字引起其讀者大腦中的已有的處理自指的過程,而句子本身的結構實際上並不包括任何自指。這種自指型別沒有向我們揭示出自指結構的複雜和奇妙,一切自指處理仍然是深藏在我們的大腦中。
如何構造乙個句子,僅僅通過分析其結構就能知道它是自指的呢?
「包含十四個字的句子可能是首詩。」
上面這句話也是自指的。它的特點是,其中並不包括「本句子」,但是我們可以通過分析它的結構(數一數它自己的字數)就知道它說的是自己。現在已經離我們的目標近了一步,不過總覺得有什麼不對勁。這個句子所描述的不僅僅是它自己,它實際上指向的是一大類句子,即所有由十四個字構成的句子。我們說的自指,更希望是自己精確地指向自己,而不是通過自己所屬的類別來指向自己,猶如讓乙個人說說自己的特點,他卻總是說人類有什麼特點。
圖1. 精確自指與指向自己的類
很容易弄明白這種自指結構的生成過程:句子可以任意長,主語是「包括xx個字的句子」,xx是包括「xx」在內的句子的長度。我們試著改進一下,讓它更精確地指向自己:
「包含二十二個字的句子,其第乙個字是「包」,可能是首詩。」
範圍已經縮小至以「包」字開頭的包含二十二個字的句子,顯然限定越多,指向的句子就越少。是不是通過這種方法最後能實現精確地自指呢?仔細分析就知道,用這種方法遞迴到無窮也得不到自指。為了描述原來的十四個字,我們加上了「其第乙個字是「包」」、「其第二個字是「含」」等短語,可是這些加上的短語又成為了句子的一部分,為了描述它們,又不得不加上「其第x個字是「其」」、「其第x+1個字是「第」」等等,顯然描述乙個字就得增加好多個字,有窮乃至無窮的情況下都得不到自己對自己的完全描述。這種嘗試很像是提著鞋帶把自己提起來,無論如何也辦不到。
此路不通,我們再回過頭瞧一瞧dna的自複製原理,或許能受到些啟發。自複製實際上就是自己列印自己,這個過程中顯然需要能指向被列印的物件,也就是自指。dna中並沒有包含自描述的**,就像上面分析的,乙個東西包含對它自己的每一部分的描述是不可能的。dna通過轉錄翻譯生成蛋白質,然後由蛋白質再回過頭來複製dna,從而完成了乙個dna的複製迴圈。乙個人不可能提著自己的鞋帶把自己提起,但是他可以拉著單槓把自己提起。也就是,自指的核心要素可能在於需要乙個外部的翻譯過程。dna只管生成蛋白質,不用管自複製的事情,而一部分特定的蛋白質恰好可以複製dna,二者一旦結合起來,就會形成穩定的dna和蛋白質的相互生成,站在dna角度看,剛好就實現了自複製。
圖2. 借助外部環境的自指
我們如法炮製(實際上是哲學家蒯因最先提出來的),定義乙個對短語的變換:後粘。「後粘」是自己起的名字,意思是在後面貼上(geb一書中侯世達給變換起的名字叫「擓摁」)。後粘,就是把乙個種子短語放在它自己的後面形成一句話,舉個例子:
「吃了飯要散步」吃了飯要散步。
這句話把短語「吃了飯要散步」放在它自己的後面,形成了語義完整的一句話,意思是「吃了飯要散步」這個東西吃過飯之後要散步。
我們選取種子短語d為「被後粘是一首詩」,看看把它後粘後是什麼:
「被後粘是一首詩」被後粘是一首詩。——句子j
稱上面的句子為句子j,句子j語義完整,說的是某句子k是一首詩,而那句子是短語d被後粘形成的。我們根據後粘變換來生成句子k:
「被後粘是一首詩」被後粘是一首詩。——句子k
句子k就是句子j!句子j說句子k是一首詩,那麼它是確定無疑地說自己是首詩,句子j在自指。
通過定義乙個外部操作,我們實現了句子的自指,這和dna與蛋白質配合實現dna的自複製何其相似。
了解了句子自指的精髓,我們就可以寫出能自己列印自己的程式。這裡以matlab**為例。可想而知,自列印的程式中必不可少的語句是「fprintf()」,下面這句話是行不通的:
fprintf('fprintf()')
這句話執行後的結果是fprintf(),而:
fprintf('fprintf(''fprintf()'')')
和上面的情況類似,也是行不通的。無論**中巢狀了多少層fprintf(),列印結果總要少一層。實際上這種方法就是上文提到的自描述的方法。
我們可以定義乙個變數s,通過列印s就能列印出來包括s的定義在內的所有**,結果如下:
% 這是一段可以列印自己的**
s = 's = %s%s%s;\nfprintf(s,char(39),s,char(39))';
fprintf(s,char(39),s,char(39))
將上述**儲存到乙個單獨的.m檔案中並執行,看看輸出結果是什麼。**中出現了char(39),是單引號的ascii碼,想想為什麼不直接用單引號而要用其ascii碼,這一點和dna與蛋白質相互成全的現象有關嗎?另外列印出的**中不包括注釋行,如何修改**能實現注釋行也能正確的列印?
作為對比,再試試下面簡潔而不正確的自列印**,看看它的問題在哪兒?
% 這是一段錯誤的可以列印自己的**
s = 's = ''%s'';\nfprintf(s,s)';
fprintf(s,s)
埃舍爾的繪畫,自指,以及羅素悖論
畫家埃舍爾擅長製作各種充滿空間悖論的圖畫,令人目眩神馳.我在很久以前就欣賞過埃舍爾的繪畫,但是那時候我的知識儲備並不充分,只是純粹地欣賞,並沒有很多想法.但是今天我偶然地又一次看到了埃舍爾的一幅畫,它立馬使我想到了集合論裡的悖論.這幅畫就是 不知讀者看懂這幅圖沒有.我把它解釋一下.如果我們認為下面那...
重拾指標(整理自乙個知乎上非常不錯的回答)
大一上學期的時候學的c語言,在那時侯接觸的指標相關知識。過去半年果然把指標忘乾淨了。今天利用剩餘時間把指標相關知識複習一遍,把指標搞通!2 操作符 對指標進行解引用的操作 記憶體可以簡化為一系列相連的無限長的單元,在單元中存放著數字,每個單元格為 1bite 1位元組 計算機的工作就是對這些單元格裡...