# HG changeset patch # User ryokka # Date 1526724859 -32400 # Node ID 907f967f662e91f820d4875868bd29506784fbe6 # Parent 35d15c091cfdc665773a157e1b196d536f120f99 remove binaryTree slides diff -r 35d15c091cfd -r 907f967f662e Paper/auto/sigos.el --- a/Paper/auto/sigos.el Mon Apr 23 21:44:32 2018 +0900 +++ b/Paper/auto/sigos.el Sat May 19 19:14:19 2018 +0900 @@ -14,13 +14,13 @@ (add-to-list 'LaTeX-verbatim-environments-local "Verbatim*") (add-to-list 'LaTeX-verbatim-environments-local "Verbatim") (add-to-list 'LaTeX-verbatim-environments-local "lstlisting") - (add-to-list 'LaTeX-verbatim-macros-with-braces-local "lstinline") (add-to-list 'LaTeX-verbatim-macros-with-braces-local "url") (add-to-list 'LaTeX-verbatim-macros-with-braces-local "path") + (add-to-list 'LaTeX-verbatim-macros-with-braces-local "lstinline") + (add-to-list 'LaTeX-verbatim-macros-with-delims-local "url") + (add-to-list 'LaTeX-verbatim-macros-with-delims-local "path") (add-to-list 'LaTeX-verbatim-macros-with-delims-local "Verb") (add-to-list 'LaTeX-verbatim-macros-with-delims-local "lstinline") - (add-to-list 'LaTeX-verbatim-macros-with-delims-local "url") - (add-to-list 'LaTeX-verbatim-macros-with-delims-local "path") (TeX-run-style-hooks "latex2e" "ipsjpapers" diff -r 35d15c091cfd -r 907f967f662e Paper/sigos.bib --- a/Paper/sigos.bib Mon Apr 23 21:44:32 2018 +0900 +++ b/Paper/sigos.bib Sat May 19 19:14:19 2018 +0900 @@ -44,7 +44,7 @@ @misc{agda, title = {The Agda wiki}, howpublished = {\url{http://wiki.portal.chalmers.se/agda/pmwiki.php}}, - note = {Accessed: 2018/2/9(Fri)} + note = {Accessed: 2018/4/23(Fri)} } @@ -68,9 +68,9 @@ @Comment % \\\verb|http://www.cse.chalmers.se/~ulfn/papers/afp08/tutorial.pdf| @misc{agda-documentation, - title = {Welcome to Agda’s documentation! — Agda 2.6.0 documentation}, - howpublished = {\url{http://agda.readthedocs.io/en/latest/index.html}}, - note = {Accessed: 2018/2/9(Fri)} + title = {Welcome to Agda’s documentation! — Agda latest documentation}, + howpublished = {\url{http://agda.readthedocs.io/en/latest/}}, + note = {Accessed: 2018/4/23(Mon)} } @book{Stump:2016:VFP:2841316, diff -r 35d15c091cfd -r 907f967f662e Paper/sigos.pdf Binary file Paper/sigos.pdf has changed diff -r 35d15c091cfd -r 907f967f662e Paper/sigos.tex --- a/Paper/sigos.tex Mon Apr 23 21:44:32 2018 +0900 +++ b/Paper/sigos.tex Sat May 19 19:14:19 2018 +0900 @@ -63,7 +63,7 @@ % 和文表題 \title{GearsOS の Agda による記述と検証} -% 英文$\lambda$式表題 +% 英文$\lambda$@$式表題 \etitle{} % 所属ラベルの定義 @@ -208,9 +208,11 @@ Agda ではこの型に対応する$\lambda$項を与えると証明が完了したことになる。 \begin{lstlisting}[caption=pushとpop,label=push-pop] - push->pop : {l : Level } {D : Set l} (x : D ) (s : SingleLinkedStack D ) -> - pushStack ( stackInSomeState s ) x (\s -> popStack s ( \s3 x1 -> (Just x - ≡ x1 ) )) +push->pop : {l : Level} {D : Set l} (x : D ) + (s : SingleLinkedStack D) -> + pushStack (stackInSomeState s) + x (\s -> popStack s + ( \s3 x1 -> (Just x ≡ x1))) \end{lstlisting} このように、CodeGear を Agda で記述し、継続部分に証明すべき性質を Agda で記述する。 @@ -247,7 +249,10 @@ $\lambda$式では\verb+\+の他に$\lambda$で表記することもできる。 \begin{lstlisting}[caption=pushStack の関数定義,label=push-stack-func] - pushStack d next = push (stackMethods ) (stack ) d (\s1 -> next (record {stack = s1 ; stackMethods = stackMethods } )) + pushStack d next = push (stackMethods) + (stack) d (\s1 -> next + (record {stack = s1 + ; stackMethods = stackMethods})) \end{lstlisting} ここで書かれている \verb+record+ は C における構造体に相当するレコード型というデー @@ -292,8 +297,8 @@ \begin{lstlisting}[caption=パターンマッチの例,label=pattern-match] popSingleLinkedStack stack cs with (top stack) -... | Nothing = cs stack Nothing -... | Just d = cs stack1 (Just data1) +... | Nothing = cs stack Nothing +... | Just d = cs stack1 (Just data1) where data1 = datum d stack1 = record { top = (next d) } @@ -308,7 +313,11 @@ たものと同じになるという論理式を型に書き、証明を行なった。 \begin{lstlisting}[caption=pushとpopを使った証明,label=push-pop] -push->pop : {l : Level } {D : Set l} (x : D ) (s : SingleLinkedStack D ) -> pushStack ( stackInSomeState s ) x ( \s1 -> popStack s1 ( \s3 x1 -> (Just x ≡ x1))) +push->pop : {l : Level} {D : Set l} + (x : D) (s : SingleLinkedStack D) + -> pushStack (stackInSomeState s) x + (\s1 -> popStack s1 (\s3 x1 + -> (Just x ≡ x1))) push->pop {l} {D} x s = refl \end{lstlisting} @@ -453,9 +462,10 @@ これにより、抽象化した Stack に対して push 、 pop を行うと push したものと同じも のを受け取れることが証明できた。 - \lstinputlisting[label=agda-in-some-state, caption=抽象的なStackの定義とpush$->$push$->$pop2 の証明]{src/AgdaStackSomeState.agda.replaced} +\lstinputlisting[label=agda-in-some-state, caption=抽象的なStackの定義とpush$\rightarrow$push$\rightarrow$pop2 の証明]{src/AgdaStackSomeState.agda.replaced} -今回の研究では、Agda を用いて GearsOS 上のモジュール化である interface の記述に +\section{まとめ} +本論文では、Agda を用いて GearsOS 上のモジュール化である interface の記述に ついて検討、実装した。また、継続を用いた記述をすることで計算途中のデータの形など を確認することができることが分かった。その他に、interface の記述を通しての証明が行えることが分かった。 diff -r 35d15c091cfd -r 907f967f662e Paper/src/AgdaStackSomeState.agda --- a/Paper/src/AgdaStackSomeState.agda Mon Apr 23 21:44:32 2018 +0900 +++ b/Paper/src/AgdaStackSomeState.agda Sat May 19 19:14:19 2018 +0900 @@ -1,5 +1,5 @@ -stackInSomeState : {l m : Level } {D : Set l} {t : Set m } (s : SingleLinkedStack D ) -> Stack {l} {m} D {t} ( SingleLinkedStack D ) +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 } -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 } +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} diff -r 35d15c091cfd -r 907f967f662e Slide/fig/cbc-hoare.xbb --- a/Slide/fig/cbc-hoare.xbb Mon Apr 23 21:44:32 2018 +0900 +++ b/Slide/fig/cbc-hoare.xbb Sat May 19 19:14:19 2018 +0900 @@ -1,8 +1,8 @@ -%%Title: cbc-hoare.pdf -%%Creator: extractbb 20160307 +%%Title: fig/cbc-hoare.pdf +%%Creator: extractbb 20180217 %%BoundingBox: 0 0 580 175 %%HiResBoundingBox: 0.000000 0.000000 580.000000 175.000000 %%PDFVersion: 1.3 %%Pages: 1 -%%CreationDate: Wed Feb 21 01:38:18 2018 +%%CreationDate: Tue May 15 18:15:06 2018 diff -r 35d15c091cfd -r 907f967f662e Slide/fig/fanctionLoop.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Slide/fig/fanctionLoop.svg Sat May 19 19:14:19 2018 +0900 @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 35d15c091cfd -r 907f967f662e Slide/fig/funcLoopinAutomata.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Slide/fig/funcLoopinAutomata.svg Sat May 19 19:14:19 2018 +0900 @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 35d15c091cfd -r 907f967f662e Slide/fig/hoare-logic.xbb --- a/Slide/fig/hoare-logic.xbb Mon Apr 23 21:44:32 2018 +0900 +++ b/Slide/fig/hoare-logic.xbb Sat May 19 19:14:19 2018 +0900 @@ -1,8 +1,8 @@ -%%Title: hoare-logic.pdf -%%Creator: extractbb 20160307 +%%Title: fig/hoare-logic.pdf +%%Creator: extractbb 20180217 %%BoundingBox: 0 0 580 76 %%HiResBoundingBox: 0.000000 0.000000 580.000000 76.000000 %%PDFVersion: 1.3 %%Pages: 1 -%%CreationDate: Wed Feb 21 01:38:18 2018 +%%CreationDate: Tue May 15 18:15:06 2018 diff -r 35d15c091cfd -r 907f967f662e Slide/fig/meta.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Slide/fig/meta.svg Sat May 19 19:14:19 2018 +0900 @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 35d15c091cfd -r 907f967f662e Slide/fig/meta.xbb --- a/Slide/fig/meta.xbb Mon Apr 23 21:44:32 2018 +0900 +++ b/Slide/fig/meta.xbb Sat May 19 19:14:19 2018 +0900 @@ -1,8 +1,8 @@ -%%Title: meta.pdf -%%Creator: extractbb 20160307 +%%Title: fig/meta.pdf +%%Creator: extractbb 20180217 %%BoundingBox: 0 0 958 148 %%HiResBoundingBox: 0.000000 0.000000 958.000000 148.000000 %%PDFVersion: 1.3 %%Pages: 1 -%%CreationDate: Wed Feb 21 01:38:18 2018 +%%CreationDate: Tue May 15 18:15:06 2018 diff -r 35d15c091cfd -r 907f967f662e Slide/prosym.md --- a/Slide/prosym.md Mon Apr 23 21:44:32 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -title: GearsOSのAgdaによる記述と検証 -author: Masataka Hokama, Shinji Kono -profile: 琉球大学 -lang: Japanese -code-engine: coderay - - - - -## プログラムの信頼性の保証 -* 動作するプログラムの信頼性を保証したい -* 信頼性の保証をするためにはプログラムの仕様を検証する必要がある -* プログラムの仕様を検証するにはモデル検査と **定理証明** の2つの手法がある - * モデル検査 はプログラムの持つ状態を数え上げて仕様を満たしているかを確認する - * 定理証明 はプログラムの性質を論理式で記述し、型を生成する関数を定義することで証明を記述できる -* また、当研究室では検証しやすい単位として CodeGear、DataGear という単位を用いてプログラムを記述する手法を提案している - -## プログラムの信頼性の保証 -* 今回は **定理証明** をつかって仕様を検証した -* 定理証明には定理証明支援系の言語 Agda を使用する - * Agda では型でプログラムの性質を論理式で記述し、型に対応する関数部分で論理式を解くことで証明を記述できる -* データ構造を仕様と実装に分けて記述するために現在ある Stack 実装とは別に Stack の仕様部分を Interface で記述した - -* 今回は Agda を用いて CodeGear 、DataGear、という単位と Interface を定義した -* CodeGear、DataGear という単位を用いて実装された Stack を Interface を通して呼び出し、その性質の一部について証明を行なった - - -## CodeGear と DataGear -* CodeGear とはプログラムを記述する際の処理の単位である -* DataGear は CodeGear で扱うデータの単位であり、処理に必要なデータが全て入っている -* CodeGear はメタ計算によって CodeGear へ接続される -* メタ計算を切り替えることで処理に変更を加えることなくプログラムの性質を検証できる - -
- goto -
- - -## Agda での popSingleLinkedStack の型 -* Agda の 関数部分は **関数名 = 値** -* この型は stack を受け取り、stack の先頭を取って、次の関数に渡すという関数の型 -* popSingleLinkedStack は Stack のpop のCodeGearで、継続に型Maybe aを受けとるCodeGear( ** (fa -> t) -> t** )に渡す -* stack は空の可能性があるので Maybe a を返す - - -```AGDA -popSingleLinkedStack : SingleLinkedStack a -> - (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t -``` - -## Maybe -* **Maybe** はNothingかJustの2つの場合を持つ型でAgda の **data** として定義されている -* Just か Nothing はパターンマッチで場合分けする -Nothing と Just a は Maybe を生成する constructor - -```AGDA -data Maybe a : Set where - Nothing : Maybe a - Just : a -> Maybe a -``` - -## data を用いた等式の Agda での証明 -* x ≡ x はAgdaでは常に正しい論理式 -* data は **data データ名 : 型** と書く -* **refl** は左右の項が等しいことを表す x ≡ x を生成する項 -* x ≡ x を証明したい時には refl と書く - -```AGDA -data _≡_ {a} {A : Set a} (x : A) : A → Set a where - refl : x ≡ x -``` - -## Agda でのpopSingleLinkedStack での定義 -* Agdaでの関数の定義は **関数名 = 関数の実装** の書く -* 関数名と = の間にある stack と cs は引数 -* popSingleLinkedStack では stack を受け取り、 stack の中から data を取り出し、新しいstack を継続し、次の CodeGear に継続している -* stack の top は Maybe a なので Nothing と Just -* 関数部分では with で data のパターンマッチを行うことができる - - -```AGDA -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)) -``` - -## SingleLinkedStack の定義(recordの例) -* record は複数のデータをまとめて記述する型 -* **record レコード名** を書き、その次の行の **field** 後に **フィールド名:型名** と列挙する -* SingleLinkedStack では top というフィールドに Maybe のかかっている Element 型の要素aが定義されている -* Element では record で data と次の要素 next が定義されている - -```AGDA -record SingleLinkedStack (a : Set) : Set where - field - top : Maybe (Element a) -``` - -## pushSingleLinkedStackの定義とrecordの構築 -* 実際に record を構築するときの例として **pushSingleLinkedStack** の関数部分を扱う -* pushSingleLinkedStack では stack と data を受け取り、 CodeGear 中で Data を stack に入れ、新しいstack を継続し、次の CodeGear に継続している -* record の構築は関数側で行う -* **record** の後ろの {} 内部で **フィールド名 = 値** で列挙する -* 複数のレコードを書くときは **;** で区切る - -```Agda -pushSingleLinkedStack stack datum next = - next record {top = Just (record {datum = datum;next =(top stack)})} -``` - -## Agda での Interface の定義 -* singleLinkedStack の仕様を実装とは別に記述するために record を使い、 Stack の Interface を記述した -* ここでの push、 pop は仕様のみの記述で実装とはここでは関係ない -* t は継続を返す型を表す -* 実装は関数の中で record を構築し、singleLinkedStack での push 、 pop と繋げられる - -```AGDA -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 -``` - - -## 証明の概要 -* 今回は singleLinkedStack の実装を抽象的に表す Interface を通し、 **任意の数** を push し pop したとき、 -push した値と pop した値が等しくなることを証明する -* このとき、どのような状態の Stack に push し、 pop をしても値が等しくなることを示したい -* そのため、**状態の不定な** Stack を作成する関数を作成した - -## 不定な Stack を作成する stackInSomeState という関数の定義 -* 不定なstackは入力(s : SingleLinkedStack a )で与える -* 入力は定義時点では決まっていないので不定 -* stackInSomeState は stack を受け取り、状態の決まっていない stack を record で作成する - -```AGDA -stackInSomeState : (s : SingleLinkedStack a ) -> Stack a ( SingleLinkedStack a ) -stackInSomeState s = record { stack = s ; stackMethods = singleLinkedStackSpec } -``` - -## Agda での Interface を含めた部分的な証明 -* push を2回したときの値と、直後に pop を2回して取れた値が等しいことを示している -* Agda 中では不明な部分を **?** と書くことができ、**?** 部分には証明が入る -* 証明部分はラムダ式で与える -* はじめにに型部分に注目する - -```AGDA -push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> - pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> - pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) -push->push->pop2 {l} {a} x y s = ? -``` - -## ラムダ式 -* **\s1 ->** はラムダ式で push->push->pop2 の型では次の CodeGear 部分にラムダ式を使いStackを渡している - -```AGDA -push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> - pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> - pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) -``` - - -## Agda での Interface を含めた部分的な証明 -* ? 部分はコンパイル時に Agda から内部に入る型を示してもらえる -* ここでは最終的に **(Just x ≡ x1) ∧ (Just y ≡ y1)** が返ってくる -* (x ≡ x1)と(y ≡ y1)の2つが同時成り立ってほしい -* そこで **∧** の部分を record で定義した - -```AGDA -push->push->pop2 {l} {a} x y s = { }0 -``` - -```AGDA --- Goal -?0 : pushStack (stackInSomeState s) x -(λ s1 → - pushStack s1 y - (λ s2 → pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1)))) -``` - -## Agda での Interface を含めた部分的な証明(∧) -* a と b の2つの証明から a かつ b という証明をするために ** ∧ ** を定義した -* 異なる2つのものを引数にとり、それらがレコードに存在することを示せればよい - - -```AGDA -record _∧_ {n : Level } (a : Set n) (b : Set n): Set n where - field - pi1 : a - pi2 : b -``` - -## Agda での Interface を含めた部分的な証明 -* x と x1 が等しいことは **refl** で証明できる -* ∧ でまとめた pi1、pi2は両方共等しいはずなので両方に refl を使う -* pi1、pi2の両方に refl を代入することで証明することができた -* これにより証明の目的であった「どのような状態の Stack に push し、 pop をしても値が等しくなる」ことを証明することができた - -```AGDA -push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> - pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> - pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) -push->push->pop2 {l} {a} x y s = record { pi1 = refl ; pi2 = refl } -``` - -## まとめと今後の課題 -* 本研究では CodeGear、DataGear を Agda で定義することができた -* また Agda で Interface の記述及び Interface を含めた一部の証明を行えた -* これにより、 Interface を経由しても一部の性質は実装と同様の働きをすることが証明できた - -* 今後の課題としては 継続を用いた Agda で Hoare Logic を表現し、その Hoare Logic をベースとして証明を行えるかを確認する -* また RedBlackTree の挿入、削除の性質に関する証明も行おうと考えている - - -## Hoare Logic -* Hoare Logic は Tony Hoare によって提案されたプログラムの部分的な正当性を検証するための手法 -* 前の状態を{P}(Pre-Condition)、後の状態を{Q}(Post-Condition)とし、前状態を C (Command) によって変更する -* この {P} C {Q} でプログラムを部分的に表すことができるp - -
- hoare -
- - -## Hoare Logic と CbC - -* Hoare Logic の状態と処理を CodeGear、 DataGear の単位で考えることができると考えている - -
- cbc-hoare -
- - -## Element -* Element の説明 -```AGDA -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) -``` diff -r 35d15c091cfd -r 907f967f662e Slide/sigos.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Slide/sigos.html Sat May 19 19:14:19 2018 +0900 @@ -0,0 +1,558 @@ + + + + + GearsOSのAgdaによる記述と検証 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ +
+ + + + + + + +
+
+

