154 "ord' x (Branch3 l p m q r) y = (ord' x l (Some (fst p)) & ord' (Some (fst p)) m (Some (fst q)) & ord' (Some (fst q)) r y)" |
153 "ord' x (Branch3 l p m q r) y = (ord' x l (Some (fst p)) & ord' (Some (fst p)) m (Some (fst q)) & ord' (Some (fst q)) r y)" |
155 |
154 |
156 definition ord0 :: "'a tree23 \<Rightarrow> bool" where |
155 definition ord0 :: "'a tree23 \<Rightarrow> bool" where |
157 "ord0 t = ord' None t None" |
156 "ord0 t = ord' None t None" |
158 |
157 |
|
158 text {* Balanced trees *} |
|
159 |
|
160 inductive full :: "nat \<Rightarrow> 'a tree23 \<Rightarrow> bool" where |
|
161 "full 0 Empty" | |
|
162 "\<lbrakk>full n l; full n r\<rbrakk> \<Longrightarrow> full (Suc n) (Branch2 l p r)" | |
|
163 "\<lbrakk>full n l; full n m; full n r\<rbrakk> \<Longrightarrow> full (Suc n) (Branch3 l p m q r)" |
|
164 |
|
165 inductive_cases full_elims: |
|
166 "full n Empty" |
|
167 "full n (Branch2 l p r)" |
|
168 "full n (Branch3 l p m q r)" |
|
169 |
|
170 inductive_cases full_0_elim: "full 0 t" |
|
171 inductive_cases full_Suc_elim: "full (Suc n) t" |
|
172 |
|
173 lemma full_0_iff [simp]: "full 0 t \<longleftrightarrow> t = Empty" |
|
174 by (auto elim: full_0_elim intro: full.intros) |
|
175 |
|
176 lemma full_Empty_iff [simp]: "full n Empty \<longleftrightarrow> n = 0" |
|
177 by (auto elim: full_elims intro: full.intros) |
|
178 |
|
179 lemma full_Suc_Branch2_iff [simp]: |
|
180 "full (Suc n) (Branch2 l p r) \<longleftrightarrow> full n l \<and> full n r" |
|
181 by (auto elim: full_elims intro: full.intros) |
|
182 |
|
183 lemma full_Suc_Branch3_iff [simp]: |
|
184 "full (Suc n) (Branch3 l p m q r) \<longleftrightarrow> full n l \<and> full n m \<and> full n r" |
|
185 by (auto elim: full_elims intro: full.intros) |
|
186 |
159 fun height :: "'a tree23 \<Rightarrow> nat" where |
187 fun height :: "'a tree23 \<Rightarrow> nat" where |
160 "height Empty = 0" | |
188 "height Empty = 0" | |
161 "height (Branch2 l _ r) = Suc(max (height l) (height r))" | |
189 "height (Branch2 l _ r) = Suc(max (height l) (height r))" | |
162 "height (Branch3 l _ m _ r) = Suc(max (height l) (max (height m) (height r)))" |
190 "height (Branch3 l _ m _ r) = Suc(max (height l) (max (height m) (height r)))" |
163 |
191 |
165 fun bal :: "'a tree23 \<Rightarrow> bool" where |
193 fun bal :: "'a tree23 \<Rightarrow> bool" where |
166 "bal Empty = True" | |
194 "bal Empty = True" | |
167 "bal (Branch2 l _ r) = (bal l & bal r & height l = height r)" | |
195 "bal (Branch2 l _ r) = (bal l & bal r & height l = height r)" | |
168 "bal (Branch3 l _ m _ r) = (bal l & bal m & bal r & height l = height m & height m = height r)" |
196 "bal (Branch3 l _ m _ r) = (bal l & bal m & bal r & height l = height m & height m = height r)" |
169 |
197 |
|
198 lemma full_imp_height: "full n t \<Longrightarrow> height t = n" |
|
199 by (induct set: full, simp_all) |
|
200 |
|
201 lemma full_imp_bal: "full n t \<Longrightarrow> bal t" |
|
202 by (induct set: full, auto dest: full_imp_height) |
|
203 |
|
204 lemma bal_imp_full: "bal t \<Longrightarrow> full (height t) t" |
|
205 by (induct t, simp_all) |
|
206 |
|
207 lemma bal_iff_full: "bal t \<longleftrightarrow> (\<exists>n. full n t)" |
|
208 by (auto elim!: bal_imp_full full_imp_bal) |
|
209 |
170 text {* The @{term "add0"} function either preserves the height of the |
210 text {* The @{term "add0"} function either preserves the height of the |
171 tree, or increases it by one. The constructor returned by the @{term |
211 tree, or increases it by one. The constructor returned by the @{term |
172 "add"} function determines which: A return value of the form @{term |
212 "add"} function determines which: A return value of the form @{term |
173 "Stay t"} indicates that the height will be the same. A value of the |
213 "Stay t"} indicates that the height will be the same. A value of the |
174 form @{term "Sprout l p r"} indicates an increase in height. *} |
214 form @{term "Sprout l p r"} indicates an increase in height. *} |
175 |
215 |
176 fun gheight :: "'a growth \<Rightarrow> nat" where |
216 primrec gfull :: "nat \<Rightarrow> 'a growth \<Rightarrow> bool" where |
177 "gheight (Stay t) = height t" | |
217 "gfull n (Stay t) \<longleftrightarrow> full n t" | |
178 "gheight (Sprout l p r) = max (height l) (height r)" |
218 "gfull n (Sprout l p r) \<longleftrightarrow> full n l \<and> full n r" |
179 |
219 |
180 lemma gheight_add: "gheight (add k y t) = height t" |
220 lemma gfull_add: "full n t \<Longrightarrow> gfull n (add k y t)" |
181 apply (induct t) |
221 apply (induct set: full) |
182 apply simp |
222 apply simp |
183 apply clarsimp |
223 apply clarsimp |
184 apply (case_tac "ord k a") |
224 apply (case_tac "ord k a") |
185 apply simp |
225 apply simp |
186 apply (case_tac "add k y t1", simp, simp) |
226 apply (case_tac "add k y l", simp, simp) |
187 apply simp |
227 apply simp |
188 apply simp |
228 apply simp |
189 apply (case_tac "add k y t2", simp, simp) |
229 apply (case_tac "add k y r", simp, simp) |
190 apply clarsimp |
230 apply clarsimp |
191 apply (case_tac "ord k a") |
231 apply (case_tac "ord k a") |
192 apply simp |
232 apply simp |
193 apply (case_tac "add k y t1", simp, simp) |
233 apply (case_tac "add k y l", simp, simp) |
194 apply simp |
234 apply simp |
195 apply simp |
235 apply simp |
196 apply (case_tac "ord k aa") |
236 apply (case_tac "ord k aa") |
197 apply simp |
237 apply simp |
198 apply (case_tac "add k y t2", simp, simp) |
238 apply (case_tac "add k y m", simp, simp) |
199 apply simp |
239 apply simp |
200 apply simp |
240 apply simp |
201 apply (case_tac "add k y t3", simp, simp) |
241 apply (case_tac "add k y r", simp, simp) |
202 done |
242 done |
203 |
243 |
204 lemma add_eq_Stay_dest: "add k y t = Stay t' \<Longrightarrow> height t = height t'" |
|
205 using gheight_add [of k y t] by simp |
|
206 |
|
207 lemma add_eq_Sprout_dest: "add k y t = Sprout l p r \<Longrightarrow> height t = max (height l) (height r)" |
|
208 using gheight_add [of k y t] by simp |
|
209 |
|
210 definition gtree :: "'a growth \<Rightarrow> 'a tree23" where |
|
211 "gtree g = (case g of Stay t \<Rightarrow> t | Sprout l p r \<Rightarrow> Branch2 l p r)" |
|
212 |
|
213 lemma gtree_simps [simp]: |
|
214 "gtree (Stay t) = t" |
|
215 "gtree (Sprout l p r) = Branch2 l p r" |
|
216 unfolding gtree_def by simp_all |
|
217 |
|
218 lemma add0: "add0 k y t = gtree (add k y t)" |
|
219 unfolding add0_def by (simp split: growth.split) |
|
220 |
|
221 text {* The @{term "add0"} operation preserves balance. *} |
244 text {* The @{term "add0"} operation preserves balance. *} |
222 |
245 |
223 lemma bal_add0: "bal t \<Longrightarrow> bal (add0 k y t)" |
246 lemma bal_add0: "bal t \<Longrightarrow> bal (add0 k y t)" |
224 unfolding add0 |
247 unfolding bal_iff_full add0_def |
225 apply (induct t) |
248 apply (erule exE) |
226 apply simp |
249 apply (drule gfull_add [of _ _ k y]) |
227 apply clarsimp |
250 apply (cases "add k y t") |
228 apply (case_tac "ord k a") |
251 apply (auto intro: full.intros) |
229 apply simp |
|
230 apply (case_tac "add k y t1") |
|
231 apply (simp, drule add_eq_Stay_dest, simp) |
|
232 apply (simp, drule add_eq_Sprout_dest, simp) |
|
233 apply simp |
|
234 apply simp |
|
235 apply (case_tac "add k y t2") |
|
236 apply (simp, drule add_eq_Stay_dest, simp) |
|
237 apply (simp, drule add_eq_Sprout_dest, simp) |
|
238 apply clarsimp |
|
239 apply (case_tac "ord k a") |
|
240 apply simp |
|
241 apply (case_tac "add k y t1") |
|
242 apply (simp, drule add_eq_Stay_dest, simp) |
|
243 apply (simp, drule add_eq_Sprout_dest, simp) |
|
244 apply simp |
|
245 apply simp |
|
246 apply (case_tac "ord k aa") |
|
247 apply simp |
|
248 apply (case_tac "add k y t2") |
|
249 apply (simp, drule add_eq_Stay_dest, simp) |
|
250 apply (simp, drule add_eq_Sprout_dest, simp) |
|
251 apply simp |
|
252 apply simp |
|
253 apply (case_tac "add k y t3") |
|
254 apply (simp, drule add_eq_Stay_dest, simp) |
|
255 apply (simp, drule add_eq_Sprout_dest, simp) |
|
256 done |
252 done |
257 |
253 |
258 text {* The @{term "add0"} operation preserves order. *} |
254 text {* The @{term "add0"} operation preserves order. *} |
259 |
255 |
260 lemma ord_cases: |
256 lemma ord_cases: |
261 fixes a b :: int obtains |
257 fixes a b :: int obtains |
262 "ord a b = LESS" and "a < b" | |
258 "ord a b = LESS" and "a < b" | |
263 "ord a b = EQUAL" and "a = b" | |
259 "ord a b = EQUAL" and "a = b" | |
264 "ord a b = GREATER" and "a > b" |
260 "ord a b = GREATER" and "a > b" |
265 unfolding ord_def by (rule linorder_cases [of a b]) auto |
261 unfolding ord_def by (rule linorder_cases [of a b]) auto |
|
262 |
|
263 definition gtree :: "'a growth \<Rightarrow> 'a tree23" where |
|
264 "gtree g = (case g of Stay t \<Rightarrow> t | Sprout l p r \<Rightarrow> Branch2 l p r)" |
|
265 |
|
266 lemma gtree_simps [simp]: |
|
267 "gtree (Stay t) = t" |
|
268 "gtree (Sprout l p r) = Branch2 l p r" |
|
269 unfolding gtree_def by simp_all |
|
270 |
|
271 lemma add0: "add0 k y t = gtree (add k y t)" |
|
272 unfolding add0_def by (simp split: growth.split) |
266 |
273 |
267 lemma ord'_add0: |
274 lemma ord'_add0: |
268 "\<lbrakk>ord' k1 t k2; opt_less k1 (Some k); opt_less (Some k) k2\<rbrakk> \<Longrightarrow> ord' k1 (add0 k y t) k2" |
275 "\<lbrakk>ord' k1 t k2; opt_less k1 (Some k); opt_less (Some k) k2\<rbrakk> \<Longrightarrow> ord' k1 (add0 k y t) k2" |
269 unfolding add0 |
276 unfolding add0 |
270 apply (induct t arbitrary: k1 k2) |
277 apply (induct t arbitrary: k1 k2) |
335 Branch3 (Branch2 ll lp lm) lq (Branch2 lr p ml) mp (Branch2 mr (if_eq or q' q) r')))))" |
342 Branch3 (Branch2 ll lp lm) lq (Branch2 lr p ml) mp (Branch2 mr (if_eq or q' q) r')))))" |
336 apply - |
343 apply - |
337 apply (cases l, cases r, simp_all only: del.simps, simp) |
344 apply (cases l, cases r, simp_all only: del.simps, simp) |
338 apply (cases l, cases m, cases r, simp_all only: del.simps, simp) |
345 apply (cases l, cases m, cases r, simp_all only: del.simps, simp) |
339 done |
346 done |
340 |
|
341 inductive full :: "nat \<Rightarrow> 'a tree23 \<Rightarrow> bool" where |
|
342 "full 0 Empty" | |
|
343 "\<lbrakk>full n l; full n r\<rbrakk> \<Longrightarrow> full (Suc n) (Branch2 l p r)" | |
|
344 "\<lbrakk>full n l; full n m; full n r\<rbrakk> \<Longrightarrow> full (Suc n) (Branch3 l p m q r)" |
|
345 |
|
346 inductive_cases full_elims: |
|
347 "full n Empty" |
|
348 "full n (Branch2 l p r)" |
|
349 "full n (Branch3 l p m q r)" |
|
350 |
|
351 inductive_cases full_0_elim: "full 0 t" |
|
352 inductive_cases full_Suc_elim: "full (Suc n) t" |
|
353 |
|
354 lemma full_0_iff [simp]: "full 0 t \<longleftrightarrow> t = Empty" |
|
355 by (auto elim: full_0_elim intro: full.intros) |
|
356 |
|
357 lemma full_Empty_iff [simp]: "full n Empty \<longleftrightarrow> n = 0" |
|
358 by (auto elim: full_elims intro: full.intros) |
|
359 |
|
360 lemma full_Suc_Branch2_iff [simp]: |
|
361 "full (Suc n) (Branch2 l p r) \<longleftrightarrow> full n l \<and> full n r" |
|
362 by (auto elim: full_elims intro: full.intros) |
|
363 |
|
364 lemma full_Suc_Branch3_iff [simp]: |
|
365 "full (Suc n) (Branch3 l p m q r) \<longleftrightarrow> full n l \<and> full n m \<and> full n r" |
|
366 by (auto elim: full_elims intro: full.intros) |
|
367 |
347 |
368 definition |
348 definition |
369 "full_del n k t = (case del k t of None \<Rightarrow> True | Some (p, b, t') \<Rightarrow> full (if b then n else Suc n) t')" |
349 "full_del n k t = (case del k t of None \<Rightarrow> True | Some (p, b, t') \<Rightarrow> full (if b then n else Suc n) t')" |
370 |
350 |
371 lemmas ord_case = ord.exhaust [where y=y and P="ord_case a b c y", standard] |
351 lemmas ord_case = ord.exhaust [where y=y and P="ord_case a b c y", standard] |