傑出學者系列講座: Euterpea: from Signals to Symphonies

中研院資科所傑出學者系列講座六月份邀請到了函數語言學界有名的 Paul Hudak. Hudak 是 Haskell 語言設計者之一,IFIP Working Group 2.8 (函數編程) 的成員,以及 Journal of Functional Programming 共同總編輯之一。

1992 – 1996 年間他曾在自己的 Jazz 樂團擔任鋼琴手,難怪他很受函數語言初學和入門者喜愛的 The Haskell School of Expression 一書會以音樂、繪圖、動畫為例示範如何以函數語言思考和解決問題。他也是耶魯大學「計算與藝術創意交融(C2 – the Creative Consilience of computing and the arts)」學程創辦人之一。這次他將介紹一個描述電腦音樂的特殊領域語言 Euterpea

  • 主題 : Euterpea: from Signals to Symphonies
  • 主講人 : Dr. Paul Hudak
  • 主講人單位 : Department of Computer Science, Yale University
  • 聯絡人 : 王佩琪小姐, Miss Peichi Wang
  • 地點 : 中央研究院資訊科學研究所 新館106演講廳
  • 時間日期 : 2010/6/25 週五, 10:00~12:00

Euterpea is a new domain-specific language and programming environ- ment for computer music applications, that showcases the use of advanced programming language ideas in its design. It is being developed in the context of Yale’s new C2 Initiative (Creative Consilience of Computing and Arts), and is the only computer music programming environment based on a purely functional programming model.

In this talk we discuss the design rationale for Euterpea, describe its basic functionality, and highlight some of its more innovative features: a vertical language design (from audio signals to symphonic compositions), a separation between structure and interpretation (form and function), a monadic musical user interface (MUI), real-time sound synthesis (using arrows), and the use of functional reactive programming (FRP) in interactive music applications. We also discuss how teaching computer music using Euterpea is an excellent way to teach fundamental principles of pro- gramming, in a fun and rewarding application area.

Posted in 活動消息 | Tagged , | Leave a comment

2010 「邏輯、語言與計算」暑期研習營 (FLOLAC ’10)

FLOLAC 2010 的網站已經做好很久了。之前一直在等所上和台大進修推廣部正式通過。今年請到了、 Yale University 的 Paul Hudak 來演講。課程則聚焦在語意上,對於正式學習程式語言相關知識應會很有用。對了,還送課本一本唷!請大家多幫忙把消息傳出去吧!

2010 Formosan Summer School on Logic, Language, and Computation (FLOLAC ’10)

2010 「邏輯、語言與計算」暑期研習營暨「高等程式語言:語意、分析與工具」暑期課程碩士學分班。

  • 日期: 2010 年六月廿八日(週一)至七月九日(週五)。
  • 時間: 每週一至週五早上九點至下午五點。
  • 地點: 國立台灣大學進修推廣部 2 樓 207 教室(台北市106羅斯福路4段107號)。

宗旨

近年來,從事基礎計算科學研究之台灣學者們已在各校各自成立研究團隊並相互合作。對基礎計算科學有興趣之學生須透過一系列課程學習基本知識。然而,國內從事此類研究的學者分散在各校,難以僅靠一己之力開設整套課程。因此,我們邀請有相同興趣的學者一同開課,訓練下一代的研究人才。

「邏輯、語言與計算」暑期研習營希望培養學員獨立進行基礎計算科學研究之能力。從第二年起,本研習營在兩大主題之間輪流替換。今年(偶數年)之主題為高等程式語言,奇數年則以模型檢查與程式驗證為主題。

本研習營同時為台灣大學進修推廣部「高等程式語言:語意、分析與工具」暑期碩士學分班,研習時數(含考試)共 54 小時。修習結束經考試及格後,授予碩士學分三學分。也歡迎有興趣之社會、業界人士參加。

「邏輯、語言與計算」暑期研習營曾在 2007、 2008 、2009 年舉辦,今年為第四屆。

課程與講者