GearsOSのAgdaによる記述と検証

+
+
+
+ Masataka Hokama, Shinji Kono + 琉球大学 +
+
+
+
+ +
+ + + + + + + + +

本発表の流れ

+ + + +
+
+ +

プログラムの信頼性の保証

+ + + +
+
+ +

プログラムの信頼性の保証

+ + + +
+
+ +

CodeGear と DataGear の定義

+ + +
+ goto +
+ + + + + +

次のスライドからは Agda の記述について解説を行う

+ + +
+
+ +

Agda での型

+ + +
popSingleLinkedStack : SingleLinkedStack a -> 
+   (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t
+
+ + +
+
+ +

Maybe

+ + +
data Maybe a : Set where
+  Nothing : Maybe a
+  Just    : a -> Maybe a
+
+ + +
+
+ +

data を用いた等式の証明

+ + +
data _≡_ {a} {A : Set a} (x : A) : A → Set a where
+  refl : x ≡ x
+
+ + +
+
+ +

Agda での関数

+ + +
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))
+
+ + +
+
+ +

Agda での record の定義

+ + +
record SingleLinkedStack (a : Set) : Set where
+  field
+    top : Maybe (Element a)
+
+ + +
+
+ +

Agda での record の構築

+ + +
pushSingleLinkedStack stack datum next = 
+    next record {top = Just (record {datum = datum;next =(top stack)})}
+
+ + +
+
+ +

