14288
|
1 |
header {* Isar-style Reasoning for Binary Tree Operations *}
|
|
2 |
theory BinaryTree = Main:
|
|
3 |
|
|
4 |
text {* We prove correctness of operations on
|
|
5 |
binary search tree implementing a set.
|
|
6 |
|
|
7 |
This document is GPL.
|
|
8 |
|
|
9 |
Author: Viktor Kuncak, MIT CSAIL, November 2003 *}
|
|
10 |
|
|
11 |
(*============================================================*)
|
|
12 |
section {* Tree Definition *}
|
|
13 |
(*============================================================*)
|
|
14 |
|
|
15 |
datatype 'a Tree = Tip | T "'a Tree" 'a "'a Tree"
|
|
16 |
|
|
17 |
consts
|
|
18 |
setOf :: "'a Tree => 'a set"
|
|
19 |
-- {* set abstraction of a tree *}
|
|
20 |
primrec
|
|
21 |
"setOf Tip = {}"
|
|
22 |
"setOf (T t1 x t2) = (setOf t1) Un (setOf t2) Un {x}"
|
|
23 |
|
|
24 |
types
|
|
25 |
-- {* we require index to have an irreflexive total order < *}
|
|
26 |
-- {* apart from that, we do not rely on index being int *}
|
|
27 |
index = int
|
|
28 |
|
|
29 |
types -- {* hash function type *}
|
|
30 |
'a hash = "'a => index"
|
|
31 |
|
|
32 |
constdefs
|
|
33 |
eqs :: "'a hash => 'a => 'a set"
|
|
34 |
-- {* equivalence class of elements with the same hash code *}
|
|
35 |
"eqs h x == {y. h y = h x}"
|
|
36 |
|
|
37 |
consts
|
|
38 |
sortedTree :: "'a hash => 'a Tree => bool"
|
|
39 |
-- {* check if a tree is sorted *}
|
|
40 |
primrec
|
|
41 |
"sortedTree h Tip = True"
|
|
42 |
"sortedTree h (T t1 x t2) =
|
|
43 |
(sortedTree h t1 &
|
|
44 |
(ALL l: setOf t1. h l < h x) &
|
|
45 |
(ALL r: setOf t2. h x < h r) &
|
|
46 |
sortedTree h t2)"
|
|
47 |
|
|
48 |
lemma sortLemmaL:
|
|
49 |
"sortedTree h (T t1 x t2) ==> sortedTree h t1" by simp
|
|
50 |
lemma sortLemmaR:
|
|
51 |
"sortedTree h (T t1 x t2) ==> sortedTree h t2" by simp
|
|
52 |
|
|
53 |
(*============================================================*)
|
|
54 |
section {* Tree Lookup *}
|
|
55 |
(*============================================================*)
|
|
56 |
|
|
57 |
consts
|
|
58 |
tlookup :: "'a hash => index => 'a Tree => 'a option"
|
|
59 |
primrec
|
|
60 |
"tlookup h k Tip = None"
|
|
61 |
"tlookup h k (T t1 x t2) =
|
|
62 |
(if k < h x then tlookup h k t1
|
|
63 |
else if h x < k then tlookup h k t2
|
|
64 |
else Some x)"
|
|
65 |
|
|
66 |
lemma tlookup_none:
|
|
67 |
"sortedTree h t & (tlookup h k t = None) -->
|
|
68 |
(ALL x:setOf t. h x ~= k)"
|
|
69 |
apply (induct t)
|
|
70 |
apply auto (* takes some time *)
|
|
71 |
done
|
|
72 |
|
|
73 |
lemma tlookup_some:
|
|
74 |
"sortedTree h t & (tlookup h k t = Some x) -->
|
|
75 |
x:setOf t & h x = k"
|
|
76 |
apply (induct t)
|
|
77 |
apply auto (* takes some time *)
|
|
78 |
done
|
|
79 |
|
|
80 |
constdefs
|
|
81 |
sorted_distinct_pred :: "'a hash => 'a => 'a => 'a Tree => bool"
|
|
82 |
-- {* No two elements have the same hash code *}
|
|
83 |
"sorted_distinct_pred h a b t == sortedTree h t &
|
|
84 |
a:setOf t & b:setOf t & h a = h b -->
|
|
85 |
a = b"
|
|
86 |
|
|
87 |
declare sorted_distinct_pred_def [simp]
|
|
88 |
|
|
89 |
-- {* for case analysis on three cases *}
|
|
90 |
lemma cases3: "[| C1 ==> G; C2 ==> G; C3 ==> G;
|
|
91 |
C1 | C2 | C3 |] ==> G"
|
|
92 |
by auto
|
|
93 |
|
|
94 |
text {* @{term sorted_distinct_pred} holds for out trees: *}
|
|
95 |
|
|
96 |
lemma sorted_distinct: "sorted_distinct_pred h a b t" (is "?P t")
|
|
97 |
proof (induct t)
|
|
98 |
show "?P Tip" by simp
|
|
99 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
100 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
101 |
fix x :: 'a
|
|
102 |
show "?P (T t1 x t2)"
|
|
103 |
proof (unfold sorted_distinct_pred_def, safe)
|
|
104 |
assume s: "sortedTree h (T t1 x t2)"
|
|
105 |
assume adef: "a : setOf (T t1 x t2)"
|
|
106 |
assume bdef: "b : setOf (T t1 x t2)"
|
|
107 |
assume hahb: "h a = h b"
|
|
108 |
from s have s1: "sortedTree h t1" by auto
|
|
109 |
from s have s2: "sortedTree h t2" by auto
|
|
110 |
show "a = b"
|
|
111 |
-- {* We consider 9 cases for the position of a and b are in the tree *}
|
|
112 |
proof -
|
|
113 |
-- {* three cases for a *}
|
|
114 |
from adef have "a : setOf t1 | a = x | a : setOf t2" by auto
|
|
115 |
moreover { assume adef1: "a : setOf t1"
|
|
116 |
have ?thesis
|
|
117 |
proof -
|
|
118 |
-- {* three cases for b *}
|
|
119 |
from bdef have "b : setOf t1 | b = x | b : setOf t2" by auto
|
|
120 |
moreover { assume bdef1: "b : setOf t1"
|
|
121 |
from s1 adef1 bdef1 hahb h1 have ?thesis by simp }
|
|
122 |
moreover { assume bdef1: "b = x"
|
|
123 |
from adef1 bdef1 s have "h a < h b" by auto
|
|
124 |
from this hahb have ?thesis by simp }
|
|
125 |
moreover { assume bdef1: "b : setOf t2"
|
|
126 |
from adef1 s have o1: "h a < h x" by auto
|
|
127 |
from bdef1 s have o2: "h x < h b" by auto
|
|
128 |
from o1 o2 have "h a < h b" by simp
|
|
129 |
from this hahb have ?thesis by simp } -- {* case impossible *}
|
|
130 |
ultimately show ?thesis by blast
|
|
131 |
qed
|
|
132 |
}
|
|
133 |
moreover { assume adef1: "a = x"
|
|
134 |
have ?thesis
|
|
135 |
proof -
|
|
136 |
-- {* three cases for b *}
|
|
137 |
from bdef have "b : setOf t1 | b = x | b : setOf t2" by auto
|
|
138 |
moreover { assume bdef1: "b : setOf t1"
|
|
139 |
from this s have "h b < h x" by auto
|
|
140 |
from this adef1 have "h b < h a" by auto
|
|
141 |
from hahb this have ?thesis by simp } -- {* case impossible *}
|
|
142 |
moreover { assume bdef1: "b = x"
|
|
143 |
from adef1 bdef1 have ?thesis by simp }
|
|
144 |
moreover { assume bdef1: "b : setOf t2"
|
|
145 |
from this s have "h x < h b" by auto
|
|
146 |
from this adef1 have "h a < h b" by simp
|
|
147 |
from hahb this have ?thesis by simp } -- {* case impossible *}
|
|
148 |
ultimately show ?thesis by blast
|
|
149 |
qed
|
|
150 |
}
|
|
151 |
moreover { assume adef1: "a : setOf t2"
|
|
152 |
have ?thesis
|
|
153 |
proof -
|
|
154 |
-- {* three cases for b *}
|
|
155 |
from bdef have "b : setOf t1 | b = x | b : setOf t2" by auto
|
|
156 |
moreover { assume bdef1: "b : setOf t1"
|
|
157 |
from bdef1 s have o1: "h b < h x" by auto
|
|
158 |
from adef1 s have o2: "h x < h a" by auto
|
|
159 |
from o1 o2 have "h b < h a" by simp
|
|
160 |
from this hahb have ?thesis by simp } -- {* case impossible *}
|
|
161 |
moreover { assume bdef1: "b = x"
|
|
162 |
from adef1 bdef1 s have "h b < h a" by auto
|
|
163 |
from this hahb have ?thesis by simp } -- {* case impossible *}
|
|
164 |
moreover { assume bdef1: "b : setOf t2"
|
|
165 |
from s2 adef1 bdef1 hahb h2 have ?thesis by simp }
|
|
166 |
ultimately show ?thesis by blast
|
|
167 |
qed
|
|
168 |
}
|
|
169 |
ultimately show ?thesis by blast
|
|
170 |
qed
|
|
171 |
qed
|
|
172 |
qed
|
|
173 |
|
|
174 |
lemma tlookup_finds: -- {* if a node is in the tree, lookup finds it *}
|
|
175 |
"sortedTree h t & y:setOf t -->
|
|
176 |
tlookup h (h y) t = Some y"
|
|
177 |
proof safe
|
|
178 |
assume s: "sortedTree h t"
|
|
179 |
assume yint: "y : setOf t"
|
|
180 |
show "tlookup h (h y) t = Some y"
|
|
181 |
proof (cases "tlookup h (h y) t")
|
|
182 |
case None note res = this
|
|
183 |
from s res have "sortedTree h t & (tlookup h (h y) t = None)" by simp
|
|
184 |
from this have o1: "ALL x:setOf t. h x ~= h y" by (simp add: tlookup_none)
|
|
185 |
from o1 yint have "h y ~= h y" by fastsimp (* auto does not work *)
|
|
186 |
from this show ?thesis by simp
|
|
187 |
next case (Some z) note res = this
|
|
188 |
have ls: "sortedTree h t & (tlookup h (h y) t = Some z) -->
|
|
189 |
z:setOf t & h z = h y" by (simp add: tlookup_some)
|
|
190 |
have sd: "sorted_distinct_pred h y z t"
|
|
191 |
by (insert sorted_distinct [of h y z t], simp)
|
|
192 |
(* for some reason simplifier would never guess this substitution *)
|
|
193 |
from s res ls have o1: "z:setOf t & h z = h y" by simp
|
|
194 |
from s yint o1 sd have "y = z" by auto
|
|
195 |
from this res show "tlookup h (h y) t = Some y" by simp
|
|
196 |
qed
|
|
197 |
qed
|
|
198 |
|
|
199 |
subsection {* Tree membership as a special case of lookup *}
|
|
200 |
|
|
201 |
constdefs
|
|
202 |
memb :: "'a hash => 'a => 'a Tree => bool"
|
|
203 |
"memb h x t ==
|
|
204 |
(case (tlookup h (h x) t) of
|
|
205 |
None => False
|
|
206 |
| Some z => (x=z))"
|
|
207 |
|
|
208 |
lemma assumes s: "sortedTree h t"
|
|
209 |
shows memb_spec: "memb h x t = (x : setOf t)"
|
|
210 |
proof (cases "tlookup h (h x) t")
|
|
211 |
case None note tNone = this
|
|
212 |
from tNone have res: "memb h x t = False" by (simp add: memb_def)
|
|
213 |
from s tNone tlookup_none have o1: "ALL y:setOf t. h y ~= h x" by fastsimp
|
|
214 |
have notIn: "x ~: setOf t"
|
|
215 |
proof
|
|
216 |
assume h: "x : setOf t"
|
|
217 |
from h o1 have "h x ~= h x" by fastsimp
|
|
218 |
from this show False by simp
|
|
219 |
qed
|
|
220 |
from res notIn show ?thesis by simp
|
|
221 |
next case (Some z) note tSome = this
|
|
222 |
from s tSome tlookup_some have zin: "z : setOf t" by fastsimp
|
|
223 |
show ?thesis
|
|
224 |
proof (cases "x=z")
|
|
225 |
case True note xez = this
|
|
226 |
from tSome xez have res: "memb h x t" by (simp add: memb_def)
|
|
227 |
from res zin xez show ?thesis by simp
|
|
228 |
next case False note xnez = this
|
|
229 |
from tSome xnez have res: "~ memb h x t" by (simp add: memb_def)
|
|
230 |
have "x ~: setOf t"
|
|
231 |
proof
|
|
232 |
assume xin: "x : setOf t"
|
|
233 |
from s tSome tlookup_some have hzhx: "h x = h z" by fastsimp
|
|
234 |
have o1: "sorted_distinct_pred h x z t"
|
|
235 |
by (insert sorted_distinct [of h x z t], simp)
|
|
236 |
from s xin zin hzhx o1 have "x = z" by fastsimp
|
|
237 |
from this xnez show False by simp
|
|
238 |
qed
|
|
239 |
from this res show ?thesis by simp
|
|
240 |
qed
|
|
241 |
qed
|
|
242 |
|
|
243 |
declare sorted_distinct_pred_def [simp del]
|
|
244 |
|
|
245 |
(*============================================================*)
|
|
246 |
section {* Insertion into a Tree *}
|
|
247 |
(*============================================================*)
|
|
248 |
|
|
249 |
consts
|
|
250 |
binsert :: "'a hash => 'a => 'a Tree => 'a Tree"
|
|
251 |
|
|
252 |
primrec
|
|
253 |
"binsert h e Tip = (T Tip e Tip)"
|
|
254 |
"binsert h e (T t1 x t2) = (if h e < h x then
|
|
255 |
(T (binsert h e t1) x t2)
|
|
256 |
else
|
|
257 |
(if h x < h e then
|
|
258 |
(T t1 x (binsert h e t2))
|
|
259 |
else (T t1 e t2)))"
|
|
260 |
|
|
261 |
text {* A technique for proving disjointness of sets. *}
|
|
262 |
lemma disjCond: "[| !! x. [| x:A; x:B |] ==> False |] ==> A Int B = {}"
|
|
263 |
by fastsimp
|
|
264 |
|
|
265 |
text {* The following is a proof that insertion correctly implements
|
|
266 |
the set interface.
|
|
267 |
Compared to @{text BinaryTree_TacticStyle}, the claim is more
|
|
268 |
difficult, and this time we need to assume as a hypothesis
|
|
269 |
that the tree is sorted. *}
|
|
270 |
|
|
271 |
lemma binsert_set: "sortedTree h t -->
|
|
272 |
setOf (binsert h e t) = (setOf t) - (eqs h e) Un {e}"
|
|
273 |
(is "?P t")
|
|
274 |
proof (induct t)
|
|
275 |
-- {* base case *}
|
|
276 |
show "?P Tip" by (simp add: eqs_def)
|
|
277 |
-- {* inductition step *}
|
|
278 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
279 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
280 |
fix x :: 'a
|
|
281 |
show "?P (T t1 x t2)"
|
|
282 |
proof
|
|
283 |
assume s: "sortedTree h (T t1 x t2)"
|
|
284 |
from s have s1: "sortedTree h t1" by (rule sortLemmaL)
|
|
285 |
from s1 and h1 have c1: "setOf (binsert h e t1) = setOf t1 - eqs h e Un {e}" by simp
|
|
286 |
from s have s2: "sortedTree h t2" by (rule sortLemmaR)
|
|
287 |
from s2 and h2 have c2: "setOf (binsert h e t2) = setOf t2 - eqs h e Un {e}" by simp
|
|
288 |
show "setOf (binsert h e (T t1 x t2)) =
|
|
289 |
setOf (T t1 x t2) - eqs h e Un {e}"
|
|
290 |
proof (cases "h e < h x")
|
|
291 |
case True note eLess = this
|
|
292 |
from eLess have res: "binsert h e (T t1 x t2) = (T (binsert h e t1) x t2)" by simp
|
|
293 |
show "setOf (binsert h e (T t1 x t2)) =
|
|
294 |
setOf (T t1 x t2) - eqs h e Un {e}"
|
|
295 |
proof (simp add: res eLess c1)
|
|
296 |
show "insert x (insert e (setOf t1 - eqs h e Un setOf t2)) =
|
|
297 |
insert e (insert x (setOf t1 Un setOf t2) - eqs h e)"
|
|
298 |
proof -
|
|
299 |
have eqsLessX: "ALL el: eqs h e. h el < h x" by (simp add: eqs_def eLess)
|
|
300 |
from this have eqsDisjX: "ALL el: eqs h e. h el ~= h x" by fastsimp
|
|
301 |
from s have xLessT2: "ALL r: setOf t2. h x < h r" by auto
|
|
302 |
have eqsLessT2: "ALL el: eqs h e. ALL r: setOf t2. h el < h r"
|
|
303 |
proof safe
|
|
304 |
fix el assume hel: "el : eqs h e"
|
|
305 |
from hel eqs_def have o1: "h el = h e" by fastsimp (* auto fails here! *)
|
|
306 |
fix r assume hr: "r : setOf t2"
|
|
307 |
from xLessT2 hr o1 eLess show "h el < h r" by auto
|
|
308 |
qed
|
|
309 |
from eqsLessT2 have eqsDisjT2: "ALL el: eqs h e. ALL r: setOf t2. h el ~= h r"
|
|
310 |
by fastsimp (* auto fails here *)
|
|
311 |
from eqsDisjX eqsDisjT2 show ?thesis by fastsimp
|
|
312 |
qed
|
|
313 |
qed
|
|
314 |
next case False note eNotLess = this
|
|
315 |
show "setOf (binsert h e (T t1 x t2)) = setOf (T t1 x t2) - eqs h e Un {e}"
|
|
316 |
proof (cases "h x < h e")
|
|
317 |
case True note xLess = this
|
|
318 |
from xLess have res: "binsert h e (T t1 x t2) = (T t1 x (binsert h e t2))" by simp
|
|
319 |
show "setOf (binsert h e (T t1 x t2)) =
|
|
320 |
setOf (T t1 x t2) - eqs h e Un {e}"
|
|
321 |
proof (simp add: res xLess eNotLess c2)
|
|
322 |
show "insert x (insert e (setOf t1 Un (setOf t2 - eqs h e))) =
|
|
323 |
insert e (insert x (setOf t1 Un setOf t2) - eqs h e)"
|
|
324 |
proof -
|
|
325 |
have XLessEqs: "ALL el: eqs h e. h x < h el" by (simp add: eqs_def xLess)
|
|
326 |
from this have eqsDisjX: "ALL el: eqs h e. h el ~= h x" by auto
|
|
327 |
from s have t1LessX: "ALL l: setOf t1. h l < h x" by auto
|
|
328 |
have T1lessEqs: "ALL el: eqs h e. ALL l: setOf t1. h l < h el"
|
|
329 |
proof safe
|
|
330 |
fix el assume hel: "el : eqs h e"
|
|
331 |
fix l assume hl: "l : setOf t1"
|
|
332 |
from hel eqs_def have o1: "h el = h e" by fastsimp (* auto fails here! *)
|
|
333 |
from t1LessX hl o1 xLess show "h l < h el" by auto
|
|
334 |
qed
|
|
335 |
from T1lessEqs have T1disjEqs: "ALL el: eqs h e. ALL l: setOf t1. h el ~= h l"
|
|
336 |
by fastsimp
|
|
337 |
from eqsDisjX T1lessEqs show ?thesis by auto
|
|
338 |
qed
|
|
339 |
qed
|
|
340 |
next case False note xNotLess = this
|
|
341 |
from xNotLess eNotLess have xeqe: "h x = h e" by simp
|
|
342 |
from xeqe have res: "binsert h e (T t1 x t2) = (T t1 e t2)" by simp
|
|
343 |
show "setOf (binsert h e (T t1 x t2)) =
|
|
344 |
setOf (T t1 x t2) - eqs h e Un {e}"
|
|
345 |
proof (simp add: res eNotLess xeqe)
|
|
346 |
show "insert e (setOf t1 Un setOf t2) =
|
|
347 |
insert e (insert x (setOf t1 Un setOf t2) - eqs h e)"
|
|
348 |
proof -
|
|
349 |
have "insert x (setOf t1 Un setOf t2) - eqs h e =
|
|
350 |
setOf t1 Un setOf t2"
|
|
351 |
proof -
|
|
352 |
have (* o1: *) "x : eqs h e" by (simp add: eqs_def xeqe)
|
|
353 |
moreover have (* o2: *) "(setOf t1) Int (eqs h e) = {}"
|
|
354 |
proof (rule disjCond)
|
|
355 |
fix w
|
|
356 |
assume whSet: "w : setOf t1"
|
|
357 |
assume whEq: "w : eqs h e"
|
|
358 |
from whSet s have o1: "h w < h x" by simp
|
|
359 |
from whEq eqs_def have o2: "h w = h e" by fastsimp
|
|
360 |
from o2 xeqe have o3: "~ h w < h x" by simp
|
|
361 |
from o1 o3 show False by contradiction
|
|
362 |
qed
|
|
363 |
moreover have (* o3: *) "(setOf t2) Int (eqs h e) = {}"
|
|
364 |
proof (rule disjCond)
|
|
365 |
fix w
|
|
366 |
assume whSet: "w : setOf t2"
|
|
367 |
assume whEq: "w : eqs h e"
|
|
368 |
from whSet s have o1: "h x < h w" by simp
|
|
369 |
from whEq eqs_def have o2: "h w = h e" by fastsimp
|
|
370 |
from o2 xeqe have o3: "~ h x < h w" by simp
|
|
371 |
from o1 o3 show False by contradiction
|
|
372 |
qed
|
|
373 |
ultimately show ?thesis by auto
|
|
374 |
qed
|
|
375 |
from this show ?thesis by simp
|
|
376 |
qed
|
|
377 |
qed
|
|
378 |
qed
|
|
379 |
qed
|
|
380 |
qed
|
|
381 |
qed
|
|
382 |
|
|
383 |
text {* Using the correctness of set implementation,
|
|
384 |
preserving sortedness is still simple. *}
|
|
385 |
lemma binsert_sorted: "sortedTree h t --> sortedTree h (binsert h x t)"
|
|
386 |
by (induct t) (auto simp add: binsert_set)
|
|
387 |
|
|
388 |
text {* We summarize the specification of binsert as follows. *}
|
|
389 |
corollary binsert_spec: "sortedTree h t -->
|
|
390 |
sortedTree h (binsert h x t) &
|
|
391 |
setOf (binsert h e t) = (setOf t) - (eqs h e) Un {e}"
|
|
392 |
by (simp add: binsert_set binsert_sorted)
|
|
393 |
|
|
394 |
(*============================================================*)
|
|
395 |
section {* Removing an element from a tree *}
|
|
396 |
(*============================================================*)
|
|
397 |
|
|
398 |
text {* These proofs are influenced by those in @{text BinaryTree_Tactic} *}
|
|
399 |
|
|
400 |
consts
|
|
401 |
rm :: "'a hash => 'a Tree => 'a"
|
|
402 |
-- {* rightmost element of a tree *}
|
|
403 |
primrec
|
|
404 |
"rm h (T t1 x t2) =
|
|
405 |
(if t2=Tip then x else rm h t2)"
|
|
406 |
|
|
407 |
consts
|
|
408 |
wrm :: "'a hash => 'a Tree => 'a Tree"
|
|
409 |
-- {* tree without the rightmost element *}
|
|
410 |
primrec
|
|
411 |
"wrm h (T t1 x t2) =
|
|
412 |
(if t2=Tip then t1 else (T t1 x (wrm h t2)))"
|
|
413 |
|
|
414 |
consts
|
|
415 |
wrmrm :: "'a hash => 'a Tree => 'a Tree * 'a"
|
|
416 |
-- {* computing rightmost and removal in one pass *}
|
|
417 |
primrec
|
|
418 |
"wrmrm h (T t1 x t2) =
|
|
419 |
(if t2=Tip then (t1,x)
|
|
420 |
else (T t1 x (fst (wrmrm h t2)),
|
|
421 |
snd (wrmrm h t2)))"
|
|
422 |
|
|
423 |
consts
|
|
424 |
remove :: "'a hash => 'a => 'a Tree => 'a Tree"
|
|
425 |
-- {* removal of an element from the tree *}
|
|
426 |
primrec
|
|
427 |
"remove h e Tip = Tip"
|
|
428 |
"remove h e (T t1 x t2) =
|
|
429 |
(if h e < h x then (T (remove h e t1) x t2)
|
|
430 |
else if h x < h e then (T t1 x (remove h e t2))
|
|
431 |
else (if t1=Tip then t2
|
|
432 |
else let (t1p,r) = wrmrm h t1
|
|
433 |
in (T t1p r t2)))"
|
|
434 |
|
|
435 |
theorem wrmrm_decomp: "t ~= Tip --> wrmrm h t = (wrm h t, rm h t)"
|
|
436 |
apply (induct_tac t)
|
|
437 |
apply simp_all
|
|
438 |
done
|
|
439 |
|
|
440 |
lemma rm_set: "t ~= Tip & sortedTree h t --> rm h t : setOf t"
|
|
441 |
apply (induct_tac t)
|
|
442 |
apply simp_all
|
|
443 |
done
|
|
444 |
|
|
445 |
lemma wrm_set: "t ~= Tip & sortedTree h t -->
|
|
446 |
setOf (wrm h t) = setOf t - {rm h t}" (is "?P t")
|
|
447 |
proof (induct t)
|
|
448 |
show "?P Tip" by simp
|
|
449 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
450 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
451 |
fix x :: 'a
|
|
452 |
show "?P (T t1 x t2)"
|
|
453 |
proof (rule impI, erule conjE)
|
|
454 |
assume s: "sortedTree h (T t1 x t2)"
|
|
455 |
show "setOf (wrm h (T t1 x t2)) =
|
|
456 |
setOf (T t1 x t2) - {rm h (T t1 x t2)}"
|
|
457 |
proof (cases "t2 = Tip")
|
|
458 |
case True note t2tip = this
|
|
459 |
from t2tip have rm_res: "rm h (T t1 x t2) = x" by simp
|
|
460 |
from t2tip have wrm_res: "wrm h (T t1 x t2) = t1" by simp
|
|
461 |
from s have "x ~: setOf t1" by auto
|
|
462 |
from this rm_res wrm_res t2tip show ?thesis by simp
|
|
463 |
next case False note t2nTip = this
|
|
464 |
from t2nTip have rm_res: "rm h (T t1 x t2) = rm h t2" by simp
|
|
465 |
from t2nTip have wrm_res: "wrm h (T t1 x t2) = T t1 x (wrm h t2)" by simp
|
|
466 |
from s have s2: "sortedTree h t2" by simp
|
|
467 |
from h2 t2nTip s2
|
|
468 |
have o1: "setOf (wrm h t2) = setOf t2 - {rm h t2}" by simp
|
|
469 |
show ?thesis
|
|
470 |
proof (simp add: rm_res wrm_res t2nTip h2 o1)
|
|
471 |
show "insert x (setOf t1 Un (setOf t2 - {rm h t2})) =
|
|
472 |
insert x (setOf t1 Un setOf t2) - {rm h t2}"
|
|
473 |
proof -
|
|
474 |
from s rm_set t2nTip have xOk: "h x < h (rm h t2)" by auto
|
|
475 |
have t1Ok: "ALL l:setOf t1. h l < h (rm h t2)"
|
|
476 |
proof safe
|
|
477 |
fix l :: 'a assume ldef: "l : setOf t1"
|
|
478 |
from ldef s have lx: "h l < h x" by auto
|
|
479 |
from lx xOk show "h l < h (rm h t2)" by auto
|
|
480 |
qed
|
|
481 |
from xOk t1Ok show ?thesis by auto
|
|
482 |
qed
|
|
483 |
qed
|
|
484 |
qed
|
|
485 |
qed
|
|
486 |
qed
|
|
487 |
|
|
488 |
lemma wrm_set1: "t ~= Tip & sortedTree h t --> setOf (wrm h t) <= setOf t"
|
|
489 |
by (auto simp add: wrm_set)
|
|
490 |
|
|
491 |
lemma wrm_sort: "t ~= Tip & sortedTree h t --> sortedTree h (wrm h t)" (is "?P t")
|
|
492 |
proof (induct t)
|
|
493 |
show "?P Tip" by simp
|
|
494 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
495 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
496 |
fix x :: 'a
|
|
497 |
show "?P (T t1 x t2)"
|
|
498 |
proof safe
|
|
499 |
assume s: "sortedTree h (T t1 x t2)"
|
|
500 |
show "sortedTree h (wrm h (T t1 x t2))"
|
|
501 |
proof (cases "t2 = Tip")
|
|
502 |
case True note t2tip = this
|
|
503 |
from t2tip have res: "wrm h (T t1 x t2) = t1" by simp
|
|
504 |
from res s show ?thesis by simp
|
|
505 |
next case False note t2nTip = this
|
|
506 |
from t2nTip have res: "wrm h (T t1 x t2) = T t1 x (wrm h t2)" by simp
|
|
507 |
from s have s1: "sortedTree h t1" by simp
|
|
508 |
from s have s2: "sortedTree h t2" by simp
|
|
509 |
from s2 h2 t2nTip have o1: "sortedTree h (wrm h t2)" by simp
|
|
510 |
from s2 t2nTip wrm_set1 have o2: "setOf (wrm h t2) <= setOf t2" by auto
|
|
511 |
from s o2 have o3: "ALL r: setOf (wrm h t2). h x < h r" by auto
|
|
512 |
from s1 o1 o3 res s show "sortedTree h (wrm h (T t1 x t2))" by simp
|
|
513 |
qed
|
|
514 |
qed
|
|
515 |
qed
|
|
516 |
|
|
517 |
lemma wrm_less_rm:
|
|
518 |
"t ~= Tip & sortedTree h t -->
|
|
519 |
(ALL l:setOf (wrm h t). h l < h (rm h t))" (is "?P t")
|
|
520 |
proof (induct t)
|
|
521 |
show "?P Tip" by simp
|
|
522 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
523 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
524 |
fix x :: 'a
|
|
525 |
show "?P (T t1 x t2)"
|
|
526 |
proof safe
|
|
527 |
fix l :: "'a" assume ldef: "l : setOf (wrm h (T t1 x t2))"
|
|
528 |
assume s: "sortedTree h (T t1 x t2)"
|
|
529 |
from s have s1: "sortedTree h t1" by simp
|
|
530 |
from s have s2: "sortedTree h t2" by simp
|
|
531 |
show "h l < h (rm h (T t1 x t2))"
|
|
532 |
proof (cases "t2 = Tip")
|
|
533 |
case True note t2tip = this
|
|
534 |
from t2tip have rm_res: "rm h (T t1 x t2) = x" by simp
|
|
535 |
from t2tip have wrm_res: "wrm h (T t1 x t2) = t1" by simp
|
|
536 |
from ldef wrm_res have o1: "l : setOf t1" by simp
|
|
537 |
from rm_res o1 s show ?thesis by simp
|
|
538 |
next case False note t2nTip = this
|
|
539 |
from t2nTip have rm_res: "rm h (T t1 x t2) = rm h t2" by simp
|
|
540 |
from t2nTip have wrm_res: "wrm h (T t1 x t2) = T t1 x (wrm h t2)" by simp
|
|
541 |
from ldef wrm_res
|
|
542 |
have l_scope: "l : {x} Un setOf t1 Un setOf (wrm h t2)" by simp
|
|
543 |
have hLess: "h l < h (rm h t2)"
|
|
544 |
proof (cases "l = x")
|
|
545 |
case True note lx = this
|
|
546 |
from s t2nTip rm_set s2 have o1: "h x < h (rm h t2)" by auto
|
|
547 |
from lx o1 show ?thesis by simp
|
|
548 |
next case False note lnx = this
|
|
549 |
show ?thesis
|
|
550 |
proof (cases "l : setOf t1")
|
|
551 |
case True note l_in_t1 = this
|
|
552 |
from s t2nTip rm_set s2 have o1: "h x < h (rm h t2)" by auto
|
|
553 |
from l_in_t1 s have o2: "h l < h x" by auto
|
|
554 |
from o1 o2 show ?thesis by simp
|
|
555 |
next case False note l_notin_t1 = this
|
|
556 |
from l_scope lnx l_notin_t1
|
|
557 |
have l_in_res: "l : setOf (wrm h t2)" by auto
|
|
558 |
from l_in_res h2 t2nTip s2 show ?thesis by auto
|
|
559 |
qed
|
|
560 |
qed
|
|
561 |
from rm_res hLess show ?thesis by simp
|
|
562 |
qed
|
|
563 |
qed
|
|
564 |
qed
|
|
565 |
|
|
566 |
lemma remove_set: "sortedTree h t -->
|
|
567 |
setOf (remove h e t) = setOf t - eqs h e" (is "?P t")
|
|
568 |
proof (induct t)
|
|
569 |
show "?P Tip" by auto
|
|
570 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
571 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
572 |
fix x :: 'a
|
|
573 |
show "?P (T t1 x t2)"
|
|
574 |
proof
|
|
575 |
assume s: "sortedTree h (T t1 x t2)"
|
|
576 |
show "setOf (remove h e (T t1 x t2)) = setOf (T t1 x t2) - eqs h e"
|
|
577 |
proof (cases "h e < h x")
|
|
578 |
case True note elx = this
|
|
579 |
from elx have res: "remove h e (T t1 x t2) = T (remove h e t1) x t2"
|
|
580 |
by simp
|
|
581 |
from s have s1: "sortedTree h t1" by simp
|
|
582 |
from s1 h1 have o1: "setOf (remove h e t1) = setOf t1 - eqs h e" by simp
|
|
583 |
show ?thesis
|
|
584 |
proof (simp add: o1 elx)
|
|
585 |
show "insert x (setOf t1 - eqs h e Un setOf t2) =
|
|
586 |
insert x (setOf t1 Un setOf t2) - eqs h e"
|
|
587 |
proof -
|
|
588 |
have xOk: "x ~: eqs h e"
|
|
589 |
proof
|
|
590 |
assume h: "x : eqs h e"
|
|
591 |
from h have o1: "~ (h e < h x)" by (simp add: eqs_def)
|
|
592 |
from elx o1 show "False" by contradiction
|
|
593 |
qed
|
|
594 |
have t2Ok: "(setOf t2) Int (eqs h e) = {}"
|
|
595 |
proof (rule disjCond)
|
|
596 |
fix y :: 'a
|
|
597 |
assume y_in_t2: "y : setOf t2"
|
|
598 |
assume y_in_eq: "y : eqs h e"
|
|
599 |
from y_in_t2 s have xly: "h x < h y" by auto
|
|
600 |
from y_in_eq have eey: "h y = h e" by (simp add: eqs_def) (* must "add:" not "from" *)
|
|
601 |
from xly eey have nelx: "~ (h e < h x)" by simp
|
|
602 |
from nelx elx show False by contradiction
|
|
603 |
qed
|
|
604 |
from xOk t2Ok show ?thesis by auto
|
|
605 |
qed
|
|
606 |
qed
|
|
607 |
next case False note nelx = this
|
|
608 |
show ?thesis
|
|
609 |
proof (cases "h x < h e")
|
|
610 |
case True note xle = this
|
|
611 |
from xle have res: "remove h e (T t1 x t2) = T t1 x (remove h e t2)" by simp
|
|
612 |
from s have s2: "sortedTree h t2" by simp
|
|
613 |
from s2 h2 have o1: "setOf (remove h e t2) = setOf t2 - eqs h e" by simp
|
|
614 |
show ?thesis
|
|
615 |
proof (simp add: o1 xle nelx)
|
|
616 |
show "insert x (setOf t1 Un (setOf t2 - eqs h e)) =
|
|
617 |
insert x (setOf t1 Un setOf t2) - eqs h e"
|
|
618 |
proof -
|
|
619 |
have xOk: "x ~: eqs h e"
|
|
620 |
proof
|
|
621 |
assume h: "x : eqs h e"
|
|
622 |
from h have o1: "~ (h x < h e)" by (simp add: eqs_def)
|
|
623 |
from xle o1 show "False" by contradiction
|
|
624 |
qed
|
|
625 |
have t1Ok: "(setOf t1) Int (eqs h e) = {}"
|
|
626 |
proof (rule disjCond)
|
|
627 |
fix y :: 'a
|
|
628 |
assume y_in_t1: "y : setOf t1"
|
|
629 |
assume y_in_eq: "y : eqs h e"
|
|
630 |
from y_in_t1 s have ylx: "h y < h x" by auto
|
|
631 |
from y_in_eq have eey: "h y = h e" by (simp add: eqs_def)
|
|
632 |
from ylx eey have nxle: "~ (h x < h e)" by simp
|
|
633 |
from nxle xle show False by contradiction
|
|
634 |
qed
|
|
635 |
from xOk t1Ok show ?thesis by auto
|
|
636 |
qed
|
|
637 |
qed
|
|
638 |
next case False note nxle = this
|
|
639 |
from nelx nxle have ex: "h e = h x" by simp
|
|
640 |
have t2Ok: "(setOf t2) Int (eqs h e) = {}"
|
|
641 |
proof (rule disjCond)
|
|
642 |
fix y :: 'a
|
|
643 |
assume y_in_t2: "y : setOf t2"
|
|
644 |
assume y_in_eq: "y : eqs h e"
|
|
645 |
from y_in_t2 s have xly: "h x < h y" by auto
|
|
646 |
from y_in_eq have eey: "h y = h e" by (simp add: eqs_def)
|
|
647 |
from y_in_eq ex eey have nxly: "~ (h x < h y)" by simp
|
|
648 |
from nxly xly show False by contradiction
|
|
649 |
qed
|
|
650 |
show ?thesis
|
|
651 |
proof (cases "t1 = Tip")
|
|
652 |
case True note t1tip = this
|
|
653 |
from ex t1tip have res: "remove h e (T t1 x t2) = t2" by simp
|
|
654 |
show ?thesis
|
|
655 |
proof (simp add: res t1tip ex)
|
|
656 |
show "setOf t2 = insert x (setOf t2) - eqs h e"
|
|
657 |
proof -
|
|
658 |
from ex have x_in_eqs: "x : eqs h e" by (simp add: eqs_def)
|
|
659 |
from x_in_eqs t2Ok show ?thesis by auto
|
|
660 |
qed
|
|
661 |
qed
|
|
662 |
next case False note t1nTip = this
|
|
663 |
from nelx nxle ex t1nTip
|
|
664 |
have res: "remove h e (T t1 x t2) =
|
|
665 |
T (wrm h t1) (rm h t1) t2"
|
|
666 |
by (simp add: Let_def wrmrm_decomp)
|
|
667 |
from res show ?thesis
|
|
668 |
proof simp
|
|
669 |
from s have s1: "sortedTree h t1" by simp
|
|
670 |
show "insert (rm h t1) (setOf (wrm h t1) Un setOf t2) =
|
|
671 |
insert x (setOf t1 Un setOf t2) - eqs h e"
|
|
672 |
proof (simp add: t1nTip s1 rm_set wrm_set)
|
|
673 |
show "insert (rm h t1) (setOf t1 - {rm h t1} Un setOf t2) =
|
|
674 |
insert x (setOf t1 Un setOf t2) - eqs h e"
|
|
675 |
proof -
|
|
676 |
from t1nTip s1 rm_set
|
|
677 |
have o1: "insert (rm h t1) (setOf t1 - {rm h t1} Un setOf t2) =
|
|
678 |
setOf t1 Un setOf t2" by auto
|
|
679 |
have o2: "insert x (setOf t1 Un setOf t2) - eqs h e =
|
|
680 |
setOf t1 Un setOf t2"
|
|
681 |
proof -
|
|
682 |
from ex have xOk: "x : eqs h e" by (simp add: eqs_def)
|
|
683 |
have t1Ok: "(setOf t1) Int (eqs h e) = {}"
|
|
684 |
proof (rule disjCond)
|
|
685 |
fix y :: 'a
|
|
686 |
assume y_in_t1: "y : setOf t1"
|
|
687 |
assume y_in_eq: "y : eqs h e"
|
|
688 |
from y_in_t1 s ex have o1: "h y < h e" by auto
|
|
689 |
from y_in_eq have o2: "~ (h y < h e)" by (simp add: eqs_def)
|
|
690 |
from o1 o2 show False by contradiction
|
|
691 |
qed
|
|
692 |
from xOk t1Ok t2Ok show ?thesis by auto
|
|
693 |
qed
|
|
694 |
from o1 o2 show ?thesis by simp
|
|
695 |
qed
|
|
696 |
qed
|
|
697 |
qed
|
|
698 |
qed
|
|
699 |
qed
|
|
700 |
qed
|
|
701 |
qed
|
|
702 |
qed
|
|
703 |
|
|
704 |
lemma remove_sort: "sortedTree h t -->
|
|
705 |
sortedTree h (remove h e t)" (is "?P t")
|
|
706 |
proof (induct t)
|
|
707 |
show "?P Tip" by auto
|
|
708 |
fix t1 :: "'a Tree" assume h1: "?P t1"
|
|
709 |
fix t2 :: "'a Tree" assume h2: "?P t2"
|
|
710 |
fix x :: 'a
|
|
711 |
show "?P (T t1 x t2)"
|
|
712 |
proof
|
|
713 |
assume s: "sortedTree h (T t1 x t2)"
|
|
714 |
from s have s1: "sortedTree h t1" by simp
|
|
715 |
from s have s2: "sortedTree h t2" by simp
|
|
716 |
from h1 s1 have sr1: "sortedTree h (remove h e t1)" by simp
|
|
717 |
from h2 s2 have sr2: "sortedTree h (remove h e t2)" by simp
|
|
718 |
show "sortedTree h (remove h e (T t1 x t2))"
|
|
719 |
proof (cases "h e < h x")
|
|
720 |
case True note elx = this
|
|
721 |
from elx have res: "remove h e (T t1 x t2) = T (remove h e t1) x t2"
|
|
722 |
by simp
|
|
723 |
show ?thesis
|
|
724 |
proof (simp add: s sr1 s2 elx res)
|
|
725 |
let ?C1 = "ALL l:setOf (remove h e t1). h l < h x"
|
|
726 |
let ?C2 = "ALL r:setOf t2. h x < h r"
|
|
727 |
have o1: "?C1"
|
|
728 |
proof -
|
|
729 |
from s1 have "setOf (remove h e t1) = setOf t1 - eqs h e" by (simp add: remove_set)
|
|
730 |
from s this show ?thesis by auto
|
|
731 |
qed
|
|
732 |
from o1 s show "?C1 & ?C2" by auto
|
|
733 |
qed
|
|
734 |
next case False note nelx = this
|
|
735 |
show ?thesis
|
|
736 |
proof (cases "h x < h e")
|
|
737 |
case True note xle = this
|
|
738 |
from xle have res: "remove h e (T t1 x t2) = T t1 x (remove h e t2)" by simp
|
|
739 |
show ?thesis
|
|
740 |
proof (simp add: s s1 sr2 xle nelx res)
|
|
741 |
let ?C1 = "ALL l:setOf t1. h l < h x"
|
|
742 |
let ?C2 = "ALL r:setOf (remove h e t2). h x < h r"
|
|
743 |
have o2: "?C2"
|
|
744 |
proof -
|
|
745 |
from s2 have "setOf (remove h e t2) = setOf t2 - eqs h e" by (simp add: remove_set)
|
|
746 |
from s this show ?thesis by auto
|
|
747 |
qed
|
|
748 |
from o2 s show "?C1 & ?C2" by auto
|
|
749 |
qed
|
|
750 |
next case False note nxle = this
|
|
751 |
from nelx nxle have ex: "h e = h x" by simp
|
|
752 |
show ?thesis
|
|
753 |
proof (cases "t1 = Tip")
|
|
754 |
case True note t1tip = this
|
|
755 |
from ex t1tip have res: "remove h e (T t1 x t2) = t2" by simp
|
|
756 |
show ?thesis by (simp add: res t1tip ex s2)
|
|
757 |
next case False note t1nTip = this
|
|
758 |
from nelx nxle ex t1nTip
|
|
759 |
have res: "remove h e (T t1 x t2) =
|
|
760 |
T (wrm h t1) (rm h t1) t2"
|
|
761 |
by (simp add: Let_def wrmrm_decomp)
|
|
762 |
from res show ?thesis
|
|
763 |
proof simp
|
|
764 |
let ?C1 = "sortedTree h (wrm h t1)"
|
|
765 |
let ?C2 = "ALL l:setOf (wrm h t1). h l < h (rm h t1)"
|
|
766 |
let ?C3 = "ALL r:setOf t2. h (rm h t1) < h r"
|
|
767 |
let ?C4 = "sortedTree h t2"
|
|
768 |
from s1 t1nTip have o1: ?C1 by (simp add: wrm_sort)
|
|
769 |
from s1 t1nTip have o2: ?C2 by (simp add: wrm_less_rm)
|
|
770 |
have o3: ?C3
|
|
771 |
proof
|
|
772 |
fix r :: 'a
|
|
773 |
assume rt2: "r : setOf t2"
|
|
774 |
from s rm_set s1 t1nTip have o1: "h (rm h t1) < h x" by auto
|
|
775 |
from rt2 s have o2: "h x < h r" by auto
|
|
776 |
from o1 o2 show "h (rm h t1) < h r" by simp
|
|
777 |
qed
|
|
778 |
from o1 o2 o3 s2 show "?C1 & ?C2 & ?C3 & ?C4" by simp
|
|
779 |
qed
|
|
780 |
qed
|
|
781 |
qed
|
|
782 |
qed
|
|
783 |
qed
|
|
784 |
qed
|
|
785 |
|
|
786 |
text {* We summarize the specification of remove as follows. *}
|
|
787 |
corollary remove_spec: "sortedTree h t -->
|
|
788 |
sortedTree h (remove h e t) &
|
|
789 |
setOf (remove h e t) = setOf t - eqs h e"
|
|
790 |
by (simp add: remove_sort remove_set)
|
|
791 |
|
|
792 |
generate_code ("BinaryTree_Code.ML")
|
|
793 |
test = "tlookup id 4 (remove id 3 (binsert id 4 (binsert id 3 Tip)))"
|
|
794 |
|
|
795 |
end
|