Mercurial > hg > Papers > 2018 > ryokka-sigos
view Slide/sigos.html @ 11:7aa41769f1f1
fix slides
author | ryokka |
---|---|
date | Sun, 20 May 2018 23:42:24 +0900 |
parents | 328bcfd300bd |
children | e20725cd6d8a |
line wrap: on
line source
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>GearsOSの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="Masataka Hokama, Shinji Kono" > <!-- 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">GearsOSのAgdaによる記述と検証</font></h1> </div> </td> </tr> <tr> <td> <div align="left"> Masataka Hokama, Shinji Kono 琉球大学 <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-05-20 23:41:15 +0900 with Markdown engine kramdown (1.15.0) using options {} --> <!-- <span style="background-color:#ffcc99"> </span> --> <!-- ```C --> <!-- <span style="background-color:#ffcc99">hoge</span> --> <!-- ``` --> <!-- ## 本発表の流れ --> <!-- * 研究目的 --> <!-- * CodeGear と DataGear の説明 --> <!-- * Agda の記述 --> <!-- * Interface の説明 --> <!-- * Agda での CodeGear 、 DataGear 、 Interface の表現 --> <!-- * 実際に行なった証明 --> <!-- * まとめ --> <!-- _S9SLIDE_ --> <h2 id="section">プログラムの信頼性の保証</h2> <ul> <li>動作するプログラムの信頼性を保証したい</li> <li>保証をするためには仕様を検証する必要がある</li> <li>仕様を検証するには <strong>モデル検査</strong> と <strong>定理証明</strong> の2つの手法がある <ul> <li><strong>モデル検査</strong> はプログラムの持つ状態を数え上げて仕様を満たしているか</li> <li><strong>定理証明</strong> はプログラムの性質を論理式で記述し、型を生成する関数を定義することで証明を記述する</li> </ul> </li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-1">プログラムの信頼性の保証</h2> <!-- * データ構造を仕様と実装に分けて記述するため、GearsOS のモジュール化の仕組みである **Interface** を記述した --> <ul> <li>当研究室では検証しやすい単位として <strong>CodeGear</strong>、<strong>DataGear</strong> という単位を用いてプログラムを記述する手法を提案している</li> <li>これは関数型プログラミングに近い形になる</li> <li>本研究では関数型の <strong>定理証明支援系</strong> の言語 <strong>Agda</strong> を用いて仕様を検証することにした</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-2">発表の流れ</h2> <ul> <li>CodeGear と DataGear の定義</li> <li>Agda の説明</li> <li>Agda での CodeGear、 DataGear の表現</li> <li>今回行なった証明</li> </ul> <!-- ## Hoare Logic --> <!-- * Hoare Logic は Tony Hoare によって提案されたプログラムの部分的な正当性を検証する手法 --> <!-- * 前の状態を{P}(Pre-Condition)、後の状態を{Q}(Post-Condition)とし、前状態を C (Command) で変更する --> <!-- * {P} が成り立つときに、 C を実行すると、実行後は必ず {Q} が成り立つとき、部分的に正当である --> <!-- <div style="text-align: center;"> --> <!-- <img src="./fig/cgdg.svg" alt="cbc-hoare" width="800"> --> <!-- </div> --> <!-- ## Hoare Logic と CodeGear、 DataGear --> <!-- * Hoare Logic の状態と処理を CodeGear、 DataGear に当てはめる事ができる --> <!-- * Pre-condition を input の DataGear , Post-Conditon を output の DataGear , Command は CodeGear そのもの --> <!-- * Pre-conditon や Post-conditon をメタ計算部分で検証し、 CodeGear、 DataGear で書かれたプログラムに対して検証する --> <!-- <div style="text-align: center;"> --> <!-- <img src="./fig/hoare-cbc.svg" alt="cbc-hoare" width="800"> --> <!-- </div> --> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda-">Agda での型定義</h2> <ul> <li>型は <strong>関数名 : 型</strong> のように <strong>:</strong> を使って定義する</li> <li>a -> b という型は、<strong>「a を受け取り、 b を返す」</strong>という型</li> <li><strong>a -> b -> c</strong> のような型は <strong>a -> (b -> c)</strong> と同じで、 <strong>「a を受け取り、 b を受け取り、 c を返す」</strong> という型</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--1">Agda での型(例)</h2> <ul> <li>実際に Stack の pop 操作の <strong>実装</strong> である <strong>popSingleLinkedStack</strong> の型を見る</li> </ul> <pre lang="AGDA"><code>popSingleLinkedStack : SingleLinkedStack a -> (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t </code></pre> <ul> <li>この型では stack と行き先の CodeGear を受け取り、次の CodeGear に継続する</li> <li>popSingleLinkedStack 継続に型 Maybe a を受けとる CodeGear ( <strong>(fa -> t) -> t</strong>) に渡している</li> <li>stack の中身は空の可能性があるので Maybe型の a を返す</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="maybe">Maybe</h2> <ul> <li><strong>Maybe</strong> はNothingかJustの2つの場合を持つ型で Agda の <strong>data</strong> として定義されている</li> <li>Just か Nothing は場合分けで Nothing と Just a は Maybe を生成する constructor</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--2">Agda でのデータ</h2> <ul> <li>データは <strong>data データ名 : 型</strong></li> <li><strong>(x : A)</strong> は ある集合(a)に属する {A} という型を持った変数 <strong>x</strong> を表現</li> <li><strong>refl</strong> は左右の項が等しいことを表す <strong>x ≡ x</strong> を生成</li> <li>x ≡ x を証明したい時には refl と書く</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="refl-">refl を使った証明</h2> <ul> <li>refl を使った例題 <strong>sym</strong></li> </ul> <pre lang="AGDA"><code>sym : {x : Set} {y : Set} -> x ≡ y -> y ≡ x sym refl = refl </code></pre> <ul> <li><strong>x ≡ y</strong> ならば <strong>y ≡ x</strong> の証明</li> <li>型は論理式として成り立っており、関数で証明を行っている</li> <li>初めの x ≡ y は引数として与えられ、これは <strong>refl</strong></li> <li><strong>x ≡ y</strong> が成り立つ時、初めて <strong>y ≡ x</strong> は refl</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--record">Agda での record の定義</h2> <ul> <li>record 複数のデータをまとめて記述する型</li> <li>ここでは SingleLinkedStack の定義を例とする</li> </ul> <pre lang="AGDA"><code>record SingleLinkedStack (a : Set) : Set where field top : Maybe (Element a) </code></pre> <ul> <li><strong>record レコード名</strong> 、下に <strong>field</strong> 、さらに下に <strong>フィールド名:型名</strong> を列挙</li> <li>フィールド名は <strong>accessor</strong></li> <li>top は Maybe (Element a) 型</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="element">Element</h2> <ul> <li>Element 型も record で定義されている</li> <li>このレコードは直積になっている</li> <li><strong>datum</strong> は Element の要素自体で、 <strong>next</strong> は次の要素</li> </ul> <pre lang="AGDA"><code>record Element (a : Set) : Set where field datum : a next : Maybe (Element a) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--3">Agda での関数</h2> <ul> <li>Agda での関数は <strong>関数名 = 関数の実装</strong></li> <li>ここでは <strong>popSingleLinkedStack</strong> の関数を例とする <ul> <li><strong>関数名</strong> と <strong>=</strong> の間に記述されてる stack 、 cg は引数</li> <li>stack の top は Maybe a なので Nothing か Just が返り、2つの場合が存在</li> <li><strong>with</strong> と <strong>|</strong> を使うことで data の場合分けができる</li> </ul> </li> </ul> <pre lang="AGDA"><code>popSingleLinkedStack : SingleLinkedStack a -> (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t popSingleLinkedStack stack cg with (top stack) popSingleLinkedStack stack cg | Nothing = cg stack Nothing popSingleLinkedStack stack cg | Just d = cg record { top = (next d) } (Just (datum d)) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--record-">Agda での record の作成</h2> <ul> <li>record の作成は関数内で行う</li> <li>例として <strong>pushSingleLinkedStack</strong> の関数部分を扱う</li> </ul> <pre lang="Agda"><code>pushSingleLinkedStack : {t : Set} {a : Set} -> SingleLinkedStack a -> a -> (Code : SingleLinkedStack a -> t) -> t pushSingleLinkedStack stack datum next = next record {top = Just (record {datum = datum;next =(top stack)})} </code></pre> <ul> <li><strong>record</strong> 後ろの <strong>{}</strong> 内部で <strong>フィールド名 = 値</strong> で列挙</li> <li>複数のフィールドを作成する際は <strong>;</strong> で区切る</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/meta_cg_dg.svg" alt="goto" width="800" /> </div> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="gearsos">GearsOS</h2> <ul> <li>本研究室では処理の単位を Code Gear、 データの単位を Data Gear を用いて 信頼性が高い処理を行う Gears OS を開発している</li> <li>GearsOS では計算をノーマルレベルとメタレベルに階層化し、 信頼性と拡張性をメタレベルで保証している</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--codegear-datagear-">Agda での CodeGear、 DataGear の表現</h2> <ul> <li>GearsOS の検証を行うため、CodeGear、DataGear を Agda で定義した</li> <li>CodeGear は処理の単位なので、 Agda では通常関数として記述する</li> <li>DataGear は Agda の record を使用し記述する</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--codegear">Agda での CodeGear</h2> <ul> <li>例として Stack への push を考える</li> <li>通常の push を normalPush と 継続を用いた push を continuePush とする</li> </ul> <pre lang="AGDA"><code>-- 通常のpushの型 normalPush : Si -> a -> Si -- 継続を用いたpushの型 continuePush : Si -> a -> (CodeGear : Si -> t) -> t </code></pre> <ul> <li>normalPush は 「<strong>stack</strong> と <strong>data</strong> を受け取り、 <strong>data が取り出された stack</strong> を返す」型</li> <li>continuePush は 「<strong>stack</strong> と <strong>data</strong> <strong>と 継続先の (Code : )</strong> を受け取り、 <strong>継続先である t</strong>を返す」型</li> <li>t は明示されていない不定な型で、継続を表している</li> <li><strong>CodeGear の型</strong> は <strong>(code: a -> t) -> t</strong> のような形になる</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="interface">Interface</h2> <ul> <li>Interface は GearsOS のモジュール化の仕組み</li> <li>ある Data Gear と それに対する操作(API) を行う Code Gear の集合を表現</li> <li>Interface を使うとデータ構造への操作を仕様と実装に分けて記述することができる</li> </ul> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface-">Agda での Interface の定義</h2> <ul> <li>GearsOS の Interface を Agda で定義した <!-- * Stack の仕様を実装とは別に記述するために record で Stack の Interface を記述した --></li> <li>ここでの push、 pop は仕様の型のみ記述され、実装は構築時に与える</li> <li>t は不定な型で継続を表し、次の CodeGear を指す</li> <li><strong>StackMethods</strong> は Stack から interface を通して singleLinkedStack への操作を行う際の型を定義してる</li> </ul> <pre lang="AGDA"><code>record StackMethods (a : Set) {t : Set} (stackImpl : Set) : Set where field push : stackImpl -> a -> (stackImpl -> t) -> t pop : stackImpl -> (stackImpl -> Maybe a -> t) -> t </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--1">Agda での Interface の記述</h2> <ul> <li>Stack を作成するとき仕様と実装を繋げている</li> <li><strong>createSingleLinkedStack</strong> は中身のない Stack を作る</li> </ul> <pre lang="AGDA"><code>createSingleLinkedStack : {t : Set} {a : Set} -> Stack {n} {m} a {t} (SingleLinkedStack a) createSingleLinkedStack = record { stack = emptySingleLinkedStack ; stackMethods = singleLinkedStackSpec } </code></pre> <ul> <li><strong>singleLinkedStackSpec</strong> は実装側の push、 pop をまとめている</li> </ul> <pre lang="AGDA"><code>singleLinkedStackSpec : {t : Set} {a : Set} -> StackMethods a {t} (SingleLinkedStack a) singleLinkedStackSpec = record { push = pushSingleLinkedStack ; pop = popSingleLinkedStack } </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-3">証明の概要</h2> <ul> <li>今回は <strong>任意の数</strong> を Stack に push し、直後にその Stack に対して 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 を作成する関数 <strong>stackInSomeState</strong></li> <li>入力を使って任意の Stack を表す</li> <li>stackInSomeState は Stack を受け取り、状態の決まっていない Stack を作成</li> </ul> <pre lang="AGDA"><code>stackInSomeState : (s : SingleLinkedStack a ) -> Stack a ( SingleLinkedStack a ) stackInSomeState s = record { stack = s ; stackMethods = singleLinkedStackSpec } </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--2">Agda での Interface を含めた部分的な証明</h2> <ul> <li><strong>push->pop</strong>では push をし、直後に pop をして取れたデータが等しい</li> <li>Agda では不明な部分を <strong>?</strong> と書くことができ、証明部分を ? としている</li> </ul> <pre lang="AGDA"><code>push->pop : {a : Set } (x : a ) (s : SingleLinkedStack a ) -> pushStack (stackInSomeState s) x (\s1 -> popStack s1 (\s2 x1 -> (Just x ≡ x1 ))) push->pop {a} x s = ? </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="push-pop-">push->pop の型</h2> <ul> <li>ラムダ計算で結果を次の実行に渡している</li> <li>ラムダ計算は関数を抽象的に扱うもので、名前がなく、入力と出力だけ</li> <li>ここでは <strong>\s1 -></strong> がラムダ計算で、受け取った Stack (s) に push を行い、更新された Stack (s1) を次の CodeGear に渡している</li> </ul> <pre lang="AGDA"><code>push->pop : {a : Set } (x : a ) (s : SingleLinkedStack a ) -> pushStack (stackInSomeState s) x (\s1 -> popStack s1 (\s2 x1 -> (Just x ≡ x1 ))) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--3">Agda での Interface を含めた部分的な証明</h2> <ul> <li><strong>?</strong> 部分はコンパイルすると <strong>{}n</strong> のように番号が付き、Agda から内部に入る型を示してもらえる</li> </ul> <pre lang="AGDA"><code>push->pop : {a : Set } (x : a ) (s : SingleLinkedStack a ) -> pushStack (stackInSomeState s) x (\s1 -> popStack s1 (\s2 x1 -> (Just x ≡ x1 ))) push->pop {a} x s = { }0 </code></pre> <pre lang="AGDA"><code>?0 : pushStack (stackInSomeState s) x (λ s1 → popStack s1 (λ s2 → _≡_ (Just x))) </code></pre> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="agda--interface--4">Agda での Interface を含めた部分的な証明</h2> <ul> <li><strong>{ }0</strong> 部分には x≡x1 が入り、これは refl</li> </ul> <pre lang="AGDA"><code>push->pop : {a : Set } (x : a ) (s : SingleLinkedStack a ) -> pushStack (stackInSomeState s) x (\s1 -> popStack s1 (\s2 x1 -> (Just x ≡ x1 ))) push->pop {a} x s = refl </code></pre> <p>とすることで証明することができた</p> </div> <div class='slide '> <!-- _S9SLIDE_ --> <h2 id="section-4">まとめと今後の方針</h2> <ul> <li>本研究では CodeGear、DataGear を Agda で定義することができた</li> <li>また Agda で Interface の記述及び Interface を含めた証明を行うことができた</li> <li>これにより、 Interface を経由しても一部の性質は実装と同様の働きをすることが証明できた</li> <li>また、CbC での Interface 記述では考えられていなかった細かな記述が明らかになった</li> <li>RedBlackTree では Stack と異なり一つの操作に複数の CodeGear が入っているため Hoare Logic を使っての証明や、関数を展開しての証明などを行う</li> <li>SynchronisedQueue の証明では並列処理シミュレーションを Agda で行うことと、動機機構などを含めての証明を行う</li> </ul> <!-- === end markdown block === --> </div> </div><!-- presentation --> </body> </html>