Agda での Interface の定義

+ + +
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
+
+ + +
+
+ +

証明の概要

+ + + +
+
+ +

状態が不定な Stack の定義

+ + +
stackInSomeState : (s : SingleLinkedStack a ) -> Stack a ( SingleLinkedStack  a )
+stackInSomeState s =  record { stack = s ; stackMethods = singleLinkedStackSpec }
+
+ + +
+
+ +

Agda での Interface を含めた部分的な証明

+ + +
push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) ->
+    pushStack ( stackInSomeState s )  x ( \s1 -> pushStack s1 y ( \s2 ->
+    pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) ))
+push->push->pop2 {l} {a} x y s = ?
+
+ + +
+
+ +

ラムダ式

+ + +
push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) ->
+    pushStack ( stackInSomeState s )  x ( \s1 ->* pushStack s1 y ( \s2 ->
+    pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) ))
+
+ + +
+
+ +

Agda での Interface を含めた部分的な証明

+ + +
push->push->pop2 {l} {a} x y s = { }0
+
+ +
-- Goal
+?0 : pushStack (stackInSomeState s) x
+(λ s1 →
+   pushStack s1 y
+   (λ s2 → pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1))))
+
+ + +
+
+ +

Agda での Interface を含めた部分的な証明

+ + +
-- Goal
+?0 : pushStack (stackInSomeState s) x
+(λ s1 →
+   pushStack s1 y
+   (λ s2 → pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1))))
+
+ + +
+
+ +