課程 講者
函數編程
Functional Programming
陳恭 Kung Chen
政治大學資訊科學系
特別演講
Special Lecture
Paul Hudak
Yale University
操作語意
Operational Semantics
陳恭 Kung Chen
政治大學資訊科學系
邏輯
Logic
謝邁思 Max Schäfer
Oxford University Computing Laboratory
莊庭瑞 Tyng-Ruey Chuang
中央研究院資訊科學研究所, 台灣大學資訊管理學系
指稱語意
Denotational Semantics
程式建構與推理
Program Construction and Reasoning
穆信成 Shin-Cheng Mu
中央研究院資訊科學研究所
使用 Frama-C: 以整合靜態分析技術驗證 C 程式
Using Frama-C: Collaboration of static analysis techniques towards the verification of C code
Pascal Cuoq
Commissariat à l’Énergie Atomique

主辦單位

中央研究院資訊科學研究所、台灣大學資訊管理學系、政治大學資訊科學系聯合主辦,台灣大學進修推廣部協辦。

課程委員

陳恭 Kung Chen, 政治大學資訊科學系。
莊庭瑞 Tyng-Ruey Chuang, 中央研究院資訊科學研究所、台灣大學資訊管理學系。
穆信成 Shin-Cheng Mu, 中央研究院資訊科學研究所。
謝邁思 Max Schaefer, Oxford University Computing Laboratory.
蔡益坤 Yih-Kuen Tsay, 台灣大學資訊管理學系。
王柏堯 Bow-Yaw Wang, 中央研究院資訊科學研究所、台灣大學資訊管理學系。

課務統籌

張少娟 Shao-Chuan Chang, 中央研究院資訊科學研究所。

報名資訊

詳見網站: http://flolac.iis.sinica.edu.tw/flolac10/

Posted in 活動消息 | Tagged | 2 Comments

中研院資訊所誠徵 2010 年暑期實習生

來自所上的消息

為鼓勵與學校教授學術交流,本所徵求暑期實習生10名

申請資格:資訊相關科系學生(研究生優先錄取)
工作時間:2010/07/01 ~ 2010/08/31
待遇:每個月新台幣貳萬元整

有興趣者請下載申請表(DOC檔),詳述您的暑期研究題目與內容,然後請您的指導教授簽名後,寄至台北市研究院路2段128號資訊科學研究所王佩琪小姐, Email: peichi@iis.sinica.edu.tw

Posted in 活動消息 | Leave a comment

Charles P. Thacker 獲得 2009 年 Turing 獎

ACM 昨天宣佈 Charles P. Thacker 為 2009 年 Turing 獎得主

Thacker 1967 年於 UC Berkeley 畢業。1974 年 Thacker 在 Xerox PARC (Palo Alto 研究中心) 製作了第一台現代個人電腦 Alto, 具有點陣式螢幕、圖形介面、和最早的所見即所得 (WYSIWYG) 文件編輯器。Thacker 同時也是 Ethernet 的共同發明者之一,直到今日 Ethernet 仍是區域網路的主要協定。

1983 年,Thacker 加入 DEC 並成為系統研究中心 (Systems Research Center) 創始者之一。在 SRC, Thacker 設計了共享記憶體非對稱多處理器工作站 Firefly。1997 年他幫忙創立微軟劍橋研究中心,並監督設計最早的 tablet PC 原型。目前他仍在微軟矽谷從事電腦結構研究。

New York Times 很快地刊出了一篇 Thacker 的專訪

Alto

Alto 技術上接近迷你電腦,但放在桌上、由一個人使用。基於這點,有人認為 Alto 是第一台個人電腦。 Alto 早期的軟體由 BCPL 寫成,後來則用 Mesa, 兩個語言在 PARC 之外都沒有得到廣泛使用。Alto 的鍵盤沒有底線符號,而多了一個表示賦值的左箭頭。有人認為這可能是 CamelCase 這種變數命名習慣的根源。

Alto 上的軟體包括:

  • 最早的所見即所得文件編輯系統 BravoGypsy,
  • email 系統 Laurel 與 Hardy,
  • 用於畫電路與其他技術圖示的矩陣圖像編輯器 Sil,
  • paint 類繪圖軟體的前身 Markup,
  • 最早的 Smalltalk 環境,
  • Interlisp,
  • 最早的多人網路遊戲之一 Alto Trek.

