---
# System prepended metadata

title: 'Theory of Computation Chapter 3, 4 - Regular Language'
tags: [NCKU]

---

# Theory of Computation Chapter 3, 4 - Regular Language

（請搭配達叔的投影片一起服用）

**正規語言 (Regular Language)**, 又稱**正則語言**，是滿足下述相互等價的一組條件的一類形式語言：
* 可以被**確定有限狀態自動機 (DFA)** 辨識
* 可以被**非確定有限狀態自動機 (NFA)** 辨識
* 可以用**正規表示式 (Regular Expression)** 描述
* 可以用**正規文法 (Regular Grammar)** 生成

（以上摘自[正規語言 - 維基百科](https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%AF%AD%E8%A8%80)）


## Regular Expression

### 如何描述一個語言

* 如果是有限集的語言，可以用窮舉法，如 $L = \{a, aa, aba, aca\}$
* 無窮集的語言，則可以用描述法，如 $L = \{x \mid n_a(x) = n_b(x)\}$
* 由於語言是一個集合，因此將多個語言用集合運算子進行運算後的結果也是一個語言，如 $L = \{aa, ab\}^* \cup \{b\}\{bb\}^*$

### 正規表達式 (Regular Expression)

* 是一種基於集合運算子進行擴充的語言描述方法
* 基本定義如下，給定一個字母表 $\Sigma$
    * $\emptyset$, $\lambda$, 和 $a \in \Sigma$ 皆為描述這個語言的**原生正規表達式 (primitive regular expressions)**
    * 如果 $r_1$ 和 $r_2$ 皆為正規表達式，則以下算式也都會是正規表達式
        * $r_1 + r_2$
        * $r_1 \cdot r_2$ （$\cdot$ 可省略）
        * $r_1^*$
        * $(r_1)$
    * 一串字串是一個正規表達式，若且唯若該字串可以由有限個原生表達式和上述的運算子組成
* 舉例
     $r = (a + b \cdot c)^*$， 用來描述 $L = \{\{a\} \cup \{bc\}\}^*$
    * 因此 $L(r) = \{\lambda , a, bc, aa, abc, bca, ...\}$
* 要注意的事
    * 正規表達式並不是一種語言，而是一個描述語言的工具
    * 對於一個語言 $L$， 我們不能說 $L = (a + b + c)^*$， 但可以說這個 $L$ 能夠用 $(a + b + c)^*$ 描述

## Connection Between REs and Regular Languages

### 正規表達式描述的語言

* 對於所有的原生正規表達式，他們所接受的語言定義為
    * $L(\emptyset) = \emptyset$
    * $L(\lambda) = \{\lambda\}$
    * $L(a) = \{a\}$
* 對於正規表達式 $r_1$ 和 $r_2$， 他們之間的運算子規則定義為
    * $L(r_1 + r_2) = L(r_1) \cup L(r_2)$
    * $L(r_1 \cdot r_2) = L(r_1)L(r_2)$
    * $L(r_1^*) = (L(r_1))^*$
    * $L((r_1)) = L(r_1)$
    * 以上運算子之間的優先度， $()$ > $^*$ > $\cdot$ > $+$
* 給定兩個正規表達式 $r_1$ 和 $r_2$， 如果 $L(r_1) = L(r_2)$， 則我們說 $r_1$ 和 $r_2$ 是等價的

### 克萊尼定理 (Kleene Theorem)

