哥德爾不完備性定理與不可知論

從《關於費爾巴哈的提綱》談起

《關於費爾巴哈的提綱》只有短短十一條,卻道出了馬克思主義新惟物哲學的核心理念:實踐。它指出:物質決定意識,意識對物質有能動的反作用,實踐是改造人類世界的重要過程。全文圍繞「實踐」展開,尤其是第二條,直接否定了人類思維問題的理論性,從這一條出發我重新認真思考了我的世界觀。《關於費爾巴哈的提綱》第二條指出: 「人的思維是否具有客觀的真理性,這並不是一個理論的問題,而是一個實踐的問題。人應該在實踐中證明自己思維的真理性,及自己思維的現實性和力量。」

《關於費爾巴哈的提綱》中對人類思維採取了一種避重就輕的態度。我相信實踐是重要的,但實踐畢竟是有限的,不能解釋無法實踐的問題。《關於費爾巴哈的提綱》把真理的解釋全部交給了實踐,不免埋下了惟實踐論「存在即合理」,的種子。很多時候這種論斷引誘人們顛倒因果關係,把現實的結果解釋成結果存在的合理性。這是一個反饋的過程,使已經存在的東西地位更加鞏固,同時扼殺尚未佔據上風的東西,進而阻礙人們進一步實踐。實踐真的能解釋人類思維的真理性嗎?我對此表示深切的懷疑。

我的世界觀的變遷

關於人類思維的思考,直接決定了我的世界觀。從小到大,在我的腦中產生過許多種不同的哲學世界觀。小時候我自發地產生了「存在即認爲」的主觀惟心主義的世界觀。隨着視野的開闊,我接受到了惟物主義,一開始心存抵觸,但慢慢接受後進入了另一個極端。我一度認同以强硬決定論爲基礎的機械惟物主義,很大程度上是受到了牛頓物理學的影響,堅信「給我一個初值,我能算出整個宇宙」的信條。正如拉普拉斯所言: 「我們可以把宇宙現在的狀態視爲其過去的因以及未來的果。如果一個智能知道某一刻所有自然運動的力和所有自然構成的物件的位置,假如他也能夠對這些數據進行分析,那宇宙裏最大的物體到最小的粒子的運動都會包含在一條簡單公式中。對於這智者來說沒有事物會是含糊的,而未來只會像過去般出現在他面前。」

在這種世界觀的支撑下,我逐漸開始相信宿命論,消極地認爲自由意志是不存在的,人完全是命運操縱下的木偶。於是我開始悲觀厭世,墮入享樂主義,認爲既然人生的一切都是命中註定,完全不可改變,人生只能靠及時行樂來完成其價值。

「哥德爾不完備性定理」與不可知論

慢慢地我接觸到了現代物理學,學習了相對論、量子學、薛定諤方程、平行宇宙原理後,認識到了現實世界中有很多不可逆過程,原先的拉普拉斯信條變成了「拉普拉斯妖」,樸素的決定論已經不能解釋許多現象,於是我重新開始思考世界的本質。後來在我學習數學的過程中,我瞭解到在1931年,希爾伯特提出了形式化公理系統中所有命題都可以被證明或證僞的論斷,藉此試圖證明數學的實質不過是一個純粹由無意義符號表達的公理加上推導規則所構成的形式系統,而數學證明只不過是在這個系統内玩的文字遊戲而已。如果這個石破天驚的論斷是成立的,那麼數千年來人類對數學研究全部都是一紙空文,今後我們只要找到了完備的公理化體系,一切證明都可以省略了。只可惜,哥德爾的證明無情地擊碎了這一個夢想。哥德爾證明了「任何相容的形式體系不能用於證明它本身的相容性」的「哥德爾不完備性定理」。哥德爾不完備性定理指出,凡是強度足以證明基本算術公理的的系統,它都是不完備的,也就是說,我們永遠不能發現一個萬能的公理系統能夠證明一切真理,而不能證明任何謬誤,甚至如果一個公理系統可以用來證明它自身的相容性,那麼它是不相容的。這個定理和公理化的一階邏輯不謀而合,完美地解釋了「我說的這句話是假話」的自指悖論。