Alto 生產了上千台,但從未成為商業產品。有些機器捐給了大學,政府曾想採購 Alto 但並未談成。後來最有名的發展就是 Steve Jobs 訪問 PARC…

Xerox 經歷過收購 SDS 但經營不善的失敗後,在個人電腦市場上相當保守。整個 70 年代, Xerox 對 PARC 的成果一直興趣缺缺。當 Xerox 終於決定進場, 甚至特別迴避了 Alto 的技術,僅推出了保守的 CP/M 機器 Xerox 820. 等到 Xerox Star 終於出現,卻也為時已晚了。

Posted in 人物, 計算算計 | Tagged , , , | Leave a comment

再看二元搜尋法 Binary Search(下)

已知兩整數 M < N 使得 Φ(M,N) 成立。上次我們介紹了 Netty van Gasteren 和 Wim Feijen 的二元搜尋法,能找到某個 l, M ≤ l < N,使得 Φ(l,l+1) 成立。給定一個排序好的陣列 a[0..N)(其元素為 a[0], a[1] ... a[N-1]), 0 ≤ N。如何用 van Gasteren 與 Feijen 的方法判斷其中是否含有某個關鍵值 K 呢?

第一個念頭是用這個 Φ:

Φ(i,j) = a[i] ≤ K < a[j]

並令 M = 0。演算法結束後,Φ(l,l+1) = a[l] ≤ K < a[l+1] 一定成立,只要再看看 a[l] 是否等於 K 就可以了。但問題來了:van Gasteren-Feijen 演算法正確的兩個先決條件之一是 M < N -- van Gasteren-Feijen 演算法的迴圈設計便假設 [M,N) 這個區段不是空的,因此我們無法處理空陣列。其次是 Φ(0,N) 得要成立,但 a[0] ≤ K < a[N] 並不一定成立呢。

我們可以把上述的例外都分開測試。但 van Gasteren 與 Feijen 建議的作法是在陣列頭尾各補一個想像元素:a[-1] 小於任何數,a[N] 大於任何數。一個等價的說法是用這個Φ:

Φ(i,j)  =  (i = -1  ∨  a[i] ≤ K)  ∧  (K < a[j]  ∨  j = N)

最初令 l, r := -1, N, 那麼初始條件就滿足了。程式如下:

  { 0 ≤ N ∧ Φ(-1,N) }
  l, r := -1, N
  { Inv: -1 ≤ l < r ≤ N  ∧  Φ(l,r),   Bound: r - l }
; do l+1 ≠ r →
    { l + 2 < r }
    m := (l + r) / 2
  ; if a[m] ≤ K → l := m
    [] K < a[m] → r := m
    fi
  od
  { -1 ≤ l < N  ∧  Φ(l,l+1) }
; if l > -1 → found := a[l] = K
  [] l = -1 → found := false
  fi

如果在陣列頭尾補元素讓你覺得很不妥,別擔心。迴圈不變量保證了 -1 < m < N,因此從頭到尾,a[-1]a[N] 兩個位置都沒被讀過 -- 陣列 a 並不用真正有什麼改變,兩個想像元素只是為了證明演算法正確而假想出來的。這也讓我們可以處理空陣列了。我覺得這是 van Gasteren-Feijen 演算法漂亮之處。

Bentley 的程式

Jon Bentley 在 Programming Pearls 一書中給的二元搜尋法程式如果翻譯成 guarded command language, 並把陣列索引從 [1..N] 改成 [0..N-1], 大約是這樣:

  l, r := 0, N-1
; do l ≤ r →
    m := (l + r) / 2
  ; if a[m] < K → l := m + 1
    [] a[m] = K → found := true; break
    [] K < a[m] → r := m - 1
    fi
  od
; found := false

Bentley 書中也有以口語描述的正確性證明。我原想在課堂上講解這個程式,畢竟這個版本流傳較廣 -- 許多函式庫裡的二元搜尋法程式就是這麼寫的。但困難之一是若要把 K < a[m]r := m - 1 牽上關係,似乎非得提早用上陣列已排序好的性質。這個演算法便比較難在更廣泛的脈絡中解釋了。當然,另一個困難是我不知如何在 Hoare logic 中簡單地解釋 break

