comparison slide/slide.md @ 10:aedb8c4f13b9

add slide and slide-mindmap
author ryokka
date Sat, 08 Feb 2020 22:07:16 +0900
parents
children 831316a767e8
comparison
equal deleted inserted replaced
9:95a5f8e76944 10:aedb8c4f13b9
1 <!-- TODO
2 - 章構成を slide.mm の形に直す。
3 - Agda の説明と Gears の説明をなおす
4 - Gears での Hoare Logic の説明する前になんで Hoare Logic ベースなのかのスライドを入れてみる
5 -->
6
7
8 title: Continuation based C での Hoare Logic を用いた記述と検証
9 author: 外間政尊
10 profile: - 琉球大学 : 並列信頼研究室
11 lang: Japanese
12
13 <!-- 発表20分、質疑応答5分 -->
14
15 ## OS の検証技術としての HoareLogic の問題点
16 - OS やアプリケーションの信頼性は重要な課題
17 - 信頼性を上げるために仕様の検証が必要
18 - 仕様検証の手法として **Hoare Logic** がある
19 - ある関数は実行する前に必要な引数があって何らかの出力がある
20 - Hoare Logic では 任意のコマンドは 事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ
21 <!-- - 関数実行前に、引数が存在していて、出力が意図した通りになる -->
22 - HoareLogic では関数が最低限のコマンドまで分割されており記述が困難(変数の代入、コマンド実行の遷移等)
23 - 大規模なプログラムは構築しづらい
24
25 ## Gears を用いた HoareLogic の導入
26 - 当研究室では 処理の単位を **CodeGear**、データの単位を **DataGear** としてプログラムを記述する手法を提案
27 - CodeGear は Input DataGear を受け取り、処理を行って Output DataGear に書き込む
28 - CodeGear は継続を用いて次の CodeGear に接続される
29 - 本研究では Gears 単位を用いた HoareLogic ベースの検証手法を提案する
30
31 ## Gears について
32 - **Gears** は当研究室で提案しているプログラム記述手法
33 - 処理の単位を **CodeGear** 、データの単位を **DataGear**
34 - CodeGear は引数として Input の DataGear を受け取り、 Output の DataGear を返す
35 - Output の DataGear は次の CodeGear の Input として接続される
36 <!-- [fig1](file://./fig/cgdg.pdf) -->
37 - CodeGear の接続処理などのメタ計算は Meta CodeGear として定義
38 - 今回は Meta CodeGear で信頼性の検証を行う
39 <p style="text-align:center;"><img src="./fig/cgdg-small.svg" alt="" width="60%" height="50%"/></p>
40 <!-- <p style="text-align:center;"><img src="./fig/cgdg-small.svg" alt="" width="75%" height="75%"/></p> -->
41
42 ## Agda での DataGear
43 - **DataGear** は CodeGear でつかわれる引数
44 - **データ型**と**レコード型**がある
45 - データ型は一つのデータ
46 ```AGDA
47 data Nat : Set where
48 zero : Nat
49 suc : Nat → Nat
50 ```
51 - レコード型は複数のデータをまとめる
52 ```AGDA
53 record Env : Set where
54 field
55 varn : Nat
56 vari : Nat
57 ```
58
59 ## Agda での Gears の記述(whileTest)
60 - Agda での CodeGear は継続渡し (CPS : Continuation Passing Style) で記述された関数
61 - **{}** は暗黙的(推論される)
62 - 継続渡しの関数は引数として継続を受け取って継続に計算結果を渡す
63 - CodeGear の型は**引数 → (Code : fa → t) → t**
64 - **t** は継続(最終的に返すもの)
65 - **(Code : fa → t)** は次の継続先
66 ```AGDA
67 whileTest : {t : Set} → (c10 : Nat)
68 → (Code : Env → t) → t
69 whileTest c10 next = next (record {varn = c10
70 ; vari = 0} )
71 ```
72
73 ## Agda での Gears の記述(whileLoop)
74 - 関数の動作を条件で変えたいときはパターンマッチを行う
75 - whileLoop は varn が 0 より大きい間ループする
76 ```AGDA
77 whileLoopPwP' : {t : Set} → (n : ℕ) → (env : Envc ) → (n ≡ varn env) → whileTestStateP s2 env
78 → (next : (env : Envc ) → (pred n ≡ varn env) → whileTestStateP s2 env → t)
79 → (exit : (env : Envc ) → whileTestStateP sf env → t) → t
80 whileLoopPwP' zero env refl refl next exit = exit env refl
81 whileLoopPwP' (suc n) env refl refl next exit =
82 next (record env {varn = pred (varn env) ; vari = suc (vari env) }) refl (+-suc n (vari env))
83 ```
84
85 ## Agda での証明
86 - 関数との違いは**型が証明すべき論理式**で**関数自体がそれを満たす導出**
87 - **refl** は **x ≡ x**
88 - **cong** は 関数と x ≡ y 受け取って、x ≡ y の両辺に関数を適応しても等しいことが変わらないこと
89 - **+zero** は任意の自然数の右から zero を足しても元の数と等しいことの証明
90 - **y = zero** のときは **zero ≡ zero** のため refl
91 - **y = suc y** のときは cong を使い y の数を減らして再帰的に**+zero**を行っている
92 - y の数を減らしても大丈夫なことを cong の関数として受け取った数を suc する関数で保証している
93 ```AGDA
94 +zero : { y : Nat } → y + zero ≡ y
95 +zero {zero} = refl
96 +zero {suc y} = cong ( λ x → suc x ) ( +zero {y} )
97 ```
98
99 <!-- ## Agda での証明(項変換) -->
100 <!-- <\!-- -- もしかしたら rewrite で代用しちゃうかも -\-> -->
101 <!-- - **x + y ≡ y + x** の証明 **+-sym** -->
102 <!-- - 項変換の例として引数が zero, suc y のパターンをみる -->
103 <!-- - **zero + suc y**を変換して**suc y + zero**にする -->
104 <!-- - begin の下の行に変形したい式を記述 -->
105 <!-- - **≡⟨ ⟩** に変形規則、その次の行に変換した結果、 **∎** が項変換終了 -->
106 <!-- ```AGDA -->
107 <!-- +-sym : { x y : Nat } → x + y ≡ y + x -->
108 <!-- +-sym {zero} {suc y} = let open ≡-Reasoning in -->
109 <!-- begin -->
110 <!-- zero + suc y -->
111 <!-- ≡⟨⟩ -->
112 <!-- suc y -->
113 <!-- ≡⟨ sym +zero ⟩ -->
114 <!-- suc y + zero -->
115 <!-- ∎ -->
116 <!-- -- sym : Symmetric {A = A} _≡_ -->
117 <!-- -- sym refl = refl -->
118 <!-- -- +zero : { y : Nat } → y + zero ≡ y -->
119 <!-- ``` -->
120
121 <!-- ## Agda での証明(項変換) -->
122 <!-- - **x + y ≡ y + x** の証明 **+-sym** -->
123 <!-- - 項の変換には **rewrite** と **** -->
124 <!-- - begin の下の行に変形したい式を記述 -->
125 <!-- - **≡⟨ ⟩** に変形規則、その次の行に変換した結果、 **∎** が項変換終了 -->
126 <!-- ```AGDA -->
127 <!-- +-comm : (x y : ℕ) → x + y ≡ y + x -->
128 <!-- +-comm zero y rewrite (+zero {y}) = refl -->
129 <!-- +-comm (suc x) y = let open ≡-Reasoning in -->
130 <!-- begin -->
131 <!-- suc (x + y) ≡⟨⟩ -->
132 <!-- suc (x + y) ≡⟨ cong suc (+-comm x y) ⟩ -->
133 <!-- suc (y + x) ≡⟨ sym (+-suc {y} {x}) ⟩ -->
134 <!-- y + suc x ∎ -->
135
136 <!-- -- +-suc : {x y : ℕ} → x + suc y ≡ suc (x + y) -->
137 <!-- -- +-suc {zero} {y} = refl -->
138 <!-- -- +-suc {suc x} {y} = cong suc (+-suc {x} {y}) -->
139 <!-- ``` -->
140
141
142 ## Hoare Logic をベースとした Gears での検証手法
143 - 今回 HoareLogic で証明する次のようなコードを検証した
144 - このプログラムは変数iとnをもち、 n>0 の間nの値を減らし、i の値を増やす
145 - n==0 のとき停止するため、終了時の変数の結果は i==10、n==0 になる
146 ```C
147 n = 10;
148 i = 0;
149
150 while (n>0)
151 {
152 i++;
153 n--;
154 }
155 ```
156
157 ## Gears をベースにしたプログラム
158 - test は whileTest と whileLoop を使った Gears のプログラム
159 - whileTest の継続先にDataGear を受け取って whileLoop に渡す
160 - **(λ 引数 → )**は無名の関数で引数を受け取って継続する
161
162 ```AGDA
163 test : Env
164 test = whileTest 10 (λ env → whileLoop env (λ env1 → env1))
165
166 -- whileTest : {t : Set} → (c10 : Nat) → (Code : Env → t) → t
167 -- whileLoop : {t : Set} → Env → (Code : Env → t) → t
168 ```
169
170
171 ## Gears をベースにした HoareLogic と証明(全体)
172 - proofGears は HoareLogic をベースとした証明
173 - 先程のプログラムと違い、引数として証明も持っている
174 - whileTest' の継続に conversion1、その継続に whileLoop' が来て最後の継続に vari が c10 と等しい
175 ```AGDA
176 -- test = whileTest 10 (λ env → whileLoop env (λ env1 → env1))
177 proofGears : {c10 : Nat } → Set
178 proofGears {c10} = whileTest' {_} {_} {c10} (λ n p1 →
179 conversion1 n p1 (λ n1 p2 → whileLoop' n1 p2
180 (λ n2 → ( vari n2 ≡ c10 ))))
181 ```
182
183 ## Gears と HoareLogic をベースにした証明(whileTest)
184 - 最初の Command なので PreCondition がない
185 - proof2は Post Condition が成り立つことの証明
186 - **_/\\_** は pi1 と pi2 のフィールドをもつレコード型
187 - これは2つのものを引数に取り、両方が同時に成り立つことを表している
188 - **refl** は **x == x** で左右の項が等しいことの証明
189 - Gears での PostCondition は **引数 → (Code : fa → PostCondition → t) → t**
190 ```AGDA
191 whileTest' : {l : Level} {t : Set l} {c10 : ℕ }
192 → (Code : (env : Env ) → ((vari env) ≡ 0) /\ ((varn env) ≡ c10) → t) → t
193 whileTest' {_} {_} {c10} next = next env proof2
194 where
195 env : Env
196 env = record {vari = 0 ; varn = c10 }
197 proof2 : ((vari env) ≡ 0) /\ ((varn env) ≡ c10) -- PostCondition
198 proof2 = record {pi1 = refl ; pi2 = refl}
199 ```
200
201 ## Gears と HoareLogic をベースにした証明(conversion)
202 - conversion は Condition から LoopInvaliant への変換を行う CodeGear
203 - Condition の条件は Loop 内では厳しいのでゆるくする
204 - proof4 は LoopInvaliant の証明
205
206 ```AGDA
207 conv : (env : Envc ) → (vari env ≡ 0) /\ (varn env ≡ c10 env) → varn env + vari env ≡ c10 env
208 conv e record { pi1 = refl ; pi2 = refl } = +zero
209 ```
210
211 ## HoareLogic の証明
212 - HoareLogic の証明では基本的に項の書き換えを行って証明している
213 - proof4 の証明部分では論理式の**varn env + vari env** を 書き換えて **c10** に変換している
214 - 変換で使っている **cong** は 関数と x ≡ y 受け取って両辺に関数を適応しても等しいことが変わらないことの証明
215 - 変換後の式を次の行に書いて変換を続ける
216 ```AGDA
217 conv1 : {l : Level} {t : Set l } → (env : Envc )
218 → ((vari env) ≡ 0) /\ ((varn env) ≡ (c10 env))
219 → (Code : (env1 : Envc ) → (varn env1 + vari env1 ≡ (c10 env1)) → t) → t
220 conv1 env record { pi1 = refl ; pi2 = refl } next = next env +zero
221 ```
222
223 ## Gears と HoareLogic をベースにした証明(whileLoop)
224 - whileLoop も whileTest と同様に PreCondition が CodeGear に入りそれに対する証明が記述されている
225 - ループステップごとに **whileLoopPwP'** で停止か継続かを判断し、 **loopPwP'** でループが回る
226
227 ```AGDA
228 whileLoopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) → (n ≡ varn env) → whileTestStateP s2 env
229 → (next : (env : Envc ) → (pred n ≡ varn env) → whileTestStateP s2 env → t)
230 → (exit : (env : Envc ) → whileTestStateP sf env → t) → t
231 whileLoopPwP' zero env refl refl next exit = exit env refl
232 whileLoopPwP' (suc n) env refl refl next exit =
233 next (record env {varn = pred (varn env) ; vari = suc (vari env) }) refl (+-suc n (vari env))
234
235 loopPwP' zero env refl refl exit = exit env refl
236 loopPwP' (suc n) env refl refl exit = whileLoopPwP' (suc n) env refl refl
237 (λ env x y → loopPwP' n env x y exit) exit
238 ```
239
240
241 ## Gears と HoareLogic をベースにした仕様記述
242 - **proofGears** では最終状態が i と c10 が等しくなるため仕様になっている
243
244 ```AGDA
245 whileProofs : (c : ℕ ) → Set
246 whileProofs c = whileTestPwP {_} {_} c
247 ( λ env s → conv1 env s
248 ( λ env s → loopPwP' (varn env) env refl s
249 ( λ env s → vari env ≡ c10 env )))
250 ```
251
252 ## Gears と HoareLogic を用いた仕様の証明
253 - 先程の **whileProofs** で行った仕様記述を型に記述し、実際に証明していく
254 - このままだと loopPwP' のループが進まず証明できない
255
256 ```AGDA
257 -- whileProofs c = whileTestPwP {_} {_} c
258 -- ( λ env s → conv1 env s
259 -- ( λ env s → loopPwP' (varn env) env refl s
260 -- ( λ env s → vari env ≡ c10 env )))
261
262 ProofGears : (c : ℕ) → whileProofs c
263 ProofGears c = whileTestPwP {_} {_} c
264 (λ env s → loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl +zero
265 (λ env₁ s₁ → {!!}))
266
267 Goal: loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl
268 +zero (λ env₂ s₂ → vari env₂ ≡ c10 env₂)
269 ————————————————————————————————————————————————————————————
270 s₁ : vari env₁ ≡ c10 env₁
271 env₁ : Envc
272 s : (vari env ≡ 0) /\ (varn env ≡ c10 env)
273 env : Envc
274 c : ℕ
275 ```
276
277 ## 検証時の Loop の解決
278 - **loopHelper** は今回のループを解決する証明
279 - ループ解決のためにループの簡約ができた
280
281 ```AGDA
282 loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) → (seq : whileTestStateP s2 env)
283 → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁))
284 loopHelper zero env eq refl rewrite eq = refl
285 loopHelper (suc n) env eq refl rewrite eq = loopHelper n
286 (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) refl (+-suc n (vari env))
287 ```
288
289 ## Gears と HoareLogic を用いた仕様の証明(完成)
290 - **loopHelper** を使って簡約することで **whileProofs** の証明を行うことができた
291
292 ```AGDA
293 -- whileProofs c = whileTestPwP {_} {_} c
294 -- ( λ env s → conv1 env s
295 -- ( λ env s → loopPwP' (varn env) env refl s
296 -- ( λ env s → vari env ≡ c10 env )))
297 ProofGears : (c : ℕ) → whileProofs c
298 ProofGears c = whileTestPwP {_} {_} c
299 (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero)
300 ```
301
302 <!-- ## Binary Tree について -->
303 <!-- - -->
304
305 ## まとめと今後の課題
306 - CodeGear、 DataGear を用いた HoareLogic ベースの仕様記述を導入した
307 - HoareLogic ベースの検証を実際に行うことができた
308 - 証明時の任意回の有限ループに対する解決を行えた
309 - 今後の課題
310 - BinaryTree の有限ループに対する証明
311 - Hoare Logic で検証されたコードの CbC 変換
312 - 並列実行での検証