クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

有限オートマトンとは

このレッスンのあとで: 遷移表をたどって、有限オートマトンがある文字列を受理するかどうか言える。

50分のレッスンコマンド3件コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

1と2のボタンだけの錠

有限オートマトンとは、決まった数の状態を持ち、入力を1文字ずつ読んで受理か拒否かを答える、最も単純な計算の機械です。自動改札や錠のように、順番に押すものの設計に使われます。

ボタンが1と2だけの錠を考えます。1、2の順に続けて押すと開く錠は、何を覚えていればよいでしょうか。答えは、直前に1を押したかどうかです。

このレッスンのゴール

メモ

遷移表をたどって、有限オートマトンがある文字列を受理するかどうか言える。

重要な言葉

ことばいみ
状態機械が今いる場所。覚えていることのすべて
遷移文字を1つ読んで、次の状態へ移ること
遷移表状態と文字から、次の状態を決める表
初期状態読み始める前にいる状態
受理状態読み終えたときここにいれば受け入れる状態
受理機械が文字列を正しいと認めること

学生が入力するセルは、このプレビューでは空白です。

機械は状態を1つずつ移る

機械は、いつも状態のどれか1つにいます。文字を1つ読むたびに、遷移表に従って次の状態へ移ります。

錠の状態は3つです。何もない「待ち」、1を押した「1押した」、開いた「開く」。覚えているのは、この3つだけです。

2112 を読むと

読む文字前の状態次の状態
2待ち待ち
1待ち1押した
11押した1押した
21押した開く
読み終わり開く受理する

学生が入力するセルは、このプレビューでは空白です。

錠を動かす Python

コード: python
# 1、2の順に押すと開く錠。状態は3つです。
table = {
    "wait": {"1": "one", "2": "wait"},
    "one": {"1": "one", "2": "open"},
    "open": {"1": "open", "2": "open"},
}
text = "2112"   # ここを "2211" に変えて、もう一度実行しましょう。
state = "wait"
for ch in text:
    state = table[state][ch]
    print(ch, "を読んで", state)
print("受理:", state == "open")

受理は最後の状態で決まる

文字をすべて読み終えたとき、受理状態にいれば受理です。いなければ拒否です。途中で通った状態は関係ありません。

何も読まない空の文字列も、初期状態が受理状態なら受理されます。表にない文字が来たときも、拒否と決めておきます。

ラボで同じ錠を動かす

同じ錠を、ラボの端末で動かします。1つ目の Run は lock.py というファイルを作るだけで、画面には何も出しません。

2つ目と3つ目は、押した順を引数に渡して、1文字ごとの状態を出します。最後の行が True なら受理です。

錠のファイルを作る

コマンド
printf 'import sys\ntable = {"wait": {"1": "one", "2": "wait"}, "one": {"1": "one", "2": "open"}, "open": {"1": "open", "2": "open"}}\nstate = "wait"\nfor ch in sys.argv[1]:\n    state = table[state][ch]\n    print(ch, state)\nprint(state == "open")\n' > lock.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

2112 を押す

コマンド
python3 lock.py 2112

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

2211 を押す

コマンド
python3 lock.py 2211

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

途中で受理状態を通れば受理、と思いがちです。そうではなく、受理かどうかは読み終えた状態だけで決まります。偶数個の1を受理する機械は、111 を読む途中で一度受理状態を通りますが、最後は奇数なので拒否です。

なぜ「有限」なのか

状態の数は決まっています。だから、1を何個読んだかを、いくつでも数え続けることはできません。

1が偶数個か奇数個かなら、2つの状態で覚えられます。この「覚えられる量に限りがある」ことが、次のレッスン以降の話の土台です。

さらに挑戦: 3の倍数の機械

2進数の文字列が、3の倍数かどうかを調べる機械を作れます。状態は3つで、「3で割った余り」が0、1、2の場合です。

遷移表を紙に書き、run_dfa に渡して、"110"(6)が受理され、"101"(5)が拒否されることを確かめましょう。

このラボとソースについて: コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。