乍看之下我以為 Bentley 演算法的搜尋範圍縮小得比 van Gasteren-Feijen 快:lr 分別設為 m+1m-1,並不是 m. 細看之後又發現並不盡然。變數 l 可設為 m+1, 因為 m 的位置已由另一個比較 a[m] = K 處理;變數 r 設為 m-1,則可能僅因為 Bentley 將陣列區段用 a[l..r-1] 表示,而 van Gasteren-Feijen 演算法把同一個區段表達為 a[l..r).

Bentley 與 van Gasteren-Feijen 演算法解的是問題並不完全相同。當 K 在陣列中出現一次以上,Bentley 演算法不限定傳回哪個,van Gasteren-Feijen 則必定傳回索引最大的那個。當 K 不在陣列中時,van Gasteren-Feijen 演算法似乎較快,因為兩者都得跑完,而 van Gasteren-Feijen 的迴圈中只有一個比較(最後一個比較可省去)。Bentley 演算法若提早發現 K 可隨時跳出迴圈,代價是迴圈中多了一個比較。當陣列中確實找得到 K, 這樣的交換是否值得呢?Timothy J. Rolfe 的實驗似乎認為只用一個比較的演算法平均上仍快一些。

習題

Van Gasteren 與 Feijen 建議的幾個習題中包括這個:假設陣列 a[0..N) 是一串嚴格遞增的數字緊接著一串嚴格遞減的數字,試用二元搜尋法找到陣列中的最大值。本問題中我覺得合理的假設是遞增和遞減數列均可能為空的,但 a 至少有一個元素:

0 < N ⋀
(∃ M: 0 ≤ M < N :
  (∀ i,j : 0 ≤ i < j ≤ M : a[i] < a[j]) ⋀
  (∀ i,j : M ≤ i < j < N : a[i] > a[j]))

這剛好是「最大密度區段」問題的演算法之一需要的一個副程式。我記得當時也是先隨便寫寫,幾次寫不對才發現真是難。現在總算是知道一點理論背景,覺得安心多了。你要試試看嗎?

中間索引怎麼取?

關於中間值 m := (l+r)/2, 後來另有些其他故事。Google 的 Joshua Bloch 發現當陣列夠大時,lr 相加可能造成溢位。他可不是故意挑毛病,這個 "bug" 是 Sun 抓到的。他建議該這麼寫:

int m = l + ((r - l) / 2);                          /* for Java/C/C++ */
int m = (l + r) >>> 1;                              /* for Java */
m = ((unsigned int)l + (unsigned int)r)) >> 1;      /* for C/C++ */

Bloch 的發現自然引起了不少討論。有人認為這是整數型別的問題,而不是二元搜尋法的 bug. 有人質疑,討論 int 無法索引的陣列是否有意義?接下來可能一路談到組合語言定址法上頭。有人說,要造成索引溢位,陣列得有 4GB 大,你這輩子在 4GB 的陣列中作二元搜尋過嗎?有人便答,人家可是 Google 來的。Google 的陣列比常人的大上幾倍也不是不可能的唷。

如果往抽象的極端走,Roland Backhouse 在 Program Construction: Calculating Implementations from Specifications 書中則建議應該用 m := (l + r - 1) / 2 -- 如此一來不管該語言的整數除法到底是無條件消去、四捨五入、或是無條件進入,算出來的 m 值都會是 ⌊(l + r)/2⌋.

參考資料

Posted in 計算算計 | Tagged , | 1 Comment

再看二元搜尋法 Binary Search(上)

如果你自認對二元搜尋(binary search, 大陸譯作折半搜索) 夠熟悉了,卻沒讀過 Netty van Gasteren 和 Wim Feijen 的研究筆記 The Binary Search Revisited, 強烈建議你找時間看看。

