diff --git a/thys/Amortized_Complexity/Splay_Tree_Analysis.thy b/thys/Amortized_Complexity/Splay_Tree_Analysis.thy --- a/thys/Amortized_Complexity/Splay_Tree_Analysis.thy +++ b/thys/Amortized_Complexity/Splay_Tree_Analysis.thy @@ -1,416 +1,416 @@ subsection "Splay Tree Analysis" theory Splay_Tree_Analysis imports Splay_Tree_Analysis_Base Amortized_Framework begin subsubsection "Analysis of splay" definition A_splay :: "'a::linorder \ 'a tree \ real" where "A_splay a t = T_splay a t + \(splay a t) - \ t" text\The following lemma is an attempt to prove a generic lemma that covers both zig-zig cases. However, the lemma is not as nice as one would like. Hence it is used only once, as a demo. Ideally the lemma would involve function @{const A_splay}, but that is impossible because this involves @{const splay} and thus depends on the ordering. We would need a truly symmetric version of @{const splay} that takes the ordering as an explicit argument. Then we could define all the symmetric cases by one final equation @{term"splay2 less t = splay2 (not o less) (mirror t)"}. This would simplify the code and the proofs.\ lemma zig_zig: fixes lx x rx lb b rb a ra u lb1 lb2 defines [simp]: "X == Node lx (x) rx" defines[simp]: "B == Node lb b rb" defines [simp]: "t == Node B a ra" defines [simp]: "A' == Node rb a ra" defines [simp]: "t' == Node lb1 u (Node lb2 b A')" assumes hyps: "lb \ \\" and IH: "T_splay x lb + \ lb1 + \ lb2 - \ lb \ 2 * \ lb - 3 * \ X + 1" and prems: "size lb = size lb1 + size lb2 + 1" "X \ subtrees lb" shows "T_splay x lb + \ t' - \ t \ 3 * (\ t - \ X)" proof - define B' where [simp]: "B' = Node lb2 b A'" have "T_splay x lb + \ t' - \ t = T_splay x lb + \ lb1 + \ lb2 - \ lb + \ B' + \ A' - \ B" using prems by(auto simp: A_splay_def size_if_splay algebra_simps in_set_tree_if split: tree.split) also have "\ \ 2 * \ lb + \ B' + \ A' - \ B - 3 * \ X + 1" using IH prems(2) by(auto simp: algebra_simps) also have "\ \ \ lb + \ B' + \ A' - 3 * \ X + 1" by(simp) also have "\ \ \ B' + 2 * \ t - 3 * \ X " using prems ld_ld_1_less[of "size1 lb" "size1 A'"] by(simp add: size_if_splay) also have "\ \ 3 * \ t - 3 * \ X" using prems by(simp add: size_if_splay) finally show ?thesis by simp qed lemma A_splay_ub: "\ bst t; Node l x r : subtrees t \ \ A_splay x t \ 3 * (\ t - \(Node l x r)) + 1" proof(induction x t rule: splay.induct) case 1 thus ?case by simp next case 2 thus ?case by (auto simp: A_splay_def) next case 4 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 5 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 7 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 10 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 12 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 13 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case (3 x b A B CD) (* A readable proof *) let ?t = "\\A, x, B\, b, CD\" let ?t' = "\A, x, \B, b, CD\\" have *: "l = A \ r = B" using "3.prems" by(fastforce dest: in_set_tree_if) have "A_splay x ?t = 1 + \ ?t' - \ ?t" using "3.hyps" by (simp add: A_splay_def) also have "\ = 1 + \ ?t' + \ \B, b, CD\ - \ ?t - \ \A, x, B\" by(simp) also have "\ = 1 + \ \B, b, CD\ - \ \A, x, B\" by(simp) also have "\ \ 1 + \ ?t - \(Node A x B)" using log_le_cancel_iff[of 2 "size1(Node B b CD)" "size1 ?t"] by (simp) also have "\ \ 1 + 3 * (\ ?t - \(Node A x B))" using log_le_cancel_iff[of 2 "size1(Node A x B)" "size1 ?t"] by (simp) finally show ?case using * by simp next case (9 b x AB C D) (* An automatic proof *) let ?A = "\AB, b, \C, x, D\\" have "x \ set_tree AB" using "9.prems"(1) by auto with 9 show ?case using log_le_cancel_iff[of 2 "size1(Node AB b C)" "size1 ?A"] log_le_cancel_iff[of 2 "size1(Node C x D)" "size1 ?A"] by (auto simp: A_splay_def algebra_simps simp del:log_le_cancel_iff) next case (6 x a b A B C) hence *: "\l, x, r\ \ subtrees A" by(fastforce dest: in_set_tree_if) obtain A1 a' A2 where sp: "splay x A = Node A1 a' A2" using splay_not_Leaf[OF \A \ Leaf\] by blast let ?X = "Node l x r" let ?AB = "Node A a B" let ?ABC = "Node ?AB b C" let ?A' = "Node A1 a' A2" let ?BC = "Node B b C" let ?A2BC = "Node A2 a ?BC" have "A_splay x ?ABC = A_splay x A + \ ?A2BC + \ ?BC - \ ?AB - \ ?A' + 1" using "6.hyps" sp by(auto simp: A_splay_def size_if_splay algebra_simps split: tree.split) also have "\ \ 3 * \ A + \ ?A2BC + \ ?BC - \ ?AB - \ ?A' - 3 * \ ?X + 2" using "6.IH" "6.prems"(1) * by(auto simp: algebra_simps) also have "\ = 2 * \ A + \ ?A2BC + \ ?BC - \ ?AB - 3 * \ ?X + 2" using sp by(simp add: size_if_splay) also have "\ < \ A + \ ?A2BC + \ ?BC - 3 * \ ?X + 2" by(simp) also have "\ < \ ?A2BC + 2 * \ ?ABC - 3 * \ ?X + 1" using sp ld_ld_1_less[of "size1 A" "size1 ?BC"] by(simp add: size_if_splay) also have "\ < 3 * \ ?ABC - 3 * \ ?X + 1" using sp by(simp add: size_if_splay) finally show ?case by simp next case (8 a x b B A C) hence *: "\l, x, r\ \ subtrees B" by(fastforce dest: in_set_tree_if) obtain B1 b' B2 where sp: "splay x B = Node B1 b' B2" using splay_not_Leaf[OF \B \ Leaf\] by blast let ?X = "Node l x r" let ?AB = "Node A a B" let ?ABC = "Node ?AB b C" let ?B' = "Node B1 b' B2" let ?AB1 = "Node A a B1" let ?B2C = "Node B2 b C" have "A_splay x ?ABC = A_splay x B + \ ?AB1 + \ ?B2C - \ ?AB - \ ?B' + 1" using "8.hyps" sp by(auto simp: A_splay_def size_if_splay algebra_simps split: tree.split) also have "\ \ 3 * \ B + \ ?AB1 + \ ?B2C - \ ?AB - \ ?B' - 3 * \ ?X + 2" using "8.IH" "8.prems"(1) * by(auto simp: algebra_simps) also have "\ = 2 * \ B + \ ?AB1 + \ ?B2C - \ ?AB - 3 * \ ?X + 2" using sp by(simp add: size_if_splay) also have "\ < \ B + \ ?AB1 + \ ?B2C - 3 * \ ?X + 2" by(simp) also have "\ < \ B + 2 * \ ?ABC - 3 * \ ?X + 1" using sp ld_ld_1_less[of "size1 ?AB1" "size1 ?B2C"] by(simp add: size_if_splay) also have "\ < 3 * \ ?ABC - 3 * \ ?X + 1" by(simp) finally show ?case by simp next case (11 b x c C A D) hence *: "\l, x, r\ \ subtrees C" by(fastforce dest: in_set_tree_if) obtain C1 c' C2 where sp: "splay x C = Node C1 c' C2" using splay_not_Leaf[OF \C \ Leaf\] by blast let ?X = "Node l x r" let ?CD = "Node C c D" let ?ACD = "Node A b ?CD" let ?C' = "Node C1 c' C2" let ?C2D = "Node C2 c D" let ?AC1 = "Node A b C1" have "A_splay x ?ACD = A_splay x C + \ ?C2D + \ ?AC1 - \ ?CD - \ ?C' + 1" using "11.hyps" sp by(auto simp: A_splay_def size_if_splay algebra_simps split: tree.split) also have "\ \ 3 * \ C + \ ?C2D + \ ?AC1 - \ ?CD - \ ?C' - 3 * \ ?X + 2" using "11.IH" "11.prems"(1) * by(auto simp: algebra_simps) also have "\ = 2 * \ C + \ ?C2D + \ ?AC1 - \ ?CD - 3 * \ ?X + 2" using sp by(simp add: size_if_splay) also have "\ \ \ C + \ ?C2D + \ ?AC1 - 3 * \ ?X + 2" by(simp) also have "\ \ \ C + 2 * \ ?ACD - 3 * \ ?X + 1" using sp ld_ld_1_less[of "size1 ?C2D" "size1 ?AC1"] by(simp add: size_if_splay algebra_simps) also have "\ \ 3 * \ ?ACD - 3 * \ ?X + 1" by(simp) finally show ?case by simp next case (14 a x b CD A B) hence 0: "x \ set_tree B \ x \ set_tree A" using "14.prems"(1) \b by(auto) hence 1: "x \ set_tree CD" using "14.prems" \b \a by (auto) obtain C c D where sp: "splay x CD = Node C c D" using splay_not_Leaf[OF \CD \ Leaf\] by blast from zig_zig[of CD x D C l r _ b B a A] 14 sp 0 show ?case by(auto simp: A_splay_def size_if_splay algebra_simps) (* The explicit version: have "A_splay x ?A = A_splay x ?R + \ ?B' + \ ?A' - \ ?B - \ ?R' + 1" using "14.prems" 1 sp by(auto simp: A_splay_def size_if_splay algebra_simps split: tree.split) also have "\ \ 3 * \ ?R + \ ?B' + \ ?A' - \ ?B - \ ?R' - 3 * \ ?X + 2" using 14 0 by(auto simp: algebra_simps) also have "\ = 2 * \ rb + \ ?B' + \ ?A' - \ ?B - 3 * \ ?X + 2" using sp by(simp add: size_if_splay) also have "\ \ \ ?R + \ ?B' + \ ?A' - 3 * \ ?X + 2" by(simp) also have "\ \ \ ?B' + 2 * \ ?A - 3 * \ ?X + 1" using sp ld_ld_1_less[of "size1 ?R" "size1 ?A'"] by(simp add: size_if_splay algebra_simps) also have "\ \ 3 * \ ?A - 3 * \ ?X + 1" using sp by(simp add: size_if_splay) finally show ?case by simp *) qed lemma A_splay_ub2: assumes "bst t" "x : set_tree t" shows "A_splay x t \ 3 * (\ t - 1) + 1" proof - from assms(2) obtain l r where N: "Node l x r : subtrees t" by (metis set_treeE) have "A_splay x t \ 3 * (\ t - \(Node l x r)) + 1" by(rule A_splay_ub[OF assms(1) N]) also have "\ \ 3 * (\ t - 1) + 1" by(simp add: field_simps) finally show ?thesis . qed lemma A_splay_ub3: assumes "bst t" shows "A_splay x t \ 3 * \ t + 1" proof cases assume "t = Leaf" thus ?thesis by(simp add: A_splay_def) next assume "t \ Leaf" from ex_in_set_tree[OF this assms] obtain x' where a': "x' \ set_tree t" "splay x' t = splay x t" "T_splay x' t = T_splay x t" by blast show ?thesis using A_splay_ub2[OF assms a'(1)] by(simp add: A_splay_def a') qed subsubsection "Analysis of insert" lemma amor_insert: assumes "bst t" -shows "T_splay x t + \(Splay_Tree.insert x t) - \ t \ 4 * log 2 (size1 t) + 2" (is "?l \ ?r") +shows "T_insert x t + \(Splay_Tree.insert x t) - \ t \ 4 * log 2 (size1 t) + 3" (is "?l \ ?r") proof cases - assume "t = Leaf" thus ?thesis by(simp) + assume "t = Leaf" thus ?thesis by(simp add: T_insert_def) next assume "t \ Leaf" then obtain l e r where [simp]: "splay x t = Node l e r" by (metis tree.exhaust splay_Leaf_iff) let ?t = "real(T_splay x t)" let ?Plr = "\ l + \ r" let ?Ps = "\ t" let ?slr = "real(size1 l) + real(size1 r)" let ?LR = "log 2 (1 + ?slr)" have opt: "?t + \ (splay x t) - ?Ps \ 3 * log 2 (real (size1 t)) + 1" using A_splay_ub3[OF \bst t\, simplified A_splay_def, of x] by (simp) from less_linear[of e x] show ?thesis proof (elim disjE) assume "e=x" have nneg: "log 2 (1 + real (size t)) \ 0" by simp thus ?thesis using \t \ Leaf\ opt \e=x\ - apply(simp add: algebra_simps) using nneg by arith + apply(simp add: T_insert_def algebra_simps) using nneg by arith next let ?L = "log 2 (real(size1 l) + 1)" assume "e < x" hence "e \ x" by simp - hence "?l = (?t + ?Plr - ?Ps) + ?L + ?LR" - using \t \ Leaf\ \e by(simp) + hence "?l = (?t + ?Plr - ?Ps) + ?L + ?LR + 1" + using \t \ Leaf\ \e by(simp add: T_insert_def) also have "?t + ?Plr - ?Ps \ 2 * log 2 ?slr + 1" using opt size_splay[of x t,symmetric] by(simp) also have "?L \ log 2 ?slr" by(simp) also have "?LR \ log 2 ?slr + 1" proof - have "?LR \ log 2 (2 * ?slr)" by (simp add:) also have "\ \ log 2 ?slr + 1" by (simp add: log_mult del:distrib_left_numeral) finally show ?thesis . qed finally show ?thesis using size_splay[of x t,symmetric] by (simp) next let ?R = "log 2 (2 + real(size r))" assume "x < e" hence "e \ x" by simp - hence "?l = (?t + ?Plr - ?Ps) + ?R + ?LR" - using \t \ Leaf\ \x < e\ by(simp) + hence "?l = (?t + ?Plr - ?Ps) + ?R + ?LR + 1" + using \t \ Leaf\ \x < e\ by(simp add: T_insert_def) also have "?t + ?Plr - ?Ps \ 2 * log 2 ?slr + 1" using opt size_splay[of x t,symmetric] by(simp) also have "?R \ log 2 ?slr" by(simp) also have "?LR \ log 2 ?slr + 1" proof - have "?LR \ log 2 (2 * ?slr)" by (simp add:) also have "\ \ log 2 ?slr + 1" by (simp add: log_mult del:distrib_left_numeral) finally show ?thesis . qed finally show ?thesis using size_splay[of x t, symmetric] by simp qed qed subsubsection "Analysis of delete" definition A_splay_max :: "'a::linorder tree \ real" where "A_splay_max t = T_splay_max t + \(splay_max t) - \ t" lemma A_splay_max_ub: "t \ Leaf \ A_splay_max t \ 3 * (\ t - 1) + 1" proof(induction t rule: splay_max.induct) case 1 thus ?case by (simp) next case (2 A) thus ?case using one_le_log_cancel_iff[of 2 "size1 A + 1"] by (simp add: A_splay_max_def del: one_le_log_cancel_iff) next case (3 l b rl c rr) show ?case proof cases assume "rr = Leaf" thus ?thesis using one_le_log_cancel_iff[of 2 "1 + size1 rl"] one_le_log_cancel_iff[of 2 "1 + size1 l + size1 rl"] log_le_cancel_iff[of 2 "size1 l + size1 rl" "1 + size1 l + size1 rl"] by (auto simp: A_splay_max_def field_simps simp del: log_le_cancel_iff one_le_log_cancel_iff) next assume "rr \ Leaf" then obtain l' u r' where sp: "splay_max rr = Node l' u r'" using splay_max_Leaf_iff tree.exhaust by blast hence 1: "size rr = size l' + size r' + 1" using size_splay_max[of rr,symmetric] by(simp) let ?C = "Node rl c rr" let ?B = "Node l b ?C" let ?B' = "Node l b rl" let ?C' = "Node ?B' c l'" have "A_splay_max ?B = A_splay_max rr + \ ?B' + \ ?C' - \ rr - \ ?C + 1" using "3.prems" sp 1 by(auto simp add: A_splay_max_def) also have "\ \ 3 * (\ rr - 1) + \ ?B' + \ ?C' - \ rr - \ ?C + 2" using 3 \rr \ Leaf\ by auto also have "\ = 2 * \ rr + \ ?B' + \ ?C' - \ ?C - 1" by simp also have "\ \ \ rr + \ ?B' + \ ?C' - 1" by simp also have "\ \ 2 * \ ?B + \ ?C' - 2" using ld_ld_1_less[of "size1 ?B'" "size1 rr"] by(simp add:) also have "\ \ 3 * \ ?B - 2" using 1 by simp finally show ?case by simp qed qed lemma A_splay_max_ub3: "A_splay_max t \ 3 * \ t + 1" proof cases assume "t = Leaf" thus ?thesis by(simp add: A_splay_max_def) next assume "t \ Leaf" show ?thesis using A_splay_max_ub[OF \t \ Leaf\] by(simp) qed lemma amor_delete: assumes "bst t" -shows "T_delete a t + \(Splay_Tree.delete a t) - \ t \ 6 * log 2 (size1 t) + 2" +shows "T_delete a t + \(Splay_Tree.delete a t) - \ t \ 6 * log 2 (size1 t) + 3" proof (cases t) case Leaf thus ?thesis by(simp add: Splay_Tree.delete_def T_delete_def) next case [simp]: (Node ls x rs) then obtain l e r where sp[simp]: "splay a (Node ls x rs) = Node l e r" by (metis tree.exhaust splay_Leaf_iff) let ?t = "real(T_splay a t)" let ?Plr = "\ l + \ r" let ?Ps = "\ t" let ?slr = "real(size1 l) + real(size1 r)" let ?LR = "log 2 (1 + ?slr)" let ?lslr = "log 2 (real (size ls) + (real (size rs) + 2))" have "?lslr \ 0" by simp have opt: "?t + \ (splay a t) - ?Ps \ 3 * log 2 (real (size1 t)) + 1" using A_splay_ub3[OF \bst t\, simplified A_splay_def, of a] by (simp add: field_simps) show ?thesis proof (cases "e=a") case False thus ?thesis using opt apply(simp add: Splay_Tree.delete_def T_delete_def field_simps) using \?lslr \ 0\ by arith next case [simp]: True show ?thesis proof (cases l) case Leaf have 1: "log 2 (real (size r) + 2) \ 0" by(simp) show ?thesis using Leaf opt apply(simp add: Splay_Tree.delete_def T_delete_def field_simps) using 1 \?lslr \ 0\ by arith next case (Node ll y lr) then obtain l' y' r' where [simp]: "splay_max (Node ll y lr) = Node l' y' r'" using splay_max_Leaf_iff tree.exhaust by blast have "bst l" using bst_splay[OF \bst t\, of a] by simp have "\ r' \ 0" apply (induction r') by (auto) have optm: "real(T_splay_max l) + \ (splay_max l) - \ l \ 3 * \ l + 1" using A_splay_max_ub3[of l, simplified A_splay_max_def] by (simp add: field_simps Node) have 1: "log 2 (2+(real(size l')+real(size r))) \ log 2 (2+(real(size l)+real(size r)))" using size_splay_max[of l] Node by simp have 2: "log 2 (2 + (real (size l') + real (size r'))) \ 0" by simp have 3: "log 2 (size1 l' + size1 r) \ log 2 (size1 l' + size1 r') + log 2 ?slr" apply simp using 1 2 by arith have 4: "log 2 (real(size ll) + (real(size lr) + 2)) \ ?lslr" using size_if_splay[OF sp] Node by simp show ?thesis using add_mono[OF opt optm] Node 3 apply(simp add: Splay_Tree.delete_def T_delete_def field_simps) using 4 \\ r' \ 0\ by arith qed qed qed subsubsection "Overall analysis" fun U where "U Empty [] = 1" | "U (Splay _) [t] = 3 * log 2 (size1 t) + 1" | -"U (Insert _) [t] = 4 * log 2 (size1 t) + 2" | -"U (Delete _) [t] = 6 * log 2 (size1 t) + 2" +"U (Insert _) [t] = 4 * log 2 (size1 t) + 3" | +"U (Delete _) [t] = 6 * log 2 (size1 t) + 3" interpretation Amortized where arity = arity and exec = exec and inv = bst and cost = cost and \ = \ and U = U proof (standard, goal_cases) case (1 ss f) show ?case proof (cases f) case Empty thus ?thesis using 1 by auto next case (Splay a) then obtain t where "ss = [t]" "bst t" using 1 by auto with Splay bst_splay[OF \bst t\, of a] show ?thesis by (auto split: tree.split) next case (Insert a) then obtain t where "ss = [t]" "bst t" using 1 by auto with bst_splay[OF \bst t\, of a] Insert show ?thesis by (auto simp: splay_bstL[OF \bst t\] splay_bstR[OF \bst t\] split: tree.split) next case (Delete a) then obtain t where "ss = [t]" "bst t" using 1 by auto with 1 Delete show ?thesis by(simp add: bst_delete) qed next case (2 t) thus ?case by (induction t) auto next case (3 ss f) show ?case (is "?l \ ?r") proof(cases f) case Empty thus ?thesis using 3(2) by(simp add: A_splay_def) next case (Splay a) then obtain t where "ss = [t]" "bst t" using 3 by auto thus ?thesis using Splay A_splay_ub3[OF \bst t\] by(simp add: A_splay_def) next case [simp]: (Insert a) then obtain t where [simp]: "ss = [t]" and "bst t" using 3 by auto thus ?thesis using amor_insert[of t a] by auto next case [simp]: (Delete a) then obtain t where [simp]: "ss = [t]" and "bst t" using 3 by auto thus ?thesis using amor_delete[of t a] by auto qed qed end diff --git a/thys/Amortized_Complexity/Splay_Tree_Analysis_Base.thy b/thys/Amortized_Complexity/Splay_Tree_Analysis_Base.thy --- a/thys/Amortized_Complexity/Splay_Tree_Analysis_Base.thy +++ b/thys/Amortized_Complexity/Splay_Tree_Analysis_Base.thy @@ -1,136 +1,139 @@ section "Splay Tree" subsection "Basics" theory Splay_Tree_Analysis_Base imports Lemmas_log Splay_Tree.Splay_Tree begin declare size1_size[simp] abbreviation "\ t == log 2 (size1 t)" fun \ :: "'a tree \ real" where "\ Leaf = 0" | "\ (Node l a r) = \ (Node l a r) + \ l + \ r" fun T_splay :: "'a::linorder \ 'a tree \ nat" where "T_splay x Leaf = 1" | "T_splay x (Node AB b CD) = (case cmp x b of EQ \ 1 | LT \ (case AB of Leaf \ 1 | Node A a B \ (case cmp x a of EQ \ 1 | LT \ if A = Leaf then 1 else T_splay x A + 1 | GT \ if B = Leaf then 1 else T_splay x B + 1)) | GT \ (case CD of Leaf \ 1 | Node C c D \ (case cmp x c of EQ \ 1 | LT \ if C = Leaf then 1 else T_splay x C + 1 | GT \ if D = Leaf then 1 else T_splay x D + 1)))" lemma T_splay_simps[simp]: "T_splay a (Node l a r) = 1" "x T_splay x (Node Leaf b CD) = 1" "a T_splay a (Node (Node A a B) b CD) = 1" "x x T_splay x (Node (Node A a B) b CD) = (if A = Leaf then 1 else T_splay x A + 1)" "x a T_splay x (Node (Node A a B) b CD) = (if B = Leaf then 1 else T_splay x B + 1)" "b T_splay x (Node AB b Leaf) = 1" "b T_splay a (Node AB b (Node C a D)) = 1" "b x T_splay x (Node AB b (Node C c D)) = (if C=Leaf then 1 else T_splay x C + 1)" "b c T_splay x (Node AB b (Node C c D)) = (if D=Leaf then 1 else T_splay x D + 1)" by auto declare T_splay.simps(2)[simp del] +definition T_insert :: "'a::linorder \ 'a tree \ nat" where +"T_insert x t = 1 + (if t = Leaf then 0 else T_splay x t)" + fun T_splay_max :: "'a::linorder tree \ nat" where "T_splay_max Leaf = 1" | "T_splay_max (Node A a Leaf) = 1" | "T_splay_max (Node A a (Node B b C)) = (if C=Leaf then 1 else T_splay_max C + 1)" definition T_delete :: "'a::linorder \ 'a tree \ nat" where "T_delete x t = - (if t = Leaf then 0 + 1 + (if t = Leaf then 0 else T_splay x t + (case splay x t of - Node l a r \ if x=a then case l of Leaf \ 0 | _ \ T_splay_max l else 0))" + Node l a r \ if x \ a then 0 else if l = Leaf then 0 else T_splay_max l))" lemma ex_in_set_tree: "t \ Leaf \ bst t \ \x' \ set_tree t. splay x' t = splay x t \ T_splay x' t = T_splay x t" proof(induction x t rule: splay.induct) case (6 x b c A) hence "splay x A \ Leaf" by simp then obtain A1 u A2 where [simp]: "splay x A = Node A1 u A2" by (metis tree.exhaust) have "b < c" "bst A" using "6.prems" by auto from "6.IH"[OF \A \ Leaf\ \bst A\] obtain x' where "x' \ set_tree A" "splay x' A = splay x A" "T_splay x' A = T_splay x A" by blast moreover hence "x'x \x \b \bst A\ by force next case (8 a x c B) hence "splay x B \ Leaf" by simp then obtain B1 u B2 where [simp]: "splay x B = Node B1 u B2" by (metis tree.exhaust) have "a < c" "bst B" using "8.prems" by auto from "8.IH"[OF \B \ Leaf\ \bst B\] obtain x' where "x' \ set_tree B" "splay x' B = splay x B" "T_splay x' B = T_splay x B" by blast moreover hence "ax \a \a \bst B\ by force next case (11 b x c C) hence "splay x C \ Leaf" by simp then obtain C1 u C2 where [simp]: "splay x C = Node C1 u C2" by (metis tree.exhaust) have "b < c" "bst C" using "11.prems" by auto from "11.IH"[OF \C \ Leaf\ \bst C\] obtain x' where "x' \ set_tree C" "splay x' C = splay x C" "T_splay x' C = T_splay x C" by blast moreover hence "bb \x \b \bst C\ by force next case (14 a x c D) hence "splay x D \ Leaf" by simp then obtain D1 u D2 where [simp]: "splay x D = Node D1 u D2" by (metis tree.exhaust) have "a < c" "bst D" using "14.prems" by auto from "14.IH"[OF \D \ Leaf\ \bst D\] obtain x' where "x' \ set_tree D" "splay x' D = splay x D" "T_splay x' D = T_splay x D" by blast moreover hence "ca \c \a \bst D\ by force qed (auto simp: le_less) datatype 'a op = Empty | Splay 'a | Insert 'a | Delete 'a fun arity :: "'a::linorder op \ nat" where "arity Empty = 0" | "arity (Splay x) = 1" | "arity (Insert x) = 1" | "arity (Delete x) = 1" fun exec :: "'a::linorder op \ 'a tree list \ 'a tree" where "exec Empty [] = Leaf" | "exec (Splay x) [t] = splay x t" | "exec (Insert x) [t] = Splay_Tree.insert x t" | "exec (Delete x) [t] = Splay_Tree.delete x t" fun cost :: "'a::linorder op \ 'a tree list \ nat" where "cost Empty [] = 1" | "cost (Splay x) [t] = T_splay x t" | -"cost (Insert x) [t] = T_splay x t" | +"cost (Insert x) [t] = T_insert x t" | "cost (Delete x) [t] = T_delete x t" end diff --git a/thys/Amortized_Complexity/Splay_Tree_Analysis_Optimal.thy b/thys/Amortized_Complexity/Splay_Tree_Analysis_Optimal.thy --- a/thys/Amortized_Complexity/Splay_Tree_Analysis_Optimal.thy +++ b/thys/Amortized_Complexity/Splay_Tree_Analysis_Optimal.thy @@ -1,495 +1,495 @@ subsection "Splay Tree Analysis (Optimal)" theory Splay_Tree_Analysis_Optimal imports Splay_Tree_Analysis_Base Amortized_Framework "HOL-Library.Sum_of_Squares" begin text\This analysis follows Schoenmakers~\cite{Schoenmakers-IPL93}.\ subsubsection "Analysis of splay" locale Splay_Analysis = fixes \ :: real and \ :: real assumes a1[arith]: "\ > 1" assumes A1: "\1 \ x; 1 \ y; 1 \ z\ \ (x+y) * (y+z) powr \ \ (x+y) powr \ * (x+y+z)" assumes A2: "\1 \ l'; 1 \ r'; 1 \ lr; 1 \ r\ \ \ * (l'+r') * (lr+r) powr \ * (lr+r'+r) powr \ \ (l'+r') powr \ * (l'+lr+r') powr \ * (l'+lr+r'+r)" assumes A3: "\1 \ l'; 1 \ r'; 1 \ ll; 1 \ r\ \ \ * (l'+r') * (l'+ll) powr \ * (r'+r) powr \ \ (l'+r') powr \ * (l'+ll+r') powr \ * (l'+ll+r'+r)" begin lemma nl2: "\ ll \ 1; lr \ 1; r \ 1 \ \ log \ (ll + lr) + \ * log \ (lr + r) \ \ * log \ (ll + lr) + log \ (ll + lr + r)" apply(rule powr_le_cancel_iff[THEN iffD1, OF a1]) apply(simp add: powr_add mult.commute[of \] powr_powr[symmetric] A1) done definition \ :: "'a tree \ 'a tree \ real" where "\ t1 t2 = \ * log \ (size1 t1 + size1 t2)" fun \ :: "'a tree \ real" where "\ Leaf = 0" | "\ (Node l _ r) = \ l + \ r + \ l r" definition A :: "'a::linorder \ 'a tree \ real" where "A a t = T_splay a t + \(splay a t) - \ t" lemma A_simps[simp]: "A a (Node l a r) = 1" "a A a (Node (Node ll a lr) b r) = \ lr r - \ lr ll + 1" "b A a (Node l b (Node rl a rr)) = \ rl l - \ rr rl + 1" by(auto simp add: A_def \_def algebra_simps) lemma A_ub: "\ bst t; Node la a ra : subtrees t \ \ A a t \ log \ ((size1 t)/(size1 la + size1 ra)) + 1" proof(induction a t rule: splay.induct) case 1 thus ?case by simp next case 2 thus ?case by auto next case 4 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 5 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 7 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 10 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 12 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case 13 hence False by(fastforce dest: in_set_tree_if) thus ?case .. next case (3 b a lb rb ra) have "b \ set_tree ra" using "3.prems"(1) by auto thus ?case using "3.prems"(1,2) nl2[of "size1 lb" "size1 rb" "size1 ra"] by (auto simp: \_def log_divide algebra_simps) next case (9 a b la lb rb) have "b \ set_tree la" using "9.prems"(1) by auto thus ?case using "9.prems"(1,2) nl2[of "size1 rb" "size1 lb" "size1 la"] by (auto simp add: \_def log_divide algebra_simps) next case (6 x b a lb rb ra) hence 0: "x \ set_tree rb \ x \ set_tree ra" using "6.prems"(1) by auto hence 1: "x \ set_tree lb" using "6.prems" \x by (auto) then obtain lu u ru where sp: "splay x lb = Node lu u ru" using "6.prems"(1,2) by(cases "splay x lb") auto have "b < a" using "6.prems"(1,2) by (auto) let ?lu = "real (size1 lu)" let ?ru = "real (size1 ru)" let ?rb = "real(size1 rb)" let ?r = "real(size1 ra)" have "1 + log \ (?lu + ?ru) + \ * log \ (?rb + ?r) + \ * log \ (?rb + ?ru + ?r) \ \ * log \ (?lu + ?ru) + \ * log \ (?lu + ?rb + ?ru) + log \ (?lu + ?rb + ?ru + ?r)" (is "?L\?R") proof(rule powr_le_cancel_iff[THEN iffD1, OF a1]) show "\ powr ?L \ \ powr ?R" using A2[of ?lu ?ru ?rb ?r] by(simp add: powr_add add_ac mult.commute[of \] powr_powr[symmetric]) qed thus ?case using 6 0 1 sp by(auto simp: A_def \_def size_if_splay algebra_simps log_divide) next case (8 b x a rb lb ra) hence 0: "x \ set_tree lb \ x \ set_tree ra" using "8.prems"(1) by(auto) hence 1: "x \ set_tree rb" using "8.prems" \b \x by (auto) then obtain lu u ru where sp: "splay x rb = Node lu u ru" using "8.prems"(1,2) by(cases "splay x rb") auto let ?lu = "real (size1 lu)" let ?ru = "real (size1 ru)" let ?lb = "real(size1 lb)" let ?r = "real(size1 ra)" have "1 + log \ (?lu + ?ru) + \ * log \ (?lu + ?lb) + \ * log \ (?ru + ?r) \ \ * log \ (?lu + ?ru) + \ * log \ (?lu + ?lb + ?ru) + log \ (?lu + ?lb + ?ru + ?r)" (is "?L\?R") proof(rule powr_le_cancel_iff[THEN iffD1, OF a1]) show "\ powr ?L \ \ powr ?R" using A3[of ?lu ?ru ?lb ?r] by(simp add: powr_add mult.commute[of \] powr_powr[symmetric]) qed thus ?case using 8 0 1 sp by(auto simp add: A_def size_if_splay \_def log_divide algebra_simps) next case (11 a x b lb la rb) hence 0: "x \ set_tree rb \ x \ set_tree la" using "11.prems"(1) by (auto) hence 1: "x \ set_tree lb" using "11.prems" \a \x by (auto) then obtain lu u ru where sp: "splay x lb = Node lu u ru" using "11.prems"(1,2) by(cases "splay x lb") auto let ?lu = "real (size1 lu)" let ?ru = "real (size1 ru)" let ?l = "real(size1 la)" let ?rb = "real(size1 rb)" have "1 + log \ (?lu + ?ru) + \ * log \ (?lu + ?l) + \ * log \ (?ru + ?rb) \ \ * log \ (?lu + ?ru) + \ * log \ (?lu + ?ru + ?rb) + log \ (?lu + ?l + ?ru + ?rb)" (is "?L\?R") proof(rule powr_le_cancel_iff[THEN iffD1, OF a1]) show "\ powr ?L \ \ powr ?R" using A3[of ?ru ?lu ?rb ?l] by(simp add: powr_add mult.commute[of \] powr_powr[symmetric]) (simp add: algebra_simps) qed thus ?case using 11 0 1 sp by(auto simp add: A_def size_if_splay \_def log_divide algebra_simps) next case (14 a x b rb la lb) hence 0: "x \ set_tree lb \ x \ set_tree la" using "14.prems"(1) by(auto) hence 1: "x \ set_tree rb" using "14.prems" \a \b by (auto) then obtain lu u ru where sp: "splay x rb = Node lu u ru" using "14.prems"(1,2) by(cases "splay x rb") auto let ?la = "real(size1 la)" let ?lb = "real(size1 lb)" let ?lu = "real (size1 lu)" let ?ru = "real (size1 ru)" have "1 + log \ (?lu + ?ru) + \ * log \ (?la + ?lb) + \ * log \ (?lu + ?la + ?lb) \ \ * log \ (?lu + ?ru) + \ * log \ (?lu + ?lb + ?ru) + log \ (?lu + ?lb + ?ru + ?la)" (is "?L\?R") proof(rule powr_le_cancel_iff[THEN iffD1, OF a1]) show "\ powr ?L \ \ powr ?R" using A2[of ?ru ?lu ?lb ?la] by(simp add: powr_add add_ac mult.commute[of \] powr_powr[symmetric]) qed thus ?case using 14 0 1 sp by(auto simp add: A_def size_if_splay \_def log_divide algebra_simps) qed lemma A_ub2: assumes "bst t" "a : set_tree t" shows "A a t \ log \ ((size1 t)/2) + 1" proof - from assms(2) obtain la ra where N: "Node la a ra : subtrees t" by (metis set_treeE) have "A a t \ log \ ((size1 t)/(size1 la + size1 ra)) + 1" by(rule A_ub[OF assms(1) N]) also have "\ \ log \ ((size1 t)/2) + 1" by(simp add: field_simps) finally show ?thesis by simp qed lemma A_ub3: assumes "bst t" shows "A a t \ log \ (size1 t) + 1" proof cases assume "t = Leaf" thus ?thesis by(simp add: A_def) next assume "t \ Leaf" from ex_in_set_tree[OF this assms] obtain a' where a': "a' \ set_tree t" "splay a' t = splay a t" "T_splay a' t = T_splay a t" by blast have [arith]: "log \ 2 > 0" by simp show ?thesis using A_ub2[OF assms a'(1)] by(simp add: A_def a' log_divide) qed definition Am :: "'a::linorder tree \ real" where "Am t = T_splay_max t + \(splay_max t) - \ t" lemma Am_simp3': "\ c Leaf\ \ Am (Node l c (Node rl b rr)) = (case splay_max rr of Node rrl _ rrr \ Am rr + \ rrl (Node l c rl) + \ l rl - \ rl rr - \ rrl rrr + 1)" by(auto simp: Am_def \_def size_if_splay_max algebra_simps neq_Leaf_iff split: tree.split) lemma Am_ub: "\ bst t; t \ Leaf \ \ Am t \ log \ ((size1 t)/2) + 1" proof(induction t rule: splay_max.induct) case 1 thus ?case by (simp) next case 2 thus ?case by (simp add: Am_def) next case (3 l b rl c rr) show ?case proof cases assume "rr = Leaf" thus ?thesis using nl2[of 1 "size1 rl" "size1 l"] log_le_cancel_iff[of \ 2 "2 + real(size rl)"] by(auto simp: Am_def \_def log_divide field_simps simp del: log_le_cancel_iff) next assume "rr \ Leaf" then obtain l' u r' where sp: "splay_max rr = Node l' u r'" using splay_max_Leaf_iff tree.exhaust by blast hence 1: "size rr = size l' + size r' + 1" using size_splay_max[of rr] by(simp) let ?l = "real (size1 l)" let ?rl = "real (size1 rl)" let ?l' = "real (size1 l')" let ?r' = "real (size1 r')" have "1 + log \ (?l' + ?r') + \ * log \ (?l + ?rl) + \ * log \ (?l' + ?l + ?rl) \ \ * log \ (?l' + ?r') + \ * log \ (?l' + ?rl + ?r') + log \ (?l' + ?rl + ?r' + ?l)" (is "?L\?R") proof(rule powr_le_cancel_iff[THEN iffD1, OF a1]) show "\ powr ?L \ \ powr ?R" using A2[of ?r' ?l' ?rl ?l] by(simp add: powr_add add.commute add.left_commute mult.commute[of \] powr_powr[symmetric]) qed thus ?case using 3 sp 1 \rr \ Leaf\ by(auto simp add: Am_simp3' \_def log_divide algebra_simps) qed qed lemma Am_ub3: assumes "bst t" shows "Am t \ log \ (size1 t) + 1" proof cases assume "t = Leaf" thus ?thesis by(simp add: Am_def) next assume "t \ Leaf" have [arith]: "log \ 2 > 0" by simp show ?thesis using Am_ub[OF assms \t \ Leaf\] by(simp add: Am_def log_divide) qed end subsubsection "Optimal Interpretation" lemma mult_root_eq_root: "n>0 \ y \ 0 \ root n x * y = root n (x * (y ^ n))" by(simp add: real_root_mult real_root_pos2) lemma mult_root_eq_root2: "n>0 \ y \ 0 \ y * root n x = root n ((y ^ n) * x)" by(simp add: real_root_mult real_root_pos2) lemma powr_inverse_numeral: "0 < x \ x powr (1 / numeral n) = root (numeral n) x" by (simp add: root_powr_inverse) lemmas root_simps = mult_root_eq_root mult_root_eq_root2 powr_inverse_numeral lemma nl31: "\ (l'::real) \ 1; r' \ 1; lr \ 1; r \ 1 \ \ 4 * (l' + r') * (lr + r) \ (l' + lr + r' + r)^2" by (sos "(((A<0 * R<1) + (R<1 * (R<1 * [r + ~1*l' + lr + ~1*r']^2))))") lemma nl32: assumes "(l'::real) \ 1" "r' \ 1" "lr \ 1" "r \ 1" shows "4 * (l' + r') * (lr + r) * (lr + r' + r) \ (l' + lr + r' + r)^3" proof - have 1: "lr + r' + r \ l' + lr + r' + r" using assms by arith have 2: "0 \ (l' + lr + r' + r)^2" by (rule zero_le_power2) have 3: "0 \ lr + r' + r" using assms by arith from mult_mono[OF nl31[OF assms] 1 2 3] show ?thesis by(simp add: ac_simps numeral_eq_Suc) qed lemma nl3: assumes "(l'::real) \ 1" "r' \ 1" "lr \ 1" "r \ 1" shows "4 * (l' + r')^2 * (lr + r) * (lr + r' + r) \ (l' + lr + r') * (l' + lr + r' + r)^3" proof- have 1: "l' + r' \ l' + lr + r'" using assms by arith have 2: "0 \ (l' + lr + r' + r)^3" using assms by simp have 3: "0 \ l' + r'" using assms by arith from mult_mono[OF nl32[OF assms] 1 2 3] show ?thesis unfolding power2_eq_square by (simp only: ac_simps) qed lemma nl41: assumes "(l'::real) \ 1" "r' \ 1" "ll \ 1" "r \ 1" shows "4 * (l' + ll) * (r' + r) \ (l' + ll + r' + r)^2" using assms by (sos "(((A<0 * R<1) + (R<1 * (R<1 * [r + ~1*l' + ~1*ll + r']^2))))") lemma nl42: assumes "(l'::real) \ 1" "r' \ 1" "ll \ 1" "r \ 1" shows "4 * (l' + r') * (l' + ll) * (r' + r) \ (l' + ll + r' + r)^3" proof - have 1: "l' + r' \ l' + ll + r' + r" using assms by arith have 2: "0 \ (l' + ll + r' + r)^2" by (rule zero_le_power2) have 3: "0 \ l' + r'" using assms by arith from mult_mono[OF nl41[OF assms] 1 2 3] show ?thesis by(simp add: ac_simps numeral_eq_Suc del: distrib_right_numeral) qed lemma nl4: assumes "(l'::real) \ 1" "r' \ 1" "ll \ 1" "r \ 1" shows "4 * (l' + r')^2 * (l' + ll) * (r' + r) \ (l' + ll + r') * (l' + ll + r' + r)^3" proof- have 1: "l' + r' \ l' + ll + r'" using assms by arith have 2: "0 \ (l' + ll + r' + r)^3" using assms by simp have 3: "0 \ l' + r'" using assms by arith from mult_mono[OF nl42[OF assms] 1 2 3] show ?thesis unfolding power2_eq_square by (simp only: ac_simps) qed lemma cancel: "x>(0::real) \ c * x ^ 2 * y * z \ u * v \ c * x ^ 3 * y * z \ x * u * v" by(simp add: power2_eq_square power3_eq_cube) interpretation S34: Splay_Analysis "root 3 4" "1/3" proof (standard, goal_cases) case 2 thus ?case by(simp add: root_simps) (auto simp: numeral_eq_Suc split_mult_pos_le intro!: mult_mono) next case 3 thus ?case by(simp add: root_simps cancel nl3) next case 4 thus ?case by(simp add: root_simps cancel nl4) qed simp lemma log4_log2: "log 4 x = log 2 x / 2" proof - have "log 4 x = log (2^2) x" by simp also have "\ = log 2 x / 2" by(simp only: log_base_pow) finally show ?thesis . qed declare log_base_root[simp] lemma A34_ub: assumes "bst t" shows "S34.A a t \ (3/2) * log 2 (size1 t) + 1" proof - have "S34.A a t \ log (root 3 4) (size1 t) + 1" by(rule S34.A_ub3[OF assms]) also have "\ = (3/2) * log 2 (size t + 1) + 1" by(simp add: log4_log2) finally show ?thesis by simp qed lemma Am34_ub: assumes "bst t" shows "S34.Am t \ (3/2) * log 2 (size1 t) + 1" proof - have "S34.Am t \ log (root 3 4) (size1 t) + 1" by(rule S34.Am_ub3[OF assms]) also have "\ = (3/2) * log 2 (size1 t) + 1" by(simp add: log4_log2) finally show ?thesis by simp qed subsubsection "Overall analysis" fun U where "U Empty [] = 1" | "U (Splay _) [t] = (3/2) * log 2 (size1 t) + 1" | -"U (Insert _) [t] = 2 * log 2 (size1 t) + 3/2" | -"U (Delete _) [t] = 3 * log 2 (size1 t) + 2" +"U (Insert _) [t] = 2 * log 2 (size1 t) + 5/2" | +"U (Delete _) [t] = 3 * log 2 (size1 t) + 3" interpretation Amortized where arity = arity and exec = exec and inv = bst and cost = cost and \ = S34.\ and U = U proof (standard, goal_cases) case (1 ss f) show ?case proof (cases f) case Empty thus ?thesis using 1 by auto next case (Splay a) then obtain t where "ss = [t]" "bst t" using 1 by auto with Splay bst_splay[OF \bst t\, of a] show ?thesis by (auto split: tree.split) next case (Insert a) then obtain t where "ss = [t]" "bst t" using 1 by auto with bst_splay[OF \bst t\, of a] Insert show ?thesis by (auto simp: splay_bstL[OF \bst t\] splay_bstR[OF \bst t\] split: tree.split) next case (Delete a) then obtain t where "ss = [t]" "bst t" using 1 by auto with 1 Delete show ?thesis by(simp add: bst_delete) qed next case (2 t) show ?case by(induction t)(simp_all add: S34.\_def) next case (3 ss f) show ?case (is "?l \ ?r") proof(cases f) case Empty thus ?thesis using 3(2) by(simp add: S34.A_def) next case (Splay a) then obtain t where "ss = [t]" "bst t" using 3 by auto thus ?thesis using S34.A_ub3[OF \bst t\] Splay by(simp add: S34.A_def log4_log2) next case [simp]: (Insert a) obtain t where [simp]: "ss = [t]" and "bst t" using 3 by auto show ?thesis proof cases - assume "t = Leaf" thus ?thesis by(simp add: S34.\_def log4_log2) + assume "t = Leaf" thus ?thesis by(simp add: S34.\_def log4_log2 T_insert_def) next assume "t \ Leaf" then obtain l e r where [simp]: "splay a t = Node l e r" by (metis tree.exhaust splay_Leaf_iff) let ?t = "real(T_splay a t)" let ?Plr = "S34.\ l + S34.\ r" let ?Ps = "S34.\ t" let ?slr = "real(size1 l) + real(size1 r)" let ?LR = "log 2 (1 + ?slr)" have opt: "?t + S34.\ (splay a t) - ?Ps \ 3/2 * log 2 (real (size1 t)) + 1" using S34.A_ub3[OF \bst t\, simplified S34.A_def, of a] by (simp add: log4_log2) from less_linear[of e a] show ?thesis proof (elim disjE) assume "e=a" have nneg: "log 2 (1 + real (size t)) \ 0" by simp thus ?thesis using \t \ Leaf\ opt \e=a\ - apply(simp add: field_simps) using nneg by arith + apply(simp add: field_simps T_insert_def) using nneg by arith next let ?L = "log 2 (real(size1 l) + 1)" assume "e a" by simp - hence "?l = (?t + ?Plr - ?Ps) + ?L / 2 + ?LR / 2" - using \t \ Leaf\ \e by(simp add: S34.\_def log4_log2) + hence "?l = (?t + ?Plr - ?Ps) + ?L / 2 + ?LR / 2 + 1" + using \t \ Leaf\ \e by(simp add: S34.\_def log4_log2 T_insert_def) also have "?t + ?Plr - ?Ps \ log 2 ?slr + 1" using opt size_splay[of a t,symmetric] by(simp add: S34.\_def log4_log2) also have "?L/2 \ log 2 ?slr / 2" by(simp) also have "?LR/2 \ log 2 ?slr / 2 + 1/2" proof - have "?LR/2 \ log 2 (2 * ?slr) / 2" by simp also have "\ \ log 2 ?slr / 2 + 1/2" by (simp add: log_mult del:distrib_left_numeral) finally show ?thesis . qed finally show ?thesis using size_splay[of a t,symmetric] by simp next let ?R = "log 2 (2 + real(size r))" assume "a a" by simp - hence "?l = (?t + ?Plr - ?Ps) + ?R / 2 + ?LR / 2" - using \t \ Leaf\ \a by(simp add: S34.\_def log4_log2) + hence "?l = (?t + ?Plr - ?Ps) + ?R / 2 + ?LR / 2 + 1" + using \t \ Leaf\ \a by(simp add: S34.\_def log4_log2 T_insert_def) also have "?t + ?Plr - ?Ps \ log 2 ?slr + 1" using opt size_splay[of a t,symmetric] by(simp add: S34.\_def log4_log2) also have "?R/2 \ log 2 ?slr / 2" by(simp) also have "?LR/2 \ log 2 ?slr / 2 + 1/2" proof - have "?LR/2 \ log 2 (2 * ?slr) / 2" by simp also have "\ \ log 2 ?slr / 2 + 1/2" by (simp add: log_mult del:distrib_left_numeral) finally show ?thesis . qed finally show ?thesis using size_splay[of a t,symmetric] by simp qed qed next case [simp]: (Delete a) obtain t where [simp]: "ss = [t]" and "bst t" using 3 by auto show ?thesis proof (cases t) case Leaf thus ?thesis by(simp add: Splay_Tree.delete_def T_delete_def S34.\_def log4_log2) next case [simp]: (Node ls x rs) then obtain l e r where sp[simp]: "splay a (Node ls x rs) = Node l e r" by (metis tree.exhaust splay_Leaf_iff) let ?t = "real(T_splay a t)" let ?Plr = "S34.\ l + S34.\ r" let ?Ps = "S34.\ t" let ?slr = "real(size1 l) + real(size1 r)" let ?LR = "log 2 (1 + ?slr)" let ?lslr = "log 2 (real (size ls) + (real (size rs) + 2))" have "?lslr \ 0" by simp have opt: "?t + S34.\ (splay a t) - ?Ps \ 3/2 * log 2 (real (size1 t)) + 1" using S34.A_ub3[OF \bst t\, simplified S34.A_def, of a] by (simp add: log4_log2 field_simps) show ?thesis proof (cases "e=a") case False thus ?thesis using opt apply(simp add: Splay_Tree.delete_def T_delete_def field_simps) using \?lslr \ 0\ by arith next case [simp]: True show ?thesis proof (cases l) case Leaf have "S34.\ Leaf r \ 0" by(simp add: S34.\_def) thus ?thesis using Leaf opt apply(simp add: Splay_Tree.delete_def T_delete_def field_simps) using \?lslr \ 0\ by arith next case (Node ll y lr) then obtain l' y' r' where [simp]: "splay_max (Node ll y lr) = Node l' y' r'" using splay_max_Leaf_iff tree.exhaust by blast have "bst l" using bst_splay[OF \bst t\, of a] by simp have "S34.\ r' \ 0" apply (induction r') by (auto simp add: S34.\_def) have optm: "real(T_splay_max l) + S34.\ (splay_max l) - S34.\ l \ 3/2 * log 2 (real (size1 l)) + 1" using S34.Am_ub3[OF \bst l\, simplified S34.Am_def] by (simp add: log4_log2 field_simps Node) have 1: "log 4 (2+(real(size l')+real(size r))) \ log 4 (2+(real(size l)+real(size r)))" using size_splay_max[of l] Node by simp have 2: "log 4 (2 + (real (size l') + real (size r'))) \ 0" by simp have 3: "S34.\ l' r \ S34.\ l' r' + S34.\ l r" apply(simp add: S34.\_def) using 1 2 by arith have 4: "log 2 (real(size ll) + (real(size lr) + 2)) \ ?lslr" using size_if_splay[OF sp] Node by simp show ?thesis using add_mono[OF opt optm] Node 3 apply(simp add: Splay_Tree.delete_def T_delete_def field_simps) using 4 \S34.\ r' \ 0\ by arith qed qed qed qed qed end