# HG changeset patch # User nipkow # Date 1445181913 -7200 # Node ID cd82b10239329c918866259c406d6631eba6d688 # Parent 7d1127ac2251c5082ac5ab2533a101181b2b41ed added 2-3 trees (simpler and more complete than the version in ex/Tree23) diff -r 7d1127ac2251 -r cd82b1023932 src/HOL/Data_Structures/RBT.thy --- a/src/HOL/Data_Structures/RBT.thy Sat Oct 17 16:08:30 2015 +0200 +++ b/src/HOL/Data_Structures/RBT.thy Sun Oct 18 17:25:13 2015 +0200 @@ -1,6 +1,6 @@ (* Author: Tobias Nipkow *) -section \Red-Black Tree\ +section \Red-Black Trees\ theory RBT imports Tree2 diff -r 7d1127ac2251 -r cd82b1023932 src/HOL/Data_Structures/Tree23.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Data_Structures/Tree23.thy Sun Oct 18 17:25:13 2015 +0200 @@ -0,0 +1,43 @@ +(* Author: Tobias Nipkow *) + +section \2-3 Trees\ + +theory Tree23 +imports Main +begin + +class height = +fixes height :: "'a \ nat" + +datatype 'a tree23 = + Leaf | + Node2 "'a tree23" 'a "'a tree23" | + Node3 "'a tree23" 'a "'a tree23" 'a "'a tree23" + +fun inorder :: "'a tree23 \ 'a list" where +"inorder Leaf = []" | +"inorder(Node2 l a r) = inorder l @ a # inorder r" | +"inorder(Node3 l a m b r) = inorder l @ a # inorder m @ b # inorder r" + + +instantiation tree23 :: (type)height +begin + +fun height_tree23 :: "'a tree23 \ nat" where +"height Leaf = 0" | +"height (Node2 l _ r) = Suc(max (height l) (height r))" | +"height (Node3 l _ m _ r) = Suc(max (height l) (max (height m) (height r)))" + +instance .. + +end + +text \Balanced:\ + +fun bal :: "'a tree23 \ bool" where +"bal Leaf = True" | +"bal (Node2 l _ r) = (bal l & bal r & height l = height r)" | +"bal (Node3 l _ m _ r) = + (bal l & bal m & bal r & height l = height m & height m = height r)" + +end diff -r 7d1127ac2251 -r cd82b1023932 src/HOL/Data_Structures/Tree23_Map.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Data_Structures/Tree23_Map.thy Sun Oct 18 17:25:13 2015 +0200 @@ -0,0 +1,155 @@ +(* Author: Tobias Nipkow *) + +section \2-3 Tree Implementation of Maps\ + +theory Tree23_Map +imports + Tree23_Set + Map_by_Ordered +begin + +fun lookup :: "('a::linorder * 'b) tree23 \ 'a \ 'b option" where +"lookup Leaf x = None" | +"lookup (Node2 l (a,b) r) x = + (if x < a then lookup l x else + if a < x then lookup r x else Some b)" | +"lookup (Node3 l (a1,b1) m (a2,b2) r) x = + (if x < a1 then lookup l x else + if x = a1 then Some b1 else + if x < a2 then lookup m x else + if x = a2 then Some b2 + else lookup r x)" + +fun upd :: "'a::linorder \ 'b \ ('a*'b) tree23 \ ('a*'b) up\<^sub>i" where +"upd a b Leaf = Up\<^sub>i Leaf (a,b) Leaf" | +"upd a b (Node2 l xy r) = + (if a < fst xy then + (case upd a b l of + T\<^sub>i l' => T\<^sub>i (Node2 l' xy r) + | Up\<^sub>i l1 q l2 => T\<^sub>i (Node3 l1 q l2 xy r)) + else if a = fst xy then T\<^sub>i (Node2 l (a,b) r) + else + (case upd a b r of + T\<^sub>i r' => T\<^sub>i (Node2 l xy r') + | Up\<^sub>i r1 q r2 => T\<^sub>i (Node3 l xy r1 q r2)))" | +"upd a b (Node3 l xy1 m xy2 r) = + (if a < fst xy1 then + (case upd a b l of + T\<^sub>i l' => T\<^sub>i (Node3 l' xy1 m xy2 r) + | Up\<^sub>i l1 q l2 => Up\<^sub>i (Node2 l1 q l2) xy1 (Node2 m xy2 r)) + else if a = fst xy1 then T\<^sub>i (Node3 l (a,b) m xy2 r) + else if a < fst xy2 then + (case upd a b m of + T\<^sub>i m' => T\<^sub>i (Node3 l xy1 m' xy2 r) + | Up\<^sub>i m1 q m2 => Up\<^sub>i (Node2 l xy1 m1) q (Node2 m2 xy2 r)) + else if a = fst xy2 then T\<^sub>i (Node3 l xy1 m (a,b) r) + else + (case upd a b r of + T\<^sub>i r' => T\<^sub>i (Node3 l xy1 m xy2 r') + | Up\<^sub>i r1 q r2 => Up\<^sub>i (Node2 l xy1 m) xy2 (Node2 r1 q r2)))" + +definition update :: "'a::linorder \ 'b \ ('a*'b) tree23 \ ('a*'b) tree23" where +"update a b t = tree\<^sub>i(upd a b t)" + +fun del :: "'a::linorder \ ('a*'b) tree23 \ ('a*'b) up\<^sub>d" +where +"del k Leaf = T\<^sub>d Leaf" | +"del k (Node2 Leaf p Leaf) = (if k=fst p then Up\<^sub>d Leaf else T\<^sub>d(Node2 Leaf p Leaf))" | +"del k (Node3 Leaf p Leaf q Leaf) = T\<^sub>d(if k=fst p then Node2 Leaf q Leaf + else if k=fst q then Node2 Leaf p Leaf else Node3 Leaf p Leaf q Leaf)" | +"del k (Node2 l a r) = (if k fst a then node22 l a (del k r) else + let (a',t) = del_min r in node22 l a' t)" | +"del k (Node3 l a m b r) = (if k ('a*'b) tree23 \ ('a*'b) tree23" where +"delete k t = tree\<^sub>d(del k t)" + + +subsection "Proofs for Lookup" + +lemma lookup: "sorted1(inorder t) \ lookup t x = map_of (inorder t) x" +by (induction t) (auto simp: map_of_simps split: option.split) + + +subsection "Proofs for Update" + +text {* Balanced trees *} + +text{* First a standard proof that @{const upd} preserves @{const bal}. *} + +lemma bal_upd: "bal t \ bal (tree\<^sub>i(upd a b t)) \ height(upd a b t) = height t" +by (induct t) (auto split: up\<^sub>i.split) + +text{* Now an alternative proof (by Brian Huffman) that runs faster because +two properties (balance and height) are combined in one predicate. *} + +lemma full\<^sub>i_ins: "full n t \ full\<^sub>i n (upd a b t)" +by (induct rule: full.induct, auto split: up\<^sub>i.split) + +text {* The @{const update} operation preserves balance. *} + +lemma bal_update: "bal t \ bal (update a b t)" +unfolding bal_iff_full update_def +apply (erule exE) +apply (drule full\<^sub>i_ins [of _ _ a b]) +apply (cases "upd a b t") +apply (auto intro: full.intros) +done + +text {* Functional correctness of @{const "update"}. *} + +lemma inorder_upd: + "sorted1(inorder t) \ inorder(tree\<^sub>i(upd a b t)) = upd_list a b (inorder t)" +by(induction t) (auto simp: upd_list_simps split: up\<^sub>i.splits) + +lemma inorder_update: + "sorted1(inorder t) \ inorder(update a b t) = upd_list a b (inorder t)" +by(simp add: update_def inorder_upd) + + +subsection "Proofs for Deletion" + +lemma height_del: "bal t \ height(del x t) = height t" +by(induction x t rule: del.induct) + (auto simp add: heights max_def height_del_min split: prod.split) + +lemma bal_tree\<^sub>d_del: "bal t \ bal(tree\<^sub>d(del x t))" +by(induction x t rule: del.induct) + (auto simp: bals bal_del_min height_del height_del_min split: prod.split) + +corollary bal_delete: "bal t \ bal(delete x t)" +by(simp add: delete_def bal_tree\<^sub>d_del) + +lemma inorder_del: "\ bal t ; sorted1(inorder t) \ \ + inorder(tree\<^sub>d (del x t)) = del_list x (inorder t)" +by(induction t rule: del.induct) + (auto simp: del_list_simps inorder_nodes del_minD split: prod.splits) + +lemma inorder_delete: "\ bal t ; sorted1(inorder t) \ \ + inorder(delete x t) = del_list x (inorder t)" +by(simp add: delete_def inorder_del) + + +subsection \Overall Correctness\ + +interpretation T23_Map: Map_by_Ordered +where empty = Leaf and lookup = lookup and update = update and delete = delete +and inorder = inorder and wf = bal +proof (standard, goal_cases) + case 2 thus ?case by(simp add: lookup) +next + case 3 thus ?case by(simp add: inorder_update) +next + case 4 thus ?case by(simp add: inorder_delete) +next + case 6 thus ?case by(simp add: bal_update) +next + case 7 thus ?case by(simp add: bal_delete) +qed simp+ + +end diff -r 7d1127ac2251 -r cd82b1023932 src/HOL/Data_Structures/Tree23_Set.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Data_Structures/Tree23_Set.thy Sun Oct 18 17:25:13 2015 +0200 @@ -0,0 +1,370 @@ +(* Author: Tobias Nipkow *) + +section \2-3 Tree Implementation of Sets\ + +theory Tree23_Set +imports + Tree23 + Set_by_Ordered +begin + +fun isin :: "'a::linorder tree23 \ 'a \ bool" where +"isin Leaf x = False" | +"isin (Node2 l a r) x = (x < a \ isin l x \ x=a \ isin r x)" | +"isin (Node3 l a m b r) x = + (x < a \ isin l x \ x = a \ (x < b \ isin m x \ x = b \ isin r x))" + +datatype 'a up\<^sub>i = T\<^sub>i "'a tree23" | Up\<^sub>i "'a tree23" 'a "'a tree23" + +fun tree\<^sub>i :: "'a up\<^sub>i \ 'a tree23" where +"tree\<^sub>i (T\<^sub>i t) = t" | +"tree\<^sub>i (Up\<^sub>i l p r) = Node2 l p r" + +fun ins :: "'a::linorder \ 'a tree23 \ 'a up\<^sub>i" where +"ins a Leaf = Up\<^sub>i Leaf a Leaf" | +"ins a (Node2 l x r) = + (if a < x then + case ins a l of + T\<^sub>i l' => T\<^sub>i (Node2 l' x r) + | Up\<^sub>i l1 q l2 => T\<^sub>i (Node3 l1 q l2 x r) + else if a=x then T\<^sub>i (Node2 l x r) + else + case ins a r of + T\<^sub>i r' => T\<^sub>i (Node2 l x r') + | Up\<^sub>i r1 q r2 => T\<^sub>i (Node3 l x r1 q r2))" | +"ins a (Node3 l x1 m x2 r) = + (if a < x1 then + case ins a l of + T\<^sub>i l' => T\<^sub>i (Node3 l' x1 m x2 r) + | Up\<^sub>i l1 q l2 => Up\<^sub>i (Node2 l1 q l2) x1 (Node2 m x2 r) + else if a=x1 then T\<^sub>i (Node3 l x1 m x2 r) + else if a < x2 then + case ins a m of + T\<^sub>i m' => T\<^sub>i (Node3 l x1 m' x2 r) + | Up\<^sub>i m1 q m2 => Up\<^sub>i (Node2 l x1 m1) q (Node2 m2 x2 r) + else if a=x2 then T\<^sub>i (Node3 l x1 m x2 r) + else + case ins a r of + T\<^sub>i r' => T\<^sub>i (Node3 l x1 m x2 r') + | Up\<^sub>i r1 q r2 => Up\<^sub>i (Node2 l x1 m) x2 (Node2 r1 q r2))" + +hide_const insert + +definition insert :: "'a::linorder \ 'a tree23 \ 'a tree23" where +"insert a t = tree\<^sub>i(ins a t)" + +datatype 'a up\<^sub>d = T\<^sub>d "'a tree23" | Up\<^sub>d "'a tree23" + +fun tree\<^sub>d :: "'a up\<^sub>d \ 'a tree23" where +"tree\<^sub>d (T\<^sub>d x) = x" | +"tree\<^sub>d (Up\<^sub>d x) = x" + +(* Variation: return None to signal no-change *) + +fun node21 :: "'a up\<^sub>d \ 'a \ 'a tree23 \ 'a up\<^sub>d" where +"node21 (T\<^sub>d t1) a t2 = T\<^sub>d(Node2 t1 a t2)" | +"node21 (Up\<^sub>d t1) a (Node2 t2 b t3) = Up\<^sub>d(Node3 t1 a t2 b t3)" | +"node21 (Up\<^sub>d t1) a (Node3 t2 b t3 c t4) = T\<^sub>d(Node2 (Node2 t1 a t2) b (Node2 t3 c t4))" + +fun node22 :: "'a tree23 \ 'a \ 'a up\<^sub>d \ 'a up\<^sub>d" where +"node22 t1 a (T\<^sub>d t2) = T\<^sub>d(Node2 t1 a t2)" | +"node22 (Node2 t1 b t2) a (Up\<^sub>d t3) = Up\<^sub>d(Node3 t1 b t2 a t3)" | +"node22 (Node3 t1 b t2 c t3) a (Up\<^sub>d t4) = T\<^sub>d(Node2 (Node2 t1 b t2) c (Node2 t3 a t4))" + +fun node31 :: "'a up\<^sub>d \ 'a \ 'a tree23 \ 'a \ 'a tree23 \ 'a up\<^sub>d" where +"node31 (T\<^sub>d t1) a t2 b t3 = T\<^sub>d(Node3 t1 a t2 b t3)" | +"node31 (Up\<^sub>d t1) a (Node2 t2 b t3) c t4 = T\<^sub>d(Node2 (Node3 t1 a t2 b t3) c t4)" | +"node31 (Up\<^sub>d t1) a (Node3 t2 b t3 c t4) d t5 = T\<^sub>d(Node3 (Node2 t1 a t2) b (Node2 t3 c t4) d t5)" + +fun node32 :: "'a tree23 \ 'a \ 'a up\<^sub>d \ 'a \ 'a tree23 \ 'a up\<^sub>d" where +"node32 t1 a (T\<^sub>d t2) b t3 = T\<^sub>d(Node3 t1 a t2 b t3)" | +"node32 t1 a (Up\<^sub>d t2) b (Node2 t3 c t4) = T\<^sub>d(Node2 t1 a (Node3 t2 b t3 c t4))" | +"node32 t1 a (Up\<^sub>d t2) b (Node3 t3 c t4 d t5) = T\<^sub>d(Node3 t1 a (Node2 t2 b t3) c (Node2 t4 d t5))" + +fun node33 :: "'a tree23 \ 'a \ 'a tree23 \ 'a \ 'a up\<^sub>d \ 'a up\<^sub>d" where +"node33 l a m b (T\<^sub>d r) = T\<^sub>d(Node3 l a m b r)" | +"node33 t1 a (Node2 t2 b t3) c (Up\<^sub>d t4) = T\<^sub>d(Node2 t1 a (Node3 t2 b t3 c t4))" | +"node33 t1 a (Node3 t2 b t3 c t4) d (Up\<^sub>d t5) = T\<^sub>d(Node3 t1 a (Node2 t2 b t3) c (Node2 t4 d t5))" + +fun del_min :: "'a tree23 \ 'a * 'a up\<^sub>d" where +"del_min (Node2 Leaf a Leaf) = (a, Up\<^sub>d Leaf)" | +"del_min (Node3 Leaf a Leaf b Leaf) = (a, T\<^sub>d(Node2 Leaf b Leaf))" | +"del_min (Node2 l a r) = (let (x,l') = del_min l in (x, node21 l' a r))" | +"del_min (Node3 l a m b r) = (let (x,l') = del_min l in (x, node31 l' a m b r))" + +fun del :: "'a::linorder \ 'a tree23 \ 'a up\<^sub>d" +where +"del k Leaf = T\<^sub>d Leaf" | +"del k (Node2 Leaf p Leaf) = (if k=p then Up\<^sub>d Leaf else T\<^sub>d(Node2 Leaf p Leaf))" | +"del k (Node3 Leaf p Leaf q Leaf) = T\<^sub>d(if k=p then Node2 Leaf q Leaf + else if k=q then Node2 Leaf p Leaf else Node3 Leaf p Leaf q Leaf)" | +"del k (Node2 l a r) = (if k a then node22 l a (del k r) else + let (a',t) = del_min r in node22 l a' t)" | +"del k (Node3 l a m b r) = (if k 'a tree23 \ 'a tree23" where +"delete k t = tree\<^sub>d(del k t)" + + +declare prod.splits [split] + +subsection "Functional Correctness" + + +subsubsection "Proofs for isin" + +lemma "sorted(inorder t) \ isin t x = (x \ elems (inorder t))" +by (induction t) (auto simp: elems_simps1) + +lemma isin_set: "sorted(inorder t) \ isin t x = (x \ elems (inorder t))" +by (induction t) (auto simp: elems_simps2) + + +subsubsection "Proofs for insert" + +lemma inorder_ins: + "sorted(inorder t) \ inorder(tree\<^sub>i(ins x t)) = ins_list x (inorder t)" +by(induction t) (auto simp: ins_list_simps split: up\<^sub>i.splits) + +lemma inorder_insert: + "sorted(inorder t) \ inorder(insert a t) = ins_list a (inorder t)" +by(simp add: insert_def inorder_ins) + + +subsubsection "Proofs for delete" + +lemma inorder_node21: "height r > 0 \ + inorder (tree\<^sub>d (node21 l' a r)) = inorder (tree\<^sub>d l') @ a # inorder r" +by(induct l' a r rule: node21.induct) auto + +lemma inorder_node22: "height l > 0 \ + inorder (tree\<^sub>d (node22 l a r')) = inorder l @ a # inorder (tree\<^sub>d r')" +by(induct l a r' rule: node22.induct) auto + +lemma inorder_node31: "height m > 0 \ + inorder (tree\<^sub>d (node31 l' a m b r)) = inorder (tree\<^sub>d l') @ a # inorder m @ b # inorder r" +by(induct l' a m b r rule: node31.induct) auto + +lemma inorder_node32: "height r > 0 \ + inorder (tree\<^sub>d (node32 l a m' b r)) = inorder l @ a # inorder (tree\<^sub>d m') @ b # inorder r" +by(induct l a m' b r rule: node32.induct) auto + +lemma inorder_node33: "height m > 0 \ + inorder (tree\<^sub>d (node33 l a m b r')) = inorder l @ a # inorder m @ b # inorder (tree\<^sub>d r')" +by(induct l a m b r' rule: node33.induct) auto + +lemmas inorder_nodes = inorder_node21 inorder_node22 + inorder_node31 inorder_node32 inorder_node33 + +lemma del_minD: + "del_min t = (x,t') \ bal t \ height t > 0 \ + x # inorder(tree\<^sub>d t') = inorder t" +by(induction t arbitrary: t' rule: del_min.induct) + (auto simp: inorder_nodes) + +lemma inorder_del: "\ bal t ; sorted(inorder t) \ \ + inorder(tree\<^sub>d (del x t)) = del_list x (inorder t)" +by(induction t rule: del.induct) + (auto simp: del_list_simps inorder_nodes del_minD) + +lemma inorder_delete: "\ bal t ; sorted(inorder t) \ \ + inorder(delete x t) = del_list x (inorder t)" +by(simp add: delete_def inorder_del) + + +subsection \Balancedness\ + + +subsubsection "Proofs for insert" + +text{* First a standard proof that @{const ins} preserves @{const bal}. *} + +instantiation up\<^sub>i :: (type)height +begin + +fun height_up\<^sub>i :: "'a up\<^sub>i \ nat" where +"height (T\<^sub>i t) = height t" | +"height (Up\<^sub>i l a r) = height l" + +instance .. + +end + +lemma bal_ins: "bal t \ bal (tree\<^sub>i(ins a t)) \ height(ins a t) = height t" +by (induct t) (auto split: up\<^sub>i.split) + +text{* Now an alternative proof (by Brian Huffman) that runs faster because +two properties (balance and height) are combined in one predicate. *} + +inductive full :: "nat \ 'a tree23 \ bool" where +"full 0 Leaf" | +"\full n l; full n r\ \ full (Suc n) (Node2 l p r)" | +"\full n l; full n m; full n r\ \ full (Suc n) (Node3 l p m q r)" + +inductive_cases full_elims: + "full n Leaf" + "full n (Node2 l p r)" + "full n (Node3 l p m q r)" + +inductive_cases full_0_elim: "full 0 t" +inductive_cases full_Suc_elim: "full (Suc n) t" + +lemma full_0_iff [simp]: "full 0 t \ t = Leaf" + by (auto elim: full_0_elim intro: full.intros) + +lemma full_Leaf_iff [simp]: "full n Leaf \ n = 0" + by (auto elim: full_elims intro: full.intros) + +lemma full_Suc_Node2_iff [simp]: + "full (Suc n) (Node2 l p r) \ full n l \ full n r" + by (auto elim: full_elims intro: full.intros) + +lemma full_Suc_Node3_iff [simp]: + "full (Suc n) (Node3 l p m q r) \ full n l \ full n m \ full n r" + by (auto elim: full_elims intro: full.intros) + +lemma full_imp_height: "full n t \ height t = n" + by (induct set: full, simp_all) + +lemma full_imp_bal: "full n t \ bal t" + by (induct set: full, auto dest: full_imp_height) + +lemma bal_imp_full: "bal t \ full (height t) t" + by (induct t, simp_all) + +lemma bal_iff_full: "bal t \ (\n. full n t)" + by (auto elim!: bal_imp_full full_imp_bal) + +text {* The @{const "insert"} function either preserves the height of the +tree, or increases it by one. The constructor returned by the @{term +"insert"} function determines which: A return value of the form @{term +"T\<^sub>i t"} indicates that the height will be the same. A value of the +form @{term "Up\<^sub>i l p r"} indicates an increase in height. *} + +fun full\<^sub>i :: "nat \ 'a up\<^sub>i \ bool" where +"full\<^sub>i n (T\<^sub>i t) \ full n t" | +"full\<^sub>i n (Up\<^sub>i l p r) \ full n l \ full n r" + +lemma full\<^sub>i_ins: "full n t \ full\<^sub>i n (ins a t)" +by (induct rule: full.induct) (auto split: up\<^sub>i.split) + +text {* The @{const insert} operation preserves balance. *} + +lemma bal_insert: "bal t \ bal (insert a t)" +unfolding bal_iff_full insert_def +apply (erule exE) +apply (drule full\<^sub>i_ins [of _ _ a]) +apply (cases "ins a t") +apply (auto intro: full.intros) +done + + +subsection "Proofs for delete" + +instantiation up\<^sub>d :: (type)height +begin + +fun height_up\<^sub>d :: "'a up\<^sub>d \ nat" where +"height (T\<^sub>d t) = height t" | +"height (Up\<^sub>d t) = height t + 1" + +instance .. + +end + +lemma bal_tree\<^sub>d_node21: + "\bal r; bal (tree\<^sub>d l'); height r = height l' \ \ bal (tree\<^sub>d (node21 l' a r))" +by(induct l' a r rule: node21.induct) auto + +lemma bal_tree\<^sub>d_node22: + "\bal(tree\<^sub>d r'); bal l; height r' = height l \ \ bal (tree\<^sub>d (node22 l a r'))" +by(induct l a r' rule: node22.induct) auto + +lemma bal_tree\<^sub>d_node31: + "\ bal (tree\<^sub>d l'); bal m; bal r; height l' = height r; height m = height r \ + \ bal (tree\<^sub>d (node31 l' a m b r))" +by(induct l' a m b r rule: node31.induct) auto + +lemma bal_tree\<^sub>d_node32: + "\ bal l; bal (tree\<^sub>d m'); bal r; height l = height r; height m' = height r \ + \ bal (tree\<^sub>d (node32 l a m' b r))" +by(induct l a m' b r rule: node32.induct) auto + +lemma bal_tree\<^sub>d_node33: + "\ bal l; bal m; bal(tree\<^sub>d r'); height l = height r'; height m = height r' \ + \ bal (tree\<^sub>d (node33 l a m b r'))" +by(induct l a m b r' rule: node33.induct) auto + +lemmas bals = bal_tree\<^sub>d_node21 bal_tree\<^sub>d_node22 + bal_tree\<^sub>d_node31 bal_tree\<^sub>d_node32 bal_tree\<^sub>d_node33 + +lemma height'_node21: + "height r > 0 \ height(node21 l' a r) = max (height l') (height r) + 1" +by(induct l' a r rule: node21.induct)(simp_all) + +lemma height'_node22: + "height l > 0 \ height(node22 l a r') = max (height l) (height r') + 1" +by(induct l a r' rule: node22.induct)(simp_all) + +lemma height'_node31: + "height m > 0 \ height(node31 l a m b r) = + max (height l) (max (height m) (height r)) + 1" +by(induct l a m b r rule: node31.induct)(simp_all add: max_def) + +lemma height'_node32: + "height r > 0 \ height(node32 l a m b r) = + max (height l) (max (height m) (height r)) + 1" +by(induct l a m b r rule: node32.induct)(simp_all add: max_def) + +lemma height'_node33: + "height m > 0 \ height(node33 l a m b r) = + max (height l) (max (height m) (height r)) + 1" +by(induct l a m b r rule: node33.induct)(simp_all add: max_def) + +lemmas heights = height'_node21 height'_node22 + height'_node31 height'_node32 height'_node33 + +lemma height_del_min: + "del_min t = (x, t') \ height t > 0 \ bal t \ height t' = height t" +by(induct t arbitrary: x t' rule: del_min.induct) + (auto simp: heights split: prod.splits) + +lemma height_del: "bal t \ height(del x t) = height t" +by(induction x t rule: del.induct) + (auto simp add: heights max_def height_del_min) + +lemma bal_del_min: + "\ del_min t = (x, t'); bal t; height t > 0 \ \ bal (tree\<^sub>d t')" +by(induct t arbitrary: x t' rule: del_min.induct) + (auto simp: heights height_del_min bals) + +lemma bal_tree\<^sub>d_del: "bal t \ bal(tree\<^sub>d(del x t))" +by(induction x t rule: del.induct) + (auto simp: bals bal_del_min height_del height_del_min) +corollary bal_delete: "bal t \ bal(delete x t)" +by(simp add: delete_def bal_tree\<^sub>d_del) + + +subsection \Overall Correctness\ + +interpretation Set_by_Ordered +where empty = Leaf and isin = isin and insert = insert and delete = delete +and inorder = inorder and wf = bal +proof (standard, goal_cases) + case 2 thus ?case by(simp add: isin_set) +next + case 3 thus ?case by(simp add: inorder_insert) +next + case 4 thus ?case by(simp add: inorder_delete) +next + case 6 thus ?case by(simp add: bal_insert) +next + case 7 thus ?case by(simp add: bal_delete) +qed simp+ + +end diff -r 7d1127ac2251 -r cd82b1023932 src/HOL/ROOT --- a/src/HOL/ROOT Sat Oct 17 16:08:30 2015 +0200 +++ b/src/HOL/ROOT Sun Oct 18 17:25:13 2015 +0200 @@ -178,6 +178,7 @@ Tree_Map AVL_Map RBT_Map + Tree23_Map document_files "root.tex" "root.bib" session "HOL-Import" in Import = HOL +