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

無料レッスン

形式手法の基礎

レッスン全文をここで読めます。無料アカウントを作成すると、実際のラボで実践できます。

仮想マシンラボ読了目安 13分コマンド7個

テストはすべてを試せない

あるゲームで、2 人のプレイヤーが同じ瞬間に最後のチケットを取れるとします。1000 回テストしても動きます。ところがバグは出来事のある特定の順番で起き、1001 回目に現れます。形式手法はケースを試しません。機械にすべてのケースを調べさせます。

このレッスンが終わると

メモ

性質が偽のとき、ソルバーとモデル検査器が何を返すかを言える。

キーワード

  • 性質: システムについて、いつも成り立つべき主張。
  • ソルバー: ルールに合う値を見つけるプログラム。
  • モデル検査器: モデルが到達できるすべての状態を試すプログラム。
  • 不変条件: すべての状態で成り立つべき性質。
  • 反例: 性質が偽であることを示す実行。
  • モデル: 細部を省いた、システムの小さな説明。

ウォームアップ: すでに知っていること

メモ

頭の中で答えましょう。1. 変数とは何ですか。2. if の条件とは何ですか。3. 2 つのプログラムが同時に同じものを変えると、何が起こりえますか。3 つ目の答えがすぐに必要になります。

始める前に

メモ

このレッスンの上のバーにあるラボを起動を押します。このラボは自分専用の Ubuntu マシンまるごとなので、コンテナより起動に少し時間がかかります。各実行ボタンは、そのコマンドをマシンのターミナルに、同じセッションの中で順番に入力します。マシンがまだ起動中と出たら、数秒待ってからもう一度押します。Java のツールは最初の実行に数秒かかります。見守りたいとき、自分で入力したいときは、バーのターミナルを開くを押します。

ソルバーは値を見つけるか、ないことを証明する

Z3 はソルバーです。ルールを渡すと、例といっしょに sat (充足可能: 合う値がある) と答えるか、unsat (合う値がない) と答えます。最初のコマンドはバージョンを表示します。2 つ目は、3 より大きく 6 より小さい数 x を求め、Z3 は sat と答えて x を 4 とします。3 つ目は、5 より大きく 3 より小さい数を求め、Z3 は unsat と答えます。こうして証明します。主張を証明するには、それが成り立たないケースを求めて unsat を得ます。

コマンド
z3 --version

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

コマンド
echo '(declare-const x Int) (assert (and (> x 3) (< x 6))) (check-sat) (get-model)' | z3 -in

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

コマンド
echo '(declare-const x Int) (assert (and (> x 5) (< x 3))) (check-sat)' | z3 -in

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

チェック

ヒント

Z3 が時間割のルールに unsat と答えました。時間割は見つかりましたか。答え: いいえ。unsat は、すべてのルールを満たす時間割がないということで、ルールが互いに矛盾しています。

モデル検査器は悪い順番を見つける

SPIN は Promela で書いたモデルを検査します。あなたのラボにもあり、2 人の作業者が共有のカウンターに 1 を足し、ロックはまだ何もしません。spinrun は検査器を作り、作業者が取りうるすべての順番に対して実行します。assertion violated (inside==1) と errors: 1 を表示し、トレースを残します。2 つ目のコマンドはそのトレースを 1 歩ずつ再生します。どちらかが出る前に、両方の作業者が inside = (inside+1) を実行しています。

コマンド
spinrun formal/spin/main.pml

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

コマンド
spin -t -p formal/spin/main.pml

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

よくある間違い

注意

モデル検査器はプログラムが正しいことを証明する、と考える人がよくいます。証明するのは、モデルが自分で書いた性質を持つことだけで、それ以上ではありません。TRUE の不変条件は決して破られないので、検査器はすぐに通し、何も教えてくれません。性質には、壊れたシステムなら満たさないことを書く必要があります。

不変条件は、正しいシステムにとっても偽になりうる

TLA+ はシステムを状態とステップで記述し、TLC がそれを検査します。ラボの Lock.tla には 2 つのプロセスがあり、それぞれ idle、wait、cs (クリティカルセクションの中) のどれかです。この不変条件は、両方が同時に待っていることはない、と言っています。これは正しいロックにとっても偽で、TLC は Invariant NotBothWaiting is violated と、両方のプロセスが wait になる 3 状態の反例を表示します。ラボ本来の課題は別の不変条件です。

コマンド
tlc formal/tla/Lock NotBothWaiting

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

反例は人の絵になることもある

Alloy は物と物の関係を記述し、主張を壊す小さな例を探します。ここでは物は人で、関係は誰が誰の友人かです。alloy はファイルの 2 つのコマンドを実行します。check Symmetric は SAT を表示します。Alloy が反例を見つけたのです。一方が相手を友人と数え、相手は数えない 2 人で、Person$1->Person$0 と表示されます。run Meet も SAT を表示し、見るための例が見つかったことを示します。check では、SAT は主張が偽ということです。

コマンド
alloy formal/alloy/model.als

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

さあ、ラボに取り組もう

ヒント

ソルバー、トレース、反例、インスタンスを見ました。ラボでは、ルール、ロック、不変条件、修正を自分で書き、それを各ツールが検査します。ターミナルで cat README.md を実行して、ホームフォルダの README.md を開きましょう。

最後のチェック

ヒント

見返さずに答えましょう。1. ルールに合う値がないとき、Z3 は何と答えますか。2. 反例とは何ですか。3. TRUE の不変条件の何がいけませんか。4. Alloy の check で SAT は何を意味しますか。答え: unsat。性質が偽であることを示す実行。決して破られないので何も証明しない。反例が見つかった。

先生へ

ヒント

このレッスンは VM ラボで進めます。生徒はそれぞれ 4 つの検証ツールが入った自分専用の Ubuntu マシンを持ち、実行ボタンはそのターミナルに入力して出力を見せます。要点: 1. ソルバーは、例とともに sat、または例なしの unsat と答える。2. モデル検査器は出来事のすべての順番を試し、性質が破れると反例を返す。3. TRUE の不変条件は何も証明しない。4. 反例はツールの証拠で、性質が間違っていたことを示すこともある。よくある間違い: 合格はシステムが正しいという意味だと考えること。準備: ラボとブラウザ。TLC と Alloy は GitHub に届くサインイン済みの VM が必要です。ヒント: spinrun の前に、悪い順番を手で見つけさせてみましょう。ラボ自体に、各ツールを実行するチェックがあります。

このラボとソースについて: 形式手法のラボ:1 つの VM で Z3、SPIN、TLA+、Alloy

授業で教えていますか?これらのレッスンを生徒に割り当て、採点と生徒ごとのラボを使えます。