Coq 20100208a

36
Coq and Why : Formal Verification Tools 2010/02/08 tmiya

description

第1回FormalMethods勉強会

Transcript of Coq 20100208a

Page 1: Coq 20100208a

Coq and Why :Formal Verification Tools

2010/02/08tmiya

Page 2: Coq 20100208a

自己紹介• ハンドル名 : tmiya

– Blog : Functional Programming Memo• http://study-func-prog.blogspot.com/• Scala とか主として関数型言語関係の勉強のメモ

– 仕事 : SIer 勤務(時々プログラミングの仕事)– 興味 : 形式手法(モデル検査とか定理証明とか)、関数型言語とか

• 2007- : Scala 普及活動– “A Scala Tutorial for Java Programmer” を和訳– Step by Step Scala 講師を数回– ITpro に Scala 2.8 の記事を書きました

• 形式仕様 : まだまだ勉強中– Coq : 社内勉強会向けにちょっと調べた– Agda : 産総研のセミナーを聞いた– B-method : 先日セミナーを聞いた

• という訳で、専門家じゃないです。

Page 3: Coq 20100208a

3

内容

• 形式手法とは?• Coq とは?• 理論的背景を少し• Coq を動かしてみよう• Design by Contract• Why を動かしてみよう• まとめ

Page 4: Coq 20100208a

4

形式手法とは?

Page 5: Coq 20100208a

形式手法 (Formal Method)

5

自然言語の仕様

形式仕様

モデル

モデル検査:モデルが仕様を満たす事を網羅的にチェック

プログラム

プログラム検証:実装が仕様を満たす事を証明プログラム生成:陰仕様から陽仕様へと具体化⇒実装を生成

形式仕様記述:機械的検証可能な記述

仕様アニメーション:実装前に仕様を動かして確認 (Lightweight FM)

形式手法といっても色々。一つのツールが複数を行う場合あり。最近は主として上流行程のミスを減らす為の手法として注目。

動作確認

上流行程

下流行程

Coq は証明からプログラム生成

Why はプログラム検証

Page 6: Coq 20100208a

6

定理証明系の色々• The Seventeen Provers of the World

– http://math.boisestate.edu/~tconklin/MATH124/Main/Readings/2%20Logic/PDFs/The%20Seventeen%20Provers%20of%20the%20World.pdf

– 各種定理証明系での「√ 2 が無理数である」ことの証明を比較

上流下流揃っているツールが最強?

全ての証明を自動化出来ない。最後は人間が証明出来ないと画竜点睛を欠く。

証明について理解していないと良い事前条件や不変条件、停止を保証するループ変数を定義出来ない。

証明の行いやすさ重要

Page 7: Coq 20100208a

7

Coq とは?

Page 8: Coq 20100208a

8

Coq とは ?

• 開発元: INRIA 研究所 @ フランス– http://coq.inria.fr/

• 定理証明支援ツール ( ある程度は自動証明 )– Coq での有名な定理の証明例• “Essential Incompleteness of Arithmetic

Verified by Coq” ( 不完全性定理 )– http://r6.ca/Goedel/goedel1.html

• “A computer-checked proof of the Four Colour Theorem” ( 四色問題 )

• プログラムの開発も出来る– プログラムを開発&正しい事を証明 ( テスト不要 )– 実行可能なプログラムを抽出 (OCaml, Haskell)

Page 9: Coq 20100208a

9

Coq 参考文献• Interactive Theorem Proving and Program

Development: Coq'Art: The Calculus of Inductive– 値段が ¥12,000 程度する…

• Certified Programming with Dependent Types– http://adam.chlipala.net/cpdt/– Harvard の授業で使用 (PDF 360 ページ程度 )– 定期的に改訂 (Latest 2010/2/3)– 読書会するとしたらこれを使うのが良さそう

• 他にも INRIA の Coq のページから Tutorial が幾つか• 浅井研のゼミ資料 ( 第1回〜第8回 )

– http://pllab.is.ocha.ac.jp/coq_print/nori_Coq1.pdf

• にわとり小屋でのプログラミング日記– http://d.hatena.ne.jp/yoshihiro503/

• Coq を使った証明 : まとめ– http://www.kmonos.net/pub/Presen/coq-

matome.ppt

Page 10: Coq 20100208a

10

理論的背景を少し

Page 11: Coq 20100208a

11

Curry-Howard Isomorphism

• 述語論理と型付き λ 計算の間に対応関係–狭義では、直観主義命題論理と自然演繹 ⇔