Agda での Interface を含めた部分的な証明(∧)

+ + +
record _∧_ {n : Level } (a : Set n) (b : Set n): Set n where
+  field
+    pi1 : a
+    pi2 : b
+
+ + +
+
+ +

Agda での Interface を含めた部分的な証明

+ + +
push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) ->
+    pushStack ( stackInSomeState s )  x ( \s1 -> pushStack s1 y ( \s2 ->
+    pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) ))
+push->push->pop2 {l} {a} x y s = record { pi1 = { }0 ; pi2 = { }1 }
+
+ +
?0 : Just x ≡
+Just
+(Element.datum
+ (.stack.element (stack (stackInSomeState s)) x
+  (λ s1 →
+     pushStack
+     (record
+      { stack = s1 ; stackMethods = stackMethods (stackInSomeState s) })
+     y
+     (λ s2 →
+        pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1))))))
+
+ + +
+
+ +

Agda での Interface を含めた部分的な証明

+ + +
push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) ->
+    pushStack ( stackInSomeState s )  x ( \s1 -> pushStack s1 y ( \s2 ->
+    pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) ))
+push->push->pop2 {l} {a} x y s = record { pi1 = refl ; pi2 = refl }
+
+ + +
+
+ +

手証明での限界

+ + + +
+
+ +