哥德爾不完備性定理給我帶來的衝擊可謂前所未有的巨大,因爲人類思維可以抽象爲一個公理系統,從形而上學到一切哲學,都是該公理系統的形式化推理結果。可怕的是,哥德爾不完備性定理指出這個公理系統不能證明它自己的完備性,這個系統中存在某些成立的定理,它是無法被這個公理系統證明出的。甚至如果假設人類思維是完備的,或者說,是真理,那麼可以推導出它的内部是存在不可解決的衝突的,於是又不是真理。如果非要證明人類思維的完備性不可,不得不依賴另一個比「人類思維」外延還要大的系統,用它來證明人類思維系統的完備性。但這個東西是没有意義的,因爲就算它存在,也是人類無法理解的,除非人類進化到「超人類」,但到那時候,「超人類」的思維的完備性依然是不能自證明的。所以說,必然有什麼東西是人類永遠無法理解的,它就算存在也没有了意義。這簡直給我當頭一棒,因爲它阻礙了人類對世界的認識——有些物質、規律是存在的、正確的,但是卻是人類永遠也不可知的。現在,我開始相信不可知論,儘管它有消極的一面,但它也鼓勵人們在人可知的範圍内繼續探索,因爲儘管人的思維存在不可知的東西,但人可知的東西也是無窮的。

令我失望的是,《關於費爾巴哈的提綱》所基於的原理卻是直觀而膚淺的。不過也難怪,畢竟任何思想都是時代的產物,馬克思主義也不能避免局限於當時人類對世界的認知。然而《關於費爾巴哈的提綱》所提倡的實踐主義在當今看來卻是無比重要的。我們必須不能停留在前人輝煌的成就中,尤其不能把任何東西當作真理,因爲真理是不可證的。通過形而上學的思考,我們所能認知的世界是有限的,正如公理系統不能自證明其完備性,恰恰賦予了數學證明的意義。也正是我們所可知的事物是有限的,恰恰指引我們只有通過實踐,纔能更加充份地認識世界。

後記

以上内容係我大學二年級課程「馬克思主義基本原理」作業之「《關於費爾巴哈的提綱》讀書報告」,全文貼出,未加删改。

實際上關於「哥德爾不完備性定理」有些地方我的理解還是不够深刻的,許多結論我也不是十分肯定,之所以敢貼出來是爲了讓大家批判的。「哥德爾不完備性定理」有兩條,第一條: 任何一個相容的數學形式化理論中,只要它強到足以蘊涵皮亞諾算術公理,就可以在其中構造在體系中既不能證明也不能否證的命題。

第二條是第一條的推論: 任何相容的形式體系不能用於證明它本身的相容性。

關於它的證明和詳細解釋,我强烈推薦一片文章「康托尔、哥德尔、图灵——永恒的金色对角线」。這個定理有不少誤解,例如:並不是所有的系統都是不完備的,哥德爾不完備性定理的前提是要求它能定義自然數和算術系統,像一階謂詞公理系統、歐氏幾何公理系統都是完備的。還有非形式化的系統也不在這個定理的約束範圍之内,例如經驗、實測。

除哥德爾不完備性定理之外,邏輯學還有一個相似的定理:「對於無窮階的形式語言,如果其元語言可證明命題是無矛盾的,那麼就不可能在元語言中構造出一個在約定意義下是充分的關於真理的定義。」這是一個真理可定義性的否證,也就是說「絕對真理」是不可定義的。此定理堪稱是數學對哲學影響最大的一個定理,它的出現使現代哲學不再去追求「絕對真理」,而是去探尋真理内在的一致性。所以說把馬克思主義奉爲圭臬是可笑的,不得不說它的許多觀點已經過時了。

至於人類思維是不是公理化系統,這個還存在爭議,我認爲人腦的運行機制實際上和計算機是一致的,也就是說人腦是圖靈等價的。人類思維可以抽象爲神經衝動、抑制的化學信號,對應集成電子中數字高低電平信號,所以人腦就是一個計算機,而圖靈機符合哥德爾不完備性定理的條件(因爲圖靈機完全可以定義自然數和算術公理),所以人類思維也符合。至於計算機爲什麽不能模擬人腦,有種觀點認爲是「量子力學不確定性和複雜非線性系統的混沌作用共同造成的」,但我覺得實際上就是計算機芯片的精密程度和效率問題,在遠不及人腦的前提下,怎麽能模擬人腦?在此基礎上從「哥德爾不完備性定理」推導出不可知論是很直觀的演繹,「不是廬山真面目,只緣身在此山中」不得不說是一個深刻的道理。