単純型付き λ 計算、の対応–証明 λ 計算の式、証明の検査型検査–例:• 連言 P∧Q (P,Q) : タプル型• 含意 P⇒Q P→Q : 関数型• Modus Ponens : (A∧(A⇒B))⇒B (A, A→B)→B

– fun t -> (snd t) (fst t) : ‘a * (‘a -> ‘b) -> ‘b– A と A→B のタプル型を引数にして B を返す関数という

Page 12: Coq 20100208a

12

自然演繹

• Gentzen による形式化。公理が少なく推論規則が多い。判りやすく「自然」。– 導入規則と除去規則(ここでは∧と⇒だけ) A B A∧B A∧B------ (∧導入 ) ------ ------ (∧除去 ) A∧B A B

[A] // 仮定 B A A⇒B------ (⇒導入 ) ------- (⇒除去 )A⇒B B

• NK:排中律ありの古典論理• NJ: 無しの直観主義論理 ( こちらを使う )

Page 13: Coq 20100208a

13

依存型 (dependent type)

• 値をパラメタとする型 = 値を引数に取って型を返す関数。– Agda, Gallina, Epigram, Isabelle とかが依存型をサポー

トする言語• 型も言語の first-class citizen 。

– Vec 5 = 要素数 5 のべクトルの「型」。• append : Vec n -> Vec m -> Vec (n+m)• 行列計算とか次数が一致している事が型で保証出来る。• コンパイラを通った時点で OutOfBounds が起きないことを保証。

• 型命題論理• 依存型一階述語論理

– ∀x∈A.P(x) Πx:A. P x

Page 14: Coq 20100208a

14

Coq を動かしてみよう

Page 15: Coq 20100208a

15

Coq の Install

• Mac の場合– MacPorts で導入して終わり

• $ sudo port install coq• ocaml, camlp5, coq をインストール

– coq-8.2-intel.dmg => Coq, CoqIde• gtk2, Coq の pkg

• Win の場合– coq-8.2-1-win.exe => Coq, CoqIde

Page 16: Coq 20100208a

16

Coq を動かしてみる% coqtop // coqtopで対話環境に入るWelcome to Coq 8.2 (March 2009)

Coq < Check 3. // Check で型を調べる。文末のピリオド重要。3 : nat

Coq < Check and.and : Prop -> Prop -> PropCoq < Unset Printing Notations.

Coq < Check 3. // 3はsyntax sugarで、実はnatはペアノの自然数S (S (S O)) : nat

Coq < Quit. // Quit.で終了%

Page 17: Coq 20100208a

17

帰納的関数の定義 / プログラム抽出Coq < Print plus. // 予め定義されているplus = fix plus (n m : nat) : nat := match n with | 0 => m | S p => S (p + m) end : nat -> nat -> natCoq < Extraction “plus.ml” plus. // OCaml プログラムとして抽出% cat plus.mltype nat = | O | S of nat(** val plus : nat -> nat -> nat **) // 普通の Ocaml の関数let rec plus n m = match n with | O -> m | S p -> S (plus p m)

Page 18: Coq 20100208a

18

帰納的関数の性質の証明 (1)Coq < Theorem t : forall n m : nat, n + m = m + n. // これを証明する。1 subgoal ============================ forall n m : nat, n + m = m + nt < intros. // forall の除去。初手は大抵 intros.1 subgoal n : nat m : nat ============================ n + m = m + nt < induction n. // n について帰納法。 0 と (S n) とに場合分け2 subgoals m : nat ============================ 0 + m = m + 0 // n=0 の場合subgoal 2 is: S n + m = m + S nt < simpl; trivial. // 0 + m = m + 0 を簡単化すると自明な式に。

Page 19: Coq 20100208a

19

帰納的関数の性質の証明 (2)1 subgoal n : nat m : nat IHn : n + m = m + n  // 帰納法の前提

============================

S n + m = m + S nt < rewrite plus_Sn_m.1 subgoal n : nat m : nat IHn : n + m = m + n

============================

S (n + m) = m + S n

t < rewrite <- plus_n_Sm.1 subgoal n : nat m : nat IHn : n + m = m + n

============================

S (n + m) = S (m + n)t < apply eq_S.1 subgoal n : nat m : nat IHn : n + m = m + n

============================

n + m = m + nt < exact IHn.Proof completed.t < Qed.

Coq < Check plus_Sn_m.plus_Sn_m: forall n m : nat, S n + m = S (n + m)