Hoare Logic

+ + +
+ hoare +
+ + +
+
+ +

Hoare Logic と CbC

+ + + +
+ cbc-hoare +
+ + +
+
+ +

Hoare Logic での例 (Binary Tree)

+ + + + +
+ f-loop +
+ +

ここでは findNode に注目する。

+ + +
+
+ +

Hoare Logic での例 (Binary Tree : findNode)

+ + +
+ f-loop-auto +
+ + +
+
+ +

まとめと今後の方針

+ + + + +
+
+ +

Element

+ +
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)
+
+ + +
+ + +
+ + diff -r 35d15c091cfd -r 907f967f662e Slide/sigos.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Slide/sigos.md Sat May 19 19:14:19 2018 +0900 @@ -0,0 +1,318 @@ +title: GearsOSのAgdaによる記述と検証 +author: Masataka Hokama, Shinji Kono +profile: 琉球大学 +lang: Japanese +code-engine: coderay + + + + + + + +## 本発表の流れ +* 研究目的 +* CodeGear と DataGear の説明 +* Agda での記述 +* Agda での CodeGear 、 DataGear 、 Interface の表現 +* 実際に行なった証明 +* 証明の改善 +* まとめ + +## プログラムの信頼性の保証 +* 動作するプログラムの信頼性を保証したい +* 保証をするためには仕様を検証する必要がある +* 仕様を検証するにはモデル検査と **定理証明** の2つの手法がある + * モデル検査 はプログラムの持つ状態を数え上げて仕様を満たしているかを確認するもの + * 定理証明 はプログラムの性質を論理式で記述し、型を生成する関数を定義することで証明を記述できるもの +* 当研究室では検証しやすい単位として CodeGear、DataGear という単位を用いてプログラムを記述する手法を提案している + +## プログラムの信頼性の保証 +* 本研究では **定理証明支援系** の言語 **Agda** をつかって仕様を検証した +* 当研究室では 信頼性の高い ~ として GearsOS という OS を開発している +* CodeGear DataGear での プログラミングは 関数型に近いかたちのプログラミングになる +* Agda は関数型言語であるため 近い形になると考えた~ +* データ構造を仕様と実装に分けて記述するため、モジュール化の仕組みである **Interface** を記述した +* 今回は Agda で CodeGear 、DataGear、という単位と Interface を定義した +* また、 CodeGear 、DataGear を用いて Agda 上に実装された Stack を Interface を通して呼び出し、その性質の一部について証明を行った + +## CodeGear と DataGear の定義 +* CodeGear とはプログラムを記述する際の処理の単位 +* DataGear は CodeGear で扱うデータの単位で、処理に必要なデータが全て入っている +* CodeGear はメタ計算によって別の CodeGear へ接続される + +
+ goto +
+ + + + + +次のスライドからは Agda の記述について解説を行う + +## Agda での型 + + + +* Agda の 型は **関数名 : 型** のように **:** を使って定義される +* ここでは Stack の**実装**である **popSingleLinkedStack** の型を例とする +* この型は stack を受け取り、stack の先頭を取って、次の関数に渡すという関数の型 +* stack は空の可能性があるので Maybe a を返す +* popSingleLinkedStack は Stack の pop のCodeGearで、継続に型 Maybe a を受けとる CodeGear ( **(fa -> t) -> t**) に渡す + +```AGDA +popSingleLinkedStack : SingleLinkedStack a -> + (Code : SingleLinkedStack a -> (Maybe a) -> t) -> t +``` + +## Maybe +(x : A) の説明 +* **Maybe** はNothingかJustの2つの場合を持つ型で Agda の **data** として定義されている +* Just か Nothing はパターンマッチで場合分けするNothing と Just a は Maybe を生成する constructor + +```AGDA +data Maybe a : Set where + Nothing : Maybe a + Just : a -> Maybe a +``` + +## data を用いた等式の証明 + +* x ≡ x は Agda では常に正しい論理式 +* data は **data データ名 : 型** +* **refl** は左右の項が等しいことを表す x ≡ x を生成する項 +* x ≡ x を証明したい時には refl と書く + +```AGDA +data _≡_ {a} {A : Set a} (x : A) : A → Set a where + refl : x ≡ x +``` + +## Agda での関数 + +* Agda での関数定義は **関数名 = 関数の実装** +* ここでは **popSingleLinkedStack** の関数を例とする +* 引数は **関数名** と **=** の間に記述する +* stack と 次の CodeGear である cs を受け取り、 stack の中から data を取り出し、新しい stack に継続し、次の CodeGear へと stack 渡している +* stack の top は Maybe a なので Nothing か Just が返ってくる +* **with** で data のパターンマッチができる + +```AGDA +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)) +``` + +## Agda での record の定義 + + + + +* record は複数のデータをまとめて記述する型 +* **record レコード名** を書き、その次の行の **field** 後に **フィールド名:型名** と列挙する +* ここでは SingleLinkedStack の定義を例とする +* 定義では top フィールドのみを定義しているが複数定義することもできる +* top には Element 型の要素 a が定義されており、 **Element** 型は現在の **data** と次の data を指す **next** を定義している + +```AGDA +record SingleLinkedStack (a : Set) : Set where + field + top : Maybe (Element a) +``` + +## Element +* Element の説明 +```AGDA +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) +``` + + +## Agda での record の構築 +* record の構築は関数側 +* **record** 後ろの **{}** 内部で **フィールド名 = 値** で列挙する +* 複数のレコードを記述するさいは **;** で区切る +* 例として **pushSingleLinkedStack** の関数部分を扱う +* pushSingleLinkedStack では stack と data を受け取り、 CodeGear 中で Data を stack に入れ、新しいstack を継続し、次の CodeGear に継続している + +```Agda +pushSingleLinkedStack stack datum next = + next record {top = Just (record {datum = datum;next =(top stack)})} +``` + +## Agda での Interface の定義 + + + +* Stack の仕様を実装とは別に記述するために record で Stack の Interface を記述した +* ここでの push、 pop は仕様の型のみ記述され、実装は構築時に与える +* t は継続を返す型を表し、次の CodeGear を指す +* ここでの push 、 pop は pushSingleLinkedStack 、 popSingleLinkedStack に繋げる + +```AGDA +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 +``` + +## 証明の概要 +* 今回は Interface を通して、 **任意の数** を stack に push し、データが入った stack に対して pop を行なう +* このとき push した値と pop した値が等しくなることを証明する +* また、どのような状態の Stack に push し、 pop をしても値が等しくなることを示したい +* そのため、**状態の不定な** Stack を作成する関数を定義した + +## 状態が不定な Stack の定義 +* ここでは状態が不定な Stack を作成する関数 **stackInSomeState** を定義する +* 不定なstackを入力(s : SingleLinkedStack a )で与える +* stackInSomeState は stack を受け取り、状態の決まっていない stack を構築する + +```AGDA +stackInSomeState : (s : SingleLinkedStack a ) -> Stack a ( SingleLinkedStack a ) +stackInSomeState s = record { stack = s ; stackMethods = singleLinkedStackSpec } +``` + +## Agda での Interface を含めた部分的な証明 +* 証明部分は型部分にラムダ式で与える +* **push->push->pop2**では push を2回したときの値と、直後に pop を2回して取れた値が等しいことを型に記述している + +```AGDA +push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> + pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> + pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) +push->push->pop2 {l} {a} x y s = ? +``` + +## ラムダ式 +* **\s1 ->** はラムダ式で push->push->pop2 の型では次の CodeGear 部分にラムダ式を使いStackを渡している + +```AGDA +push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> + pushStack ( stackInSomeState s ) x ( \s1 ->* pushStack s1 y ( \s2 -> + pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) +``` + +## Agda での Interface を含めた部分的な証明 +* Agda では不明な部分を **?** と書くことができる +* **?** 部分はコンパイルすると **{}n** のように番号が付き、Agda から内部に入る型を示してもらえる + +```AGDA +push->push->pop2 {l} {a} x y s = { }0 +``` + +```AGDA +-- Goal +?0 : pushStack (stackInSomeState s) x +(λ s1 → + pushStack s1 y + (λ s2 → pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1)))) +``` + +## Agda での Interface を含めた部分的な証明 +* ここでは最終的に **(Just x ≡ x1) ∧ (Just y ≡ y1)** が返ってくる必要がある +* **(x ≡ x1)** と **(y ≡ y1)** の2つが同時に成り立つ必要がある +* そこで **∧** の部分を record で定義した + +```AGDA +-- Goal +?0 : pushStack (stackInSomeState s) x +(λ s1 → + pushStack s1 y + (λ s2 → pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1)))) +``` + +## Agda での Interface を含めた部分的な証明(∧) +* a と b の2つの証明から a かつ b という証明を行うため **∧** を定義する +* これには異なる2つのものを引数にとり、それらがレコードに同時に存在することが示せれば良い +* **∧** は 型 a と 型b をもつ2つの要素を左右にとり、 それらが同時に存在することを示すレコード型 + +```AGDA +record _∧_ {n : Level } (a : Set n) (b : Set n): Set n where + field + pi1 : a + pi2 : b +``` + +## Agda での Interface を含めた部分的な証明 +* 定義した ∧ を関数部分で構築する +* ここでは **pi1** 、 **pi2** の両方を **?** としておく + + +```AGDA +push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> + pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> + pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) +push->push->pop2 {l} {a} x y s = record { pi1 = { }0 ; pi2 = { }1 } +``` + +```AGDA +?0 : Just x ≡ +Just +(Element.datum + (.stack.element (stack (stackInSomeState s)) x + (λ s1 → + pushStack + (record + { stack = s1 ; stackMethods = stackMethods (stackInSomeState s) }) + y + (λ s2 → + pop2Stack s2 (λ s3 y1 x1 → (Just x ≡ x1) ∧ (Just y ≡ y1)))))) +``` + +## Agda での Interface を含めた部分的な証明 +* ∧ で定義された左右に **x ≡ x1** と **y ≡ y1** が入る +* **x ≡ x1**、 **y ≡ y1** は共に **refl** で証明できる +* pi1、pi2 は両方 refl が入ることで証明ができる +* また、型に書かれた順で値が取り出されている為、最後のラムダ式で stack の性質である FIFO 通りに値が取れていることが分かる +* これにより証明の目的であった「どのような状態の Stack に push し、 pop をしても値が等しくなる」ことを証明することができた + +```AGDA +push->push->pop2 : {l : Level } {a : Set l} (x y : a ) (s : SingleLinkedStack a ) -> + pushStack ( stackInSomeState s ) x ( \s1 -> pushStack s1 y ( \s2 -> + pop2Stack s2 ( \s3 y1 x1 -> (Just x ≡ x1 ) ∧ (Just y ≡ y1 ) ) )) +push->push->pop2 {l} {a} x y s = record { pi1 = refl ; pi2 = refl } +``` + +## 手証明での限界 +* 現在 Binary Tree に対して近い証明を書いている +* これは 「Tree に対して node を put し、 get した時取れる node の値は put した node と等しい」というもの +* Tree に対する操作では root Node から Node を辿る Loop があり、それを展開しながら証明を書く +* Agda 側が put した node と get した node が等しいことを分かってくれず、証明が完成していない… +* 今後は新しい証明規則を導入して証明を行おうと考えている + +## Hoare Logic +* Hoare Logic は Tony Hoare によって提案されたプログラムの部分的な正当性を検証するための手法 +* 前の状態を{P}(Pre-Condition)、後の状態を{Q}(Post-Condition)とし、前状態を C (Command) によって変更するといったもの +* この {P} C {Q} でプログラムを部分的に表すことができる +* {P} が成り立つときに、 C を実行すると、実行後は必ず {Q} が成り立つとき、部分的に正当である + +
+ hoare +
+ + +## Hoare Logic と CbC + +* Hoare Logic の状態と処理を CodeGear、 DataGear の単位で考えることができると考えている +* Pre-condition を input DataGear , Post-Conditon を output DataGear , Command は CodeGear そのものとして扱えると考えている。 + +
+ cbc-hoare +
+ + + +## まとめと今後の方針 +* 本研究では CodeGear、DataGear を Agda で定義することができた +* また Agda で Interface の記述及び Interface を含めた証明を行うことができた +* これにより、 Interface を経由しても一部の性質は実装と同様の働きをすることが証明できた +* また、CbC での Interface 記述では考えられていなかった細かな記述が明らかになった +* 今後は RedBlackTree や syncronisedQueue に対して証明を行う + +