オートマトンから正規表現への変換
任意の有限オートマトンを正規表現に変換する方法を説明します。
アルゴリズムの概要
入力として NFA A が与えられているとします。まず、これを GNFA に変換します。次の段階では、1ステップごとに状態を1つ除去し、そのたびに遷移関数を正しく修正します。これを、初期状態と受理状態の2つの状態だけが残るまでくり返します。その2つの状態の間には辺が1本あり、その辺につけられた正規表現がアルゴリズム全体の結果になります。つまり、この方法の中心は、状態を1つ除去したあと、等価なオートマトンになるようにオートマトンを修正することです。
状態を1つ除去する方法
状態を1つ除去する方法を、簡単な例で見てみましょう。オートマトンの一部が次のようになっているとします。
ここで、Ri はある正規表現です。状態 qr を除去すると、オートマトンはどうなるでしょうか。状態 qi にいるとして、この部分でどんな語をつくれるかを考えてみます。状態 qi から状態 qj へ直接進む場合は、正規表現 R4 に当てはまるすべての語がつくれます。
一方、状態 qr へ進む場合は、R1 の形の語がつくれます。さらに、状態 qr では正規表現 R2 についてループできるので、実際には
これで、オートマトンのこの部分からは、R4 の形の語か、
ここまでくれば、状態 qr を除去して qi と qj の2つの状態だけを残し、R4 の代わりに、いま求めた正規表現を書くだけです。
この手順を、各状態 qi から状態 qj へのすべての辺について行います。自己ループ、つまり qi = qj の場合も含みます。
状態を1つ除去すると、等価なオートマトン、つまり同じ言語を受理するオートマトンが得られます。
アルゴリズム全体
入力として NFA A = ⟨Q, Σ, δ, q0, F⟩ が与えられているとします。
- NFA A を GNFA Z = ⟨Q′, Σ, δ′, q0′, qf′⟩ に変換します。以下、Z の状態の個数を文字 k で表します。
- k = 2 ならアルゴリズムは終了し、初期状態と受理状態の間の辺についている正規表現が求める結果です。
- k>2 なら、初期状態とも受理状態とも異なる任意の状態 qr、つまり qr ≠ q0′ かつ qr ≠ qf′ を満たす状態を選びます。そして、次の条件を満たす新しい GNFA Z′ = ⟨Q′′, Σ, δ′′,q0′,qf′⟩ をつくります。
また、すべての qi ∈ Q′′ ∖ {qf′} とすべての qj ∈ Q′′ ∖ {q0′} について、次のように定めます。 ここで、R1 = δ′(qi,qr)、R2 = δ′(qr,qr)、R3 = δ′(qr, qj)、R4 = δ′(qi, qj) です。 そのあと、手順2にもどります。
例
入力として、次の有限オートマトンが与えられているとします。
まず、これを GNFA に変換します(不要な ∅ の遷移はかきません)。
次に、アルゴリズムの後半を適用して、ノードを1つ除去します。ノード q2 から始めましょう。ノード q2 を除去し、状態 q1 から状態 qf への遷移を加えます。この遷移には b(a|b)∗ をつけます。ノード q1 からは b の形の語で状態 q2 に移り、そこで a|b についてループできるので (a|b)∗ が得られ、最後に ε 遷移で qf に移るからです。このとき、b(a|b)∗ϵ = b(a|b)∗ が成り立ちます。次のオートマトンが得られます。
残りは最後の状態 q1 の除去です。状態 qs から状態 qf への辺を加えます。この辺には何をつければよいでしょうか。状態 q1 へは ε 遷移で移るので、これはそのまま省けます。次に、a についてループできるので、正規表現 a∗ が得られます。最後に辺を通って qf に移るので、この式に b(a|b)∗ を連接します。したがって、この辺には正規表現 a∗ b(a|b)∗ をつけます。
オートマトンの状態は2つだけになったので、アルゴリズムは終了します。辺についているのが、求める正規表現です。
参考文献
- 例とアルゴリズムの説明は M. Sipser: Introduction to the Theory of Computation によります。
章: 正規表現, 正規表現からオートマトンへの変換, 一般化非決定性有限オートマトン, オートマトンから正規表現への変換