Mercurial > hg > Members > kono > Proof > automaton
annotate a04/lecture.ind @ 381:113330c6e896
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 Jul 2023 15:49:41 +0900 |
parents | 6f3636fbc481 |
children | 3d0aa205edf9 |
rev | line source |
---|---|
37 | 1 -title: 非決定性オートマトン |
2 | |
3 決定性オートマトンは入力に対して次の状態が一意に決まる。一つの入力に対して可能な状態が複数ある場合を考える。 | |
141 | 4 例えば、ドアの鍵がテンキーだったら、次に何を入れるかには自由度がある。 |
5 この拡張は容易で、状態遷移関数が状態の代わりに状態のリストを返せば良い。しかし、リストを使うとかなり煩雑になる。 | |
37 | 6 |
141 | 7 このようなものが必要な理由は、 Regular Language の Concatを考えるためである。 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
8 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
9 Regular Language は Concatについて閉じている。これは オートマトン A と B があった時に、z を前半 x ++ y |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
10 にわけて x を A が受理し、y を B で受理するものを、単一ののオートマトンで実現できると言う意味である。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
11 しかい、 これを決定性オートマトンで示すのは難しい。A ++ B の 境目がどこかを前もって予測することができないからである。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
12 |
331 | 13 二つのオートマトンが、a0..ae b0..be につながる様子を図にしてみる。 |
14 | |
141 | 15 <center><img src="fig/concat.svg"></center> |
16 | |
17 このためには後半のB automatonを、前半のA automatonが終わる可能性がある時だけ、 | |
18 一文字毎に増やしてやればよい。増やしたものの一つでも成功すればよい。Bが増えるので、その増えた状態を覚えておく必要がある。 | |
19 | |
20 an (Aのn番目の状態)と、b0...bn の部分集合 | |
21 | |
22 状態はAの状態とBの状態の部分集合の組になる。 | |
23 | |
331 | 24 --(a.*f)(b.*f) を考えよう |
25 | |
26 abcfbffbcdf は、この正規表現にマッチする。a.*fb.*f と書いても良い。 | |
27 | |
28 a.*f は以下の状態遷移で書ける。 | |
29 | |
30 State は a0,a1,ae,af で、ae ならば受理。 | |
31 | |
32 δa a0 a = a1 | |
33 δa a1 f = ae | |
34 δa a1 _ = a1 | |
35 δa a0 _ = af | |
36 | |
37 b.*f もどうように書ける。 | |
38 | |
39 δb b0 b = b1 | |
40 δb b1 f = be | |
41 δb b1 _ = b1 | |
42 δb b0 _ = bf | |
43 | |
44 これを使って、a.*fb.*f を受理してみる。 | |
45 | |
46 <center><img src="fig/af-concat.svg"></center> | |
47 | |
48 受理パターンは二通りある。これを非決定性があるという。 | |
49 | |
50 この状況は、f がきた時に a.*f を終了しても良く、終了しなくてよいことから来てる。 | |
51 | |
52 なので、それを許すオートマトンを考える。 | |
53 | |
141 | 54 --非決定性オートマトン |
55 | |
331 | 56 オートマトンの状態遷移は関数だった。 |
57 | |
58 δ : Q → Σ → Q | |
59 | |
60 その代わりに、複数の状態を許したい。Aの場合なら、f でaeにもa1にもいって良い。 | |
61 それには、a1の状態で f がきた時に ae と a1 で true を返すようにすると良い。 | |
62 行き先の状態を Q → Bool で、部分集合として指定する。 | |
141 | 63 |
331 | 64 record NAutomaton ( Q : Set ) ( Σ : Set ) |
65 : Set where | |
66 field | |
67 Nδ : Q → Σ → Q → Bool | |
68 Nend : Q → Bool | |
69 | |
70 これを非決定性オートマトンという。 | |
71 | |
72 入力にそって、可能な状態の集合を作ってやれば良い。そうすると | |
73 決定性オートマトンにできる。 | |
74 | |
75 <center><img src="fig/afbf.svg"></center> | |
76 | |
77 | |
78 --もう一つの例 | |
79 | |
80 | |
81 この場合では 1 が来た時に q1 に行っても、q2,q3 に行っても良い。q1から始める。 | |
141 | 82 |
83 q1 0 → q1 | |
84 q1 1 → q1 | |
85 q1 1 → q2 | |
86 q1 1 → q3 | |
87 q2 0 → q3 | |
88 q3 1 → q4 | |
89 q4 0 → q4 | |
90 q4 1 → q4 | |
91 | |
92 最後に q4で accept。 | |
93 | |
94 <center><img src="fig/nfa.svg"></center> | |
95 | |
96 この時に、入力に従って状態の部分集合を計算していく方法でNFAのacceptを決定できる。 | |
97 | |
98 このNFA(nondeterministic automaton)は .*(101|11).* に対応している。 | |
99 | |
100 | |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
101 --Agda での非決定性オートマトン |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
102 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
103 ここでは、部分集合を写像を使って表す。集合 Q から Bool (true または false) への写像を使う。true になる要素が |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
104 部分集合になる。すると、遷移関数は入力Σと状態から Bool への写像となる。終了条件は変わらない。 |
37 | 105 |
106 record NAutomaton ( Q : Set ) ( Σ : Set ) | |
107 : Set where | |
108 field | |
69 | 109 Nδ : Q → Σ → Q → Bool |
110 Nend : Q → Bool | |
37 | 111 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
112 これを非決定性オートマトンという。Agda では同じ名前を使いまわしすることはできない(monomorpphism)ので、Nを付けた。 |
37 | 113 |
331 | 114 たとえば、以下のように非決定的な状態遷移を定義する |
115 | |
116 transition3 : States1 → In2 → States1 → Bool | |
117 transition3 sr i0 sr = true | |
118 transition3 sr i1 ss = true | |
119 transition3 sr i1 sr = true | |
120 transition3 ss i0 sr = true | |
121 transition3 ss i1 st = true | |
122 transition3 st i0 sr = true | |
123 transition3 st i1 st = true | |
124 transition3 _ _ _ = false | |
125 | |
126 | |
127 <a href="../agda/src/nfa.agda"> nfa.agda </a> | |
37 | 128 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
129 --NAutomatonの受理と遷移 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
130 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
131 非決定性オートマトンでは、一つの入力に対して、複数の状態が行き先になる。複数の状態を経由した経路のどれかが |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
132 入力を読み終わった後に、終了状態になれば受理されることになる。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
133 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
134 このためには、状態の集合Qから条件 P : Q → Bool で true になるものを見つけ出す必要がある。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
135 |
326 | 136 --状態と入力の List を使って深さ優先探索する |
137 | |
138 {-# TERMINATING #-} | |
139 NtraceDepth : { Q : Set } { Σ : Set } | |
140 → NAutomaton Q Σ | |
141 → (Nstart : Q → Bool) → List Q → List Σ → List (List ( Σ ∧ Q )) | |
142 NtraceDepth {Q} {Σ} M sb all is = ndepth all sb is [] [] where | |
143 ndepth : List Q → (q : Q → Bool ) → List Σ → List ( Σ ∧ Q ) → List (List ( Σ ∧ Q ) ) → List (List ( Σ ∧ Q ) ) | |
144 ndepth1 : Q → Σ → List Q → List Σ → List ( Σ ∧ Q ) → List ( List ( Σ ∧ Q )) → List ( List ( Σ ∧ Q )) | |
145 ndepth1 q i [] is t t1 = t1 | |
146 ndepth1 q i (x ∷ qns) is t t1 = ndepth all (Nδ M x i) is (⟪ i , q ⟫ ∷ t) (ndepth1 q i qns is t t1 ) | |
147 ndepth [] sb is t t1 = t1 | |
148 ndepth (q ∷ qs) sb [] t t1 with sb q /\ Nend M q | |
149 ... | true = ndepth qs sb [] t ( t ∷ t1 ) | |
150 ... | false = ndepth qs sb [] t t1 | |
151 ndepth (q ∷ qs) sb (i ∷ is) t t1 with sb q | |
152 ... | true = ndepth qs sb (i ∷ is) t (ndepth1 q i all is t t1 ) | |
153 ... | false = ndepth qs sb (i ∷ is) t t1 | |
154 | |
155 確かに動く。しかし、複雑すぎる。 | |
156 | |
157 --状態の部分集合を使う | |
158 | |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
159 true になるものは複数あるので、やはり部分集合で表される。つまり、 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
160 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
161 exists : ( P : Q → Bool ) → Q → Bool |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
162 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
163 このような関数を実現する必要がある。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
164 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
165 もし、Q が有限集合なら、P を順々に調べていけばよい。やはり List で良いのだが、ここでは Agda の Data.Fin を使ってみよう。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
166 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
167 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
168 --NAutomatonの受理と遷移 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
169 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
170 状態の受理と遷移は exists を使って以下のようになる。 |
37 | 171 |
172 Nmoves : { Q : Set } { Σ : Set } | |
173 → NAutomaton Q Σ | |
332 | 174 → (exists : ( Q → Bool ) → Bool) |
175 → ( Qs : Q → Bool ) → (s : Σ ) → ( Q → Bool ) | |
176 Nmoves {Q} { Σ} M exists Qs s = λ q → exists ( λ qn → (Qs qn /\ ( Nδ M qn s q ) )) | |
37 | 177 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
178 Qs は Q → Bool の型を持っているので、Qs qn は true または false である。今の状態集合 Qs に含まれていて、 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
179 Nδ M qn s q つまり、非決定オートマトン M の遷移関数 Nδ : Q → Σ → Q → Bool で true を返すものが存在すれば |
326 | 180 遷移可能になる。(だいぶ簡単になった) |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
181 |
332 | 182 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
183 Naccept : { Q : Set } { Σ : Set } |
37 | 184 → NAutomaton Q Σ |
332 | 185 → (exists : ( Q → Bool ) → Bool) |
69 | 186 → (Nstart : Q → Bool) → List Σ → Bool |
332 | 187 Naccept M exists sb [] = exists ( λ q → sb q /\ Nend M q ) |
188 Naccept M exists sb (i ∷ t ) = Naccept M exists (λ q → exists ( λ qn → (sb qn /\ ( Nδ M qn i q ) ))) t | |
69 | 189 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
190 Naccept では終了条件を調べる。状態の集合 sb で Nend を満たすものがあることを exists を使って調べればよい。 |
69 | 191 |
37 | 192 --例題 |
193 | |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
194 例題1.36 を考えよう。状態遷移関数は以下のようになる。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
195 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
196 transition136 : StatesQ → A2 → StatesQ → Bool |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
197 transition136 q1 b0 q2 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
198 transition136 q1 a0 q1 = true -- q1 → ep → q3 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
199 transition136 q2 a0 q2 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
200 transition136 q2 a0 q3 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
201 transition136 q2 b0 q3 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
202 transition136 q3 a0 q1 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
203 transition136 _ _ _ = false |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
204 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
205 教科書にはε遷移(入力がなくても遷移できる)があるが、ここでは、ε遷移先の矢印を全部手元に持ってきてしまうという |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
206 ことしてしまう。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
207 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
208 end136 : StatesQ → Bool |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
209 end136 q1 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
210 end136 _ = false |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
211 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
212 start136 : StatesQ → Bool |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
213 start136 q1 = true |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
214 start136 _ = false |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
215 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
216 nfa136 : NAutomaton StatesQ A2 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
217 nfa136 = record { Nδ = transition136; Nend = end136 } |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
218 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
219 <a href=" ../agda/nfa136.agda"> 1.36 の例題 </a> |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
220 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
221 example136-1 = Naccept nfa136 finStateQ start136( a0 ∷ b0 ∷ a0 ∷ [] ) |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
222 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
223 最初の状態 q1 から a0 ∷ b0 ∷ a0 ∷ [] の入力を受けとる場合を考える。 |
37 | 224 |
104
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
225 a0 を受けとると、q1 にしか行けない。q1 で b0 を受けとると、q2 に移動する。q2 で a0 を受けとると、q3 か、または、 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
226 q2 に行ける。どちらも終了状態ではないので、不受理となる。ここで、もう一つ a0 が来れば q3 から q1 に行ける。q2 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
227 から行けないが、どれかの経路が成功すれば良いので受理となる。 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
228 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
229 example136-2 = Naccept nfa136 finStateQ start136( a0 ∷ b0 ∷ a0 ∷ a0 ∷ [] ) |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
230 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
231 |
fba1cd54581d
use exists in cond, nfa example
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
69
diff
changeset
|
232 |
326 | 233 |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 |