Coq < Check eq_S.eq_S: forall x y : nat, x = y -> S x = S y

Page 20: Coq 20100208a

20

自然演繹の推論規則と tactic記号 導入

( Goal に記号がある時 )

除去(仮定に記号がある時 )

→ (->) intro. apply H.

∧ (/¥) split. elim H.

∨ (¥/) left. か right. elim H.

¬ (~) intro. elim H.

∃ (exists) exists v. elim H.

∀ (forall) intro. apply H.

Page 21: Coq 20100208a

21

その他のコマンド (tactic)

• Require Import ライブラリ .– 例えば Arith とか。

• Undo. : 一手戻る。• Locate パターン . : 定義を探す– Locate “_ < _”.– Locate したら Print で内容確認。

• Search 演算子 : 定理を探す ( 重要 !!)– Search eq. とか。

• SearchPattern パターン : 定理を探す– SearchPattern ((_ + _) * _ = _) とか

Page 22: Coq 20100208a

22

その他の tactic• Tactic は 50個以上ある…。全部は紹介出来ない(フォローしてない)• apply は ( 定理の仮定だけじゃなく )既存定理にも使える

• 書かれてないだけで仮定に入っていると考えても良い• apply 定理• apply 定理 with ( 変数 := 値 ) ( 変数 := 値 )• apply ( 定理 引数 引数 … )

• cut 中間ゴール , assert 中間ゴール : 証明の中間ゴールを設定する• rewrite 仮定 . : = を含む仮定を Goal に適用(左辺値を右辺値で置換)

• Goal の右辺値を左辺値で、は rewite <- 仮定。• 等式の証明では良く使う。• rewrite (仮定 引数 1 引数 2 …) で仮定に代入出来る。

• reflexivity. : apply refl_equal. (Goal が x=x の時使う )• unfold 定義 . : 関数の定義を Goal に適用。 fold は逆。• 自動証明 : auto, eauto, tauto, intuition, trivial, ring, omega, …

• それぞれ微妙に違う。色々証明を自動的にやってくれます。• Coq/tactics : Tactic の一覧と解説 ( 日本語 ) 。お薦め。

Page 23: Coq 20100208a

23

練習問題• Coq本より

– Theorem ex561 : forall A B C : Prop, A/\(B/\C) -> (A/\B)/\C.– Theorem ex562 : forall A B C D : Prop, (A->B)/\(C->D)/\A/\C

-> B/\D.– Theorem ex563 : forall A : Prop, ~(A/\~A).– Theorem ex564 : forall A B C : Prop, A\/(B\/C) -> (A\/B)\/C.– Theorem ex565 : forall A : Prop, ~~(A\/~A).– Theorem ex566 : forall A B : Prop, (A\/B)/\~A -> B.– Theorem ex567 : forall A:Set, forall P Q:A->Prop, (forall x,

P x)\/(forall y, Q y)->forall x, P x\/Q x.

• パズルゲーム感覚で解けます。– というか端から色々試すアドヴェンチャーゲーム?– 適用出来ない tactic はエラーメッセージが出るだけ。

Page 24: Coq 20100208a

24

Design by Contract

Page 25: Coq 20100208a

25

Design by Contract

• Design by Contract : 契約プログラミング– プログラムが満たすべき仕様記述をコードに埋め込む設計の安全性向上

– 事前条件、事後条件、不変条件– Eiffel で有名。 D とかも。– JML (Java Modeling Language) : コメントでアノテーションする

• Hoare 論理– 「事前条件が成立する状態で、プログラムを実行

したら、事後条件が成立する」– テスト有限な場合しかテスト出来ない。– 数学的に証明常に正しい

Page 26: Coq 20100208a

26

Hoare 論理– Hoare : プログラムが仕様に対して部分正当である

ことを証明する為の公理的手法 (1969)– Hoare Triplet : {P}S{Q}

• 事前条件 P を満たすとき、• プログラム S を実行すると• 事後条件 Q を満たす

– 命令型プログラミング言語の公理• 代入文/複合文/ if 文/while 文/帰結の公理

– 関数型言語の方が Hoare Triplet を書きやすいはず• 再帰を用いた帰納的関数のほうが相性がいい

– 良いループ不変条件を抽出するのは難しいが再帰なら楽

• 再代入、副作用が無い方が簡単に書ける– 逆にグローバル変数、ポインタ、共用体とかあると困難

Page 27: Coq 20100208a

27