最近為了今夏的 FLOLAC 研習營開始找些資料。為了教些離開研習營後仍有用的東西,今年我想教 Hoare 邏輯與 Dijkstra 使用最弱前提(weakest precondition) 的程式建構法。對想寫好程式的人來說,這應是基礎知識,但大家對這些題目卻陌生得令人驚訝。

二元搜尋似乎是個該談到的例子:給一個排序好、長度為 N 的陣列,在 O(log N) 的時間內決定其中是否有某個值。資訊系學生在演算法課上一定學過二元搜尋。身經百戰的程式員寫個二元搜尋程式應該也不是難事吧?然而 Jon Bentley 在他有名的 Programming Pearls 一書中卻提到只有大約一成的專業程式員能第一次把這程式寫對。這一定要親身試試看才會相信。我抱著警覺心試了一次,寫了一個應該正確(畢竟我對這套方法算是比較熟了),但不怎麼漂亮的程式。請朋友寫寫看,也果然出現了一些常見的 bug. 看來這確實是個程式設計課堂上該講的好例子。

迴圈、不變量、與界限

Van Gasteren 和 Feijen 在一篇 1995 年的研究筆記中釐清了大家常有的一個迷思:你認為你對二元搜尋很了解嗎?那您可知道,二元搜尋其實並不一定要用在排序好的陣列上?事實上,他們認為總是把二元搜尋類比為翻字典找字,反倒造成了一個教學盲點。

Van Gasteren 和 Feijen 先試解一個更廣的問題:給定整數 MN, 和一個接受兩個整數參數的布林函數 Φ,已知 M < N,並知 Φ(M,N) 成立。Φ 另需滿足一些條件,待會兒再談。試寫一個程式,找兩個介於 MN 之間、滿足 Φ 的相鄰整數。若寫成邏輯式子,程式執行完畢後需滿足:

M ≤ l < N   ∧   Φ(l,l+1)

這是 Van Gasteren 和 Feijen 的程式:

  { M < N ∧ Φ(M,N) }
  l, r := M, N
  { Inv: M ≤ l < r ≤ N  ∧  Φ(l,r),   Bound: r - l }
; do l+1 ≠ r →
    { l + 2 < r }
    m := (l + r) / 2
  ; if Φ(m,r) → l := m
    [] Φ(l,m) → r := m
    fi
  od
  { M ≤ l < N  ∧  Φ(l,l+1) }

這裡的虛擬碼使用的是 Dijkstra 的 Guarded Command Language。多個變數可同時設值(如 l, r := M, N),do 相當於 while 迴圈。條件判斷 if 和一般程式語言不同之處是若不只一個條件成立,程式可任選一個分支執行。註解依照 Algol 系語言的傳統用大括號,但此處我們也把註解視作斷言 (assertion), 表示程式執行到此處一定會成立的條件。這是給人看的資訊,也是我們藉以證明程式正確的重要線索。

證明迴圈正確性的兩大關鍵是其不變量 (loop invariant)界限 (bound)。本程式只有一個迴圈,不變量和界限註記在這一行:

{ Inv: M ≤ l < r ≤ N  ∧  Φ(l,r),   Bound: r - l }

「不變量」事實上並不是一個「量」,而是程式每次執行到迴圈進入點前必定會滿足的條件。此處不變量為 M ≤ l < r ≤ NΦ(l,r)。變數 lr 的初始值分別是 MN. 依照假設,M = l < r = NΦ(l,r) = Φ(M,N) 確實成立。因此第一次執行到迴圈之前,不變量確實是滿足的。

迴圈的進入條件是 l+1 ≠ r,和不變量中的 l < r 合起來看,意思是 lr 不是相鄰的整數。因此m := (l + r) / 2 執行後,m 必定在 lr 之間,但不等於 lr。接下來的 if 敘述中,變數 l 會被設成 m 的先決條件是 Φ(m,r),變數 r 會被設成 m 的先決條件是 Φ(l,m)。不論是哪種情形,執行完 if 敘述後,Φ(l,r) 一定還是成立。所以再回到迴圈開頭時,不變量仍被滿足。