* 正規表達式可以描述的語言集合，就是正規語言
* **克萊尼定理 (Kleene Theorem)**： 由於正規表達式和有限自動機所能夠描述 / 接受的語言集合是一樣的，因此可以說**正規表達式等價於有限自動機**
* 對於每一個正規語言，都存在一條正規表達式可以描述他；對於每一個正規表達式，都存在其可以描述的一個正規語言
* 透過證明「正規表達式可描述的語言等同於正規語言」，可以證明克來尼定理
    ![原生正規表達式可以很簡單的畫出對應的NFA](https://i.imgur.com/iiY6ydX.png)
    > Figure 1. 原生正規表達式可以很簡單的畫出對應的NFA
    >
    ![$+$ 運算子的NFA](https://i.imgur.com/8pLf8fM.png)
    > Figure 2. $+$ 運算子的 NFA
    >
    ![$\cdot$ 運算子的 NFA](https://i.imgur.com/AK7smMt.png)
    > Figure 3. $\cdot$ 運算子的 NFA
    > 
    ![$^*$ 運算子的 NFA](https://i.imgur.com/4qiS7YK.png)
    > Figure 4. $^*$ 運算子的 NFA
    * 證明「正規表達式可描述的語言 $\subseteq$ 正規語言」
        * 如果針對每一個正規表達式所描述的語言，我們都能夠建立一個可以接受該語言的有限自動機的話，就能證明正規表達式所描述的語言包含於正規語言
        * 對於原生正規表達式，其描述的語言可以簡單的畫出 Fig. 1 中的 NFA
        * 對於正規表達式當中所有的運算子，他們的規則都可以用 Fig. 2-4 的 NFA 表達（ $()$ 運算子不用 NFA 也可以得知）
        * 透過這些 NFA， 我們可以將正規表達式當中的每一個運算都畫出來，並且組合在一起，得到最後只有一個終止狀態的 NFA
        * 由於所有的正規表達式都可以做這樣的轉換（所有的正規表達式都有一個對應的 NFA），所以正規表達式可以描述的語言包含於正規語言
        * 同時我們也得知，在這些運算子之下，正規語言會形成一個[閉包 (Closure)](https://zh.wikipedia.org/zh-tw/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6))
    ![這張圖的正規表達式為 $r = r1^*r2(r4 + r3r1^*r2)^*$](https://i.imgur.com/cnJm1IN.png)
    > Figure 5. 這張圖的正規表達式為 $r = r1^*r2(r4 + r3r1^*r2)^*$
    * 證明「正規語言 $\subseteq$ 正規表達式可描述的語言」
        * 泛化狀態轉移圖 (Generalized Transition Graphs, GTG)， 是一個狀態轉移圖，其每一個有向邊都是一條正規表達式
        * 每一個 NFA 都可以透過合併轉移函式和合併狀態的方式轉換成一個 GTG。 當一個 NFA 被化簡為只有起始狀態和終止狀態的 GTG 後，就可以簡單的得到與該 NFA 等價的正規表達式
        * 值得注意的是，當我們要將 NFA 轉換成 Complete GTG （所有的邊都填上的 GTG） 時
            * 由於 NFA 允許轉移函式的輸出為空集合，因此在轉換成 GTG 時需要補上一個 $\emptyset$ 的自環，而我們額外定義 $\emptyset^* = \lambda$
            * 由於 NFA 原本的轉移函式中，可能會有一個狀態無法走到另一個狀態，在無法連通的狀態之間，也需要補上 $\emptyset$ 的路徑，而我們額外定義 $r + \emptyset = r$， $r \cdot \emptyset = \emptyset$
        * 由於每一個 NFA 都可以透過 GTG 轉換得到一條對應的正規表達式，因此正規語言包含於正規表達式可以接受的語言
    * 由於兩個集合互相包含對方，證明兩個集合相等，所以正規語言等於正規表達式可描述的語言

## Regular Grammars

### 形式文法(Grammars)

* 可以表示為一個四元組 $(V, T, S, P)$
    * $V$ 是**非終結符號 / 變數 (variables)** 的有限集
    * $T$ 是**終止符號 (terminals)** 的有限集
    * $S$ 是**起始符號 (start variable)**， $S \in V$
    * $P$ 是**產生式規則 (production rules)** 的有限集
* 給定一個形式文法 $G$， 根據以上定義，其可以產生的語言為 $L(G) = \{w \in T^* : S \Rightarrow w \}$
    * 如果 $w \in L(G)$， 則序列 $S \Rightarrow w_1 \Rightarrow w_2 \Rightarrow ... \Rightarrow w_n \Rightarrow w$ 為 $w$ 的**推導 (derivation)**
    * 其中 $S, w_1, w_2, ... w_n$ （在代換的途中還有變數沒被換掉的狀態）稱為**句型 (sentential form)**
* 線性文法 (Linear Grammar) 為形式文法的子集，其所有的產生是規則的右手邊最多只包含一個變數
    * **右線性文法 (Right-Linear Grammar)**， 為線性文法當中，所有規則右手邊中唯一的變數都在最右邊的文法
    * **左線性文法 (Left-Linear Grammar)**， 為線性文法當中，所有規則右手邊中唯一的變數都在最左邊的文法
    * 左線性文法和右線性文法都屬於**正規文法 (Regular Grammar)**

### 正規文法與正規語言

* 正規文法產生的語言集合，就是正規語言
* 證明「正規文法可產生的語言 $\subseteq$ 正規語言」
    * 如果是右線性文法，可以透過以下映射將文法轉換成有限自動機
        * 將每一個變數都視為狀態，起始符號視為起始狀態，終止符號視為終止狀態
        * 將每一條產生式規則都視為是一個轉移函式，如 $A \rightarrow aB$ 可以視為 $\delta (A, a) = B$
        * 從起始符號開始，將所有的產生式規則都視為轉移函式畫為狀態機，直到連接終止符號為止
        * 得到一個等價於該文法的 NFA
    * 如果是左線性文法，則透過以下映射
        * 將每一個變數都視為狀態，起始符號視為終止狀態，終止符號視為起始狀態
        * 將每一條產生式規則都視為是一個反向的轉移函式，如 $A \rightarrow Ba$ 可以視為 $\delta (B, a) = A$
        * 從終止符號開始，將所有的產生式規則都視為轉移函式畫為狀態機，直到連起始符號為止
        * 由於起始狀態只能有一個，所以在多個起始狀態前多加一個起始狀態，並且用空字串轉移連接到原本的多個起始狀態，得到一個等價於該文法的 NFA
    * 由於所有的正規文法都可以透過以上映射得到等價的 NFA，所以正規文法產生的語言包含於正規語言
* 證明「正規語言 $\subseteq$ 正規文法可產生的語言」
    * 由於有限狀態機當中的每個元素都可以對應正規文法中的某些元素（如上方證明所述），所以可以透過反向映射的方式，用跟上方相似的步驟，將有限狀態機以一個正規文法描述（敘述略）
    * 由於所有的正規語言都對應到一個有限狀態機，而每一個有限狀態機都可以轉換為正規文法，所以正規語言包含於正規文法所產生的語言
* 兩個集合互相包含對方，證明兩個集合相等，所以正規語言等於正規文法可產生的語言

## Closure Properties of Regular Languages

略。

## Elementary Questions about Regular Languages

* 目前為止我們已經學過了幾種正規語言的標準表達方式 (Standard Representation)，包含：
    * 確定有限狀態自動機 (DFA)
    * 非確定有限狀態自動機 (NFA)
    * 正規表示式 (Regular Expression)
    * 正規文法 (Regular Grammar)
* 當我們說有一個正規語言 $L$， 這表示 $L$ 一定是以上述幾個方法之一來描述的

### Some Questions about Regular Language

* 給定一個正規語言 $L$ 和一個字串 $w$， 我們怎麼確認 $w \in L$ ？ (Membership Question)
    * 畫出一個可以接受 $L$ 的 DFA， 然後看看 $w$ 能不能被該 DFA 接受。若能，則 $w$ 屬於 $L$， 反之則否
* 給定一個正規語言 $L$， 我們怎麼確認 $L$ 是空集合 （$L = \emptyset$）？
    * 畫出一個可以接受 $L$ 的 DFA， 然後看看起始狀態是否有路徑可以走到終止狀態。若有，則 $L$ 非空集合，反之則是空集合
* 給定一個正規語言 $L$， 我們怎麼確認 $L$ 是有限集合 (finite set)？
    * 畫出一個可以接受 $L$ 的 DFA， 然後看看從起始狀態走到終點狀態的路徑中有沒有環的存在。若有，則 $L$ 不是有限集合，反之則是有限集合
* 給定兩個正規語言 $L_1$ 和 $L_2$， 我們怎麼確認 $L_1 = L_2$ ？
    * 確認是否 $(L_1 \cap L_2) \cup (L_1 \cap L_2) = \emptyset$ 。若是，則 $L_1 = L_2$， 反之則否

## Identifying Nonregular Languages

![](https://i.imgur.com/lpkZje3.png)
> Figure 6. 有限語言 $\subset$ 正規語言 $\subset$ 非正規語言

有些語言並不屬於正規語言的集合，我們該如何證明一個語言 $L$ 不是正規語言呢？我們或許可以證明沒有任何一個 DFA 可以接受這個語言，但是窮舉出所有的 DFA 並不是一件容易的事（是做不到的事），所以我們需要用到一個工具 —— **泵引理 (Pumping Lemma)**。

### Pigeonhole Principle

*參考離散數學。*

簡單來說，如果有 $m$ 隻鴿子要裝進 $n$ 個鴿籠，當 $m > n$ 時，必定會有某個籠子裡至少有兩隻鴿子。

### Pigeonhole Principle and DFAs

![](https://i.imgur.com/0GmlkAB.png)
> Figure 7. 鴿籠定理與 DFA

對於任意一個有 $n$ 個狀態的 DFA $M$， 如果有一個字串 $w$， 其中 $|w| \geq m$， 則 $w$ 在 $M$ 當中所經過的路徑，必定有其中一個狀態 $q$ 被重複走過了至少兩次，如 Fig. 7 所示。

![](https://i.imgur.com/tb2R60Z.png)
> Figure 8. 一個長度為 4 的 DFA
* 例如： 對於 Fig. 8 中的 DFA 來說， $a$, $aa$, $aab$ 等字串因為長度小於該 DFA 的狀態數量，所以不一定有重複走過的狀態。但是像 $aabb$, $bbaa$, $bababb$ 這些字串，其長度已經大於或等於該 DFA 的狀態數量了，所以在 DFA 消化他的過程當中，必定會有至少一個狀態被走過了兩次

### Pumping Lemma

* 定義： 給定一個無限正規語言 $L$， 必定存在一個整數 $m$ （代表可以接受 $L$ 的 DFA 的狀態數量），對於任意字串 $w \in L$ 且 $|w| \geq m$， 可以表示為 $w = xyz$， 其中 $|xy| \leq m$ 且 $|y| \geq 1$， 使得 $xy^iz \in L , i = 0, 1, 2,...$
    :::danger
    很重要！！ 上面要整段背起來！！
    :::
* 應用： 可以搭配反證法來證明某語言**不是**正規語言。證明過程如下：
    1. 假設給定的語言為正規語言，故滿足 pumping lemma （需要完整寫出上面這一段）
    2. 舉出任意一個字串 $w$， 此字串必須要滿足 $w \in L$ 且 $|w| \geq m$， 所以通常會將 $m$ 用在該字串的參數當中
    3. 將 $w$ 拆解成 $xyz$ 三段，其中 $|xy| \leq m$ 且 $|y| \geq 1$， 注意 $xy$ 的選擇務必滿足這些條件
    4. 證明至少有一個 $xy^iz$ 不屬於 $L$
    5. 由於 4. 違反了 pumping lemma， 跟「給定的語言是正規語言」的假設矛盾，故給定的語言並非正規語言
* Pumping lemma 常見的誤用
    * 用 Pumping lemma 證明某語言是正規語言
        * 就算一個語言符合 pumping lemma， 也不能保證他一定是正規語言。 符合 pumping lemma 是正規語言的充份條件，而不是必要條件
    * 在 2. 時舉出了一個不在 $L$ 當中的字串
        * 例： $L = \{a^n: \textrm{n is a prime number}\}$
        * $w = a^m$ 並不是一個好的選項，因為 $m$ 不一定是質數
        * $w = a^P$， 其中 $P$ 是一個比 $m$ 大的質數，才是正確的挑法
    * 對於 $xyz$ 分解做出過度假設
        * 例： $L = \{a^n: \textrm{n is a prime number}\}$
        * 令 $y = ak$， 其中 $k$ 是一個奇數。這是一個不對的假設，因為這樣沒有考慮到 $k$ 是偶數時的狀況