Hoare 論理の公理{Q[e/x]}x:=e{Q}

{P}S1{R}, {R}S2{Q} ------------------------

{P}S1;S2{Q}

{P∧B}S1{Q}, {P∧¬B}S2{Q}-----------------------------

{P} if B then S1 else S2 {Q}

{P∧B}S{P}-----------------------------

{P} while B do S end {P∧¬B}

PP1, {P1}S{Q1}, Q1Q------------------------------

{P}S{Q}

Page 28: Coq 20100208a

28

Why

プログラムから証明へ

• Why: プログラム検証用ツール– Caduceus は obsolate Frama-C へ移行–外部の各種の証明器と連携

*.java (JML)

*.c

*.v 他Krakatoa

Caduceus

Alt-Ergo 他

自動証明。他に Simplify, CVCL, …

手動証明Coq

他に PVS, Isabelle/HOL, etc.

gwhy : GUI環境Eclipse plugin 有

Page 29: Coq 20100208a

29

Why を動かしてみよう

Page 30: Coq 20100208a

30

why をインストール (1)• Windows : whyダウンロードページに installer• Linux, Mac, etc.: ソースから make する

– 前提: OCaml, Coq // 既にインストールしてあるはず– 前提: LablGTK // GUI環境のため

lablgtk-2.14.0.tar.gz 入手 ⇒ gunzip, tar –xf⇒ ./configure ⇒ make world ⇒ sudo make install

– why の導入% lswhy-2.23.tar.gz% gunzip why-2.23.tar.gz% tar -xf why-2.23.tar % cd why-2.23% ./configure% make% sudo make install% why –version

Page 31: Coq 20100208a

31

why をインストール (2)• インストールは基本、 gunzip, tar –xf, ./configure, make, sudo

make install を繰り返すだけ。 • Alt-Ergoインストール (http://ergo.lri.fr/) : alt-ergo-0.9.tar.gz

– 前提 : ocamlgraph (http://ocamlgraph.lri.fr/) : ocamlgraph-1.3.tar.gz

• Simplifyインストール (https://mobius.ucd.ie/repos/src/mobius.atp/mobius.simplify/simplify/) : simplify-1.5.5.macosx– chmod +x simplify-1.5.5.macosx– sudo cp -p Simplify-1.5.5.macosx /usr/local/bin/simplify

Page 32: Coq 20100208a

32

Krakatoa を動かす (1)% cat Lesson1.javapublic class Lesson1 { /*@ ensures \result >= x && \result >= y && @ \forall integer z; z >= x && z >= y ==> z >= \result; @*/ public static int max(int x, int y) { if (x>y) { return x; } else { return x; }  // わざと間違い }}% why-config 最初の1回だけ% gwhy Lesson1.java GUI起動

Page 33: Coq 20100208a

33

Krakatoa を動かす (2)

… その次のサンプルコードが動かない… orz

Page 34: Coq 20100208a

34

Why を動かす (1)% cat test.whylogic min: int, int -> int axiom min_ax: forall x,y:int. min(x,y) <= x parameter r: int ref let f (n:int) = {} r := min !r n { r <= r@ }

% gwhy test.why // GUI起動 自動証明器で確認 あるいは why –-simplify で

% why --coq test.why // Coq用に proof obligationを生成する% cat test_why.v...(*Why goal*) Lemma f_po_1 : forall (n: Z), forall (r0: Z), forall (r: Z), forall (HW_1: r = (min r0 n)), r <= r0.Proof.(* FILL PROOF HERE *)Save....

Page 35: Coq 20100208a

35

Why を動かす (2)

CoqIDE 上で test_why.v を証明する。

Page 36: Coq 20100208a

36

まとめ• Coq面白いよ!

– 関数型言語ブームの次は依存型が来るよね(多分)• See “Why Dependent Types Matter” (PDF)• Java のジェネリクスの有無同様、依存型の有無が

• 「証明 =難しい」じゃなくて「証明 =パズルゲーム」– でも、覚えるべき tactic が多過ぎて大変– 多分、練習問題を沢山解かないと使い方は身に付かない– でも、事前条件、不変条件をうまく書けば事後条件はかなり自

動証明されるのでは?• 人工無脳との対話めいた感もあり

– 一昔前で言うところのエキスパートシステム– コードレヴューで人間に説明する代わりに、定理証明系に説明

すると思えば良い• Coq/Why の勉強会やりません?

– 私もプレゼン用に上っ面を撫でただけなので…