長此以往,直到有一天剛好 l+1 ≠ r 不成立了,也就是說 lr 已是相鄰的整數,和不變量合起來看,剛好我們要的 結束條件 M ≤ l < N ∧ Φ(l,l+1) 就被滿足了!

只是還有兩個但書:首先,if 敘述中的 Φ(m,r)Φ(l,m) 這兩個條件至少要有一個成立。這是 Φ 的另一個要求:

 Φ(l,r)  ∧  l < m < r   ⇒   Φ(l,m)  ∨  Φ(m,r)(*)

其次,我們怎知道迴圈會有停下來的一天呢?這就是「界限」 r-l 處理的部份。由於 M < N, 我們知道 r-l 最初會是一個正整數。而如前所述,每次進入迴圈後,m 的值必定在 lr 之間,但不等於 lr。因此迴圈每執行一次,r-l 就變小一些。當 r-l 等於一時,迴圈就得停了。因此我們知道這迴圈不可能永遠執行下去。

以上便是該程式正確的大略證明。我們只是用中文說說,更仔細的證明是應該要有些數學演算的。關於什麼算是證明、為何要有「形式」證明,希望以後有機會寫寫看。

有哪些函數 Φ 滿足條件 (*) 呢? Van Gasteren 與 Feijen 舉的例子包括:

  • Φ(i,j) = a[i] ≠ a[j],此處 a[M..N] 是某陣列。程式會幫我們找到兩個相鄰但不相等的元素。Van Gasteren 與 Feijen 認為這個特例可能是解說二元搜尋比較合適的例子。
  • Φ(i,j) = a[i] × a[j] ≤ 0, 程式將找到兩個相鄰但正負號不相等,或至少有一個為零的元素。
  • Φ(i,j) = a[i] < a[j],
  • Φ(i,j) = a[i] ∨ a[j], 等等。

再回到最初的問題:怎麼在排序好的陣列中找某個關鍵值呢?理想上我們希望設計某個 Φ,然後套用上面的程式。先賣個關子,下回分解。 :)

參考資料

Posted in 計算算計 | Tagged , | 3 Comments

演算邏輯 Calculational Logic(二)騎士與惡棍之島

一個島上住著兩種人,騎士 (knight) 與惡棍 (knave) 。騎士總說實話,惡棍總說謊話,但從外表看不出誰是騎士或惡棍。某天,居民 A 和你說「B 剛剛說他自己是騎士」。由此你可知道 A 說的是實話還是謊話嗎?B 呢?傳說島上藏著金子,怎麼設計一個問題,查出傳言的真假呢?

只要有耐心把各種狀況列出來作分析,這類邏輯問題總是可以找到解答的。既然演算邏輯號稱是為了應用設計的邏輯,以演算邏輯的眼光看這種問題,是否比較好解呢?

上次我們談到 這個運算元,知道它滿足交換律和結合律,是演算邏輯最基礎的運算元。在談騎士與惡棍問題之前,我們得先提另一條規則:

[const. true] true ≡ p ≡ p

如果讀解成 true ≡ (p ≡ p), 意思是 也滿足同一律:任何值都等於自己。如果讀解成 (true ≡ p) ≡ p,則是強調 true 的單位元素。

騎士與惡棍

我們將「A 是騎士」簡寫成 A. 如果 A 說了某個陳述 S, 我們無法知道 S 是否成立,但我們知道

A ≡ S

如果 A 是騎士,S 便是真的;如果 A 是惡棍,S便是假的。

假設我們問 A:「你是騎士嗎?」A 回答「是的。」這可以記成 A ≡ A. 然而,根據 [const. true] 規則,A ≡ A 可以化簡為 true. 意思是,在這個島上不管你問誰「你是騎士嗎」,對方都會回答是。

如果 A 說:「B 是騎士」呢? 這可以記成 A ≡ B. 我們仍不知道 B 到底是騎士還是惡棍,但我們可以知道 AB 是同一種人。

如果 A 說:「我和 B 是同一種人」呢?這可記成 A ≡ (A ≡ B)。我們算算看:

  A ≡ (A ≡ B)
=   { 結合律 }
  (A ≡ A) ≡ B
=   { [const. true] }
  true ≡ B
