260 likes | 363 Views
全体ミーティング 2009-09-16. M1 渡邊裕貴. 今日の内容. Ynot 命令型言語の形式的検証を行う 定理 証明支援 系 Coq のためのライブラリ http://ynot.cs.harvard.edu/ “ Ynot : Reasoning with the Awkward Squad” Aleksandar Nanevski , et al. ICFP'08
E N D
全体ミーティング2009-09-16 M1 渡邊裕貴
今日の内容 • Ynot • 命令型言語の形式的検証を行う • 定理証明支援系 Coq のためのライブラリ • http://ynot.cs.harvard.edu/ • “Ynot: Reasoning with the Awkward Squad”AleksandarNanevski, et al. ICFP'08 • “Effective Interactive Proofs for Higher-Order Imperative Programs”Adam Chlipala, et al. ICFP'09
Ynotの目新しいところ • 自動化された証明と人間による証明を両方扱える • 高階関数を扱う命令型言語の(ある程度) 自動化された検証
前提知識 • Coq • 定理証明支援系 • Separation Logic • 命令型言語のメモリ操作を検証する論理体系 • Hoare Type Theory • 高階関数を扱う命令型言語を検証する型システム
Coq • 定理証明支援系 • 人間が証明を書くのを対話的フロントエンドで補助する • 証明が正しいかどうかチェックする • http://coq.inria.fr/ • Ynot ではプログラムが仕様を満たしているかどうかを定理として証明する
Coqでの証明の例 証明する命題を宣言 Coq < Goal 1 + 1 = 2. 1 subgoal ============================ 1 + 1 = 2 Unnamed_thm < unfold plus. 1 subgoal ============================ 2 = 2 Unnamed_thm < reflexivity. Proof completed. 証明を進めるコマンド (tactic) を入力
Separation Logic • 命令型言語のメモリ操作を検証する論理体系 • Reynolds 2002 • メモリ領域をうまく細分化することでメモリの変化・不変化を容易に検証する • ホーア論理の拡張 • 公理の例 { emp } p = ref v { p↦v } { ∃v. p↦ v } p := w { p↦w }
Separation Logic の Frame Rule • 「コードが触らないメモリ領域は変化しない」 • P1 * P2は P1と P2が表わす二つのメモリ領域を合わせた状態を指す。ただし二つの領域は重ならない。 • これを使うと例えば{ p↦1 * q↦1 } p := 2 { p↦2 * q↦1 } が証明できる
Hoare Type Theory • 型付ラムダ計算にホーア論理を組込んだ型システム • Nanevski and Morrisett 2005, 2006 アサーションの正しさを型システムで検証
命令のモナド化 • 命令をモナドに閉じ込め、専用の型を与える • ラムダ計算では副作用のある命令を直接扱えないので • モナドの型は「事前条件」「計算結果の型」「事後条件」からなる • 例えば命令「ref 1」のモナドの型は{ emp } p : pointer { p↦1 }
Ynot • Hoare Type Theory で定義された言語と検証ルールを Coq 上に実装したライブラリ • 基本的な使い方: • 書きたいプログラムの仕様 (=型) を与える • その仕様を満たすプログラムを与える+ それが仕様を満たしていることを証明する
簡単な例 • 「ref」を定義してみる Definition ref (T : Set) (v : T) : Cmdemp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac. Defined. • ref: • 型 Tとその型の値 vを受け取り、新たなメモリ領域一つを確保し、vで初期化し、そのポインタを返す
簡単な例 • 「ref」を定義してみる Definition ref (T : Set) (v : T) : Cmdemp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac. Defined. ref の名前と引数の宣言
簡単な例 • 「ref」を定義してみる Definition ref (T : Set) (v : T) : Cmdemp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac. Defined. 事前条件 結果の型 事後条件 モナドの型 (=プログラムの仕様) を与える
簡単な例 • 「ref」を定義してみる Definition ref (T : Set) (v : T) : Cmdemp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac. Defined. プログラム プログラムを与え、仕様を満たしていることを証明する
何を証明するのか? • 宣言した事前条件は実際に書いたプログラムの事前条件を満たすこと • 実際に書いたプログラムの事後条件は宣言した事後条件を満たすこと • 事前条件の強化・事後条件の弱化
ダミーの引数 • ポインタの指す自然数をインクリメントする例 Definition incr (p : ptr) (n : [nat]) : Cmd (n ~~ p --> n) (fun _ : unit => n ~~ p --> (n + 1)). intros; refine (v <- !p; {{p ::= v + 1}}); sep fail idtac. Defined. • 実際のプログラムの引数ではないが事前・事後条件を表すために nを使っている
通常の論理式を条件に含める • ポインタの指す値を読み取る例 Definition read (T : Set) (p : ptr) (v : [T]) : Cmd (v ~~ p --> v) (fun v' => v ~~ p --> v * [v = v']). intros; refine {{!p}}; sep fail idtac. Defined. • 事前・事後条件の中に普通の論理式を書くには[ ]を用いる
The “sep” tactic • Ynot ライブラリ内で定義された tactic • Separation Logic に関する証明の多くを自動で行う • 定義は非常に複雑です…… Definition ref (T : Set) (v : T) : Cmdemp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac. Defined.
“sep” の働き (1) • 単純な制約の解決 • 例:p↦v⇒ ?1 (?1 に当てはまる式を見つける) • ?1 = p↦v
“sep” の働き (2) • もう少し複雑な制約の解決 • 例:∃v. p↦ v * P(v) ⇒ ?2 *∃x. p↦ x • p↦ v’ * P(v’) ⇒ ?2 *p↦ ?3 • p↦ v’ と p↦ ?3を対応させると ?3 = v’ • P(v’) ⇒ ?2 • 量化子を戻して • ∃v. P(v) ⇒ ?2 • ?2 = ∃v. P(v)
“sep” の限界 • “sep” tactic の二つの引数は探索の前・途中に試す tactic を指定する • いつも “sep fail idtac” でうまくいくわけではない • 再帰的データ構造の場合分けなど • “fail”, “idtac” は何もしない tactic • 必要に応じてユーザーが引数を指定する • データ構造に応じた補題の証明・適用
Ynotで実装できるもの • ライブラリに実装例があるもの • スタック • キュー • 配列 • ハッシュテーブル • ファイルの読み書き • PEG パーサ
評価 • プログラム対証明比は他の検証ツールとほぼ同じ • vs. Smallfoot, vs. Jahob • 実装例のソース内訳
まとめ • 高階関数を扱う命令型言語を検証するライブラリ Ynotを紹介した • 簡単な例 • “sep” tactic の働き
Future Work • Concurrency • Full correctness • 停止性の保証 • I/O