Mercurial > hg > Papers > 2018 > ryokka-thesis
view slide/slide.html @ 16:989de96fe049
fix slide
author | ryokka |
---|---|
date | Thu, 22 Feb 2018 03:18:45 +0900 |
parents | 22f582c4908d |
children |
line wrap: on
line source
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>Agda による継続を用いたプログラムの検証</title> <meta name="generator" content="Slide Show (S9) v2.5.0 on Ruby 2.4.1 (2017-03-22) [x86_64-darwin16]"> <meta name="author" content="外間 政尊" > <!-- style sheet links --> <link rel="stylesheet" href="s6/themes/projection.css" media="screen,projection"> <link rel="stylesheet" href="s6/themes/screen.css" media="screen"> <link rel="stylesheet" href="s6/themes/print.css" media="print"> <link rel="stylesheet" href="s6/themes/blank.css" media="screen,projection"> <!-- JS --> <script src="s6/js/jquery-1.11.3.min.js"></script> <script src="s6/js/jquery.slideshow.js"></script> <script src="s6/js/jquery.slideshow.counter.js"></script> <script src="s6/js/jquery.slideshow.controls.js"></script> <script src="s6/js/jquery.slideshow.footer.js"></script> <script src="s6/js/jquery.slideshow.autoplay.js"></script> <!-- prettify --> <link rel="stylesheet" href="scripts/prettify.css"> <script src="scripts/prettify.js"></script> <script> $(document).ready( function() { Slideshow.init(); $('code').each(function(_, el) { if (!el.classList.contains('noprettyprint')) { el.classList.add('prettyprint'); } }); prettyPrint(); } ); </script> <!-- Better Browser Banner for Microsoft Internet Explorer (IE) --> <!--[if IE]> <script src="s6/js/jquery.microsoft.js"></script> <![endif]--> </head> <body> <div class="layout"> <div id="header"></div> <div id="footer"> <div align="right"> <img src="s6/images/logo.svg" width="200px"> </div> </div> </div> <div class="presentation"> <div class='slide cover'> <table width="90%" height="90%" border="0" align="center"> <tr> <td> <div align="center"> <h1><font color="#808db5">Agda による継続を用いたプログラムの検証</font></h1> </div> </td> </tr> <tr> <td> <div align="left"> 外間 政尊 @並列信頼研 <hr style="color:#ffcc00;background-color:#ffcc00;text-align:left;border:none;width:100%;height:0.2em;"> </div> </td> </tr> </table> </div> <div class='slide '> <!-- === begin markdown block === generated by markdown/1.2.0 on Ruby 2.4.1 (2017-03-22) [x86_64-darwin16] on 2018-02-22 03:18:20 +0900 with Markdown engine kramdown (1.15.0) using options {} --> <!-- _S9SLIDE_ --> <h2 id="section">プログラムの信頼性の保証</h2> <ul> <li>動作するプログラムの信頼性を保証したい <!-- ちょっとあれかも --></li> <li>信頼性の保証をするためにはプログラムの仕様を検証する必要がある</li> <li>プログラムの仕様を検証するにはモデル検査と <strong>定理証明</strong> の2つの手法がある <ul> <li>モデル検査 はプログラムの持つ状態を数え上げて仕様を満たしているかを確認する</li> <li>定理証明 はプログラムの性質を論理式で記述しそれが常に正しいことを証明する</li> </ul> </li> <li>また、当研究室では検証しやすい単位として CodeGear、DataGear という単位を用いてプログラムを記述する手法を提案している</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-1">プログラムの信頼性の保証</h2> <ul> <li>今回は <strong>定理証明</strong> をつかって仕様を検証する</li> <li>定理証明には定理証明支援系の言語 Agda を使用する <ul> <li>Agda では型でプログラムの性質を論理式で記述し、型に対応する関数部分で論理式を解くことで証明を記述できる <!-- interface の説明 --></li> </ul> </li> <li>今回は Agda を用いて CodeGear 、DataGear、Interfaceを定義した</li> <li>この単位を用いて実装された Stack に Interface を実装し、性質の一部を証明した</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="codegear--datagear">CodeGear と DataGear</h2> <ul> <li>CodeGear とはプログラムを記述する際の処理の単位である</li> <li>DataGear は CodeGear で扱うデータの単位であり、処理に必要なデータが全て入っている</li> <li>CodeGear はメタ計算によって CodeGear へ接続される</li> <li>メタ計算を切り替えることで処理に変更を加えることなくプログラムの性質を検証できる</li> </ul> <div style="text-align: center;"> <img src="./fig/cgdg.svg" alt="goto" width="800" /> </div> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda-">Agda の型</h2> <ul> <li>例として popSingleLinkedStack を使う</li> <li>singleLinkedStack は Stack の実装部分で push、 pop の</li> <li>Agda の 型は <strong>関数名 : 型</strong> で定義される</li> <li>Agda の 項、関数部分は <strong>関数名 = 値</strong></li> <li>なにかを受け取って計算して次の関数に継続する型(<strong>-> (fa -> t) -> t</strong>) <!-- * stackを受け取り、stackの先頭を取ってという処理を行い、次の関数に渡すという関数の型 --></li> <li>このような形で CodeGear を Agda で定義できる</li> </ul> <pre lang="AGDA"><code>popSingleLinkedStack : -> SingleLinkedStack a -> (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="maybe">Maybe</h2> <ul> <li><strong>Maybe</strong> はNothingかJustを返す型でAgda の <strong>data</strong> として定義されている</li> <li>ここでは Just か Nothing をパターンマッチで返す</li> <li>要素にも型を書く必要がある</li> </ul> <pre lang="AGDA"><code>data Maybe a : Set where Nothing : Maybe a Just : a -> Maybe a </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--1">Agda でのデータの定義</h2> <ul> <li>Agda でのデータの定義の例として <strong>refl</strong> 定義を使用する</li> <li>data は <strong>data データ名 : 型</strong> と書く</li> <li><strong>refl</strong> は左右の項が等しいことを表している</li> </ul> <pre lang="AGDA"><code>data _≡_ {a} {A : Set a} (x : A) : A → Set a where refl : x ≡ x </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda">Agdaの関数</h2> <ul> <li>例として popSingleLinkedStack を使う</li> <li>Agdaでの関数の定義は <strong>関数名 = 関数の実装</strong> の書く <!-- * 関数での引数は **関数名 a b =** のように書く --></li> </ul> <pre lang="AGDA"><code>popSingleLinkedStack : -> SingleLinkedStack a -> (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t popSingleLinkedStack stack cs with (top stack) popSingleLinkedStack stack cs | Nothing = cs stack Nothing popSingleLinkedStack stack cs | Just d = cs record { top = (next d) } (Just (datum d)) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="record">record</h2> <ul> <li>record は複数のデータを纏めて記述する型</li> <li><strong>record レコード名</strong> と書き、その次の行に <strong>field</strong> と書く</li> <li>その下の行に <strong>フィールド名:型名</strong> と列挙する</li> <li>SingleLinkedStack では top というフィールドに Maybe のかかっている Element 型の要素aが定義されている</li> <li>Element では record で data と次の要素 next を定義している</li> </ul> <!-- * 他の言語のオブジェクトのように **レコード名.フィールド名** でアクセスできる。例えば **SingleLinkedStack.top** のようにアクセスできる --> <pre lang="AGDA"><code>record SingleLinkedStack (a : Set) : Set where field top : Maybe (Element a) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="pushsinglelinkedstackrecord">pushSingleLinkedStackの定義とrecordの構築</h2> <ul> <li>pushSingleLinkedStack の型では stack と data を受け取り、 CodeGear 中で Data を stack に入れ、新しいstack を継続し、次の CodeGear に継続している</li> <li>関数側では record の構築を行う</li> <li><strong>record</strong> の後ろの {} 内部で <strong>フィールド名 = 値</strong> の形で列挙する</li> <li>複数書くときは <strong>;</strong> で区切る</li> </ul> <pre lang="Agda"><code>pushSingleLinkedStack : {n m : Level } {t : Set m } {Data : Set n} -> SingleLinkedStack Data -> Data -> (Code : SingleLinkedStack Data -> t) -> t pushSingleLinkedStack stack datum next = next record {top = Just (record {datum = datum;next =(top stack)})} </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface-">Agda での Interface の定義</h2> <ul> <li>singleLinkedStack の色々な実装を抽象的に表すために record を使い <strong>StackMethods</strong> をつくった</li> <li>実装時は関数の中で record を構築している</li> <li>push、 pop は実装によらないAPI <!-- わかりやすい説明を! --></li> <li>push、 pop に singlelinkedstack の実装が入る</li> </ul> <pre lang="AGDA"><code>record StackMethods {n m : Level } (a : Set n ) {t : Set m }(stackImpl : Set n ) : Set (m Level.⊔ n) where field push : stackImpl -> a -> (stackImpl -> t) -> t pop : stackImpl -> (stackImpl -> Maybe a -> t) -> t </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-2">証明の概要</h2> <ul> <li>今回は singleLinkedStack の実装を抽象的に表す Interface を通し、 <strong>任意の数</strong> を push し pop したとき、 push した値と pop した値が等しくなることを証明する</li> <li>このとき、どのような状態の Stack に push し、 pop をしても値が等しくなることを示したい</li> <li>そのため、<strong>状態の不定な</strong> Stack を作成する関数を作成した</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="stack-">不定な Stack の定義</h2> <ul> <li>不定な Stack を作成する stackInSomeState という関数を作成した</li> <li>stackInSomeState は stack を受け取り、状態の決まっていない stack を record を作成する</li> </ul> <pre lang="AGDA"><code>stackInSomeState : {l m : Level } {D : Set l} {t : Set m } (s : SingleLinkedStack D ) -> Stack {l} {m} D {t} ( SingleLinkedStack D ) stackInSomeState s = record { stack = s ; stackMethods = singleLinkedStackSpec } </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--1">Agda での Interface を含めた部分的な証明</h2> <ul> <li>push を2回行い、直後に pop を2回した値が push した値がpopした後の値と等しいことを示している</li> <li>Agda 中では不明な部分を <strong>?</strong> と書くことができ、<strong>?</strong>部分には証明が入る</li> <li>証明部分はラムダ式で与える</li> <li>型部分に注目する</li> </ul> <pre lang="AGDA"><code>push->push->pop2 : {l : Level } {D : Set l} (x y : D ) (s : SingleLinkedStack D ) -> pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) push->push->pop2 {l} {D} x y s = ? </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-3">ラムダ式</h2> <ul> <li>ラムダ式は関数内で無名の関数を定義することができる</li> <li><strong>\s1 -></strong> はラムダ式で push->push->pop2 の型では次の CodeGear 部分にラムダ式を使いStackを渡している</li> </ul> <pre lang="AGDA"><code>push->push->pop2 : {l : Level } {D : Set l} (x y : D ) (s : SingleLinkedStack D ) -> pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--2">Agda での Interface を含めた部分的な証明</h2> <ul> <li> <p>? 部分はコンパイル時に Agda から内部に入る型を示してもらえる</p> </li> <li> <p>ここでは最終的に <strong>(Just x ≡ x1) ∧ (Just y ≡ y1)</strong> が返ってくる事がわかる</p> </li> <li> <p>(Just x ≡ x1)と(Just y ≡ y1)の2つが同時成り立ってほしい</p> </li> <li> <p>そこで <strong>∧</strong> の部分を record で定義した</p> </li> </ul> <pre lang="AGDA"><code>push->push->pop2 {l} {D} x y s = { }0 </code></pre> <pre lang="AGDA"><code>-- Goal ?0 : pushStack (stackInSomeState s) x (λ s1 → pushStack s1 y (λ s2 → pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1)))) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--3">Agda での Interface を含めた部分的な証明(∧)</h2> <ul> <li>a と b の証明から a かつ b を作るために</li> <li>直積を表す型を定義する</li> </ul> <pre lang="AGDA"><code>record _∧_ {n : Level } (a : Set n) (b : Set n): Set n where field pi1 : a pi2 : b </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--4">Agda での Interface を含めた部分的な証明</h2> <ul> <li>∧でまとめたpi1、pi2は <strong>refl</strong> で証明することができた</li> </ul> <pre lang="AGDA"><code>push->push->pop2 : {l : Level } {D : Set l} (x y : D ) (s : SingleLinkedStack D ) -> pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) push->push->pop2 {l} {D} x y s = record { pi1 = refl ; pi2 = refl } </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-4">まとめと今後の課題</h2> <ul> <li>本研究では CodeGear、DataGear を Agda に定義できた</li> <li>また Agda で Interface の記述及び Interface を含めた一部の証明を行えた</li> <li>これにより、 Interface を経由しても一部の性質は実装と同様の働きをすることが証明できた <!-- * また、これにより CbC での Interface 記述では考えられていなかった細かな記述が明らかになった --></li> <li>今後の課題としては 継続を用いた Agda で Hoare Logic を表現し、その Hoare Logic をベースとして証明を行えるかを確認する</li> <li>また RedBlackTree の挿入、削除の性質に関する証明も行おうと考えている</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="hoare-logic">Hoare Logic</h2> <ul> <li>Hoare Logic は Tony Hoare によって提案されたプログラムの部分的な正当性を検証するための手法</li> <li>前の状態を{P}(Pre-Condition)、後の状態を{Q}(Post-Condition)とし、前状態を C (Command) によって変更する</li> <li>この {P} C {Q} でプログラムを部分的に表すことができるp</li> </ul> <div style="text-align: center;"> <img src="./fig/hoare.svg" alt="hoare" width="1000" /> </div> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="hoare-logic--cbc">Hoare Logic と CbC</h2> <ul> <li>Hoare Logic の状態と処理を CodeGear、 DataGear の単位で考えることができると考えている</li> </ul> <div style="text-align: center;"> <img src="./fig/hoare-cbc.svg" alt="cbc-hoare" width="800" /> </div> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="element">Element</h2> <ul lang="AGDA"> <li>Element の説明</li> </ul> <pre><code>record Element {l : Level} (a : Set l) : Set l where inductive constructor cons field datum : a -- `data` is reserved by Agda. next : Maybe (Element a) </code></pre> <!-- === end markdown block === --> </div> </div><!-- presentation --> </body> </html>