=   { [const. true] }
  B

啊,所以我們雖仍不知道 A 到底是騎士還是惡棍,卻可以知道 B 一定是騎士!

若不用演算邏輯,一般人的推理方式可能是把 A是騎士或惡棍、B是騎士或惡棍的四種可能性一一嘗試。由此我們可以體會到 Gries 所說「演算邏輯為解決問題而設計」的意思 — 利用 的性質,讓一個式子盛載多重的意義,因此我們可同時處理好幾種狀況,讓推理相當精簡迅速。當然,前提是要對邏輯規則夠熟練。

所以,要怎麼想出一個問題問 A,用來判斷島上到底有沒有金子呢?經過剛剛的討論,讀者也許已經可以猜得出來。但 Backhouse 建議我們避免瞎猜。我們應該用代數解未知數的方式把問題推演出來。把「島上有金子」這個命題記為 G. 我們希望問某個問題 Q, 如果 A 回答「是」,就表示島上有金子,反之則否:

  • 「A 對問題 Q 回答『是』」記為 A ≡ Q
  • 「A 對問題 Q 回答『是』,島上便有金子」應該是一個若且唯若的命題,寫成 G ≡ (A ≡ Q)

而根據交換律和結合律,G ≡ (A ≡ Q) 就是 Q ≡ (G ≡ A)。我們要問 A 的問題就是 G ≡ A:「『島上有金子』和『你是騎士』是不是等價的呢?」?

希望這個島上不論騎士或惡棍,邏輯都蠻不錯的,才聽得懂這種問題囉!

否定運算元

以上的討論只用了三條規則:交換律、結合律、和[const. true]. 結束本篇之前,我們再看一條關於false 與「否定」運算元 ¬ 的規則:

[negation] ¬p ≡ p ≡ false

把括號放在後面,¬p ≡ (p ≡ false)¬ 的定義;若讀解成 (¬p ≡ p) ≡ false,這條規則讓我們把算式中看到的 p¬p 兩兩消去成 false.

方才我們把「A 是騎士」記為 A,「A 是惡棍」自然是 ¬A 了。以下的練習除 3. 以外皆取自 Backhouse 的書。

  1. A 說:「我和 B 是不同種的。」由此我們可推導出什麼關於 AB 的資訊呢?
  2. 用上述的做法,推導出一個問題問A ,若 A 回答「是」,我們可得知 AB 真的不同種類。
  3. A 說:「B 說他是騎士。」由此我們可以得知什麼關於 AB 的訊息?如果 A 說:「B 說他是惡棍」呢?
  4. 試證明 ¬(p ≡ q) = (p ≡ ¬q)

參考資料

本文內容皆來自 Roland BackhouseProgram Construction: Calculating Implementations from Specifications 第五章。

Posted in 計算算計 | Tagged | 7 Comments

演算邏輯 Calculational Logic(一)若且唯若

最近準備一些教材,讀了 Roland BackhouseProgram Construction: Calculating Implementations from Specifications 一書,其中有兩章講「演算邏輯 (calculational logic)」。¹ 覺得這是很有趣的資料,可惜沒有早點學到。

演算邏輯是另一種形式化的古典邏輯,先後由 Edsger Dijkstra, Carel Scholten (因此被稱作 Dijkstra-Scholten 邏輯), David Gries, Wim H.J. Feijen, Netty van Gasteren, 和 Backhouse 等人提倡。Gries 說,邏輯學家發展形式邏輯是為了研究邏輯本身,而演算邏輯則是設計來解決問題的。我想這裡要加個但書:演算邏輯熟悉後確實很好用,但就和其他數學演算一樣,仍是要花點功夫去學,才能得心應手的。

以下的內容來自 Backhouse。

若且唯若

Backhouse 提到,在數學發展史中,不少重要的觀念往往很晚才被發現。「零」是個經典例子,希臘人甚至不把「一」當作數字,更別說零。「等於」的觀念更晚成型,= 符號到了 1557 年才由 Robert Recorde 在 The Whetstone of Witte 一書中採用。

