Mercurial > hg > Papers > 2021 > soto-prosym
comparison slide/slide.md @ 11:8a97e69f8615
いったんスライドは完成
author | soto <soto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 06 Jan 2022 16:57:53 +0900 |
parents | 60d4617eac84 |
children | 62e56d73f104 |
comparison
equal
deleted
inserted
replaced
10:60d4617eac84 | 11:8a97e69f8615 |
---|---|
72 - 処理の単位を Code Gear, データの単位を Data Gear として記述するプログラミング言語 | 72 - 処理の単位を Code Gear, データの単位を Data Gear として記述するプログラミング言語 |
73 - CbC のプログラミングでは Data Gear を Code Gear で変更し、その変更を次の Code Gear に渡して処理を行う。 | 73 - CbC のプログラミングでは Data Gear を Code Gear で変更し、その変更を次の Code Gear に渡して処理を行う。 |
74 | 74 |
75 | 75 |
76 # Agda の基本 | 76 # Agda の基本 |
77 - Agdaとは定理証明支援器であり、関数型言語である | 77 - Agdaとは定理証明支援器であり、関数型言語 |
78 - Agdaでの関数は、最初に型について定義した後に、関数を定義する事で記述できる | 78 - Agdaでの関数は、最初に型について定義した後に、関数を定義する事で記述する |
79 - これが Curry-Howard 対応となる | 79 - これが Curry-Howard 対応となる |
80 - 型の定義部分で、入力と出力の型を定義できる | 80 - 型の定義部分で、入力と出力の型を定義できる |
81 - input → output のようになる | 81 - input → output のようになる |
82 - 関数の定義は = を用いて行う | 82 - 関数の定義は = を用いて行う |
83 - 関数名の後、 = の前で受け取る引数を記述します | 83 - 関数名の後、 = の前で受け取る引数を記述します |
84 | |
85 <!-- | |
84 ``` | 86 ``` |
85 sample1 : (A : Set ) → Set | 87 sample1 : (A : Set ) → Set |
86 sample1 a = a | 88 sample1 a = a |
87 | 89 |
88 sample2 : (A : Set ) → (B : Set ) → Set | 90 sample2 : (A : Set ) → (B : Set ) → Set |
89 sample2 a b = b | 91 sample2 a b = b |
90 ``` | 92 ``` |
91 | 93 --> |
92 | 94 |
93 # Agda の基本 record | 95 # Agda の基本 record |
94 - 2つのものが同時に存在すること | 96 オブジェクトあるいは構造体 |
95 - Record 型とはオブジェクトあるいは構造体 | |
96 ``` | 97 ``` |
97 record Env : Set where | 98 record Env : Set where |
98 field | 99 field |
99 varn : N | 100 varn : N |
100 vari : N | 101 vari : N |
121 whileLoop : {l : Level} {t : Set l} → Env → (Code : Env → t) → t | 122 whileLoop : {l : Level} {t : Set l} → Env → (Code : Env → t) → t |
122 whileLoop env next with lt 0 (varn env) | 123 whileLoop env next with lt 0 (varn env) |
123 whileLoop env next | false = next env | 124 whileLoop env next | false = next env |
124 whileLoop env next | true = whileLoop (record {varn = (varn env) - 1 ; vari = (vari env) + 1}) next | 125 whileLoop env next | true = whileLoop (record {varn = (varn env) - 1 ; vari = (vari env) + 1}) next |
125 ``` | 126 ``` |
126 - t を返すで継続を表す(tは呼び出し時に任意に指定してもよい. testに使える) | 127 - t を返すことで継続を表す(tは呼び出し時に任意に指定してもよい. testに使える) |
127 - tail call により light weight continuation を定義している | 128 - tail call により light weight continuation を定義している |
128 | 129 |
129 | 130 |
130 # Gears Agda と Gears CbC の対応 | 131 # Gears Agda と Gears CbC の対応 |
131 Gears Agda | 132 Gears Agda |
216 proofGearsTermS : {c10 : N} → ⊤ | 217 proofGearsTermS : {c10 : N} → ⊤ |
217 proofGearsTermS {c10} = whileTest' {_} {_} {c10} (λ n p → conversion1 n p (λ n1 p1 → | 218 proofGearsTermS {c10} = whileTest' {_} {_} {c10} (λ n p → conversion1 n p (λ n1 p1 → |
218 TerminatingLoopS Env (λ env → varn env)(λ n2 p2 loop → whileLoopSeg {_} {_} {c10} n2 p2 loop | 219 TerminatingLoopS Env (λ env → varn env)(λ n2 p2 loop → whileLoopSeg {_} {_} {c10} n2 p2 loop |
219 (λ ne pe → whileTestSpec1 c10 ne pe)) n1 p1 )) | 220 (λ ne pe → whileTestSpec1 c10 ne pe)) n1 p1 )) |
220 ``` | 221 ``` |
221 - conversion1は | 222 - conversion1はPre Condition をPost Conditionに変換する |
222 - whileLoopSeg | 223 - whileLoopSeg |
223 - ⊤ | 224 - ⊤ |
224 | 225 |
225 # test との違い | 226 # test との違い |
226 - test では実数を与えた際の出力が仕様に沿ったものであるかを検証する | 227 - test では実数を与えた際の出力が仕様に沿ったものであるかを検証する |
228 - 今回の定理証明を用いた証明では実数を必要としない | 229 - 今回の定理証明を用いた証明では実数を必要としない |
229 - そのため、入力の型の範囲全てに対して仕様を満たしているか検証できる | 230 - そのため、入力の型の範囲全てに対して仕様を満たしているか検証できる |
230 | 231 |
231 | 232 |
232 # Gears Agda による BinaryTree の実装 | 233 # Gears Agda による BinaryTree の実装 |
233 - Agdaが変数への再代入を許していないためそのままでは木構造を実装できない | 234 CbCと並行した実装をするため、Stackを明示した実装をする |
234 - 木構造を辿る際に現在いるノード以下の木構造をそのまま stack に格納する | 235 |
235 - replace / delete などの操作を行った後に stack を参照し Tree を再構築する | 236 ``` |
236 - CbCへの変換の時に問題になりそうな予感 | 237 find : {n m : Level} {A : Set n} {t : Set m} → (key : ℕ) → (tree : bt A ) → List (bt A) |
237 - ここの説明いらないかも? | 238 → (next : bt A → List (bt A) → t ) → (exit : bt A → List (bt A) → t ) → t |
238 | |
239 | |
240 # Gears Agda による BinaryTree の実装 find node | |
241 ``` | |
242 find : {n m : Level} {A : Set n} {t : Set m} → (env : Env A ) | |
243 → (next : (env : Env A ) → t ) → (exit : (env : Env A ) → t ) → t | |
244 find key leaf st _ exit = exit leaf st | 239 find key leaf st _ exit = exit leaf st |
245 find key (node key₁ v1 tree tree₁) st next exit with <-cmp key key₁ | 240 find key (node key₁ v1 tree tree₁) st next exit with <-cmp key key₁ |
246 find key n st _ exit | tri≈ ¬a b ¬c = exit n st | 241 find key n st _ exit | tri≈ ¬a b ¬c = exit n st |
247 find key n@(node key₁ v1 tree tree₁) st next _ | tri< a ¬b ¬c = next tree (n ∷ st) | 242 find key n@(node key₁ v1 tree tree₁) st next _ | tri< a ¬b ¬c = next tree (n ∷ st) |
248 find key n@(node key₁ v1 tree tree₁) st next _ | tri> ¬a ¬b c = next tree₁ (n ∷ st) | 243 find key n@(node key₁ v1 tree tree₁) st next _ | tri> ¬a ¬b c = next tree₁ (n ∷ st) |
249 ``` | 244 ``` |
245 置き換えるnodeまでTreeを辿り、Stackに逆順にTreeを積んでいく | |
250 | 246 |
251 <!-- | 247 <!-- |
252 findは全部書いても大丈夫そう | 248 findは全部書いても大丈夫そう |
253 --> | 249 --> |
254 | 250 |
255 # Gears Agda による BinaryTree の実装 replace node | 251 # Gears Agda による BinaryTree の実装 replace node |
252 置き換えたnodeをStackを解消しながらTreeを再構成する | |
256 ``` | 253 ``` |
257 replace : {n m : Level} {A : Set n} {t : Set m} | 254 replace : {n m : Level} {A : Set n} {t : Set m} |
258 → (key : N) → (value : A) → bt A → List (bt A) | 255 → (key : N) → (value : A) → bt A → List (bt A) |
259 → (next : N → A → bt A → List (bt A) → t ) | 256 → (next : N → A → bt A → List (bt A) → t ) |
260 → (exit : bt A → t) → t | 257 → (exit : bt A → t) → t |
274 | 271 |
275 <!-- | 272 <!-- |
276 これは途中省略してよさそう | 273 これは途中省略してよさそう |
277 --> | 274 --> |
278 | 275 |
279 | 276 # Binary Tree の3種類の Invariant |
280 # Gears Agda による BinaryTree の実装 loop connecter | 277 Tree Invariant |
281 ``` | 278 - Binary Tree が Key の順序に沿って構成されていることを表すData構造 |
282 | 279 |
283 ``` | 280 Stack Invariant |
284 | 281 - Stackが木の昇順に構成されていることを表す |
285 # Gears Agda による Binary Tree の検証 Invariant | 282 |
286 具体的な例を一つ挙げて、Invariantの説明を行う | 283 Replace Tree |
287 - Binary Tree の性質である、左の子のkeyは親より小さく、 | 284 - 2つの木の1つのnodeが入れ替わっていることを示す |
288 右の子のkeyは親より大きいことを検証 | 285 |
289 - Stack に格納されているTreeはその次のStackの減少列になっているか | 286 # Tree Invariant |
290 - Tree を正しく入れ替えられているか | 287 - Invariant というよりも可能な Binary Tree 全体の集合を表す型 |
291 | 288 - 制約付きのBinary Tree |
292 # Gears Agda による Binary Tree の検証 Invariant | |
293 - Tree Invariant | |
294 ``` | 289 ``` |
295 data treeInvariant {n : Level} {A : Set n} : (tree : bt A) → Set n where | 290 data treeInvariant {n : Level} {A : Set n} : (tree : bt A) → Set n where |
296 t-leaf : treeInvariant leaf | 291 t-leaf : treeInvariant leaf |
297 t-single : (key : N) → (value : A) → treeInvariant (node key value leaf leaf) | 292 t-single : (key : N) → (value : A) → treeInvariant (node key value leaf leaf) |
298 t-right : {key key₁ : N} → {value value₁ : A} → {t₁ t₂ : bt A} → (key < key₁) | 293 t-right : {key key₁ : N} → {value value₁ : A} → {t₁ t₂ : bt A} → (key < key₁) |
307 → treeInvariant (node key₂ value₂ t₃ t₄) | 302 → treeInvariant (node key₂ value₂ t₃ t₄) |
308 → treeInvariant (node key₁ value₁ (node key value t₁ t₂) (node key₂ value₂ t₃ t₄)) | 303 → treeInvariant (node key₁ value₁ (node key value t₁ t₂) (node key₂ value₂ t₃ t₄)) |
309 ``` | 304 ``` |
310 | 305 |
311 <!-- | 306 <!-- |
307 t-leaf はコンストラクタ | |
308 | |
309 | |
312 コードの解説 | 310 コードの解説 |
313 省略した方がたぶん絶対良い | 311 省略した方がたぶん絶対良い |
314 right と left なんかはほとんど対照的なので省略とかでよさそう | 312 right と left なんかはほとんど対照的なので省略とかでよさそう |
315 あとは、木構造の仕様を満たすためにData型になっている説明があるとよさそう | 313 あとは、木構造の仕様を満たすためにData型になっている説明があるとよさそう |
316 --> | 314 --> |
317 | 315 |
318 | 316 |
319 # Gears Agda による Binary Tree の検証 Invariant | 317 # Stack Invariant |
320 - Stack Invariant | 318 - StackにはTreeを辿った履歴が残っている |
319 - 辿り方はKeyの値に依存する | |
320 - 実際のStackよりも豊富な情報を持っている<!--Keyの比較が入っているから--> | |
321 | |
321 ``` | 322 ``` |
322 data stackInvariant {n : Level} {A : Set n} (key : N) : (top orig : bt A) | 323 data stackInvariant {n : Level} {A : Set n} (key : N) : (top orig : bt A) |
323 → (stack : List (bt A)) → Set n where | 324 → (stack : List (bt A)) → Set n where |
324 s-single : {tree0 : bt A} → stackInvariant key tree0 tree0 (tree0 ∷ []) | 325 s-single : {tree0 : bt A} → stackInvariant key tree0 tree0 (tree0 ∷ []) |
325 s-right : {tree tree0 tree₁ : bt A} → {key₁ : N } → {v1 : A } → {st : List (bt A)} | 326 s-right : {tree tree0 tree₁ : bt A} → {key₁ : N } → {v1 : A } → {st : List (bt A)} |
328 s-left : {tree₁ tree0 tree : bt A} → {key₁ : N } → {v1 : A } → {st : List (bt A)} | 329 s-left : {tree₁ tree0 tree : bt A} → {key₁ : N } → {v1 : A } → {st : List (bt A)} |
329 → key < key₁ → stackInvariant key (node key₁ v1 tree₁ tree) tree0 st | 330 → key < key₁ → stackInvariant key (node key₁ v1 tree₁ tree) tree0 st |
330 → stackInvariant key tree₁ tree0 (tree₁ ∷ st) | 331 → stackInvariant key tree₁ tree0 (tree₁ ∷ st) |
331 ``` | 332 ``` |
332 | 333 |
333 # Gears Agda による Binary Tree の検証 Invariant | 334 # Replace Tree |
334 - Replace Invariant | 335 - 木の特定のnodeが正しく置き換えられているか |
335 ``` | 336 ``` |
336 data replacedTree {n : Level} {A : Set n} (key : N) (value : A) : (before after : bt A) → Set n where | 337 data replacedTree {n : Level} {A : Set n} (key : N) (value : A) : (before after : bt A) → Set n where |
337 r-leaf : replacedTree key value leaf (node key value leaf leaf) | 338 r-leaf : replacedTree key value leaf (node key value leaf leaf) |
338 r-node : {value₁ : A} → {t t₁ : bt A} | 339 r-node : {value₁ : A} → {t t₁ : bt A} |
339 → replacedTree key value (node key value₁ t t₁) (node key value t t₁) | 340 → replacedTree key value (node key value₁ t t₁) (node key value t t₁) |
343 r-left : {k : N } {v1 : A} → {t t1 t2 : bt A} | 344 r-left : {k : N } {v1 : A} → {t t1 t2 : bt A} |
344 → key < k → replacedTree key value t1 t | 345 → key < k → replacedTree key value t1 t |
345 → replacedTree key value (node k v1 t1 t2) (node k v1 t t2) | 346 → replacedTree key value (node k v1 t1 t2) (node k v1 t t2) |
346 ``` | 347 ``` |
347 | 348 |
348 # Gears Agda による Binary Tree の検証 | 349 # find の Hoare Condition |
349 Binary Tree の実装に対して上述した3つのInvariantを | 350 findPでは treeInvariant をつかって stackInvariant を生成する |
350 Meta Data Gear として渡しながら実行できるように記述する | 351 停止性を証明する木の深さの不等式も証明する |
351 ``` | 352 ``` |
352 findP : {n m : Level} {A : Set n} {t : Set m} → (env : Env A) | 353 findP : {n m : Level} {A : Set n} {t : Set m} → (key : ℕ) → (tree tree0 : bt A ) → (stack : List (bt A)) |
353 → treeInvariant env ∧ stackInvariant env | 354 → treeInvariant tree ∧ stackInvariant key tree tree0 stack |
354 → (exit : (env : Env A) → treeInvariant env ∧ stackInvariant env → t ) → t | 355 → (next : (tree1 : bt A) → (stack : List (bt A)) |
355 ``` | 356 → treeInvariant tree1 ∧ stackInvariant key tree1 tree0 stack |
356 | 357 → bt-depth tree1 < bt-depth tree → t ) |
358 → (exit : (tree1 : bt A) → (stack : List (bt A)) | |
359 → treeInvariant tree1 ∧ stackInvariant key tree1 tree0 stack | |
360 → (tree1 ≡ leaf ) ∨ ( node-key tree1 ≡ just key ) → t ) → t | |
361 ``` | |
362 | |
363 # Hoare Condition の拡張 | |
364 testなどでは仮定が入ることがある | |
365 Hoare Conditionを拡張可能な部分があるrecordで定義する | |
366 Cが拡張される部分で, これはDataの継続に相当する | |
367 Code Gear に継続があるように Data Gearにも継続がある | |
368 ``` | |
369 record findPR {n : Level} {A : Set n} (key : ℕ) (tree : bt A ) (stack : List (bt A)) | |
370 (C : ℕ → bt A → List (bt A) → Set n) : Set n where | |
371 field | |
372 tree0 : bt A | |
373 ti0 : treeInvariant tree0 | |
374 ti : treeInvariant tree | |
375 si : stackInvariant key tree tree0 stack | |
376 ci : C key tree stack -- data continuation | |
377 ``` | |
378 | |
379 # 拡張部分の記述と推論 | |
380 拡張部分はrecord findPC で定義する | |
381 拡張部分の推論はrecord findExt で定義する | |
382 ``` | |
383 record findPC {n : Level} {A : Set n} (value : A) (key1 : ℕ) (tree : bt A ) (stack : List (bt A)) : Set n where | |
384 field | |
385 tree1 : bt A | |
386 ci : replacedTree key1 value tree1 tree | |
387 | |
388 record findExt {n : Level} {A : Set n} (key : ℕ) (C : ℕ → bt A → List (bt A) → Set n) : Set (Level.suc n) where | |
389 field | |
390 c1 : {key₁ : ℕ} {tree tree₁ : bt A } {st : List (bt A)} {v1 : A} | |
391 → findPR key (node key₁ v1 tree tree₁) st C → key < key₁ → C key tree (tree ∷ st) | |
392 c2 : {key₁ : ℕ} {tree tree₁ : bt A } {st : List (bt A)} {v1 : A} | |
393 → findPR key (node key₁ v1 tree tree₁) st C → key > key₁ → C key tree₁ (tree₁ ∷ st) | |
394 ``` | |
395 | |
396 # replade Node の Invariant | |
397 repraceTree は置き換えるべきnodeが実行時に決まるので関数を挟んだInvariantになる | |
398 ``` | |
399 child-replaced : {n : Level} {A : Set n} (key : ℕ) (tree : bt A) → bt A | |
400 child-replaced key leaf = leaf | |
401 child-replaced key (node key₁ value left right) with <-cmp key key₁ | |
402 ... | tri< a ¬b ¬c = left | |
403 ... | tri≈ ¬a b ¬c = node key₁ value left right | |
404 ... | tri> ¬a ¬b c = right | |
405 | |
406 record replacePR {n : Level} {A : Set n} (key : ℕ) (value : A) (tree repl : bt A ) | |
407 (stack : List (bt A)) (C : bt A → bt A → List (bt A) → Set n) : Set n where | |
408 field | |
409 tree0 : bt A | |
410 ti : treeInvariant tree0 | |
411 si : stackInvariant key tree tree0 stack | |
412 ri : replacedTree key value (child-replaced key tree ) repl | |
413 ci : C tree repl stack -- data continuation | |
414 ``` | |
415 | |
416 # 最終的な証明コード | |
417 insertしたkeyをfindすると元の値が取れてくることを証明する | |
418 insertTreeSpec0が仕様 | |
419 conteinsTreeがtestコードかつ証明になっている | |
420 証明の詳細はコードのHoara condition の証明に入っている | |
421 ``` | |
422 insertTreeSpec0 : {n : Level} {A : Set n} → (tree : bt A) → (value : A) | |
423 → top-value tree ≡ just value → ⊤ | |
424 insertTreeSpec0 _ _ _ = tt | |
425 | |
426 containsTree : {n : Level} {A : Set n} → (tree tree1 : bt A) → (key : ℕ) → (value : A) | |
427 → treeInvariant tree1 → replacedTree key value tree1 tree → ⊤ | |
428 containsTree {n} {A} tree tree1 key value P RT = | |
429 TerminatingLoopS (bt A ∧ List (bt A) ) | |
430 {λ p → findPR key (proj1 p) (proj2 p) (findPC value ) } (λ p → bt-depth (proj1 p)) | |
431 ⟪ tree , tree ∷ [] ⟫ ? | |
432 $ λ p P loop → findPPC1 key value (proj1 p) (proj2 p) P (λ t s P1 lt → loop ⟪ t , s ⟫ P1 lt ) | |
433 $ λ t1 s1 P2 found? → insertTreeSpec0 t1 value (lemma6 t1 s1 found? P2) | |
434 ``` | |
435 | |
436 # replace Tree の性質 | |
437 Replace Tree 自体は Tree に特定の値が入っていることを示すData構造になっている | |
438 これをHoare条件として持ち歩くことにより、Binary Treeの詳細に立ち入らず何が入っているかを指定できる | |
439 | |
440 これにより木を用いるプログラムでの証明を記述できる | |
441 insert Tree や Find Node の停止性も証明されている | |
357 | 442 |
358 # 今後の研究方針 | 443 # 今後の研究方針 |
359 - 現在は Binary Tree の検証までしか行えていないが、 | 444 - Deleteの実装 |
360 今回定義した条件はそのまま Red Black Tree の検証に使用できるはず | 445 - Red Black Tree の実装 |
361 - 今後は Gears Agda による実装と条件の追加をおこなう | 446 - 今回定義した条件はそのまま Red Black Tree の検証に使用できるはず |
447 - Contextを用いた並列実行時のプログラムの正しさの証明 | |
448 - syncronized queue | |
449 - concarent tree | |
450 - xv.6への適用 | |
362 - モデル検査 | 451 - モデル検査 |
363 | 452 |
364 # まとめ | 453 # まとめ |
365 - Gears Agda にて Binary Tree を検証することができた | 454 - Gears Agda にて Binary Tree を検証することができた |
366 - Gears Agda における Termination を使用しない実装の仕方を確率した | 455 - Gears Agda における Termination を使用しない実装の仕方を確率した |
367 - Hoare Logic による検証もできるようになった | 456 - Hoare Logic による検証もできるようになった |
368 - 今後は Red Black Tree の検証をすすめる | 457 - 今後は Red Black Tree の検証をすすめる |
369 - モデル検査をしたい | 458 - モデル検査をしたい |
370 | 459 |
371 英語版も欲しい | 460 <!-- 英語版も欲しい--> |
372 | |
373 condition を テンプレみたいに作ってかきやすくする話 | |
374 |