正規語言的封閉性(closure properties)
想像一個樂高積木箱,箱裡任何拼出來的東西都保證還能放回同一個箱子。正規語言(regular language)就像這個箱子:把正規語言用某些標準方式組合起來,結果「仍然」是正規語言——永遠不會逃出這個家族。我們說正規語言對這些運算是「封閉的」(closed)。這正是用簡單元件搭建複雜辨識器的工坊祕訣。
具體來說,若 L 與 M 都是正規語言,則以下也都是正規語言:聯集 L ∪ M(屬於任一者的字串)、串接 LM(先一個 L 的字串、再接一個 M 的字串)、Kleene 星號 L*(把零個或多個 L 的字串黏接起來)、交集 L ∩ M(同時屬於兩者的字串)、L 的補集(字母表上「不」屬於 L 的所有字串)、差集 L 減 M、L 的反轉(每個字串倒著拼)、以及 L 在同態(homomorphism,逐符號改名)下的像。每一項都用明確的「構造」來證明:一個食譜,輸入 L 與 M 的自動機或正規表示式,輸出結果的自動機。例如積構造法(product construction)處理聯集與交集,而對調接受狀態與非接受狀態則處理補集。
封閉性之所以重要有兩個相反的理由。正面地說,它讓你能用「組合」來設計:分別辨識「合法識別字」與「保留關鍵字」,再取差集就能辨識「不是關鍵字的識別字」——而且你知道仍然存在單一的有限自動機。反面地說,封閉性是一把「證明的武器」:如果把一個神祕語言和已知是正規的零件(用交集、補集、同態、反轉)組合,會逼出某個非正規語言變成正規,那這個神祕語言一開始就不可能是正規的。
設 A = 在 {a, b} 上含偶數個 a 的字串,B = 以 b 結尾的字串,兩者都是正規語言。則 A ∩ B(偶數個 a「且」以 b 結尾)是正規語言,A 的補集(奇數個 a)是正規語言,A 減 B(偶數個 a 且不以 b 結尾)也是正規語言——每一個都由 A 與 B 的 DFA 機械化地建出。
封閉性保證這些組合仍落在正規語言家族之內。
封閉性指的是在「有限次」運算下封閉:每一次單一運算都讓你保持正規,因此任何有限的組合也是如此。要注意:上下文無關語言「不」對交集或補集封閉——不同語言家族的封閉性各不相同。