一個概念往往要到有了符號後才成為可談論的東西。「等於」用符號 = 表示後,一些性質也比較容易表達。我們知道 滿足交換律(若 a = b 成立,b = a 也成立)和遞移律(若 a = b, b = c, 則 a = c)。既然 滿足遞移律,一般我們常寫「a = b = c」同時表達三件事情。 這種用法精簡地表達了很多性質,已經成為習慣,也有其方便性。

但另一種看法是把 = 當作傳回布林值的運算元:3 = 3true, 3 = 5false。很多人不知道這個意義下的 = 其實還滿足結合律:如果 (p = q) = r 為真,p = (q = r) 也為真,反之亦然。當然這時 p, q, r 都必須是布林值。讀者不妨代幾個布林值試試看,例如:(true = false) = false 成立,true = (false = false) 也成立。Backhouse 說,許多數學家都不知道這個性質,更別說計算科學家了。

為了區分這兩種用法,我們把第二種意義的「等於」(也是邏輯上的「若且唯若」)寫成 。既然滿足結合律, 連續出現時可不用加括號。算式 true ≡ false ≡ false 是成立的, true = false = false 則否。Backhouse 建議把 p ≡ q 念成 "p equivals q" . 至於中文該怎麼念… 請大家提供想法囉。

運算元 和其結合律讓我們用精簡的符號承載大量的資訊。例如以下的式子:

even (m + n) ≡ even m ≡ even n

若讀成even (m + n) ≡ (even m ≡ even n),我們知道如果 mn 的奇偶同位相同,m+n 是偶數;反之 m+n 是奇數。如果讀成 (even (m + n) ≡ even m) ≡ even n,我們知道把 m 加上一個偶數(n)不會改變其奇偶性質。

在其他形式邏輯中,同樣的性質可能會用許多個狀況分析來證明:檢查一下 even meven n 的情況、even modd n 的情況… 等等。當變數多、狀況更多,演算就難了。盡量使用結合律,避免使用狀況分析,是演算邏輯的主要風格。

參考資料

附註

  1. "Calculation" 常見的翻譯似乎是「計算」,但 "compute" 也翻成「計算」。「演算」比較強調推演的過程,似乎是合適的翻譯。不幸地, "arithmetics" 也常翻成「演算」。此外, "algorithm" 譯成「演算法」也是慣例。
Posted in 計算算計 | Tagged | 13 Comments

OOPSLA 改名為 SPLASH

物件導向技術的頂尖會議 OOPSLA 從今年起改名為 SPLASH — Systems, Programming, Languages and Applications: Software for Humanity。而 OOPSLA 則成為協同舉辦的兩個會議之一。

藉著改名,SPLASH 也正式將領域擴展到其他軟體相關議題。OOPSLA 近年來已不只談物件,新名字也許是反應了這樣的趨勢。SPLASH 公式網頁說:

The future is becoming more intriguing with multicore computers, a variety of scripting and dynamic languages, ultra-large scale, new concepts for computing, and new societal, commercial, engineering, and scientific demands, to name a few things; and so SPLASH is taking on those challenges…

SPLASH 的新範疇似乎包羅萬象。程式語言領域中,POPL 公認是競爭最激烈的會議之一:此外較強調實作的有 PLDI, 偏函數語言的有 ICFP。OOPSLA 成為 SPLASH 後,會形成什麼風格,帶來什麼變化,仍有待觀察。

Posted in 活動消息 | 2 Comments

IFIP Working Group 2.1 Meeting #65

IFIP Working Group 2.1 第 65 次集會的「正式」決議:

The members of WG2.1 and the observers present at the 65th meeting in Póvoa de Lanhoso, Braga, Portugal, wish to thank José Nuno Oliveira, João Saraiva, Luis Barbosa and Sara Fernandes from the University of Minho for a meeting that was warm, refreshing and enlightening.

In fact, from a study of the superlative room temperatures of the meeting room and the coffee room we determined a connection that can precisely and concisely be summarized as

    C ⊢ M.

A little reflection led to glear galculations that dispelled glouds of obsgurity. After digesting what we were presented with, we ended the week at maximum density.

留作紀念。

Posted in 計算算計 | Leave a comment