Coq 20100208a

5,256 views
5,194 views

Published on

第1回FormalMethods勉強会

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,256
On SlideShare
0
From Embeds
0
Number of Embeds
1,550
Actions
Shares
0
Downloads
32
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Coq 20100208a

  1. 1. Coq and Why :Formal Verification Tools<br />2010/02/08<br />tmiya<br />
  2. 2. 自己紹介<br />ハンドル名 : tmiya<br />Blog : Functional Programming Memo<br />http://study-func-prog.blogspot.com/<br />Scalaとか主として関数型言語関係の勉強のメモ<br />仕事 :SIer勤務(時々プログラミングの仕事)<br />興味: 形式手法(モデル検査とか定理証明とか)、関数型言語とか<br />2007- : Scala普及活動<br />“A Scala Tutorial for Java Programmer” を和訳<br />Step by Step Scala講師を数回<br />ITproにScala 2.8の記事を書きました<br />形式仕様 : まだまだ勉強中<br />Coq : 社内勉強会向けにちょっと調べた<br />Agda : 産総研のセミナーを聞いた<br />B-method : 先日セミナーを聞いた<br />という訳で、専門家じゃないです。<br />
  3. 3. 内容<br />形式手法とは?<br />Coqとは?<br />理論的背景を少し<br />Coqを動かしてみよう<br />Design by Contract<br />Whyを動かしてみよう<br />まとめ<br />3<br />
  4. 4. 形式手法とは?<br />4<br />
  5. 5. 形式手法 (Formal Method)<br />自然言語の仕様<br />形式仕様記述:<br />機械的検証可能な記述<br />上流行程<br />仕様アニメーション:<br />実装前に仕様を動かして確認 (Lightweight FM)<br />形式仕様<br />モデル検査:<br />モデルが仕様を満たす事を網羅的にチェック<br />動作確認<br />モデル<br />形式手法といっても色々。一つのツールが複数を行う場合あり。<br />最近は主として上流行程のミスを減らす為の手法として注目。<br />プログラム検証:<br />実装が仕様を満たす事を証明<br />プログラム生成:<br />陰仕様から陽仕様へと具体化⇒実装を生成<br />プログラム<br />下流行程<br />Coqは証明からプログラム生成<br />Whyはプログラム検証<br />5<br />
  6. 6. 定理証明系の色々<br />6<br />TheSeventeenProversoftheWorld<br />http://math.boisestate.edu/~tconklin/MATH124/Main/Readings/2%20Logic/PDFs/The%20Seventeen%20Provers%20of%20the%20World.pdf<br />各種定理証明系での「√2 が無理数である」ことの証明を比較<br />上流下流揃っている<br />ツールが最強?<br />全ての証明を自動化出来ない。<br />最後は人間が証明出来ないと画竜点睛を欠く。<br />証明について理解していないと良い事前条件や不変条件、停止を保証するループ変数を定義出来ない。<br />証明の行いやすさ重要<br />
  7. 7. Coqとは?<br />7<br />
  8. 8. Coqとは?<br />開発元:INRIA研究所@フランス<br />http://coq.inria.fr/<br />定理証明支援ツール (ある程度は自動証明)<br />Coqでの有名な定理の証明例<br />“Essential Incompleteness of Arithmetic Verified by Coq” (不完全性定理)<br /> http://r6.ca/Goedel/goedel1.html<br />“A computer-checked proof of the Four Colour Theorem” (四色問題)<br />プログラムの開発も出来る<br />プログラムを開発&正しい事を証明(テスト不要)<br />実行可能なプログラムを抽出 (OCaml, Haskell)<br />8<br />
  9. 9. Coq参考文献<br />Interactive Theorem Proving and Program Development: Coq&apos;Art: The Calculus of Inductive<br />値段が¥12,000程度する…<br />Certified Programming with Dependent Types<br />http://adam.chlipala.net/cpdt/<br />Harvardの授業で使用 (PDF 360ページ程度)<br />定期的に改訂 (Latest 2010/2/3)<br />読書会するとしたらこれを使うのが良さそう<br />他にもINRIAのCoqのページからTutorialが幾つか<br />浅井研のゼミ資料 (第1回〜第8回)<br />http://pllab.is.ocha.ac.jp/coq_print/nori_Coq1.pdf<br />にわとり小屋でのプログラミング日記<br />http://d.hatena.ne.jp/yoshihiro503/<br />Coq を使った証明 : まとめ<br />http://www.kmonos.net/pub/Presen/coq-matome.ppt<br />9<br />
  10. 10. 理論的背景を少し<br />10<br />
  11. 11. Curry-Howard Isomorphism<br />述語論理と型付きλ計算の間に対応関係<br />狭義では、直観主義命題論理と自然演繹 ⇔ 単純型付きλ計算、の対応<br />証明λ計算の式、証明の検査型検査<br />例:<br />連言 P∧Q  (P,Q) : タプル型<br />含意P⇒Q P->Q : 関数型<br />Modus Ponens : (A∧(A⇒B))⇒B  (A, A->B)->B<br />fun t -&gt; (sndt) (fstt) : ‘a * (‘a -&gt; ‘b) -&gt; ‘b<br />AとA->Bのタプル型を引数にしてBを返す関数という型<br />11<br />
  12. 12. 自然演繹<br />Gentzenによる形式化。公理が少なく推論規則が多い。判りやすく「自然」。<br />導入規則と除去規則(ここでは∧と⇒だけ)<br />A B A∧B A∧B<br />------ (∧導入) ------ ------ (∧除去) <br /> A∧B A B<br /> [A] // 仮定<br /> B A A⇒B<br />------ (⇒導入) ------- (⇒除去)<br />A⇒B B<br />NK:排中律ありの古典論理<br />NJ:無しの直観主義論理 (こちらを使う)<br />12<br />
  13. 13. 依存型 (dependent type)<br />値をパラメタとする型 = 値を引数に取って型を返す関数。<br />Agda, Gallina, Epigram, Isabelleとかが依存型をサポートする言語<br />型も言語のfirst-class citizen。<br />Vec 5 = 要素数5のべクトルの「型」。<br />append : Vecn -&gt; Vecm -&gt; Vec (n+m)<br />行列計算とか次数が一致している事が型で保証出来る。<br />コンパイラを通った時点でOutOfBoundsが起きないことを保証。<br />型命題論理<br />依存型一階述語論理<br />∀x∈A.P(x) Πx:A. P x<br />13<br />
  14. 14. Coqを動かしてみよう<br />14<br />
  15. 15. CoqのInstall<br />Macの場合<br />MacPortsで導入して終わり<br />$ sudo port install coq<br />ocaml, camlp5, coqをインストール<br />coq-8.2-intel.dmg =&gt; Coq, CoqIde<br />gtk2, Coqのpkg<br />Winの場合<br />coq-8.2-1-win.exe =&gt; Coq, CoqIde<br />15<br />
  16. 16. Coqを動かしてみる<br />% coqtop// coqtopで対話環境に入る<br />Welcome to Coq 8.2 (March 2009)<br />Coq &lt; Check 3. // Check で型を調べる。文末のピリオド重要。<br />3<br /> : nat<br />Coq &lt; Check and.<br />and<br /> : Prop -&gt; Prop -&gt; Prop<br />Coq &lt; Unset Printing Notations.<br />Coq &lt; Check 3. // 3はsyntax sugarで、実はnatはペアノの自然数<br />S (S (S O))<br /> : nat<br />Coq &lt; Quit. // Quit.で終了<br />% <br />16<br />
  17. 17. 帰納的関数の定義 / プログラム抽出<br />Coq &lt; Print plus. // 予め定義されている<br />plus = <br />fix plus (nm : nat) : nat := match n with<br /> | 0 =&gt; m<br /> | S p =&gt; S (p + m)<br /> end<br /> : nat -&gt; nat -&gt; nat<br />Coq &lt; Extraction “plus.ml” plus. // OCamlプログラムとして抽出<br />% cat plus.ml<br />type nat =<br /> | O<br /> | S of nat<br />(** val plus : nat -&gt; nat -&gt; nat **)// 普通のOcamlの関数<br />let rec plus nm =<br /> match n with<br /> | O -&gt; m<br /> | S p -&gt; S (plus pm)<br />17<br />
  18. 18. 帰納的関数の性質の証明(1)<br />Coq &lt; Theorem t : forallnm : nat, n + m = m + n. // これを証明する。<br />1 subgoal<br /> ============================<br />forallnm : nat, n + m = m + n<br />t &lt; intros. // forallの除去。初手は大抵intros.<br />1 subgoal<br />n : nat<br />m : nat<br /> ============================<br />n + m = m + n<br />t &lt; induction n. // nについて帰納法。0と(S n)とに場合分け<br />2 subgoals<br />m : nat<br /> ============================<br /> 0 + m = m + 0 // n=0 の場合<br />subgoal 2 is:<br /> S n + m = m + S n<br />t &lt; simpl; trivial. // 0 + m = m + 0 を簡単化すると自明な式に。<br />18<br />
  19. 19. 帰納的関数の性質の証明(2)<br />1 subgoal<br />n : nat<br />m : nat<br />IHn : n + m = m + n // 帰納法の前提<br /> ============================<br />S n + m = m + S n<br />t &lt; rewrite plus_Sn_m.<br />1 subgoal<br />n : nat<br />m : nat<br />IHn : n + m = m + n<br /> ============================<br />S (n + m) = m + S n<br />t &lt; rewrite &lt;- plus_n_Sm.<br />1 subgoal<br />n : nat<br />m : nat<br />IHn : n + m = m + n<br /> ============================<br /> S (n + m) = S (m + n)<br />t &lt; apply eq_S.<br />1 subgoal<br />n : nat<br />m : nat<br />IHn : n + m = m + n<br /> ============================<br />n + m = m + n<br />t &lt; exact IHn.<br />Proof completed.<br />t &lt; Qed.<br />19<br />Coq &lt; Check plus_Sn_m.<br />plus_Sn_m<br />: forallnm : nat, S n + m = S (n + m)<br />Coq &lt; Check eq_S.<br />eq_S<br />: forallxy : nat, x = y -&gt; S x = S y<br />
  20. 20. 自然演繹の推論規則とtactic<br />20<br />
  21. 21. その他のコマンド(tactic)<br />Require Import ライブラリ.<br />例えばArithとか。<br />Undo. : 一手戻る。<br />Locate パターン. : 定義を探す<br />Locate “_ &lt; _”.<br />LocateしたらPrintで内容確認。<br />Search 演算子 : 定理を探す(重要!!)<br />Search eq. とか。<br />SearchPatternパターン : 定理を探す<br />SearchPattern ((_ + _) * _ = _) とか<br />21<br />
  22. 22. その他のtactic<br /><ul><li>Tacticは50個以上ある…。全部は紹介出来ない(フォローしてない)
  23. 23. apply は(定理の仮定だけじゃなく)既存定理にも使える
  24. 24. 書かれてないだけで仮定に入っていると考えても良い
  25. 25. apply 定理
  26. 26. apply 定理 with (変数 := 値) (変数 := 値)
  27. 27. apply (定理引数引数 …)
  28. 28. cut 中間ゴール, assert 中間ゴール : 証明の中間ゴールを設定する
  29. 29. rewrite仮定. : =を含む仮定をGoalに適用(左辺値を右辺値で置換)
  30. 30. Goalの右辺値を左辺値で、はrewite <- 仮定。
  31. 31. 等式の証明では良く使う。
  32. 32. rewrite (仮定引数1 引数2 …) で仮定に代入出来る。
  33. 33. reflexivity. : apply refl_equal. (Goalがx=xの時使う)
  34. 34. unfold定義. : 関数の定義をGoalに適用。foldは逆。
  35. 35. 自動証明 : auto, eauto, tauto, intuition, trivial, ring, omega, …
  36. 36. それぞれ微妙に違う。色々証明を自動的にやってくれます。
  37. 37. Coq/tactics : Tacticの一覧と解説 (日本語)。お薦め。</li></ul>22<br />
  38. 38. 練習問題<br />Coq本より<br />Theorem ex561 : forall A B C : Prop, A/(B/C) -&gt; (A/B)/C.<br />Theorem ex562 : forall A B C D : Prop, (A-&gt;B)/(C-&gt;D)/A/C -&gt; B/D.<br />Theorem ex563 : forall A : Prop, ~(A/~A).<br />Theorem ex564 : forall A B C : Prop, A/(B/C) -&gt; (A/B)/C.<br />Theorem ex565 : forall A : Prop, ~~(A/~A).<br />Theorem ex566 : forall A B : Prop, (A/B)/~A -&gt; B.<br />Theorem ex567 : forallA:Set, forall P Q:A-&gt;Prop, (forallx, P x)/(forally, Q y)-&gt;forallx, P x/Q x.<br />パズルゲーム感覚で解けます。<br />というか端から色々試すアドヴェンチャーゲーム?<br />適用出来ないtacticはエラーメッセージが出るだけ。<br />23<br />
  39. 39. Design by Contract<br />24<br />
  40. 40. Design by Contract<br />Design by Contract : 契約プログラミング<br />プログラムが満たすべき仕様記述をコードに埋め込む設計の安全性向上<br />事前条件、事後条件、不変条件<br />Eiffel で有名。Dとかも。<br />JML (Java Modeling Language) : コメントでアノテーションする<br />Hoare論理<br />「事前条件が成立する状態で、プログラムを実行したら、事後条件が成立する」<br />テスト有限な場合しかテスト出来ない。<br />数学的に証明常に正しい<br />25<br />
  41. 41. Hoare論理<br />Hoare : プログラムが仕様に対して部分正当であることを証明する為の公理的手法 (1969)<br />Hoare Triplet : {P}S{Q}<br />事前条件Pを満たすとき、<br />プログラムSを実行すると<br />事後条件Qを満たす<br />命令型プログラミング言語の公理<br />代入文/複合文/if文/while文/帰結の公理<br />関数型言語の方がHoare Tripletを書きやすいはず<br />再帰を用いた帰納的関数のほうが相性がいい<br />良いループ不変条件を抽出するのは難しいが再帰なら楽<br />再代入、副作用が無い方が簡単に書ける<br />逆にグローバル変数、ポインタ、共用体とかあると困難<br />26<br />
  42. 42. Hoare論理の公理<br />{Q[e/x]}x:=e{Q}<br />{P}S1{R}, {R}S2{Q} <br />------------------------<br />{P}S1;S2{Q}<br />{P∧B}S1{Q}, {P∧¬B}S2{Q}<br />-----------------------------<br />{P} if B then S1 else S2 {Q}<br />{P∧B}S{P}<br />-----------------------------<br />{P} while B do S end {P∧¬B}<br />PP1, {P1}S{Q1}, Q1Q<br />------------------------------<br />{P}S{Q}<br />27<br />
  43. 43. Why<br />プログラムから証明へ<br />Why: プログラム検証用ツール<br />CaduceusはobsolateFrama-C へ移行<br />外部の各種の証明器と連携<br />gwhy : GUI環境<br />Eclipse plugin有<br />*.java (JML)<br />Krakatoa<br />*.v他<br />Coq<br />手動証明<br />*.c<br />Caduceus<br />他にPVS, Isabelle/HOL, etc.<br />自動証明。他にSimplify, CVCL, …<br />Alt-Ergo他<br />28<br />
  44. 44. Whyを動かしてみよう<br />29<br />
  45. 45. whyをインストール(1)<br />Windows : whyダウンロードページにinstaller<br />Linux, Mac, etc.: ソースからmakeする<br />前提:OCaml, Coq // 既にインストールしてあるはず<br />前提:LablGTK// GUI環境のため<br />lablgtk-2.14.0.tar.gz 入手⇒gunzip, tar –xf<br />⇒ ./configure ⇒ make world ⇒ sudo make install<br />why の導入<br />% ls<br />why-2.23.tar.gz<br />% gunzip why-2.23.tar.gz<br />% tar -xf why-2.23.tar<br />% cdwhy-2.23<br />% ./configure<br />% make<br />% sudo make install<br />% why –version<br />30<br />
  46. 46. whyをインストール(2)<br />インストールは基本、gunzip, tar –xf, ./configure, make, sudo make install を繰り返すだけ。<br /><ul><li>Alt-Ergoインストール (http://ergo.lri.fr/) : alt-ergo-0.9.tar.gz</li></ul>前提 : ocamlgraph (http://ocamlgraph.lri.fr/) : ocamlgraph-1.3.tar.gz<br />Simplifyインストール(https://mobius.ucd.ie/repos/src/mobius.atp/mobius.simplify/simplify/) : simplify-1.5.5.macosx<br />chmod +x simplify-1.5.5.macosx<br />sudocp -p Simplify-1.5.5.macosx /usr/local/bin/simplify<br />31<br />
  47. 47. Krakatoaを動かす(1)<br />% cat Lesson1.java<br />public class Lesson1 {<br />/*@ ensures esult &gt;= x && esult &gt;= y &&<br /> @ forall integer z; z &gt;= x && z &gt;= y ==&gt; z &gt;= esult;<br /> @*/<br /> public static intmax(intx, inty) {<br /> if (x&gt;y) { return x; } else { returnx; } // わざと間違い<br /> }<br />}<br />% why-config最初の1回だけ<br />% gwhy Lesson1.java<br /> GUI起動<br />32<br />
  48. 48. Krakatoaを動かす(2)<br />33<br />…その次のサンプルコードが動かない…orz<br />
  49. 49. Whyを動かす(1)<br />% cat test.why<br />logic min: int, int -&gt; int<br />axiom min_ax: forallx,y:int. min(x,y) &lt;= x<br />parameter r: int ref <br />let f (n:int) = {} r := min !rn { r &lt;= r@ }<br />% gwhytest.why// GUI起動自動証明器で確認 あるいは why –-simplify で<br />% why --coq test.why// Coq用にproof obligationを生成する<br />% cat test_why.v<br />...<br />(*Why goal*) Lemma f_po_1 : <br />forall (n: Z),<br />forall (r0: Z),<br />forall (r: Z),<br />forall (HW_1: r = (min r0 n)),<br />r &lt;= r0.<br />Proof.<br />(* FILL PROOF HERE *)<br />Save.<br />...<br />34<br />
  50. 50. Whyを動かす(2)<br />35<br />CoqIDE上でtest_why.vを証明する。<br />
  51. 51. まとめ<br />Coq面白いよ!<br />関数型言語ブームの次は依存型が来るよね(多分)<br />See “Why Dependent Types Matter” (PDF)<br />Javaのジェネリクスの有無同様、依存型の有無が<br />「証明=難しい」じゃなくて「証明=パズルゲーム」<br />でも、覚えるべきtacticが多過ぎて大変<br />多分、練習問題を沢山解かないと使い方は身に付かない<br />でも、事前条件、不変条件をうまく書けば事後条件はかなり自動証明されるのでは?<br />人工無脳との対話めいた感もあり<br />一昔前で言うところのエキスパートシステム<br />コードレヴューで人間に説明する代わりに、定理証明系に説明すると思えば良い<br />Coq/Whyの勉強会やりません?<br />私もプレゼン用に上っ面を撫でただけなので…<br />36<br />

×