src/HOL/ex/Tree23.thy
changeset 45334 3f74e041e05c
parent 45333 04b21922ed68
child 45335 a68ce51de69a
equal deleted inserted replaced
45333:04b21922ed68 45334:3f74e041e05c
   134             Branch3 (Branch2 ll lp lm) lq (Branch2 lr p ml) mp (Branch2 mr (if_eq or q' q) r')))))"
   134             Branch3 (Branch2 ll lp lm) lq (Branch2 lr p ml) mp (Branch2 mr (if_eq or q' q) r')))))"
   135 
   135 
   136 definition del0 :: "key \<Rightarrow> 'a tree23 \<Rightarrow> 'a tree23" where
   136 definition del0 :: "key \<Rightarrow> 'a tree23 \<Rightarrow> 'a tree23" where
   137 "del0 k t = (case del (Some k) t of None \<Rightarrow> t | Some(_,(_,t')) \<Rightarrow> t')"
   137 "del0 k t = (case del (Some k) t of None \<Rightarrow> t | Some(_,(_,t')) \<Rightarrow> t')"
   138 
   138 
   139 
   139 text {* Ordered trees *}
   140 text {* Specifying correctness *}
       
   141 
   140 
   142 definition opt_less :: "key option \<Rightarrow> key option \<Rightarrow> bool" where
   141 definition opt_less :: "key option \<Rightarrow> key option \<Rightarrow> bool" where
   143   "opt_less x y = (case x of None \<Rightarrow> True | Some a \<Rightarrow> (case y of None \<Rightarrow> True | Some b \<Rightarrow> a < b))"
   142   "opt_less x y = (case x of None \<Rightarrow> True | Some a \<Rightarrow> (case y of None \<Rightarrow> True | Some b \<Rightarrow> a < b))"
   144 
   143 
   145 lemma opt_less_simps [simp]:
   144 lemma opt_less_simps [simp]:
   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]
   431         unfolding full_del_def by (auto split: ord.split) }
   411         unfolding full_del_def by (auto split: ord.split) }
   432     { case goal26 thus ?case by simp }
   412     { case goal26 thus ?case by simp }
   433   qed (fact A | fact B)+
   413   qed (fact A | fact B)+
   434 qed
   414 qed
   435 
   415 
   436 lemma full_imp_height: "full n t \<Longrightarrow> height t = n"
       
   437   by (induct set: full, simp_all)
       
   438 
       
   439 lemma full_imp_bal: "full n t \<Longrightarrow> bal t"
       
   440   by (induct set: full, auto dest: full_imp_height)
       
   441 
       
   442 lemma bal_imp_full: "bal t \<Longrightarrow> full (height t) t"
       
   443   by (induct t, simp_all)
       
   444 
       
   445 lemma bal_iff_full: "bal t \<longleftrightarrow> full (height t) t"
       
   446   using bal_imp_full full_imp_bal ..
       
   447 
       
   448 lemma bal_del0: "bal t \<Longrightarrow> bal (del0 k t)"
   416 lemma bal_del0: "bal t \<Longrightarrow> bal (del0 k t)"
   449   unfolding del0_def
   417   unfolding del0_def
   450   apply (drule bal_imp_full)
   418   apply (drule bal_imp_full)
   451   apply (case_tac "height t", simp, simp)
   419   apply (case_tac "height t", simp, simp)
   452   apply (frule full_del [where k="Some k"])
   420   apply (frule full_del [where k="Some k"])