全体ミーティング 2009-09-16
DESCRIPTION
全体ミーティング 2009-09-16. M1 渡邊裕貴. 今日の内容. Ynot 命令型言語の形式的検証を行う 定理 証明支援 系 Coq のためのライブラリ http://ynot.cs.harvard.edu/ “ Ynot : Reasoning with the Awkward Squad” Aleksandar Nanevski , et al. ICFP'08 - PowerPoint PPT PresentationTRANSCRIPT
今日の内容• Ynot– 命令型言語の形式的検証を行う– 定理証明支援系 Coq のためのライブラリ
– http://ynot.cs.harvard.edu/– “Ynot: Reasoning with the Awkward Squad”
Aleksandar Nanevski, et al. ICFP'08– “Effective Interactive Proofs for Higher-Order Imperative
Programs”Adam Chlipala, et al. ICFP'09
前提知識• 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
9
ラムダ計算 ホーア論理関数型プログラミング 命令型プログラミング
• 副作用のない演算 自然数の加算・比較など
• 高階関数
• 副作用を持つ命令 メモリ領域の確保や読み書
き• 事前条件・事後条件による
アサーションアサーションの正しさを型システムで検証
命令のモナド化• 命令をモナドに閉じ込め、専用の型を与
える– ラムダ計算では副作用のある命令を直接扱えないの
で
– モナドの型は「事前条件」「計算結果の型」「事後条件」からなる
– 例えば命令「 ref 1 」のモナドの型は{ emp } p : pointer { p ↦ 1 }
Ynot
• Hoare Type Theory で定義された言語と検証ルールを Coq 上に実装したライブラリ
• 基本的な使い方 :1. 書きたいプログラムの仕様 (= 型 ) を与える2. その仕様を満たすプログラムを与える
+ それが仕様を満たしていることを証明する
簡単な例• 「 ref 」を定義してみる
Definition ref (T : Set) (v : T) : Cmd emp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac.Defined.
• ref: – 型 T とその型の値 v を受け取り、
新たなメモリ領域一つを確保し、 v で初期化し、
そのポインタを返す
簡単な例• 「 ref 」を定義してみる
Definition ref (T : Set) (v : T) : Cmd emp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac.Defined.
ref の名前と引数の宣言
簡単な例• 「 ref 」を定義してみる
Definition ref (T : Set) (v : T) : Cmd emp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac.Defined.
事前条件 結果の型 事後条件
モナドの型 (= プログラムの仕様 ) を与える
簡単な例• 「 ref 」を定義してみる
Definition ref (T : Set) (v : T) : Cmd emp (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) : Cmd emp (fun p : ptr => p --> v). intros; refine {{New v}}; sep fail idtac.Defined.
“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
– 必要に応じてユーザーが引数を指定する• データ構造に応じた補題の証明・適用
評価• プログラム対証明比は他の検証ツールとほぼ同じ– vs. Smallfoot, vs. Jahob
• 実装例のソース内訳仕様の宣言 プログラム本体 証明 ( 補題等含
む )
ハッシュテーブル
21 行 34 行 142 行
PEG パーサ 110 行 277 行 162 行