寫道這裏我想起科幻小說《三體》中三體人創造了一個「智子」將人類科學封死的故事,「哥德爾不完備性定理」的出現有力地支持了不可知論,這會不會阻斷了人類對世界的認識的可能性呢?我覺得不會,至少目前不會,因爲第一人類絕大多數領域的發展還遠遠没有抵達可知性所造成的瓶頸,第二非公理化體系並不受限制,例如實驗,我們完全可以依靠非形式化的手段以期「瞎貓碰着死耗子」。

關係數據庫的事務隔離、鎖定與並發控制

事務隔離(Isolation),指的是在數據庫系統中並發事務(Transaction)之間的可見性,以及如何相互影響的定義。事務隔離是ACID的四個特性(原子性、一致性、隔離性、持久性)之一。在ANSI/ISO的SQL標準中,定義了四個事務隔離級別,分別用於不同的場合。在傳統的數據庫系統的實現中,一般實現不同等級的隔離性的方法是使用鎖定(lock),根據具體需求可細分爲讀取鎖(read lock)寫入鎖(write lock)範圍鎖(range-locks)

可序列化

可序列化(SERIALIZABLE)最高的隔離級別。在此級別下,所有事務的完整性都被保留,這意味着所有的事務可以被序列化地執行。當只有兩個事務之前沒有任何衝突時,纔能並發地執行。

可重複讀取

可重複讀取(REPEATABLE READS)級別下,數據庫系統會在在整個事務期間保持所有讀取鎖寫入鎖,但相較於可序列化範圍鎖不會被管理,所以幻象讀取(phantom reads)可能會出現。

授權讀取

授權讀取(READ COMMITTED)級別下,數據庫系統在整個事務期間保持寫入鎖,但讀取鎖會在SELECT執行後立即釋放,所以不可重複讀取(non-repeatable reads)可能會出現。

未授權讀取

未授權讀取(READ UNCOMMITTED)最低的隔離級別。這個級別允許出現骯髒讀取(dirty reads)

下列的示例解釋了幻象讀取(phantom reads)不可重複讀取(non-repeatable reads)骯髒讀取(dirty reads)。數據在下表中定義:

users
id name age
1 Joe 20
2 Jill 25

骯髒讀取

當一個事務試圖讀取另一個還未提交的事務正在修改的某一行數據時,骯髒讀取(dirty reads)就會發生。

下列示例中,事務2正在修改某行,但還沒有提交。事務1試圖讀取這一行。如果事務2回滾了(rolls back)變更,或者後面又進行了其他的修改,那麼事務1就獲得了骯髒(dirty)的數據。

事務1 事務2
sql /* Query 1 */ SELECT * FROM users WHERE id = 1;
sql /* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; /* No commit here */
sql /* Query 1 */ SELECT * FROM users WHERE id = 1;
sql ROLLBACK; /* lock-based DIRTY READ */

不可重複讀取

當一個事務正在執行的時候,對某一行兩次讀取的結果不一致,則稱發生了不可重複讀取(non-repeatable reads)

以下示例中事務1讀取了某行,之後事務2立刻修改了這一行並提交了結果,事務1再讀取這一行的時候,結果就不一致了。

事務1 事務2
sql /* Query 1 */ SELECT * FROM users WHERE id = 1;
sql /* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; COMMIT; /* in multiversion concurrency control, or lock-based READ COMMITTED */
sql /* Query 1 */ SELECT * FROM users WHERE id = 1; COMMIT; /* lock-based REPEATABLE READ */

幻象讀取

幻象讀取(phantom reads)指的是兩次集合查詢之間返回了不一致的結果。以下示例展現了這一現象。

