annotate rbtree.ind @ 0:170b950774a3

add files
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 15 Apr 2023 11:39:08 +0900
parents
children 25fe88d3fb88
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 -title: GearsAgdaによる Red Black Tree の検証
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 -author: 河野真治
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 --abstract:
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 --検証された Red Black Treeの重要性
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 OSを含むアプリケーションの
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 --CbCに証明を付け加えた GearsAgda
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 CbC は goto 文中心に記述する言語で、\verb+__code+ という単位で実行される。この実行単位は
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 有限な時間(OSのtickなど)で実行することが想定されている。つまり、不定なloop はgoto文の
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 外で組み合わされる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 CbC はLLVM/GCC で実装されている。コンパイラの Basic block に相当すると考えてもよい。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 C form では例えば以下のように記述する。ここでは変数は record Env に格納されている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 __code whileLoop(Env *en, __code next(Env *en)) {
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 if ( 0 >= en->varn ) goto next(en);
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 else {
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 en->varn = en->varn - 1;
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 en->vari = en->vari + 1;
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 goto whileLoop(en, next);
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 }
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 }
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 Agda は pure fuctional な depedent type languageで証明を記述できる。CbC の実行単位 codeGear は
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 以下の形式 Agda form で記述する。常に不定の型{\tt t}を返すのが特徴になっている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 Agda ではCの構造体に対応するのは record で、以下のように定義する。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 record Env ( c : ℕ ) : Set where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 field
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 varn : ℕ
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 vari : ℕ
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 これにより、codeGear からは指定された継続(continuation)を呼ぶしか型的に緩されない。これが、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 CbCのgoto文に相当する。変数の初期化を行う codeGear は以下のようになる。\verb+record {}+
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 が record の初期化になっている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 whileTest : {l : Level} {t : Set l} → (c10 : ℕ) → (Code : Env → t) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 whileTest c10 next = next (record {varn = c10 ; vari = 0} )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 ここで、\verb+ a → b → c + は、\verb+ ( a → b ) → c + であり、Curry化に対応している。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 例えば、仕様は
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 whileTestSpec1 : (c10 : ℕ) → (e1 : Env c10 ) → vari e1 ≡ c10 → ⊤
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 whileTestSpec1 _ _ x = tt
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 という形に書ける。ここで、⊤は、tt というただひとつの値を持つ型
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 data ⊤ : Set where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 tt : ⊤
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 である。これにより、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 initTest : {l : Level} {t : Set l} → (c10 : ℕ) → (Code : (en : Env c10 ) → vari en ≡ c10 → t) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 initTest c10 next = next (record {vari = c10 ; varn = 0 }) refl
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 という風に初期化が正しく値を設定していることを証明付きで書ける。ここで
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 data _≡_ {A : Set } (x y : A) : Set where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 refl {x : A} → x ≡ x
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 で、x = x つまり、自分自身は等しいという自然演繹の等式の推論になっている。この等しさは、λ項の既約項同士の
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 単一化なので、かなり複雑な操作になる。なので、一般的には等式の証明は自明にはならない。Agda では
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 式変形をサポートしているので、少し見やすくすることが可能になってる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 実際に whilteTestSpec1 を検証するには
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 test0 : {l : Level} {t : Set l} → (c10 : ℕ) → ⊤
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 test0 c10 = initTest c10 (λ en eq → whileTestSpec1 c10 en eq )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 とする。initTest は値を提供している。Agda では証明は証明操作を表すλ項なので値になっている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 仕様は複雑なプログラムの動作の結果として満たされるものなので、プログラムの内部に記述する必要がある。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 initTest の\verb+vari en ≡ c10+ の証明は、その場で refl で行われている。whilteTestSpec1 はそれを
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 受け取っているだけになっている。test1 での en は「任意のEnv record」なので、\verb+vari en ≡ c10+ の証明
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 は持っていない。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 --古典的な手法
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 プログラムを検証する方法としては、Hoare Logic \cite{hoare} が知られている。これは、プログラムを command で記述し、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 前提に成立する条件 Pre と 実行後に成立する条件 Post との
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 {Pre} command {Post}
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 の三つ組で条件を command 毎に記述していく方法である。command を例えばアセンブラ的な命令にすれば、プログラムの正しさを
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 証明できる。loop の停止性の証明は、command 対してそれぞれ別に行う必要がある。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 この方法では command 毎に Hoare logic のSoundnessを定義する必要がある。実際に Hoare logic をAgdaで実装した
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 例がある\cite{}。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 --GearsAgda でのプログラム検証手法
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 プログラムの仕様はそのままAgdaの変数として持ち歩いているが、loop に関する証明を行うにはいくつか問題がある。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 普通に while 文を書くと、Agdaが警告を出す。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 {-# TERMINATING #-}
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 whileLoop : {l : Level} {t : Set l} → Env → (Code : Env → t) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 whileLoop env next with lt 0 (varn env)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 whileLoop env next | false = next env
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 whileLoop env next | true =
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 whileLoop (record {varn = (varn env) - 1 ; vari = (vari env) + 1}) next
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 test1 : Env
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 test1 = whileTest 10 (λ env → whileLoop env (λ env1 → env1 ))
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 \verb+{-# TERMINATING #-}+ はAgdaが 停止性が確認できないことを示している。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 --simple while loop と証明付きデータ構造
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 loop の証明には、性質が保存する invariant (不変条件) と、停止性を示す reduction parameter (loopのたびに減少する自然数)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 の二つを使う。この時に、invariant を別な条件として使うと、プログラム全体が複雑になる。そこで、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 データ構造そのものに invariant を付加するとよい。上の例題では、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 record Env ( c : ℕ ) : Set where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 field
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 varn : ℕ
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 vari : ℕ
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 n+i=c : varn + vari ≡ c
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 とすると良い。この invariant を発見するのは一般的には難しいが、loop の構造とデータ構造、つまり、アルゴリズムとデータ構造
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 から決まる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 whileLoop にinvariantの証明を足し、軽量継続で loop を分割すると、停止性を codeGear の段階で Agda が判断する必要がなくなる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 whileLoopSeg : {l : Level} {t : Set l} → (c10 : ℕ ) → (env : Env c10 )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 → (next : (e1 : Env c10 ) → varn e1 < varn env → t)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 → (exit : (e1 : Env c10 ) → vari e1 ≡ c10 → t) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 whileLoopSeg c10 env next exit with ( suc zero ≤? (varn env) )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 whileLoopSeg c10 env next exit | no p = exit env ?
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 whileLoopSeg c10 env next exit | yes p = next env1 ? where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 ここでは肝心の証明は \verb+?+ で省略している。Agda は、この様に証明を延期することができる。実際のコードでは
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 証明が提供されている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 停止性を示す reducde と、loop中にinvariantが保存することから、loop を Agda で直接に証明することができる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 TerminatingLoopS : {l : Level} {t : Set l} (Index : Set ) → ( reduce : Index → ℕ)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 → (loop : (r : Index) → (next : (r1 : Index) → reduce r1 < reduce r → t ) → t)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 → (r : Index) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 TerminatingLoopS {_} {t} Index reduce loop r with <-cmp 0 (reduce r)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 ... | tri≈ ¬a b ¬c = loop r (λ r1 lt → ⊥-elim (lemma3 b lt) )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 ... | tri< a ¬b ¬c = loop r (λ r1 lt1 → TerminatingLoop1 (reduce r) r r1 (≤-step lt1) lt1 ) where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 TerminatingLoop1 : (j : ℕ) → (r r1 : Index) → reduce r1 < suc j → reduce r1 < reduce r → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 TerminatingLoop1 zero r r1 n≤j lt = loop r1 (λ r2 lt1 → ⊥-elim (lemma5 n≤j lt1))
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 TerminatingLoop1 (suc j) r r1 n≤j lt with <-cmp (reduce r1) (suc j)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 ... | tri< a ¬b ¬c = TerminatingLoop1 j r r1 a lt
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 ... | tri≈ ¬a b ¬c = loop r1 (λ r2 lt1 → TerminatingLoop1 j r1 r2 (subst (λ k → reduce r2 < k ) b lt1 ) lt1 )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 ... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c n≤j )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 ここで、\verb+tri≈+などは、二つの自然数を比較した <,=,> の三つの場合を表す data である。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 \verb+<-cmp 0 (reduce r)+ で、その三つの場合を作っている。そして、 \verb+... | tri> ¬a ¬b c = \+という形
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 で受ける。\verb+⊥-elim ( nat-≤> c n≤j ) +は、矛盾の削除則である。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 TerminatingLoopS では、loop からの脱出は記述されていない。indexが 0 以下になることはありえないので、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 loop はその前に終了しているはずである。それは、whileLoopSeg でのreduce の証明がそれを
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 保証している。つまり脱出条件は、TerminatingLoopS ではなく、whileLoopSeg で記述されている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 つまり、TerminatingLoopS は loop の接続を表す connector と考えることができる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 実際の証明は
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 proofGearsTermS : (c10 : ℕ ) → ⊤
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 proofGearsTermS c10 =
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 TerminatingLoopS (Env c10) (λ env → varn env) (λ n2 loop → whileLoopSeg c10 n2 loop (λ ne pe → whileTestSpec1 c10 ne pe ) )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 record { varn = 0 ; vari = c10 ; n+i=c = refl }
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 というようになる。最初の初期化の証明と同じように、プログラムは値の部分にあり実際に実行されていて、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 それが仕様を満たしている証明を\verb+whileTestSpec1 c10 ne pe+が受け取っている。loop 変数が
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 whileLoopSeg の軽量継続を停止性込みで接続している。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 --Hoare Logic との比較
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 Hoare Logicでは、command と条件の書き方を規定して、その規定の中で Logic のSoundnessを示している。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 条件の接続の段階で証明が必要であり、さらに Soundness での汎用的な証明が必要になる。commandによる
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 記述はアセンブラ的になる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 GearsAgda では、commandではなく、GearAgda の形式を満たして入れば良い。codeGear中で
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 dataGear の持つ条件を証明することになる。Soundness は connector に閉じていて、比較的容易に
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 証明される。さらに、? で証明を省略してもコード自体の実行は可能である。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 この二つは、基本的に平行していて、Hoare Logic を理解していれば、GearsAgdaを理解することは問題ない。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 また、Agda を知っていれば、これが Hoare Logic だというように説明することも可能である。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 これが可能になっているのは、GearsAgda の軽量継続による分解であり、任意の関数呼び出しては、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 それに合わせて、TerminatingLoopS に相当するものを記述する必要がある。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 ただし、GearsAgda 自体が軽量継続による制限から、アセンブラ的(コンパイラの基本単位)になっている
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 ので、一般的な人向けのプログラミング言語のような可読性はない。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 --binary tree
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 二分木では、要素は自然のkeyによって順序付られている。普通のプログラミングでは、その順序付けは
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 明示されていない。GearsAgda で、それを invariant として記述することができる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 GearsAgda は、軽量継続による制約により再帰呼び出しはしないことになっている。これにより、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 CbC との直接の対応が可能になっている。なので、二分木への挿入 insert は、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205   find による挿入点の探索と、stackの構成
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206   stackをほどきながら木を置換していく操作
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 の二段階の構成になる。Haskell などでは、工夫された高階関数が使われるので stack は明示されない。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 data bt {n : Level} (A : Set n) : Set n where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 leaf : bt A
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 node : (key : ℕ) → (value : A) →
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 (left : bt A ) → (right : bt A ) → bt A
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 data treeInvariant {n : Level} {A : Set n} : (tree : bt A) → Set n where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 t-leaf : treeInvariant leaf
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 t-single : (key : ℕ) → (value : A) → treeInvariant (node key value leaf leaf)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 t-right : {key key₁ : ℕ} → {value value₁ : A} → {t₁ t₂ : bt A} → (key < key₁) → treeInvariant (node key₁ value₁ t₁ t₂)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 → treeInvariant (node key value leaf (node key₁ value₁ t₁ t₂))
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 t-left : {key key₁ : ℕ} → {value value₁ : A} → {t₁ t₂ : bt A} → (key < key₁) → treeInvariant (node key value t₁ t₂)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 → treeInvariant (node key₁ value₁ (node key value t₁ t₂) leaf )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 t-node : {key key₁ key₂ : ℕ} → {value value₁ value₂ : A} → {t₁ t₂ t₃ t₄ : bt A} → (key < key₁) → (key₁ < key₂)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 → treeInvariant (node key value t₁ t₂)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 → treeInvariant (node key₂ value₂ t₃ t₄)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 → treeInvariant (node key₁ value₁ (node key value t₁ t₂) (node key₂ value₂ t₃ t₄))
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 これが二分木のデータ構造と invariant の実装になる。これは、invariant というよりは、順序付された二分木の可能な値全部の集合
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 であり、二分木の表示的意味論\cite{}そのものになっている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 ここで、\reb+(key < key₁)+は、Agdaの型であり、そこには順序を示す data 構造が配る。つまり、二分木の順序は木の構成時に証明する
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 必要がある。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 さらに、stack が木をたどった順に構成されていることと、木が置き換わっていることを示す invariant が必要である。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 data stackInvariant {n : Level} {A : Set n} (key : ℕ) : (top orig : bt A) → (stack : List (bt A)) → Set n where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 s-nil : {tree0 : bt A} → stackInvariant key tree0 tree0 (tree0 ∷ [])
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 s-right : {tree tree0 tree₁ : bt A} → {key₁ : ℕ } → {v1 : A } → {st : List (bt A)}
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 → key₁ < key → stackInvariant key (node key₁ v1 tree₁ tree) tree0 st → stackInvariant key tree tree0 (tree ∷ st)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 s-left : {tree₁ tree0 tree : bt A} → {key₁ : ℕ } → {v1 : A } → {st : List (bt A)}
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 → key < key₁ → stackInvariant key (node key₁ v1 tree₁ tree) tree0 st → stackInvariant key tree₁ tree0 (tree₁ ∷ st)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 data replacedTree {n : Level} {A : Set n} (key : ℕ) (value : A) : (before after : bt A ) → Set n where
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 r-leaf : replacedTree key value leaf (node key value leaf leaf)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 r-node : {value₁ : A} → {t t₁ : bt A} → replacedTree key value (node key value₁ t t₁) (node key value t t₁)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 r-right : {k : ℕ } {v1 : A} → {t t1 t2 : bt A}
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 → k < key → replacedTree key value t2 t → replacedTree key value (node k v1 t1 t2) (node k v1 t1 t)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 r-left : {k : ℕ } {v1 : A} → {t t1 t2 : bt A}
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 → key < k → replacedTree key value t1 t → replacedTree key value (node k v1 t1 t2) (node k v1 t t2)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 木の構造は同じ順序を持っていても、同じ形にはならない。このreplacedTree は、そういう場合が考慮されていない。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 findP : {n m : Level} {A : Set n} {t : Set m} → (key : ℕ) → (tree tree0 : bt A ) → (stack : List (bt A))
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 → treeInvariant tree ∧ stackInvariant key tree tree0 stack
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 → (next : (tree1 : bt A) → (stack : List (bt A)) → treeInvariant tree1 ∧ stackInvariant key tree1 tree0 stack → bt-depth tree1 < bt-depth tree → t )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 → (exit : (tree1 : bt A) → (stack : List (bt A)) → treeInvariant tree1 ∧ stackInvariant key tree1 tree0 stack
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 → (tree1 ≡ leaf ) ∨ ( node-key tree1 ≡ just key ) → t ) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 findP key leaf tree0 st Pre _ exit = exit leaf st Pre (case1 refl)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 findP key (node key₁ v1 tree tree₁) tree0 st Pre next exit with <-cmp key key₁
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 findP key n tree0 st Pre _ exit | tri≈ ¬a refl ¬c = exit n st Pre (case2 refl)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 findP {n} {_} {A} key (node key₁ v1 tree tree₁) tree0 st Pre next _ | tri< a ¬b ¬c = next tree (tree ∷ st)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 ⟪ ? , ? ⟫ ?
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 findP key n@(node key₁ v1 tree tree₁) tree0 st Pre next _ | tri> ¬a ¬b c = next tree₁ (tree₁ ∷ st)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 ⟪ ? , ? ⟫ ?
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
265
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 ここでも、実際の証明は? と省略している。ここで、木の深さをloopの停止条件として使っている。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
267
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 replaceNodeP : {n m : Level} {A : Set n} {t : Set m} → (key : ℕ) → (value : A) → (tree : bt A)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 → (tree ≡ leaf ) ∨ ( node-key tree ≡ just key )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 → (treeInvariant tree ) → ((tree1 : bt A) → treeInvariant tree1 → replacedTree key value (child-replaced key tree) tree1 → t) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 repplaceのプログラムはさらに煩雑なので型だけを示す。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
273
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 最終的に、これらを loop connector で接続して証明付きのプログラムが完成する。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
275
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 insertTreeP : {n m : Level} {A : Set n} {t : Set m} → (tree : bt A) → (key : ℕ) → (value : A) → treeInvariant tree
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 → (exit : (tree repl : bt A) → treeInvariant repl ∧ replacedTree key value tree repl → t ) → t
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 insertTreeP {n} {m} {A} {t} tree key value P0 exit =
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 TerminatingLoopS (bt A ∧ List (bt A) ) {λ p → treeInvariant (proj1 p) ∧ stackInvariant key (proj1 p) tree (proj2 p) } (λ p → bt-depth (proj1 p)) ⟪ tree , tree ∷ [] ⟫ ⟪ P0 , s-nil ⟫
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 $ λ p P loop → findP key (proj1 p) tree (proj2 p) P (λ t s P1 lt → loop ⟪ t , s ⟫ P1 lt )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 $ λ t s P C → replaceNodeP key value t C (proj1 P)
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 $ λ t1 P1 R → TerminatingLoopS (List (bt A) ∧ bt A ∧ bt A )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 {λ p → replacePR key value (proj1 (proj2 p)) (proj2 (proj2 p)) (proj1 p) (λ _ _ _ → Lift n ⊤ ) }
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 (λ p → length (proj1 p)) ⟪ s , ⟪ t , t1 ⟫ ⟫ record { tree0 = tree ; ti = P0 ; si = proj2 P ; ri = R ; ci = lift tt }
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 $ λ p P1 loop → replaceP key value (proj2 (proj2 p)) (proj1 p) P1
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 (λ key value {tree1} repl1 stack P2 lt → loop ⟪ stack , ⟪ tree1 , repl1 ⟫ ⟫ P2 lt )
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 $ λ tree repl P → exit tree repl ⟪ RTtoTI0 _ _ _ _ (proj1 P) (proj2 P) , proj2 P ⟫
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
288
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 このプログラムは順序付きの二分木のinvariantと、それが置換されているinvariantを返すので、そこから、
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 必要な仕様をすべて導出することができる。例えば、木がソートされていること、置換したもの以外は保存されていることなどである。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
291
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
292
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 --red black tree
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
294
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 赤黒木は、バランスした二分木の実装の一つである。木のノードに赤と黒の状態を持たせ、黒のノードの個数を左右でバランスさせる。
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 かなり複雑な操作だが、ここでは非破壊的な赤黒木を使うので
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
297
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
298
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
299
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 --Concurrency
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
301
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 --実際に実行するには
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
303
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 --証明のスケーラビリティ
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
305
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 --まとめ
170b950774a3 add files
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
307