├── source ├── focus.md ├── people.md ├── science.md ├── video.md ├── article.md ├── discuss.md ├── message.md ├── preface.md ├── pdffooter.htm ├── linkToGodel.md ├── md0.js ├── Makefile ├── convert.exe ├── mimetex.exe ├── title.md ├── tex2img.bat ├── metadata.xml ├── header.htm ├── editor.md ├── footer.htm ├── license.md ├── reflink.md9 ├── discuss1.md ├── people2.md ├── article3.md ├── article3.md0 ├── home.md ├── video1.md ├── article4.md ├── info.md ├── people1.md ├── focus3.md0 ├── focus3.md ├── article1.md ├── focus4.md ├── focus4.md0 ├── focus1.md ├── message1.md ├── focus1.md0 ├── focus2.md0 ├── focus2.md ├── article2.md └── article6.md ├── book ├── A4.pdf ├── A4.epub ├── ipad.epub └── ipad.pdf ├── img ├── cover.jpg ├── VbBigAdd.JPG ├── VbBigMul.JPG ├── coverA4.png ├── missoni2dll.jpg ├── Bertrand_Russell.jpg ├── open2_pro_inc_en.jpg ├── open2_pro_lib1_en.jpg ├── open2_pro_lib2_en.jpg ├── ArduinoSensorGraph1.png ├── ArduinoSensorGraph10.png ├── ArduinoSensorGraph2.png ├── ArduinoSensorGraph3.png ├── ArduinoSensorGraph4.png ├── ArduinoSensorGraph5.png ├── ArduinoSensorGraph6.png ├── ArduinoSensorGraph7.png ├── ArduinoSensorGraph8.png └── ArduinoSensorGraph9.png ├── timg ├── 21fa3adc303f.jpg ├── 297f1fa5c654.jpg ├── 32ff223f4b92.jpg ├── 41d3eb0c5f8c.jpg ├── 514fcee4eee7.jpg ├── 602ca9944b4f.jpg ├── 622fa223aee6.jpg ├── 66f17dc26b90.jpg ├── 806819bdab01.jpg ├── 8668dd090624.jpg ├── 8b141f94d437.jpg ├── 9018c1f2e831.jpg ├── 940130743f3d.jpg ├── b4ffcfd79743.jpg ├── b6252c47c600.jpg ├── cae1b722691a.jpg ├── cfe6e9a974af.jpg ├── d01e95cc8ac8.jpg ├── d12b91ab3a7b.jpg ├── d37038cf1d92.jpg ├── d82c48c778d0.jpg ├── f01700400c28.jpg ├── f5389bc891c5.jpg ├── f8c868b454f3.jpg └── fa3ac188a800.jpg ├── README.md ├── htm ├── video.html ├── article.html ├── message.html ├── people.html ├── linkToGodel.html ├── preface.html ├── focus.html ├── science.html ├── discuss.html ├── title.html ├── editor.html ├── license.html ├── discuss1.html ├── article3.html ├── people2.html ├── video1.html ├── home.html ├── people1.html ├── info.html ├── focus3.html ├── article4.html ├── article1.html ├── focus4.html ├── focus1.html ├── message1.html └── article2.html └── css └── pmag.css /source/focus.md: -------------------------------------------------------------------------------- 1 | # 本期焦點 2 | -------------------------------------------------------------------------------- /source/people.md: -------------------------------------------------------------------------------- 1 | 2 | # 人物速寫 3 | -------------------------------------------------------------------------------- /source/science.md: -------------------------------------------------------------------------------- 1 | # 程式與科學 2 | -------------------------------------------------------------------------------- /source/video.md: -------------------------------------------------------------------------------- 1 | 2 | # 影音頻道 3 | -------------------------------------------------------------------------------- /source/article.md: -------------------------------------------------------------------------------- 1 | 2 | # 程式人文集 3 | -------------------------------------------------------------------------------- /source/discuss.md: -------------------------------------------------------------------------------- 1 | # 程式人討論區 2 | 3 | -------------------------------------------------------------------------------- /source/message.md: -------------------------------------------------------------------------------- 1 | 2 | # 程式人短訊 3 | -------------------------------------------------------------------------------- /source/preface.md: -------------------------------------------------------------------------------- 1 | # 前言 2 | 3 | 4 | -------------------------------------------------------------------------------- /source/pdffooter.htm: -------------------------------------------------------------------------------- 1 |
# 影音頻道
17 |# 程式人文集
17 |# 程式人短訊
17 |# 人物速寫
17 |在本期的「程式人雜誌」中,聚焦的主題是「邏輯推論的歷史」,包含理論與演進過程!
23 |邏輯推論在「離散數學」「計算理論」與「人工智慧」當中通常是課程的焦點之一,也是電腦的重要技術之一,理解邏輯理論與歷史可以讓程式人具備足夠的理論基礎,對修鍊「內功」是有些幫助的。
24 |當然、本期不只有「邏輯推論」的相關文章,還有更精彩的 Arduino, VB, OpenNI, 開放電腦計畫等內容,希望讀者會喜歡這期的「程式人雜誌」!
25 |---- (程式人雜誌編輯 - 陳鍾誠)
26 |本雜誌許多資料修改自維基百科,採用 創作共用:姓名標示、相同方式分享 授權,若您想要修改本書產生衍生著作時,至少應該遵守下列授權條件:
23 |另外、當本雜誌中有文章或素材並非採用 姓名標示、相同方式分享 時,將會在該文章或素材後面標示其授權,此時該文章將以該標示的方式授權釋出,請修改者注意這些授權標示,以避免產生侵權糾紛。
28 |例如有些文章可能不希望被作為「商業性使用」,此時就可能會採用創作共用:姓名標示、非商業性、相同方式分享 的授權,此時您就不應當將該文章用於商業用途上。
29 |最後、懇請勿移除公益捐贈的相關描述,以便讓愛心得以持續散播!
30 |機器語言,是由什麼語言寫的? -- https://www.facebook.com/groups/programmerMagazine/permalink/780470388636346/
是否有文章介紹如何做出一個程式語言?一個程式語言設計的極限是什麼? -- https://www.facebook.com/groups/programmerMagazine/permalink/780457841970934/
可能有人會好奇,計算機如何求得開根號數值,這裡提供個人所知的兩種方法。
23 |方法一: 長除式演算法,可直接筆算求平方根值。
24 |運用 (a + b)2- (2a + b) b = a2,初值 a = 0,反覆求 a 的後一位數值 b 。
25 |例 Square(152.276)
26 | 1 2. 3 4
27 | ------------ 列式時以小數點為基準,兩位兩位一組。
28 | / 1 52.27 60 (2a + b) b
29 | 1 = (2 x 0 + 1) x 1 , a = 0
30 | ------------
31 | 52
32 | 44 = (2 x 10 + 2) x 2 , a = 10
33 | ------------
34 | 8 27
35 | 7 29 = (2 x 120 + 3) x 3 , a = 120
36 | ------------
37 | 98 60
38 | 98 56 = (2 x 1230 + 4) x 4 , a = 1230
39 | ------------
40 | 6
41 | 42 |
方法二: 以 牛頓迭代法 計算求解
43 |X = A1/N,將 A 開 N 次方根,
44 |
45 | Xn+1 = [(N-1)Xn + A/XnN-1]/N ,(N>0)
46 |
47 | N = 2 時 ,A>1,1<Xn<A
48 | Xn+1 = [Xn + A/Xn]/2 ,(挑選適當的 Xn 初值可以快速收斂,只要計算兩三次就可得到正確數值)
49 | 其原理為,
50 |X = [X + A/X]/2
51 | 2X = X + A/X
52 | 2X2 = X2 + A
53 | X2 = A
54 | X = A1/2
55 | 這方法是我從 Engineering Formulas 這本書學到的,此書為 Reiner Gieck, Kurt Gieck 合著 McGraw-Hill 出版 ISBN 9780070234550,它是我在公司文管中心發現的寶藏。
56 |在網際網路尚未發達前,這類工具書對工程師是非常重要的,尤其需要常常查工程或數學公式很有用。
57 |(本文來自「研發養成所」 Bridan 的網誌,原文網址為 http://4rdp.blogspot.tw/2008/04/blog-post_9406.html ,由陳鍾誠編輯後納入程式人雜誌)
58 |從前我總認為,那些在教科書中提到的偉大數學家,他們必然是備受推崇,令人尊敬的。因此他們應該都是屬於「人生勝利組」的那群人,但是後來,我發現我錯了!
23 |圖靈 (Alan Turing) 應該是「電腦領域」最為人所之的偉大數學家了吧,但是如果你知道圖靈怎麼死的,那應該會覺得很驚訝且難過,因為圖靈在 1952 年由於同性戀而受審,結果在兩年後吃了一顆塗有「氰化物」的蘋果死了。
24 |而物理學之父「牛頓」應該算是人生較為順利的了,他還創建了「微積分」這門重要的學問,而且曾經擔任英國皇家鑄幣局局長,擔任局長讓他的薪水大增,並且因為表現優秀,還被英國女皇授予「艾薩克爵士」的貴族稱號,這應該算是人生勝利組了吧?
25 |但是在牛頓的生命中,除了關心物理與數學之外,他其實很著迷於「鍊金術」這門學問,他在鑄幣局局長任內,將黃金價格定為「每金衡盎司等於三英鎊十七先令10.5便士,讓英鎊成為金本位貨幣。
26 |但也因為迷戀黃金的緣故,讓牛頓用個人儲蓄大舉投資「南海公司」,結果到了 1720 年暴發了「南海泡沫」事件,南海公司的股價從 1,000英鎊狂跌到 190 英磅以下,結果牛頓損失了超過兩萬英鎊的美元 (這相當於牛頓十幾年的鑄幣局長薪水),於是他說了下列這句經典名言:
27 |28 |31 |我能精準計算天體的運行規律,卻無法預測人類行為的瘋狂。
29 |I can calculate the motions of heavenly bodies, but not the madness of people.
30 |
而且、在牛頓死後,他的身體內發現了大量水銀,這很可能是研究鍊金術導致汞中毒,因此也讓牛頓晚年的一些怪異行徑得到了解釋。
32 |而「哥德爾」這位二十世紀的傳奇數學家,他的人生也同樣並不精彩,而且可以說是充滿悲劇的!
33 |「哥德爾」自幼多病,而且從小就患了強迫症,後來還得了憂鬱症,並且自殺過幾次。
34 |在哥德爾的晚年,他疑神疑鬼,由於他認為別人給的飯菜有毒,因此拒絕吃其他人給的飯菜,只相信他太太 Adele Nimbursky 給的,但是後來他的太太也病倒了,結果最後哥德爾死於營養不良與進食不足,死時體重只有 65 磅,享年 72 歲。
35 |【本文由陳鍾誠取材並修改自 維基百科,採用創作共用的 姓名標示、相同方式分享 授權】
42 |Lua 的語法很簡單,執行環境也很簡單,如果您用的是 Linux,應該從 Lua 官網上下載 建置一下就可以了,以下是官網所提供的建置方法:
23 |curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz
24 | tar zxf lua-5.2.3.tar.gz
25 | cd lua-5.2.3
26 | make linux test
27 | 如果您用 MS. Windows ,那麼就可以安裝 Lua for Windows,以下是其網址:
28 |下載安裝後,您會發現在「開始/所有程式」裏有個 Lua 的資料夾,裏面有「iLua, Lua Command Line, Lua Examples, QuickLuaTour」等項目,建議您看看「QuickLuaTour」,它會帶領你快速的熟悉 Lua 的語法與範例。
32 |接著您可以直接起動命令列,然後用任何的編輯器,像是「Notepad++」等,開始寫一些簡單的程式,然後直接用 lua <程式名稱> 去執行您的程式即可。以下是筆者執行幾個 Lua 程式的過程:
D:\Dropbox\Public\pmag\201402\code>lua hello.lua
34 | Hello World!
35 |
36 | D:\Dropbox\Public\pmag\201402\code>lua fact.lua
37 | factorial(5)=120
38 |
39 | D:\Dropbox\Public\pmag\201402\code>lua obj.lua
40 | 10,20
41 | 30,40
42 | 50,60
43 |
44 | D:\Dropbox\Public\pmag\201402\code>lua obj.lua
45 | point(10,20)
46 | point(30,40)
47 | point(50,60)
48 | 您可以以看看下列 Lua 的影片,以便瞭解 Lua 的程式寫法:
49 || 影片 | 53 |連結 | 54 |
|---|---|
| Lua Tutorial #1: Introduction and Setup | 59 |http://youtu.be/dHURyRLMOK0 | 60 |
| Lua Tutorial #2: Hello World | 63 |http://youtu.be/aSxoOCn6Y4E | 64 |
| Lua Tutorial #3: Variables and User Input | 67 |http://youtu.be/ClThmOGuMi4 | 68 |
| Lua Tutorial #4: Basic Mathematics | 71 |http://youtu.be/jQ40M1DObl4 | 72 |
| Lua Tutorial #5: If and Else | 75 |http://youtu.be/vlJftHgeByg | 76 |
當然、多寫多看,應該是學習程式的不二法門。學程式與學習游泳一樣,只有下水開始扭動身體,才有機會真正學會游泳,也只有真正開始上機寫程式,才有可能真正學會寫程式。對於 Lua 、當然也是如此!
80 |程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌。
18 || 出刊年月 | 23 |epub | 24 |ipad:PDF | 25 |A4:PDF | 26 |單頁 HTM | 27 |原始碼 | 28 |全部下載 | 29 |
|---|---|---|---|---|---|---|
| 2014年2月 | 34 |epub | 35 |ipad.pdf | 36 |A4.pdf | 37 |pmag.html | 38 |code.zip | 39 |github | 40 |
程式人雜誌預定於每個月 1 日出刊,您可以從下列網址取得程式人雜誌的所有內容 (包含當月最新出刊的雜誌)。
74 | 77 |竭誠歡迎程式人投稿,或者成為本雜誌的專欄作家,現在就可以加入 程式人雜誌社團 一同共襄盛舉。
79 |本雜誌編輯為「陳鍾誠 (@ccckmit)」,若要聯絡編輯,請寄信到 。
85 |羅素出生於1872年的一個貴族家庭,當時大英帝國正值巔峰,逝於1970年,此時英國經歷過兩次世界大戰,其帝國已經沒落。
23 |羅素的家族相當顯赫,祖父約翰·羅素勛爵在1840年代曾兩次出任英國首相,是「輝格黨」的核心成員。羅素的父母分別在他兩歲與四歲時過世,因此羅素是擔任兩次首相的祖父所扶養長大的。
24 |
圖、伯特蘭·羅素 (Bertrand Arthur William Russell)
26 |在婚姻生活方面,羅素於 17 歲時便與美國籍的 Alys Pearsall Smith 墜入情網,22 歲時兩人結婚,但由於羅素有婚外情的關係,所以在 39 歲時離婚了。49 歲時又娶了 Dora Black 並育有兩個孩子,55 歲時夫妻兩人一起創立了「皮肯·希爾教育實驗學校」(Beacon Hill School),後來羅素因反戰活動而被劍橋大學開除。接著羅素又有了婚外情,於是與 Dora Black 又離婚了。64 歲時羅素與牛津大學學生 Patricia Spence 結婚。72 歲時羅素回到英國,並重新執教於劍橋大學三一學院。80 歲時羅素再度離婚,並與一名美國的英語教授結婚。88 歲時羅素出版了自傳,並曾參與了甘迺迪遇刺事件的調查。後來羅素活到了 98 歲高齡,於1970年去世。
28 |在學術方面,羅素 18 歲時進入劍橋大學三一學院學習哲學、邏輯學和數學。他起初對數學感興趣,並認為數學是邏輯學的一部分,於是試圖用邏輯建構整個數學體系,1901 年他發現了「理髮師悖論」,並於 1910 年與老師懷海德一起發表了《數學原理》這部巨著。
29 |所謂的「羅素理髮師悖論」,是有「一位理髮師,宣稱要為所有不自己理頭髮的人理髮,但是不為任何自己理頭髮的人理髮」。這句話是有問題的,因為該理髮師會在要不要為自己理頭髮這件事情上產生矛盾。
30 |羅素發現的悖論,也讓他開始思考邏輯學的問題,後來他與「摩爾、弗雷格、維根斯坦和懷特海」等人創立了「邏輯分析哲學」,企圖將哲學問題轉化為邏輯符號,讓哲學家們就能夠更容易地推導出結果,而不會被不夠嚴謹的語言所誤導。
31 |他們企圖建構出能夠解釋世界本質的理想邏輯語言。但是「哥德爾」所證明的「不完備定理」卻毀了這個想法,
32 |1920年羅素訪問俄國和中國,並在北京與杜威同時期進行一年的講學,在長沙時期,青年毛澤東曾經擔任記錄員。他回到歐洲後解了一本《中國問題》,孫中山並稱羅素為「唯一真正理解中國的西方人」。
33 |徐志摩年輕時曾經到英國劍橋想拜羅素為師,但那時羅素已經離開劍橋大學,否則徐志摩很可能會成為羅素的學生。
34 |羅素的著作很多,列舉如下:
35 |《幾何學基礎》(1897年)
36 | 《數學原理》(懷特海合著,1910, 1912, 1913年)
37 | 《哲學論文集》(1910年)
38 | 《哲學問題》(1912年)
39 | 《社會重建原則》(1916年)
40 | 《自由之路》(1918年)
41 | 《中國問題》(1922年)
42 | 《工業文明的前景》(合著,1923年)
43 | 《科學的未來》(1924年)
44 | 《相對論入門》(1925年)
45 | 《論兒童教育》(1926)
46 | 《物之分析》(The Analysis of Matter,1927年)
47 | 《我為什麼不是基督徒》(1927年)
48 | 《心靈分析》(1927年)
49 | 《懷疑論》(1928年)
50 | 《婚姻與道德》(1929年),(1950年,羅素因此書而獲得諾貝爾文學獎)
51 | 《幸福的贏得》(1930年)
52 | 《哲學與現代世界》(1932年)
53 | 《自由與組織》(1934年)
54 | 《宗教與科學》(1935年)
55 | 《權力:一種新的社會分析》(1938年)
56 | 《西方哲學史》(1945年)
57 | 《權威與個人》(1949年)
58 | 《名人的惡夢》(1954年)
59 | 《羅素回憶錄》(1956年)
60 | 《我的哲學發展》(1959年)
61 | 《人類有將來嗎》(1962年)
62 | 《文明之路》
63 | 《人類為什麼戰鬥》
64 | 羅素於 67 歲時搬到美國,但卻因為《婚姻與道德》這部作品而被法官「麥吉漢」認為有道德問題,取消了「紐約城市大學聘任羅素為哲學教授的任命」一案,但是到了 78 歲的時候,羅素卻又因這部作品而得到「諾貝爾文學獎」,成為第一個非文學領域作家得到諾貝爾文學獎的人。
65 |筆者對羅素為何會以《婚姻與道德》獲得「諾貝爾文學獎」這件事較有興趣,於是上網查了一下這本書,其內容如下:
66 |第一章 為什麼需要性道德
67 | 第二章 無父之鄉
68 | 第三章 父親的勢力範圍
69 | 第四章 生殖器崇拜,制慾主義,與罪惡
70 | 第五章 基督教的道德
71 | 第六章 浪漫的愛
72 | 第七章 婦女的解放
73 | 第八章 性知識的禁忌
74 | 第九章 愛在人生中的地位
75 | 第十章 婚姻
76 | 第十一章 娼妓
77 | 第十二章 試婚制
78 | 第十三章 現在的家庭
79 | 第十四章 家庭對個人心理的影響
80 | 第十五章 家庭與國家
81 | 第十六章 離婚
82 | 第十七章 人口
83 | 第十八章 優生學
84 | 第十九章 性與個人的福利
85 | 第二十章 性在人類價值中的地位
86 | 第二十一章 結論
87 | 從這本書的目錄中,我想大家應該也可以理解為何羅素結婚、外遇與離婚的次數那麼的頻繁了,以及為何會遭受到那麼多的爭議,我想這應該也與他的學術思想有關吧!
88 |【本文由陳鍾誠取材並修改自 維基百科,採用創作共用的 姓名標示、相同方式分享 授權】
94 |程式人雜誌是一個結合「開放原始碼與公益捐款活動」的雜誌,簡稱「開放公益雜誌」。開放公益雜誌本著「讀書做善事、寫書做公益」的精神,我們非常歡迎程式人認養專欄、或者捐出您的網誌,如果您願意成為本雜誌的專欄作家,請加入 程式人雜誌社團 一同共襄盛舉。
29 |我們透過發行這本雜誌,希望讓大家可以讀到想讀的書,學到想學的技術,同時也讓寫作的朋友的作品能產生良好價值 – 那就是讓讀者根據雜誌的價值捐款給慈善團體。 讀雜誌做公益也不需要有壓力,您不需要每讀一本就急著去捐款,您可以讀了十本再捐,或者使用固定的月捐款方式,當成是雜誌訂閱費,或者是季捐款、一年捐一次等都 OK ! 甚至是單純當個讀者我們也都很歡迎!
30 |本雜誌每期參考價:NT 50 元,如果您喜歡本雜誌,請將書款捐贈公益團體。例如可捐贈給「羅慧夫顱顏基金會 彰化銀行(009) 帳號:5234-01-41778-800」。(若匯款要加註可用「程式人雜誌」五個字)
31 |給專欄寫作者: 做公益不需要有壓力。如果您願意撰寫專欄,您可以輕鬆的寫,如果當月的稿件出不來,我們會安排其他稿件上場。
33 |給網誌捐贈者: 如果您沒時間寫專欄或投稿,沒關係,只要將您的網誌以 [創作共用的「姓名標示、非商業性、相同方式分享」授權] 並通知我們,我們會自動從中選取需要的文章進行編輯,放入適當的雜誌當中出刊。
34 |給文章投稿者: 程式人雜誌非常歡迎您加入作者的行列,如果您想撰寫任何文章或投稿,請用 markdown 或 LibreOffice 編輯好您的稿件,並於每個月 25 日前投稿到程式人雜誌社團 的檔案區,我們會盡可能將稿件編入隔月1號出版程式人雜誌當中,也歡迎您到社團中與我們一同討論。
35 |如果您要投稿給程式人雜誌,我們最希望的格式是採用 markdown 的格式撰寫,然後將所有檔按壓縮為 zip 上傳到社團檔案區給我們, 如您想學習 markdown 的撰寫出版方式,可以參考 看影片學 markdown 編輯出版流程 一文。
36 |如果您無法採用 markdown 的方式撰寫,也可以直接給我們您的稿件,像是 MS. Word 的 doc 檔或 LibreOffice 的 odt 檔都可以,我們 會將這些稿件改寫為 markdown 之後編入雜誌當中。
37 |您也可以擔任程式人雜誌的編輯,甚至創造一個全新的公益雜誌,我們誠摯的邀請您加入「開放公益出版」的行列,如果您想擔任編輯或創造新雜誌,也歡迎到 程式人雜誌社團 來與我們討論相關事宜。
39 || 公益團體 | 48 |聯絡資訊 | 49 |服務對象 | 50 |捐款帳號 | 51 |
|---|---|---|---|
| 財團法人羅慧夫顱顏基金會 | 56 |http://www.nncf.org/ 02-27190408分機 232 |
62 | 顱顏患者 (如唇顎裂、小耳症或其他罕見顱顏缺陷) | 63 |銀行:009彰化銀行民生分行 帳號:5234-01-41778-800 |
64 |
| 社團法人台灣省兒童少年成長協會 | 67 |http://www.cyga.org/ 04-23058005 |
73 | 單親、隔代教養.弱勢及一般家庭之兒童青少年 | 74 |銀行:新光銀行 戶名:台灣省兒童少年成長協會 帳號:103-0912-10-000212-0 |
75 |
在 布林邏輯與推論系統 -- 何謂嚴格的數學證明? 這篇文章中,我們介紹了「布林邏輯」(Boolean Logic) 這種簡單的推論系統,這種邏輯系統又稱為「命題邏輯」(Propositional Logic)。
24 |在本文中,我們將介紹一個能力較強大的邏輯系統,稱為「一階邏輯」(First Order Logic) 系統,這是一種「謂詞邏輯」(Predicate Logic) 的實例,然後再說明這種邏輯系統中的一個重要定理,稱為「哥德爾完備定理」。
25 |在布林邏輯中,只有用來代表真假值的簡單變數,像是 A, B, C, X, Y, Z .... 等,所以邏輯算式看來通常如下:
27 |這種命題邏輯裏沒有函數的概念,只有簡單的命題 (Proposition),因此才稱為命題邏輯。
33 |而在謂詞邏輯裏,則有「布林函數」的概念,因此其表達能力較強,例如以下是一些謂詞邏輯的範例。
34 |您可以看到在這種邏輯系統裏,有「布林變數」的概念 (像是 x, y, z 等等),也有函數的概念,像是 Parent(), Father(), Ancestor() 等等。
41 |在上述這種謂詞邏輯系統中,如果我們加上
(對於所有) 或
(存在) 這兩個變數限定符號,而其中的謂詞不可以是變項,而必須要是常項,這種邏輯就稱為一階邏輯。
; 人都是會死的。
; 蘇格拉底是人。
; 蘇格拉底會死。當然、規則可以更複雜,像是以下這個範例,就說明了「存在一些人可以永遠被欺騙」。
49 |
如果一階邏輯中的謂詞,放寬成可以是變項的話 (這些變項可以加上
與
等符號的約束),那就變成了二階邏輯,以下是一些二階邏輯的規則範例。


; 數學歸納法。在邏輯系統中,所謂的「一致性」,是指公理系統本身不會具有矛盾的現象。假如我們用 A 代表該公理系統,那麼 A 具有一致性就是 A 不可能導出兩個矛盾的結論,也就是 A => P 與 A=> -P 不可能同時成立。
61 |哥德爾於 1929 年證明了「哥德爾完備定理」(Gödel's Complete Theorem),這個定理較簡化的陳述形式如下:
63 |以下是哥德爾完備定理的兩種陳述形式,詳細的證明方法請參考 Wikipedia:Original proof of Gödel's completeness theorem。
67 |Theorem 1. Every formula valid in all structures is provable.
Theorem 2. Every formula φ is either refutable or satisfiable in some structure
「哥德爾完備性定理」似乎得到了一個很正向的結果,讓人對邏輯系統的能力擁有了一定的信心。
73 |但是、當哥德爾進一步擴展這個邏輯系統,加入了「自然數的加法與乘法」等運算之後,卻發現了一個令人沮喪的結果,那就是「包含自然數加法與乘法的一階邏輯系統,如果不是不一致的,那就肯定是不完備的,不可能兩者都成立」。
74 |這將引出我們的下一篇文章, 從程式人的角度證明「哥德爾不完備定理」。
75 |【本文由陳鍾誠取材並修改自 維基百科,採用創作共用的 姓名標示、相同方式分享 授權】
87 |Private Sub Command1_Click()
46 | Text3 = ""
47 | ReDim TempArray(999)
48 |
49 | K = 0
50 |
51 | For i = Len(Text1) To 1 Step -1
52 | TempArray(K) = Mid(Text1, i, 1)
53 | K = K + 1
54 | Next i
55 |
56 | K = 0
57 |
58 | For i = Len(Text2) To 1 Step -1
59 | Temp = Val(TempArray(K)) + Val(Mid(Text2, i, 1))
60 | TempArray(K) = Temp Mod 10
61 | K = K + 1
62 | TempArray(K) = Val(TempArray(K)) + Val(Temp \ 10)
63 | Next i
64 |
65 | For i = 0 To UBound(TempArray)
66 | If Val(TempArray(i)) > 9 Then
67 | Temp = TempArray(i)
68 | TempArray(K) = Temp Mod 10
69 | K = K + 1
70 | TempArray(K) = Val(TempArray(K)) + Val(Temp \ 10)
71 | End If
72 | Next i
73 |
74 | For i = UBound(TempArray) To 0 Step -1
75 | Text3 = Text3 & TempArray(i)
76 | Next i
77 |
78 | Do Until Val(Mid(Text3, 1, 1)) <> 0
79 | Text3 = Mid(Text3, 2)
80 | Loop
81 | End Sub
82 | Private Sub Command1_Click()
90 | Text3 = ""
91 | ReDim TempArray(999)
92 |
93 | K = 0
94 |
95 | For i = Len(Text1) To 1 Step -1
96 | NowIndex = K
97 | For j = Len(Text2) To 1 Step -1
98 | Temp = TempArray(NowIndex) + Mid(Text1, i, 1) * Mid(Text2, j, 1)
99 | TempArray(NowIndex + 1) = Temp \ 10 + TempArray(NowIndex + 1)
100 | TempArray(NowIndex) = Temp Mod 10
101 | NowIndex = NowIndex + 1
102 | Next j
103 | K = K + 1
104 | Next i
105 |
106 | For i = UBound(TempArray) To 0 Step -1
107 | Text3 = Text3 & TempArray(i)
108 | Next i
109 |
110 | Do Until Val(Mid(Text3, 1, 1)) <> 0
111 | Text3 = Mid(Text3, 2)
112 | Loop
113 | End Sub
114 | 【本文作者為「廖憲得」,原文網址為: http://www.dotblogs.com.tw/0xde/archive/2013/11/13/129111.aspx 與 http://www.dotblogs.com.tw/0xde/archive/2013/11/13/129101.aspx ,由陳鍾誠編輯後納入本雜誌】
118 |這篇是寫給 amarino 初學者看的,目的是教導你如何執行 Amarino 的 SensorGraph 範例程式。
23 |到 http://www.amarino-toolkit.net/ 下載下列 App 並安裝到 Android 手機上:
32 |SensorGraph (這是 buildcircuit.com 的版本)
如果你電腦上還沒有 Arduino IDE,請先到 http://arduino.cc/en/Main/Software 下載軟體,下載後解壓縮即可。
39 |接著下載 MeetAndroid Library ,把 MeetAndroid 解到 Arduino IDE 安裝目錄下的 libraries 資料夾下。
40 |重新啟動 Arduino IDE,在 Sketch > Import Library 底下應該會看到 MeetAndroid,如下圖:
41 |
43 | 參考下圖,把可變電阻中間腳位接到 Analog Input pin 5,剩下的兩支腳位,一支接到 5V,另外一支接到 GND:
46 |
48 | 如果你使用的是光敏電阻,電路的接法請參考 這篇 。
50 |點 File > Examples > MeetAndroid > SensorGraph Tutorial 打開 SensorGraph Tutorial 程式:
52 |
54 | 程式所用的 baud rate 預設是 57600 bps,如果你的藍芽模組不是 57600 bps,請做適當的調整:
56 |
58 | 然後把程式上傳到 Arduino 板子上。
60 |我用的是 廣州匯承信息科技 的 HC-0x 系列藍芽模組,下圖是 HC-0x 藍芽模組的外觀:
62 |
▲ HC-0x 藍芽模組 (圖左:正面圖,圖右:背面圖)
64 |這個藍芽模組連接方法很簡單,照下表把 Arduino 和藍芽模組連接起來就好:
66 || Arduino | 70 |藍芽模組 | 71 |備註 | 72 |
|---|---|---|
| 5V | 77 |VCC | 78 |注意電源不可接錯 | 79 |
| GND | 82 |GND | 83 |注意電源不可接錯 | 84 |
| RXD | 87 |TXD | 88 |89 | |
| TXD | 92 |RXD | 93 |94 | |
99 | 連接的時候有兩點要注意:第一是電源千萬不可接錯,不然可能會把藍芽模組燒壞,第二是 Arduino 的 RXD 要接藍芽模組的 TXD,而 Arduino 的 TXD 要接藍芽模組的 RXD。
101 |通電之後,藍芽模組上的 LED 會一直閃爍:
102 |
104 | 首先,先利用 Amarino 搜尋藍芽設備,找到設備後,將藍芽設備的 MAC Address 抄起來( 記得不要在 Amarino 設定任何 Event! ):
107 |
109 | 打開 SensorGraph App,輸入剛剛抄下來的 MAC Address,然後按下【Set Device ID】:
111 |
113 | 如果一切順利,Android 手機就會跟 Arduino 建立連線,並且呈現如下圖的畫面。其中,畫面上方會繒製感測讀值的圖形,而下方則顯示其即時數值(至於最底下的 SeekBar,因為我們沒有用到,所以可以忽略不管):
115 |
117 | 【本文作者為馬萬圳,原文網址為: http://coopermaa2nd.blogspot.tw/2012/06/sensorgraph.html ,由陳鍾誠編輯後納入本雜誌】
129 || NOT | AND | OR |
| 64 | 65 | | x | !x | 66 | |------|-----| 67 | | 0 | 1 | 68 | | 1 | 0 | 69 | 70 | | 71 | 72 | | x | y | x&y | 73 | |---|---|-----| 74 | | 0 | 0 | 0 | 75 | | 0 | 1 | 0 | 76 | | 1 | 0 | 0 | 77 | | 1 | 1 | 1 | 78 | 79 | | 80 | 81 | 82 | | x | y | x`|`y | 83 | |---|---|-------| 84 | | 0 | 0 | 0 | 85 | | 0 | 1 | 1 | 86 | | 1 | 0 | 1 | 87 | | 1 | 1 | 1 | 88 | 89 | | 90 |
| NOT | AND | OR |
| 64 | 65 | | x | !x | 66 | |------|-----| 67 | | 0 | 1 | 68 | | 1 | 0 | 69 | 70 | | 71 | 72 | | x | y | x&y | 73 | |---|---|-----| 74 | | 0 | 0 | 0 | 75 | | 0 | 1 | 0 | 76 | | 1 | 0 | 0 | 77 | | 1 | 1 | 1 | 78 | 79 | | 80 | 81 | 82 | | x | y | x`|`y | 83 | |---|---|-------| 84 | | 0 | 0 | 0 | 85 | | 0 | 1 | 1 | 86 | | 1 | 0 | 1 | 87 | | 1 | 1 | 1 | 88 | 89 | | 90 |
1900 年,德國的偉大數學家希爾伯特 (Hilbert),提出了著名的 23 個數學問題,其中的第二個問題如下所示。
42 |43 |45 |證明算術公理系統的無矛盾性 The compatibility of the arithmetical axioms.
44 |
在上述問題中,希爾伯特的意思是要如何證明算術公理系統的 Compatibility,Compatibility 這個詞意謂著必須具有「一致性」 (Consistency) 與「完備性」(Completeness)。
46 |為此、許多數學家花費了一輩子的心力,企圖建構出一個「既一致又完備」的邏輯推論系統,像是「羅素與懷德海」就寫了一本「數學原理」,希望為數學建構出非常扎實的「公理系統」。
47 |結果、這樣的企圖心被哥德爾的一個定理給毀了,那個定理就是「哥德爾不完備定理」。
48 |要瞭解「哥德爾不完備定理」之前,最好先瞭解一下「邏輯悖論」這個概念。
49 |當初、羅素在努力的建構數學原理時,卻發現了數學中存在著邏輯悖論,於是發出感嘆:「當我所建構的科學大廈即將完工之時,卻發現它的地基已經動搖了...」。
50 |羅素的話,其原文是德文,據說翻譯成英文之後意義如下:
51 |52 |54 |Hardly anything more unwelcome can befall a scientific writer than that one of the foundations of his edifice be shaken after the work is finished
53 |
結果,在 1950年,羅素穫得諾貝爾文學獎 (天啊!羅素不是數學家嗎!但是看他上面那句話的文筆,我很能體會他得諾貝爾文學獎的原因了 ...)
55 |理髮師悖論可以描述如下:
57 |58 |61 |在某一個小世界裏,有一個理髮師,他宣稱要為該世界中所有不自己理頭髮的人理髮,但是不為任何一個自己理頭髮的人理髮!
59 |請問、他做得到嗎?
60 |
您覺得呢?
62 |這個問題的答案是,他絕對做不到,原因出在他自己身上:
63 |64 |67 |如果他「為」自己理頭髮,那麼他就為「一個自己理頭髮的人理髮」,違反了後面的宣言。
65 |如果他「不為」自己理頭髮,那麼他就沒有為「該世界中 "所有" 不自己理頭髮的人理髮」,因此違反了前面的宣言。
66 |
於是、他理也不是、不理也不是,這就像中國傳說故事裏「矛與盾」的故事一樣,他的問題陷入兩難,產生「矛盾」了。
68 |所以、該理髮師想做的事情是不可能做得到的!
69 |這樣的悖論,在邏輯與電腦的理論裏有很深遠的影響,哥德爾正是因為找到了邏輯體系的悖論而發展出「哥德爾不完備定理」,而電腦之父圖靈也事發現了「停止問題」會造成悖論而證明了有些事情電腦做不到 ....
70 |當初「哥德爾」提出的「不完備定理」,大致有下列兩種描述方法,後來簡稱為「哥德爾第一不完備定理」與「哥德爾第二不完備定理」,如下所示。
72 |哥德爾第一不完備定理
73 |74 |76 |定理 G1:若公理化邏輯系統 T 是個包含基本算術 (皮諾公設)的一致性系統,那麼 T 中存在一種語句 S,但是你無法用 T 證明 S ,卻也無法否證 S。
75 |
哥德爾第二不完備定理
77 |78 |80 |定理 G2:若公理化邏輯系統 T 是個包含基本算術 (皮諾公設)的一致性系統,那麼 T 無法證明自己的一致性。
79 |
但是、對於「程式人」而言,上述描述都太邏輯了,讓我們改用「程式人」的角度來看這個問題,提出另一種「程式型版本」的說法:
81 |哥德爾不完備定理的程式型:
82 |83 |85 |定理 G3:不存在一個程式,可以正確判斷一個「包含算術的一階邏輯字串」是否為定理。
84 |
接著、就讓我們來「證明」一下上述的程式型「哥德爾不完備定理」吧!
87 |由於牽涉到矛盾,所以我們將採用反證法:
88 |證明:
89 |假如這樣一個程式存在,那麼代表我們可以寫出一個具有下列功能的函數。
90 |function Proveable(str)
91 | if (str is a theorem)
92 | return 1;
93 | else
94 | return 0;
95 | end
96 | 這樣的函數本身,並不會造成甚麼問題,「包含算術的一階邏輯」(簡稱為 AFOL) 夠強,強到可以用邏輯式描述 Provable(str) 這件事,因此我們可以寫出 Provable(s) 這樣一個邏輯陳述。
更厲害的是,我們也可以將一個字串在 AFOL 裏,是否為定理這件事情,寫成邏輯陳述 (註:邏輯符號 ∃ 代表存在,- 代表 not, & 代表 and, | 代表 or)。
98 |接著、我們就可以問一個奇怪的問題了!那個問題描述如下。
99 |100 |102 |請問 isTheorem(∃s -Provable(s) & -Provable(-s)) 是否為真呢?
101 |
讓我們先用 T 代表 ∃s -Provable(s) & -Provable(-s) 這個邏輯式的字串,然後分別討論「真假」這兩個情況:
103 |如果 isTheorem(T) 為真,那麼代表存在無法證明的定理,也就是 Provable 函數沒辦法證明所有的定理。
如果 isTheorem(T) 為假,那麼代表 -T 應該為真。這樣的話,請問 Provable(-T) 會傳回甚麼呢?讓我們分析看看:
function Proveable(-T)
108 | if (-T is a theorem) // 2.1 這代表 -(∃s -Provable(s) & -Provable(-s)) 是個定理,也就是 Provable() 可以正確證明所有定理。
109 | return 1; // 但這樣的話,就違反了上述 「2. 如果 isTheorem(T) 為假」的條件了。
110 | else // 2.2 否則代表 -T 不是個定理,也就是存在 (∃) 某些定理 s 是無法證明的。
111 | return 0; // 但這樣的話,又違反上述「2. 如果 isTheorem(T) 為假」的條件了。
112 | end
113 | 於是我們斷定:如果 Provable() 對所有輸入都判斷正確的話,那麼 2 便是不可能的,因為 (2.1, 2.2) 這兩條路都違反 2 的假設,也就是只有 1 是可能的,所以我們可以斷定 Provable(s) 沒辦法正確證明所有定理。
114 |在本文中,我們沒有寫出 Provable(s) 的邏輯陳述,也沒有寫出 isTheorem() 的邏輯陳述,因為這需要對「程式的指令集」,也就是 CPU 做一個邏輯描述,這樣說來故事就太長了!
116 |而這個 CPU,通常後來的「計算理論」書籍裏會用「圖靈機」來描述,但這並不是哥德爾當初的證明,因為「哥德爾證明不完備定理」的年代,圖靈還沒有提出「圖靈機」的概念。
117 |事實上、當初「哥德爾」的證明,根本也沒有「程式與電腦的概念」,所以「哥德爾」花了很多力氣建構了一個「哥德爾化的字串編碼概念」,這種字串編碼是建構在包含「+, *」兩個運算的算術系統上,也就是「皮亞諾公設」所描述的那種系統。這也是為何要引進「算術」到一階邏輯中,才能證明「哥德爾不完備定理」的原因了。
118 |1931 年「哥德爾」證明出「不完備定理」之後,後來「圖靈」於 1936 年又提出了一個電腦絕對無法完全做到的「停止問題」(Halting Problem),該問題乃是希望設計出一個函數 isHalting(code, data) ,可以判斷程式 code 在輸入 data 之後會不會停,也就是 code(data) 會不會停。圖靈利用圖靈機的架構,證明了該問題同樣是不可判定的,也就是沒有任何一個程式可以完全正確的判定這樣的問題。
119 |「圖靈」的手法,與「哥德爾」非常類似,但是卻又更加簡單清楚。(不過既使如此,我還是很難直接理解圖靈的證明,因為本人在碩博士時連續被「圖靈機」荼毒了兩次,再也不希望跟「圖靈機」有任何瓜葛了 ....)
120 |但是、我們仍然希望能夠讓「對程式有興趣」的朋友們,能夠清楚的理解「圖靈」與「哥德爾」在「計算理論」上的成就與貢獻,以免過於自大的想寫出一個「可以解決所有問題的程式」,我想只有站在前人的肩膀上,才能看清楚「程式」到底是個甚麼東西吧!
121 |(當然、其實想要「寫出一個可以解決所有問題的程式」是非常好的想法。雖然「圖靈」與「哥德爾」已經都告訴過我們這是不可能的,但是身為一個程式人,就應該有挑戰不可能任務的決心,不是嗎? ........ 雖然、不一定要去做這種不可能的問題啦 ....)
122 |【本文由陳鍾誠取材並修改自 維基百科,採用創作共用的 姓名標示、相同方式分享 授權】
133 |邏輯學是西方科學中淵遠流長的一門學問,從西元前 350 年亞里斯多德的三段論開始,就開啟了歐洲文明對邏輯學的興趣之窗。然而這一個興趣同樣隨著西方文明的發展而起伏不定,直到西元 1850 年左右,George Boole (布爾) 開始研究布林代數,才讓邏輯學成為近代數學的一個重要領域。接著,Gottlob Frege 在 1870 年左右所提出的一階邏輯系統,繼承布林系統並向上延伸,形成一個數學基礎穩固且強大的邏輯系統,於是整個經典的邏輯系統建立完成。
24 |雖然如此,這些邏輯系統仍然是掌上的玩物,而且沒有人能確定這樣的邏輯系統,其能力到底有多強,是否一致且完備,是否有某些極限。希爾伯特在 1900 年所提出的 25 個數學問題中,這個問題被排在第二個提出。然而,希爾伯特並沒有能證明一階邏輯系統的完備性,而是在 1929 年由哥德爾證明完成了。
25 |哥德爾的成就不僅於此,1931 年他更進一步證明了一個非常令人驚訝的定理,在「一階邏輯的擴充系統 - 皮諾數論系統」當中,不具有完備性,而且它證明了假如該系統是完備的,將會導致矛盾。
26 |哥德爾在證明完備定理與不完備定理時,採用的都是矛盾証法,也就是透過排中律所證明的,這樣的証明並非建構性的,因此即使建立了完備定理,也沒有人能構造出一個建構式的証明方法,可以檢證一階邏輯的定理。
27 |1965 年,Robinson 提出了一條非常簡單的邏輯證明規則 -- Resolution,並且說明了如何利用矛盾檢證程序 Refutation,證明邏輯規則在某系統中的真假,這個方法既簡單又優美,因此廣為數學界與計算機科學界所稱道。以下,我們將更詳細的說明上述人物在邏輯學上的貢獻。
28 |亞里斯多德在其其理則學 (zoology) 研究中,提出了下列的三段式推論規則 Barbara,簡稱為三段論。
30 || 類型 | 34 |語句 | 35 |說明 | 36 |
|---|---|---|
| 大前提 | 41 |所有人都終會死亡 | 42 |普遍原理 | 43 |
| 小前提 | 46 |蘇格拉底是人 | 47 |特殊陳述 | 48 |
| 結論 | 51 |蘇格拉底終會死亡 | 52 |推論結果 | 53 |
Boole 研究邏輯時,提出了一種只有真值與假值的邏輯,稱為二值邏輯,通常我們用 0 代表假值,1 代表真值。布爾研究這種邏輯系統,並寫出了一些代數規則,稱為布林代數,以下是其中的一些代數規則。
58 || 規則 (數學寫法) | 62 |名稱 | 63 |
|---|---|
![]() |
68 | OR 的結合律 | 69 |
![]() |
72 | OR 的交換律 | 73 |
![]() |
76 | AND 的結合律 | 77 |
![]() |
80 | AND 的交換律 | 81 |
![]() |
84 | 狄摩根定律(1) | 85 |
![]() |
88 | 狄摩根定律(2) | 89 |
說明:上述規則中的
代表邏輯或 (AND) (在程式語言裏常寫為 & 或 and),
代表邏輯或 (OR) (在程式語言裏常寫為 | 或 or)。所以若改用程式領域的寫法,可改寫如下。
| 規則 (數學寫法) | 97 |名稱 | 98 |
|---|---|
x | (y | z) = (x | y) | z |
103 | OR 的結合律 | 104 |
x | y = y | z |
107 | OR 的交換律 | 108 |
x & (y & z) = (x & y) & z |
111 | AND 的結合律 | 112 |
x & y = y & x |
115 | AND 的交換律 | 116 |
-(x|y) = -x & -y |
119 | 狄摩根定律(1) | 120 |
-(x&y) = -x | -y |
123 | 狄摩根定律(2) | 124 |
Frege 在研究邏輯系統時,將函數的概念引入到邏輯系統當中,這種函數被稱為謂詞,因此該邏輯系統被稱為謂詞邏輯。然後,Frege 又引入了兩個量詞運算,
(對於所有) 與
(存在),透過謂詞的限定作用,以及這兩個量詞,Frege 架構出了這種具有函數的邏輯系統,後來被稱為一階邏輯系統 (First Order Logic)。
以下是我們將亞里斯多德的三段論,轉化為一階邏輯後,所寫出的一階邏輯規則。
130 || 類型 | 134 |語句 | 135 |說明 | 136 |
|---|---|---|
| 大前提 | 141 |![]() |
142 | 所有人都終會死亡 | 143 |
| 小前提 | 146 |![]() |
147 | 蘇格拉底是人 | 148 |
| 結論 | 151 |![]() |
152 | 蘇格拉底終會死亡 | 153 |
事實上,在電腦被發明之前,數學界早已開始探索「公理系統」的能力極限。在西元 1900 年時,德國的偉大數學家希爾伯特 (Hilbert),提出了著名的 23 個數學問題,其中的第二個問題如下所示。
158 |159 |161 |證明算術公理系統的無矛盾性 The compatibility of the arithmetical axioms.
160 |
在上述問題中,希爾伯特的意思是要如何證明算術公理系統的 Compatibility,Compatibility 這個詞意謂著必須具有「一致性」 (Consistency) 與「完備性」(Completeness)。
162 |所謂的「一致性」,是指公理系統本身不會具有矛盾的現象。假如我們用 A 代表該公理系統,那麼 A 具有一致性就是 A 不可能導出兩個矛盾的結論,也就是 A => P 與 A=> -P 不可能同時成立。
163 |所謂的「完備性」,是指所有「永遠為真的算式」(也就是定理) 都是可以被証明的,沒有任何一個定理可以逃出該公理系統的掌握範圍。
164 |然而,希爾伯特耗盡了整個後半生,卻也無法證明整數公理系統的一致性與完備性。或許是造化弄人,這個任務竟然被希爾伯特的一位優秀學生 - 哥德爾 (Godel) 所解決了,或者應該說是否決了。
165 |哥德爾實際上證明了兩個定理,第一個是 1929 年提出的「哥德爾完備定理」(Gödel's Complete Theorem),第二個是 1931 年證明的「哥德爾不完備定理」(Gödel's Incomplete Theorem),這兩個定理看來似乎相當矛盾,但事實上不然,因為兩者所討論的是不同的公理系統,前者的焦點是「一階邏輯系統」(First Order Logic),而後者的焦點則是「具備整數運算體系的一階邏輯系統」。
167 |哥德爾完備定理證明了下列數學陳述:
168 |169 |171 |一階邏輯系統是一致且完備的
170 |
一致性代表一階邏輯系統不會具有矛盾的情況,而完備性則說明了一階邏輯當中的所有算式都可以被証明或否証。
172 |哥德爾不完備定理證明了下列數學陳述:
173 |174 |176 |任何一致且完備的「數學形式化系統」中,只要它強到足以蘊涵「皮亞諾算術公理」,就可以在其中構造在體系內「既不能證明也不能否證的命題」。
175 |
哥德爾不完備定理改用另一個說法,如下所示:
177 |178 |180 |如果一個包含算術的公理系統可以用來描述它自身時,那麼它要麼是不完備的,要麼是不一致的,不可能兩者皆有!
179 |
(筆者註:若該公理系統包含無限條公理時,必須是可列舉的 recursive enumerable)
181 |雖然哥德爾證明了一階邏輯是完備的,但是卻沒有給出一個建構式的方法,可以推理出所有的的一階邏輯定理。這個問題由 John Alan Robinson 在 1965 年解決了。
183 |Robinson 提出的 refutation 邏輯推論法是一種反證法,任何一階邏輯的算式 P 只要在系統 S 當中是真的,只要將 -P 加入該系統 S 中,就可以經由反證法導出矛盾。如果 P 在系統 S 當中不是真的,那麼將 P 加入 S 當中就無法導出矛盾。
184 |所謂的 refutation 反證法是依靠一個稱為 resolution 的邏輯規則,該規則如下所示:
185 |
187 | 假如我們將上述算式中的
寫為 A,將
寫為 B,則上述算式可以改寫如下:
191 | 邏輯學在西方文化中扮演了非常重要的角色,而且可以說是「現代科學」會出現在歐洲的重要原因,假如將「邏輯學」從西方文化中拿掉,或許工業革命就不會出現在歐洲了?
194 |您可以想像「孔子」整天追根究柢,常常和人辯論一件事情到底是真的還假,而且要轉換成符號,並且用邏輯的方式去證明嗎?
195 |但是「亞里斯多德」在那個年代就是這樣追根究柢的,所以他才會去研究解剖學,把動物給切開看看裡面有甚麼,我想這也是他提出三段論背後的原因吧!
196 |【本文由陳鍾誠取材並修改自 維基百科,採用創作共用的 姓名標示、相同方式分享 授權】
219 |邏輯學是西方科學中淵遠流長的一門學問,從西元前 350 年亞里斯多德的三段論開始,就開啟了歐洲文明對邏輯學的興趣之窗。然而這一個興趣同樣隨著西方文明的發展而起伏不定,直到西元 1850 年左右,George Boole (布爾) 開始研究布林代數,才讓邏輯學成為近代數學的一個重要領域。接著,Gottlob Frege 在 1870 年左右所提出的一階邏輯系統,繼承布林系統並向上延伸,形成一個數學基礎穩固且強大的邏輯系統,於是整個經典的邏輯系統建立完成。
24 |雖然如此,這些邏輯系統仍然是掌上的玩物,而且沒有人能確定這樣的邏輯系統,其能力到底有多強,是否一致且完備,是否有某些極限。希爾伯特在 1900 年所提出的 25 個數學問題中,這個問題被排在第二個提出。然而,希爾伯特並沒有能證明一階邏輯系統的完備性,而是在 1929 年由哥德爾證明完成了。
25 |哥德爾的成就不僅於此,1931 年他更進一步證明了一個非常令人驚訝的定理,在「一階邏輯的擴充系統 - 皮諾數論系統」當中,不具有完備性,而且它證明了假如該系統是完備的,將會導致矛盾。
26 |哥德爾在證明完備定理與不完備定理時,採用的都是矛盾証法,也就是透過排中律所證明的,這樣的証明並非建構性的,因此即使建立了完備定理,也沒有人能構造出一個建構式的証明方法,可以檢證一階邏輯的定理。
27 |1965 年,Robinson 提出了一條非常簡單的邏輯證明規則 -- Resolution,並且說明了如何利用矛盾檢證程序 Refutation,證明邏輯規則在某系統中的真假,這個方法既簡單又優美,因此廣為數學界與計算機科學界所稱道。以下,我們將更詳細的說明上述人物在邏輯學上的貢獻。
28 |亞里斯多德在其其理則學 (zoology) 研究中,提出了下列的三段式推論規則 Barbara,簡稱為三段論。
30 || 類型 | 34 |語句 | 35 |說明 | 36 |
|---|---|---|
| 大前提 | 41 |所有人都終會死亡 | 42 |普遍原理 | 43 |
| 小前提 | 46 |蘇格拉底是人 | 47 |特殊陳述 | 48 |
| 結論 | 51 |蘇格拉底終會死亡 | 52 |推論結果 | 53 |
Boole 研究邏輯時,提出了一種只有真值與假值的邏輯,稱為二值邏輯,通常我們用 0 代表假值,1 代表真值。布爾研究這種邏輯系統,並寫出了一些代數規則,稱為布林代數,以下是其中的一些代數規則。
58 || 規則 (數學寫法) | 62 |名稱 | 63 |
|---|---|
![]() |
68 | OR 的結合律 | 69 |
![]() |
72 | OR 的交換律 | 73 |
![]() |
76 | AND 的結合律 | 77 |
![]() |
80 | AND 的交換律 | 81 |
![]() |
84 | 狄摩根定律(1) | 85 |
![]() |
88 | 狄摩根定律(2) | 89 |
說明:上述規則中的
代表邏輯或 (AND) (在程式語言裏常寫為 & 或 and),
代表邏輯或 (OR) (在程式語言裏常寫為 | 或 or)。所以若改用程式領域的寫法,可改寫如下。
| 規則 (數學寫法) | 97 |名稱 | 98 |
|---|---|
x | (y | z) = (x | y) | z |
103 | OR 的結合律 | 104 |
x | y = y | z |
107 | OR 的交換律 | 108 |
x & (y & z) = (x & y) & z |
111 | AND 的結合律 | 112 |
x & y = y & x |
115 | AND 的交換律 | 116 |
-(x|y) = -x & -y |
119 | 狄摩根定律(1) | 120 |
-(x&y) = -x | -y |
123 | 狄摩根定律(2) | 124 |
Frege 在研究邏輯系統時,將函數的概念引入到邏輯系統當中,這種函數被稱為謂詞,因此該邏輯系統被稱為謂詞邏輯。然後,Frege 又引入了兩個量詞運算,
(對於所有) 與
(存在),透過謂詞的限定作用,以及這兩個量詞,Frege 架構出了這種具有函數的邏輯系統,後來被稱為一階邏輯系統 (First Order Logic)。
以下是我們將亞里斯多德的三段論,轉化為一階邏輯後,所寫出的一階邏輯規則。
130 || 類型 | 134 |語句 | 135 |說明 | 136 |
|---|---|---|
| 大前提 | 141 |![]() |
142 | 所有人都終會死亡 | 143 |
| 小前提 | 146 |![]() |
147 | 蘇格拉底是人 | 148 |
| 結論 | 151 |![]() |
152 | 蘇格拉底終會死亡 | 153 |
事實上,在電腦被發明之前,數學界早已開始探索「公理系統」的能力極限。在西元 1900 年時,德國的偉大數學家希爾伯特 (Hilbert),提出了著名的 23 個數學問題,其中的第二個問題如下所示。
158 |159 |161 |證明算術公理系統的無矛盾性 The compatibility of the arithmetical axioms.
160 |
在上述問題中,希爾伯特的意思是要如何證明算術公理系統的 Compatibility,Compatibility 這個詞意謂著必須具有「一致性」 (Consistency) 與「完備性」(Completeness)。
162 |所謂的「一致性」,是指公理系統本身不會具有矛盾的現象。假如我們用 A 代表該公理系統,那麼 A 具有一致性就是 A 不可能導出兩個矛盾的結論,也就是 A => P 與 A=> -P 不可能同時成立。
163 |所謂的「完備性」,是指所有「永遠為真的算式」(也就是定理) 都是可以被証明的,沒有任何一個定理可以逃出該公理系統的掌握範圍。
164 |然而,希爾伯特耗盡了整個後半生,卻也無法證明整數公理系統的一致性與完備性。或許是造化弄人,這個任務竟然被希爾伯特的一位優秀學生 - 哥德爾 (Godel) 所解決了,或者應該說是否決了。
165 |哥德爾實際上證明了兩個定理,第一個是 1929 年提出的「哥德爾完備定理」(Gödel's Complete Theorem),第二個是 1931 年證明的「哥德爾不完備定理」(Gödel's Incomplete Theorem),這兩個定理看來似乎相當矛盾,但事實上不然,因為兩者所討論的是不同的公理系統,前者的焦點是「一階邏輯系統」(First Order Logic),而後者的焦點則是「具備整數運算體系的一階邏輯系統」。
167 |哥德爾完備定理證明了下列數學陳述:
168 |169 |171 |一階邏輯系統是一致且完備的
170 |
一致性代表一階邏輯系統不會具有矛盾的情況,而完備性則說明了一階邏輯當中的所有算式都可以被証明或否証。
172 |哥德爾不完備定理證明了下列數學陳述:
173 |174 |176 |任何一致且完備的「數學形式化系統」中,只要它強到足以蘊涵「皮亞諾算術公理」,就可以在其中構造在體系內「既不能證明也不能否證的命題」。
175 |
哥德爾不完備定理改用另一個說法,如下所示:
177 |178 |180 |如果一個包含算術的公理系統可以用來描述它自身時,那麼它要麼是不完備的,要麼是不一致的,不可能兩者皆有!
179 |
(筆者註:若該公理系統包含無限條公理時,必須是可列舉的 recursive enumerable)
181 |雖然哥德爾證明了一階邏輯是完備的,但是卻沒有給出一個建構式的方法,可以推理出所有的的一階邏輯定理。這個問題由 John Alan Robinson 在 1965 年解決了。
183 |Robinson 提出的 refutation 邏輯推論法是一種反證法,任何一階邏輯的算式 P 只要在系統 S 當中是真的,只要將 -P 加入該系統 S 中,就可以經由反證法導出矛盾。如果 P 在系統 S 當中不是真的,那麼將 P 加入 S 當中就無法導出矛盾。
184 |所謂的 refutation 反證法是依靠一個稱為 resolution 的邏輯規則,該規則如下所示:
185 |
187 | 假如我們將上述算式中的
寫為 A,將
寫為 B,則上述算式可以改寫如下:
191 | 邏輯學在西方文化中扮演了非常重要的角色,而且可以說是「現代科學」會出現在歐洲的重要原因,假如將「邏輯學」從西方文化中拿掉,或許工業革命就不會出現在歐洲了?
194 |您可以想像「孔子」整天追根究柢,常常和人辯論一件事情到底是真的還假,而且要轉換成符號,並且用邏輯的方式去證明嗎?
195 |但是「亞里斯多德」在那個年代就是這樣追根究柢的,所以他才會去研究解剖學,把動物給切開看看裡面有甚麼,我想這也是他提出三段論背後的原因吧!
196 |【本文由陳鍾誠取材並修改自 維基百科,採用創作共用的 姓名標示、相同方式分享 授權】
219 |在前一篇 《OpenNI 2 簡介》 裡,Heresy 大概解釋了 OpenNI 2.0 的基本功能以及他的架構。而接下來的這一篇,就是要來講怎麼寫 OpenNI 2 的程式了~如果是要了解 OpenNI 1.x 版的程式開發的話,請參考 《OpenNI 1.x 教學文章》 這系列的文章。
42 |首先,在安裝好 OpenNI 2.0 的 SDK 後,在安裝目錄(預設是 C:Files2)裡面,會有下列的資料夾:
43 || 目錄 | 47 |用途 | 48 |32 位元 | 49 |64 位元 | 50 |
|---|---|---|---|
| Documentation | 55 |OpenNI SDK 開發程式的參考文件 | 56 |57 | | 58 | |
| Driver | 61 |官方支援硬體的驅動程式 | 62 |63 | | 64 | |
| Include | 67 |程式開發時必須的 header 檔 | 68 |$(OPENNI2_INCLUDE) |
69 | $(OPENNI2_INCLUDE64) |
70 |
| Lib | 73 |程式開發時必須的 lib 檔 | 74 |$(OPENNI2_LIB) |
75 | $(OPENNI2_LIB64) |
76 |
| Redist | 79 |程式執行時必須的 runtime library(dll) | 80 |$(OPENNI2_REDIST) |
81 | $(OPENNI2_REDIST64) |
82 |
| Samples | 85 |範例程式 | 86 |87 | | 88 | |
| Tools | 91 |工具,目前只有 NiViewer | 92 |93 | | 94 | |
而如果是使用 Visual Studio 2010 來開發 OpenNI 2 的程式的話,基本上要在新建立的專案、或是現有專案裡,針對 including 和 linking 做設定,他的基本方法如下(附註 1):
99 |$(OPENNI2_INCLUDE) ,如果是 64 位元的專案,則是加上 $(OPENNI2_INCLUDE64) 。 (附註 2)
(中文版畫面)
105 |$(OPENNI2_LIB) ,如果是 64 位元的專案,則是加上 $(OPENNI2_LIB64)。
(中文版畫面)
111 |
(中文版畫面)
117 |這樣,基本的專案設定就完成了。
119 |要注意的是,在 Visual Studio 裡,不同的建置組態,例如 debug、release、Win32、x64,這些設定都是不同的~所以如果變更建置組態後,這些設定也是需要另外設定的。 另外,在執行時要注意的是,OpenNI 2 的運作模式和 OpenNI 1.x 不一樣,所以它是設計成讓每個應用程式,可以個別擁有各自的 runtime library(dll 檔)等檔案,所以要執行的時候,就必須要讓程式找的到 OpenNI 2 安裝資料夾中,Redist 目錄下的檔案,否則程式執行時,就會出現找不到 OpenNI2.dll 的錯誤(如下圖)。這點,其實算是比較接近一般 C++ 函式庫的使用方法的。 在 Windows 下,基本上應用程式在執行的時候,會優先去找程式執行的目錄下、是否有所需要的 dll 檔;所以最簡單的方法,就是把 Redist 目錄下所有的檔案,都複製一份到程式執行檔所在目錄就可以了。
120 |
圖、找不到 OpenNI2.dll 的錯誤
122 |不過如果是在 Visual Srudio 裡面進行開發的話,由於 VisualStduio 是可以設定執行時的工作目錄的,而工作目錄並不一定會是執行檔所在的路徑(預設不是),所以直接把 Redist 目錄下的檔案複製到執行檔所在路徑,在進行偵錯的時候並不一定有用。
124 |而要確定 Visual Studio 的工作路徑在哪,可以透過點選專案、按右鍵後選擇右鍵選單的「Properties」(屬性),然後在左側選擇「Configuration Properties」(組態屬性)底下的「Debugging」(偵錯);這之後右邊會有「Working Directory」(工作目錄),他的值就代表了在透過 VisualStudio 針對這個專案進行偵錯時,他的工作目錄(英文版螢幕截圖、中文版螢幕截圖)。而如果是 Visual Studio 的預設值的話,他的值應該是「 $(ProjectDir) 」,也就是專案所在目錄(vcxproj 檔所在的地方)。
這時候可以採取的方法主要有幾種:
126 |$(OPENNI2_REDIST) 。$(OPENNI2_REDIST) 加入到系統路徑(參考)。哪種方法好?基本上是看狀況,見仁見智的。由於很多時候,程式還會用到其他函式庫,也有可能會需要用到他們各自的 dll 檔,所以把這些 dll 檔統一放在一起,其實也是一種解決方案。
132 |在專案設定好後,要使用 OpenNI 2 來讀取感應器的資料的話,他的基本流程,大致如下:
134 |include OpenNI.h 這個檔案。之後,OpenNI C++ API 的東西,都會在 openni 這個 namespace 下。openni::OpenNI::initialize() 這個函式來完成 OpenNI 2 環境的初始化。openni::Device 的物件,並透過他所提供的 open() 這個函式,來完成裝置初始化。
138 | openni::OpenNI::enumerateDevices() 這個函式,來取得可使用的裝置列表,再透過指定 URI 的方式,來指定要開啟哪個裝置。openni::ANY_DEVICE 當作 URI,讓系統自動決定要使用哪個裝置。openni::VideoStream 的物件,透過他的 create() 這個函式,指定這個 video stream 要使用哪個裝置的哪種感應器(紅外線、彩色影像、深度影像)。 建立完成後,則是可以透過 start() 和 stop(),來控制資料的讀取。readFrame() 這個函式,來把資料寫到 openni::VideoFrameRef 裡;而之後則是再透過 VideoFrameRef 所提供的函式,來做資料處理。openni::VideoStream 的 destory() 這個函式,關閉 video stream。openni::Device 的 close(),關閉裝置。openni::OpenNI::shutdown(),來關閉整個 OpenNI 的環境。上面是用文字來做描述,實際上寫成程式碼,就會類似 OpenNI 官方所提供的「SimpleRead」這個範例一樣(預設位置在 C:\Program Files\OpenNI2\Samples\SimpleRead )。而下面,Heresy 則是在把程式碼做進一步的簡化(主要是刪掉錯誤偵測的部分),變成:
// STL Header
154 | #include <iostream>
155 |
156 | // 1. include OpenNI Header
157 | #include "OpenNI.h"
158 |
159 | int main( int argc, char** argv )
160 | {
161 | // 2. initialize OpenNI
162 | openni::OpenNI::initialize();
163 |
164 | // 3. open a device
165 | openni::Device devAnyDevice;
166 | devAnyDevice.open( openni::ANY_DEVICE );
167 |
168 | // 4. create depth stream
169 | openni::VideoStream streamDepth;
170 | streamDepth.create( devAnyDevice, openni::SENSOR_DEPTH );
171 | streamDepth.start();
172 |
173 | // 5 main loop, continue read
174 | openni::VideoFrameRef frameDepth;
175 | for( int i = 0; i < 100; ++ i )
176 | {
177 | // 5.1 get frame
178 | streamDepth.readFrame( &frameDepth );
179 |
180 | // 5.2 get data array
181 | const openni::DepthPixel* pDepth
182 | = (const openni::DepthPixel*)frameDepth.getData();
183 |
184 | // 5.3 output the depth value of center point
185 | int idx = frameDepth.getWidth() * ( frameDepth.getHeight() + 1 ) / 2;
186 | std::cout << pDepth[idx] << std::endl;
187 | }
188 |
189 | // 6. close
190 | streamDepth.destroy();
191 | devAnyDevice.close();
192 |
193 | // 7. shutdown
194 | openni::OpenNI::shutdown();
195 |
196 | return 0;
197 | }
198 | 程式碼的內容,大致上就如同上一個段落所說明的,所以基本上這邊就只針對部分地方做補充的說明。 首先是第四部份,建立 VideoStream 的部分。這邊基本上是透過 VideoStream 物件(devAnyDevice)本身的 create() 函式,來指定這個 video stream 要使用哪個裝置的哪種感應器;在這個例子裡,所使用的是 openni::SENSOR_DEPTH,也就是深度感應器的部分。而在目前的 OpenNI 2 裡,除了 SENSOR_DEPTH 外,還有對應到彩色影像的 SENSOR_COLOR,以及對應到紅外線影像的 SENSOR_IR 可以使用。
而在資料讀取、也就是「5」的部分,在透過 VideoStream 的 readFrame() 這個函式,把這個時間點的影像資料,寫到 VideoFrameRef 後,要讀取深度資料,就是要透過 VideoFrameRef 的物件(frameDepth)來做存取了~在一般狀況下,主要是透過他的 getWidth() 和 getHeight() 這兩個函式,來取得這個影像的大小。而透過 getData(),則可以取得這個影像的資料;他所回傳的型別,是無型別的指標、 void* ,實際上是指到一個儲存影像資料的陣列的指標。 由於 OpenNI 2 把影像資料的讀取統一化了,同時也把 OpenNI 1.x 的 MapMetaData 的概念拿掉了,所以在資料的讀取上,會變得比較「低階」一點。首先,如果要做資料的讀取,需要自己根據影像的類型,來做轉型的動作。像在這邊由於是使用深度感應器,影像中每一個像素的資料型別都是 openni::DepthPixel;所以在這邊,就是需要把 void* 強制轉型成為 DepthPixel 的指標來使用(上方範例 5.2 的部分)(附註 3)。
經過這樣的處理,pDpeth 就是一個指到這張深度影像資料的一維振烈的指標,而這個陣列的大小,就是他的寬(透過 getWidth() 取得)乘上高(透過 getHieght() 取得);如果是 640 x 480 的話,pDpeth 所指到的陣列,大小就是 640 x480 = 307,200 了~而其中每一項,都代表一個點的深度;如果是要取得 ( x, y ) 這個點的值的話,就是要做一個簡單的座標換算,去取得他在陣列中的 index。這個基本的換算公式,就是:
202 |204 |int idx = x + y * width;
203 |
只要把 x 和 y 帶入上面的公式,就可以簡單地算出每一個點在陣列中的位置,並取出他的值了。 而如果是要使用彩色影像的話,他預設的型別是 openni::RGB888Pixel 這個 structure,裡面是以三個 unsigned char 的變數,分別儲存著 RGB 三種顏色的值;而如果是紅外線影像的話,型別則是 openni::Grayscale16Pixel ,實際型別則是和 DepthPixel 一樣,是 unsigned short。
這篇算是 OpenNI 2 的第一篇教學文章,就先寫到這了~這邊的範例,基本上應該就算是一個算是最簡單,透過 OpenNI 2 來做深度資料讀取的範例了;其中有很大的篇幅,其實是在講如何設定專案就是了。
207 |而這個範例程式在執行後,會讀取深度感應器的 100 個畫面,並把影像中樣的深度值做輸出,所以在執行後,會看到畫面上有一堆數字出現;由於這部分的程式並沒有繪圖的部分,所以執行後只會看到一串數字,是不會有影像出現的。
208 |實際上,這個範例程式比較好的寫法,應該還是要像官方的「SimpleRead」這個範例一樣,加上錯誤偵測會更好,不過這邊為了篇幅,還是先把它拿掉了。而另外,這邊基本上是只針對單一個 video stream 做操作的寫法,如果是要同時讀取的彩色影像和深度影像的話,則可能還要再做一點的修改。
209 |接下來…就期待下一篇文章吧~
210 |【本文來自 Heresy's Space 的網誌,原文網址為: http://kheresy.wordpress.com/2012/12/24/openni2-basic-example/ ,由 Heresy 捐出網誌給程式人雜誌,經陳鍾誠編輯後納入雜誌】
216 |