事務1 事務2
sql /* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30;
sql /* Query 2 */ INSERT INTO users VALUES ( 3, 'Bob', 27 ); COMMIT;
sql /* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30;

隔離級別與讀取現象

隔離級別 骯髒讀取 不可重複讀取 幻象讀取
未授權讀取 可能發生 可能發生 可能發生
授權讀取 - 可能發生 可能發生
可重複讀取 - - 可能發生
可序列化 - - -

隔離級別與鎖定

隔離級別 寫入鎖 讀取鎖 範圍鎖
未授權讀取 - - -
授權讀取 需要 - -
可重複讀取 需要 需要 -
可序列化 需要 需要 需要

樂觀鎖與多版本並發控制

在鎖定控制的數據庫系統中,死鎖(dead lock)指的是兩個以上的事務互相依賴等待,從而都被阻塞的現象。與多線程程序的設計不同,鎖定控制的數據庫中死鎖出現是很正常現象,而且是無法根本上避免的。當死鎖出現並且被數據庫系統檢測到時,所有死鎖的事務都會被駁回,用戶不得不根據需要進行重提交。然而死鎖不僅檢測代價是很高昂的,而且還會浪費大量資源,如果死鎖頻繁出現,會大大降低數據庫系統的並發性能。但我們不能爲了避免死鎖而降低隔離等級,而且有一點可以肯定的是,事務隔離級別越高,死鎖出現的概率就越大。

爲了提高性能,樂觀鎖(optimistic locking)機制被提出。與傳統的悲觀鎖(optimistic locking)「先取鎖再訪問」的保守策略不同,樂觀鎖相信事物之間的數據競爭(data race)的概率是比較小的,因此盡可能直接做下去,直到提交的時候纔去鎖定。但如果直接簡單這麼做,還是有可能會遇到不可預期的結果,例如兩個事務都讀取了數據庫的某一行,經過修改以後寫回數據庫,這時就遇到了問題。

一種可靠的樂觀鎖的實現是使用「多版本控制(multi-version control)」,即在每一行加一個version屬性。修改這一行時將version增加1,寫回數據庫要檢查當前的version值是否還是獲取時的那個值了。如果還是,說明期間沒有其他事務對其修改,直接提交即可,如果已經不是了,說明期間已經有別的事務修改了這一行,當前事務獲取的數據已經過期了,事務失敗。

在PostgreSQL及MySQL的InnoDB引擎的實現中,多版本控制的樂觀鎖是內置的(build-in),所以這個無需手動添加version字段。默認情況下,PostgreSQL/MySQL會盡可能使用樂觀鎖,除非遇到顯式的鎖定命令,如"select * from sometable for update"這樣的語句,纔會主動使用悲觀鎖。<o

參考資料

http://en.wikipedia.org/wiki/Isolation_(database_systems) http://www.blogjava.net/loocky/archive/2006/11/15/81138.html

PostgreSQL的硬傷

PostgreSQL是一個強大的開源關係型數據庫,有着不少吸引人的特性,例如支持Bitmap索引、部份索引、異步IO、更穩定的ACID支持等等,但不可否認的是它有一個巨大的硬傷:對開發者和管理員不夠友好。

對開發者來說

  • 官方文檔不詳,尤其是缺乏樣例,許多函數令人不知所云。
  • 名字縮寫不統一,PG和PQ都常見。libpq中所有函數以PQ開頭,數據類型卻是PGconn,PGresult。
  • 沒有C++接口,libpq++本來好好的,PostgreSQL 8.0以後突然不見了。
  • 函數庫過於精簡,封裝過少,缺乏必要的語法糖。
  • PQexec, PQexecParams, PQprepare, PQexecPrepared函數返回的PGresult *指針必須被PQclear釋放,否則會內存泄露。
  • PQexecParams, PQexecPrepared裏面的paramValues參數如果要設置爲int, float之類,必須手動調用htonl函數轉換網絡字節序。
  • 在Windows下用VC編譯PostgreSQL如噩夢般可怕,不僅要配置非常複雜的編譯環境,還可能會遇到各種各樣奇怪的問題。
  • 在Windows下調用libpq無法使用靜態鏈接。

對管理員來說

  • DB Shell和系統Shell耦合,不少時候會帶來意想不到的麻煩。
  • 同樣是文檔不詳,配置複雜而且無參考。
  • 缺乏強大的圖形界面管理工具,pgAdmin不敢恭維。

和MySQL比起來,PostgreSQL是典型的學院派的作品,看過代碼就會發現,PostgreSQL寫得比MySQL優美無數倍。然而PostgreSQL之所以在產業界不成氣候,很大程度上是因爲它缺乏必要的商業支持,以至於沒有很強技術水平的人不敢輕易嘗試它,只能被束之高閣了。一個軟件的好壞不僅僅是其本身的功能的好壞所能決定的,還要看它的包裝如何,以及在其周圍是否產生了一個良性發展的生態圈。