這個問題的緣起,是這樣的:
如何證明實數比自然數多?
這個問題沒有它看上去那么簡單。
比如說,自然數和偶數是否一樣多?和能被七整除的自然數是否一樣多?
看上去,偶數或者能被七整除的自然數,都是自然數這個大集合的一個子集,是它的一部分,所以應該是自然數更多,但實際情況卻不是這樣。
我們在比較兩個集合是否一樣多的時候,采用的是一種“找朋友”的原則。
即,如果存在一個一一映射,可以將A中的元素一個不落地映射到B,同時其逆可以將B中的元素一個不落地映射到A,那么我們就說A和B的元素一樣多。
如果不存在這樣的映射,那么就說A和B不是一樣多。
這樣的原則本身應該是沒問題的。
于是,自然數和偶數,通過一個簡單的乘2,就被一一映射到了一起,一個不多,一個不少,兩邊的每個元素都可以找到各自在對面的匹配,從而它們具有一樣多的元素。。。
我們并不能因為某一個映射不滿足這點,而認為所有的映射都無法滿足這點,這是這個原則里最有趣的部分。
也所以,自然數和整數也是一樣多的。
PS:這個找朋友的原則本身也可以帶來很多有意思的東西,比如說在《豪斯道夫-巴拿赫-塔斯基分球怪論》中所介紹的分球怪論,本身也是基于這個原則來做出“相等”的判斷的。
所以,誰說一個集合的子集的元素數量一定比這個集合少?
那么,實數和自然數的元素數量呢?
是否可能找到一個映射,將每一個自然數,都與一個實數對應起來,同時也將每一個實數,與一個自然數對應起來?
顯然,尋找這么一個函數是一件傷腦筋的事情,尤其是當你不知道這樣的函數是否存在的時候。
而更頭疼的,就是要證明這樣的函數是不存在的。
現在,讓我們假定這樣的函數是存在的。
這就是說,任意一個實數,都可以通過這么一個映射,映射到一個自然數上,即對于任意不同的實數r1和r2,存在函數f,使得n1=f(r1)、n2=f(r2)為自然熟,且n1不等于n2。
既然如此,那就是說我們可以為實數排一個序——雖然實數集本來就是良序集。
接下來,為了方便討論,我們假定現在考慮的是[0,1]這個范圍里的實數是否可以和自然數一樣多——因為整個實數集總可以通過映射和[0,1]內的實數對應起來的,比如f(x)=(0.5-x)/x/(x-1)
。
然后,我們將這些實數寫成二進制的形式,于是就有了一個列表,形如下面這個(下面輸入是打個比方):
實數 \ 小數位 | 1 | 2 | 3 | 4 | ... |
---|---|---|---|---|---|
n1 | 0 | 1 | 1 | 0 | ... |
n2 | 1 | 1 | 0 | 0 | ... |
n3 | 0 | 0 | 1 | 1 | ... |
... | ... | ... | ... | ... | ... |
假如實數可以和自然數一樣多,那么這樣的事情我們總是可以做到的,而且,這個表格的行數和列數也是相等的,因為第n列就是二進制下實數的小數部分第n位的數值(0或者1)。我們可以用ni_j
來表示實數ni
的第j位小數的數值。
接著,我們假定有這么一個數x
,它的第i位小數記為x_i
。
這個特殊的數具有這么一個特點:x_i = 1 - ni_i
。
它自然也是一個實數了,從而存在自然數y=f(x)。而且,很顯然,它也是在[0,1]這個區間內的,所以它就在表格的第y行,即x=ny
。
那么,問題來了,x_y是多少?
按照x的定義,x_y = 1 - ny_y
。同時,我們又有x=ny
。綜上所述,就有ny_y = 1 - ny_y
,即:ny_y = 0.5
。
但,喪勒格笛的,ny_y只能是0或者1啊。
這也就是說,如果x存在,它的第y位小數是1,那么按照x的定義,這一位小數應該是0;反之亦然。
x與其自身在第y位的問題上矛盾沖突了起來。
對于可以像自然數一樣一一羅列的數來說,上述表格總是可以建立起來的。
而小數部分也總是可以一位一位地寫出來。
因此,表格本身的存在沒有問題。
既然表格的存在沒有問題,那么對表格中數據的查詢也就不應該有問題,從而x是可以通過這個表格定義出來。
所以,在上述矛盾中,唯一的錯漏就只可能發生在“實數和自然數一樣多”這個假設上了。
這樣的做法可以構造出很多有趣的東西,比如下面這個——
自然數中是否存在不屬于自然數的數?
這個問題看上去非常地自我矛盾,但,卻未必不是一個大問題。
還記得一開始所提的“找朋友”的原則么?或者我們可以稍微正式一點地稱它為配對原則。
利用配對原則,我們“似乎”可以在[0,1]內的實數和自然數之間建立起一種一一對應的映射,從而來“證明”自然數和實數一樣多——而這一結論剛剛被我們給否定了。
這個映射是這樣的:
一個[0,1]內的實數可以在二進制下寫為0.10100011...這樣的形式,即r(i) = ∑ r(i,j) × 2 ^ (-j)
。
因此,我們可以將小數點后的0/1序列“反轉”一下,整個倒序后搬到小數點前,從而一個這樣的實數就可以對應到一個自然數:n(i) = ∑ r(i,j) × 2 ^ (j - 1)
。很容易證明這樣的映射是一一映射,而且看上去在像和源兩邊也都是“滿”的,從而我們就在自然數和[0,1]內實數之間建立起了一種配對關系,那么,按照配對原則,它們就應該是一樣多的——但,這點才被我們給否定。
問題出在哪里呢?是不是這個配對關系我們找的有問題?
好,讓我們換一個角度來看這個問題。
將所有的自然數排一個序,從而每個自然數n都對應一個序號i,序號自然也是自然數了,因此我們得到一個從自然數到自然數的映射:f(i)=n
。
然后,將任意自然數f(i)寫成二進制:f(i,j) = ∑ f(i,j) × 2 ^ (j - 1)
,f(i,j)要么是0,要么是1。j是自然數。
顯然,這里的f(i,j)就是上面我們所構造的那個表格。
f(i,j)也可以寫為n_j,其中n=f(i)。
于是,我們構造一個數x,它滿足:x_j = 1 - f(j,j)
。
也就是說,這個數x的第i位,和表格中第i個自然數的第i位,加在一起等于1,從而一個是0另一個就必然是1。
這樣的定義方式和之前上面一節中我們所作的其實是完全一樣的。
然后,我們發現,這個數x必然不能出現在這個表格中。
因為,如果數x在表格中,那么它自己必然有一個序號,即存在一個自然數y使得x=f(y),那么按照定義,x_y=f(y,y)=1-f(y,y)從而f(y,y)既不能是0也不能是1(這里第一個等號是x的第y位數值的定義,第二個等號是x的定義)。
但,這樣構造的數x本身卻看上去“非常像一個自然數”,因為按照定義,x的每一位要么是0要么是1,而且沒有小數部分,怎么能不是一個自然數呢?
但有些東西的確就不是自然數可以表達的。
讓我們來看一個實際的排序方式好了,比如:
對于自然數集,排序方式就是從1開始的偏序鏈,那么我們的表格現在就是:
自然數 \ 數位 | 1 | 2 | 3 | 4 | ... |
---|---|---|---|---|---|
1 | 1 | 0 | 0 | 0 | ... |
2 | 0 | 1 | 0 | 0 | ... |
3 | 1 | 1 | 0 | 0 | ... |
4 | 0 | 0 | 1 | 0 | ... |
... | ... | ... | ... | ... | ... |
我們發現,這個表格的對角線上的值,除了最開始兩位是1,別的情況下都是0,因此,按照定義,我們所定義的數x實際上就是∑i=2∞ 2i,即一個無窮大,從而是超出自然數范圍的——當然了,如果是在自然數范圍的,那么我們上面就得出悖論了。
而,超出自然數范圍的一個無窮大這樣的數,不免讓人想到了一個有趣的東西。
在自然數范圍之外的代表無窮大的數,以及由此而引出的整個數字集合,就是超現實數(Surreal Number)。
【不熟的朋友可以看這篇介紹:《睡前說:超現實數》】
超現實數中,存在一個比所有自然數都大的數:ω。
它可以被視為是無窮大——當然,它實際上比所有實數都大。
和非標準分析中引入的超實數(Hyperreal Number)相比,兩邊關于這個定義的無窮大的運算規則存在些許不同。
超現實數n=<a|b>的定義要求,用于定義n的左集a中沒有數字比n大,n也不比其右集b中任何數字大。而,ω的定義就是:ω=<{1,2,3,4...}|>,也就是說,ω的定義就是:比所有自然數都大。
而,最有趣的是,按照超現實數的加減乘除等運算法則的定義,我們可以計算ω-1和ω/2這樣的數,而且這樣的數字同時還是比任意自然數都大。
甚至于,我們可以構造諸如ωω、ωω(重冪,即ω的ω次ω冪,參見Knuth表示法)、ω↑ωω(Knuth表示法所表示的極度夸張的大數)這樣的龐然大數(但依然可以構造出更夸張更大的數)。
事實上,只要你有一個數n,那么<{n}|>就是比n更大的數。
超現實數中,最基本的數字是0,可以天然通過空集來構造:0=<|>。其左集和右集都是空集,不需要任何別的已知數就可以構造出來。
而后,<{0}|>就可以被定義為1,以此類推。
這樣的構造法和基數及序數構造自然數的方法很類似。
讓我們將通過n得到<{n}|>的過程成為“后繼”,那么只要一個對象可以通過“后繼”操作獲得另一個與之前已有的對象截然不同的新對象,那么我們就可以將這個對象序列與超現實數對應到一起。
那么,ω的存在其實就是說:存在兩個對象A和B,B比A大,但B無法通過A的任意有限或無限次后繼來獲得。
回到上一節的那個表格。
自然數當然可以通過“后繼”操作,從1開始整個地被找出來,從而一行行地寫入表格中。
但ω以及所有通過ω構造出的數(比如ω+1)則不能從1開始通過“后繼”操作來獲得——它是全然跳出這個序列的,雖然我們知道它比任何一個實數(自然也就包括了自然數)都大,從而原則上是在上述序列之“后”的。
也因此,ω不能寫在這張表格內,要寫下ω,就必須在這張表格之外另取一張表格——但此時,每一行的每個空格到底要寫什么,卻也是并不清楚的。
同樣的,在證明[0,1]內的實數不可數時,我們通過表格所構造出的矛盾中,那個奇特的數x本質上也是游離在自然數之外的,是比所有自然數都大的數。
事實上,實數集的勢為?1,而大家普遍相信?1=?1(連續統假設,但即便該假設不對,我們也有?1≥?1)。又有?1=2?0=2ω,所以實數的數量顯然是遠大于所有自然數的,但依然可以使用超現實數來表達。
你看,一旦引入超現實數,我們就發現那張無限乘無限的表格似乎不夠用了。
讓我們換一個問題來考慮。
我們現在有一個遍歷可枚舉語言L,它總共有l個字母。
然后,我們有一個接受L的通用圖靈機U,它接受兩個參數u和d,分別表示一個特殊功能的圖靈機,以及它所接受的參數數據。u和d都可以表達為字符串s,從而總可以表達為一個l進制數n,即:p(s)=n
。同樣的,自然數n也總可以對應到一個字符串s_n。
如果我們要在U上運行具有特定輸入d的特定圖靈機u,那么就可以表達為U(u,d)。
圖靈機本身當然也是一種數據,但數據卻未必都是圖靈機,因此如果一個d不是U上可運行的圖靈機,則可以視為U(d,*)直接停機,輸出為空。
這么一來,我們就可以建立如下表格:
- 將所有可能的字符串s根據p(s)排序,作為表格的每一行與每一列的指標;
- 表格第i行第j列的內容,為U(s_i,s_j)是否停機,停機則為true,不能停機則為false;
這樣一張表格其實就對應了一個停機判定機HaltCheck:
HaltCheck = (machine) ->
if (machine can halt) return true
else return false
在最傳統的證明停機判定機不存在的方法中,我們假定HaltCheck存在,于是構造下面這樣的圖靈機:
paradox = () ->
while (HaltCheck(paradox))
你看,如果paradox被HaltCheck判定為可以停機,則paradox會陷入while true的死循環,從而不會停機;而如果paradox被HaltCheck判定為不會停機,則paradox立刻跳出while循環立即停機。
這一自相矛盾的唯一解釋,就是HaltCheck不存在。
這個非常傳統的證明方法,也可以通過上面的表格來給出:
上述表格本身也可以視為一組數據(記為table),其對角線(記為diag),也就是第i行i列的數據,也構成一組數據。
再加上圖靈機本身也是一組數據,因此,每臺圖靈機都可以獲得自身所對應的序號,然后通過查詢上述表格的對角線數據,來獲知自身是否可能停機,從而構成悖論:
paradox = () ->
while (diag[p(paradox)])
這一自相矛盾指出:如果表格可以將自身作為元素(從而表格本身是圖靈機可接受的數據,從而也可以表示為字符串),或者任意字符串都可以被對應到一個自然數(從而p函數存在),那么這個表格就必然是不自洽的。
由于第二點看上去似乎完全沒有問題,那么有問題的就必然是第一條了,即使:
上述構造的表格不能作為數據存在,從而無法以字符串的形式給出。
但,這又怎么可能呢?我們不是正是以字符串的形式來寫下、構建這個表格的么?
這其實和實數的問題一樣:我們不也是以十進制小數的形式寫下一個[0,1]范圍內的實數的呢?可它依然不能對應到一個自然數。
因此,能以字符串的形式來寫下表格的一部分,并不表示表格本身可以對應到某個字符串。
換言之,表格本身是這張表格之外的東西,表格無法自指。
讓我們這么來想:
任意一個非空字符串,都可以通過另一個字符串通過以下兩種方式之一來獲得:
如果字符串的最后一個字母不是字母表的最后一個字母,則將該最后一個字母變換到一個它的后繼字母;如果最后一個字母是字母表最后一個字母,則在該字符串之后添加字母表上的第一個字母。
字母表的第一個字母就可以通過空字符串以第二條途徑獲得。
因此,我們可以說,任意非空字符串都可以表達為某一確定字符串的“后繼”,后繼方法就是上面這條方法。
因此,任意字符串都可以對應到一個自然數——也就是說,字符串不可能對應到ω,而ω因為不對應任何字符串。
在上述體系下,ω所對應的東西是字符串表達能力之外的東西,但它和字符串同屬一個體系——超現實數。
顯然,上面所構造的表格便是這么一種超出字符串表達能力的東西,它可以被視為對應到ω。
而,任何以表格為基礎構建出來的函數或者說“圖靈機”,都不對應任何字符串,從而不是可以可以作為數據接受的東西。
或者,我們可以這么來說:
判斷所有圖靈機是否可以停機的機器,是存在的,但它不是圖靈機。
停機判定機是超越圖靈機的東西,而所有用上了這個停機判定機的機器也都是超越圖靈機的東西,它們都無法被停機判定機判定,因為它們不是圖靈機。
是不是覺得我在耍賴?
我們可以進一步來問這么一個問題:是否存在判定這類超越圖靈機的機器是否會停機的東西?
比如說,我們將判定任意圖靈機是否會停機的機器成為超圖靈機(Hyper-Turing Machine),那么是否存在判定任意HTM是否停機的機器?
這就好比從ω到ωω,當然存在,只不過這類機器也不是HTM,而是超越HTM的東西,比如H2TM,二階超圖靈機。
我們總可以構造出更高階的超圖靈機,它們可以判定比它們低階的超圖靈機是否可以停機,但就是不能判定自身。甚至于,由于超現實數允許ω-1的存在,所以我們也可以構造HωTM這樣的東西,它的停機判定問題可以交由Hω+1TM處理。
這樣的東西,不也是極好的么?
腦洞似乎有點大了。
那么,HTM除了有HaltCheck,還有什么呢?
至少還應該有K:K氏復雜度計算機。
我們知道K氏復雜度是不可計算的,因為假如存在圖靈機K(s)可以計算任意字符串的K氏復雜度,那么我們可以構造這樣的圖靈機:
BadK = () ->
for (s in AllStrings)
if (K(s) > len(BadK) + len(K) + ln(len(s)) / ln(l) + C) then return s
其中C是一個固定常數。
這個圖靈機輸出一個字符串,該字符串的K氏復雜度比這臺圖靈機輸出該字符串所需的長度要長,但一旦能輸出這樣的字符串,那么它的K氏復雜度就應該等于這臺圖靈機輸出該字符串所需的長度,從而矛盾。
這個矛盾指出了K氏復雜度的不可計算性,但,函數K壓根就不是圖靈機呢?如果K壓根就不能在通用圖靈機內表達,K是超越圖靈機的某種機器,那么上述不可計算性的證明本身就沒有了用武之地,因為len(K)可能是一個ω級甚至更大的無窮大數——而,只要len(K)是無窮大,那么對于任意字符串來說,K氏復雜度的可計算性便能恢復。
事實上,不可計算性本身就表明這樣的機器在圖靈機范疇內是不存在的,從而如果圖靈機總能映射到一個自然數,那么這個不可計算的機器就必然是自然數以外的東西,比如,ω。
可,K本身是否真的具有這種“超越性”呢?
事實上,我們可以寫出如下的K:
K = (s) ->
max = len(s)
for (u in AllTuringMachines)
if (u() is s and len(u) < max)
max = len(u)
return max
看上去好像很簡單,對不對?
但這樣的寫法本身卻可能出現程序根本無法輸出結果的困境,而如果K不能停機,那么上面的BadK也就無意義了,K(s)這一步都無法完成計算,又談何比較大小呢?
而,K的可能不會停機,源自這段代碼中u()可能無法停機,從而一個真正可用的K是這樣的:
K = (s) ->
max = len(s)
for (u in AllTuringMachines)
if (CanHalt(u) and u() is s and len(u) < max)
max = len(u)
return max
你看,我們需要停機判定函數CanHalt(),這樣才能構造一個有效的K氏復雜度計算函數,從而K本身至少和CanHalt同屬超越圖靈機,而且應該同屬HTM。
而這也正是其不可計算性的意義:HTM不在TM集中。
好了,今天基本就說這些了。
當然,從超現實數之后開始的內容都是開腦洞的,并不是嚴格的論證,所以,我只能說開個腦洞發現,如果自然數和圖靈機是對應的,那么超現實數中就存在太多太多無法對應到圖靈機的東西了,而,停機判定、K氏復雜度這些東西,看上去仿佛就是如超現實數中的ω一般的存在。
至于這個想法對還是不對,呵呵,等啥時候不是睡前了,再來考慮吧。
今天的睡前嘮嗑就到這里,歐耶~~~