diff --git a/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis.thy b/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis.thy --- a/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis.thy +++ b/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis.thy @@ -1,332 +1,332 @@ (* Author: Tobias Nipkow (based on Hauke Brinkop's tree proofs) *) subsection \Okasaki's Pairing Heap\ theory Pairing_Heap_List1_Analysis imports Pairing_Heap.Pairing_Heap_List1 Amortized_Framework Priority_Queue_ops_merge Lemmas_log begin text \Amortized analysis of pairing heaps as defined by Okasaki \cite{Okasaki}.\ fun hps where "hps (Hp _ hs) = hs" lemma merge_Empty[simp]: "merge heap.Empty h = h" by(cases h) auto lemma merge2: "merge (Hp x lx) h = (case h of heap.Empty \ Hp x lx | (Hp y ly) \ (if x < y then Hp x (Hp y ly # lx) else Hp y (Hp x lx # ly)))" by(auto split: heap.split) lemma pass1_Nil_iff: "pass\<^sub>1 hs = [] \ hs = []" by(cases hs rule: pass\<^sub>1.cases) auto subsubsection \Invariant\ fun no_Empty :: "'a :: linorder heap \ bool" where "no_Empty heap.Empty = False" | "no_Empty (Hp x hs) = (\h \ set hs. no_Empty h)" abbreviation no_Emptys :: "'a :: linorder heap list \ bool" where "no_Emptys hs \ \h \ set hs. no_Empty h" fun is_root :: "'a :: linorder heap \ bool" where "is_root heap.Empty = True" | "is_root (Hp x hs) = no_Emptys hs" lemma is_root_if_no_Empty: "no_Empty h \ is_root h" by(cases h) auto lemma no_Emptys_hps: "no_Empty h \ no_Emptys(hps h)" by(induction h) auto lemma no_Empty_merge: "\ no_Empty h1; no_Empty h2\ \ no_Empty (merge h1 h2)" by (cases "(h1,h2)" rule: merge.cases) auto lemma is_root_merge: "\ is_root h1; is_root h2\ \ is_root (merge h1 h2)" by (cases "(h1,h2)" rule: merge.cases) auto lemma no_Emptys_pass1: "no_Emptys hs \ no_Emptys (pass\<^sub>1 hs)" by(induction hs rule: pass\<^sub>1.induct)(auto simp: no_Empty_merge) lemma is_root_pass2: "no_Emptys hs \ is_root(pass\<^sub>2 hs)" proof(induction hs) case (Cons _ hs) show ?case proof cases assume "hs = []" thus ?thesis using Cons by (auto simp: is_root_if_no_Empty) next assume "hs \ []" thus ?thesis using Cons by(auto simp: is_root_merge is_root_if_no_Empty) qed qed simp subsubsection \Complexity\ fun size_hp :: "'a heap \ nat" where "size_hp heap.Empty = 0" | "size_hp (Hp x hs) = sum_list(map size_hp hs) + 1" abbreviation size_hps where "size_hps hs \ sum_list(map size_hp hs)" fun \_hps :: "'a heap list \ real" where "\_hps [] = 0" | "\_hps (heap.Empty # hs) = \_hps hs" | "\_hps (Hp x hsl # hsr) = \_hps hsl + \_hps hsr + log 2 (size_hps hsl + size_hps hsr + 1)" fun \ :: "'a heap \ real" where "\ heap.Empty = 0" | "\ (Hp _ hs) = \_hps hs + log 2 (size_hps(hs)+1)" lemma \_hps_ge0: "\_hps hs \ 0" by (induction hs rule: \_hps.induct) auto lemma no_Empty_ge0: "no_Empty h \ size_hp h > 0" by(cases h) auto declare algebra_simps[simp] lemma \_hps1: "\_hps [h] = \ h" by(cases h) auto lemma size_hp_merge: "size_hp(merge h1 h2) = size_hp h1 + size_hp h2" by (induction h1 h2 rule: merge.induct) simp_all lemma pass\<^sub>1_size[simp]: "size_hps (pass\<^sub>1 hs) = size_hps hs" by (induct hs rule: pass\<^sub>1.induct) (simp_all add: size_hp_merge) lemma \\_insert: "\ (Pairing_Heap_List1.insert x h) - \ h \ log 2 (size_hp h + 1)" by(cases h)(auto simp: size_hp_merge) lemma \\_merge: "\ (merge h1 h2) - \ h1 - \ h2 \ log 2 (size_hp h1 + size_hp h2 + 1) + 1" proof(induction h1 h2 rule: merge.induct) case (3 x lx y ly) thus ?case using ld_le_2ld[of "size_hps lx" "size_hps ly"] log_le_cancel_iff[of 2 "size_hps lx + size_hps ly + 2" "size_hps lx + size_hps ly + 3"] by (auto simp del: log_le_cancel_iff) qed auto fun sum_ub :: "'a heap list \ real" where "sum_ub [] = 0" | "sum_ub [_] = 0" | "sum_ub [h1, h2] = 2*log 2 (size_hp h1 + size_hp h2)" | "sum_ub (h1 # h2 # hs) = 2*log 2 (size_hp h1 + size_hp h2 + size_hps hs) - 2*log 2 (size_hps hs) - 2 + sum_ub hs" lemma \\_pass1_sum_ub: "no_Emptys hs \ \_hps (pass\<^sub>1 hs) - \_hps hs \ sum_ub hs" (is "_ \ ?P hs") proof (induction hs rule: sum_ub.induct) case (3 h1 h2) then obtain x hsx y hsy where [simp]: "h1 = Hp x hsx" "h2 = Hp y hsy" by simp (meson no_Empty.elims(2)) have 0: "\x y::real. 0 \ x \ x \ y \ x \ 2*y" by linarith show ?case using 3 by (auto simp add: add_increasing 0) next case (4 h1 h2 h3 hs) hence IH: "?P(h3#hs)" by auto from "4.prems" obtain x hsx y hsy where [simp]: "h1 = Hp x hsx" "h2 = Hp y hsy" by simp (meson no_Empty.elims(2)) from "4.prems" have s3: "size_hp h3 > 0" apply auto using size_hp.elims by force let ?ry = "h3 # hs" let ?rx = "Hp y hsy # ?ry" let ?h = "Hp x hsx # ?rx" have "\_hps(pass\<^sub>1 ?h) - \_hps ?h \ log 2 (1 + size_hps hsx + size_hps hsy) - log 2 (1 + size_hps hsy + size_hps ?ry) + sum_ub ?ry" using IH by simp also have "log 2 (1 + size_hps hsx + size_hps hsy) - log 2 (1 + size_hps hsy + size_hps ?ry) \ 2*log 2 (size_hps ?h) - 2*log 2 (size_hps ?ry) - 2" proof - have "log 2 (1 + size_hps hsx + size_hps hsy) + log 2 (size_hps ?ry) - 2*log 2 (size_hps ?h) = log 2 ((1 + size_hps hsx + size_hps hsy)/(size_hps ?h) ) + log 2 (size_hps ?ry / size_hps ?h)" using s3 by (simp add: log_divide) also have "\ \ -2" proof - have "2 + \ \ 2*log 2 ((1 + size_hps hsx + size_hps hsy) / size_hps ?h + size_hps ?ry / size_hps ?h)" using ld_sum_inequality [of "(1 + size_hps hsx + size_hps hsy) / size_hps ?h" "(size_hps ?ry / size_hps ?h)"] using s3 by simp also have "\ \ 0" by (simp add: field_simps log_divide add_pos_nonneg) finally show ?thesis by linarith qed finally have "log 2 (1 + size_hps hsx + size_hps hsy) + log 2 (size_hps ?ry) + 2 \ 2*log 2 (size_hps ?h)" by simp moreover have "log 2 (size_hps ?ry) \ log 2 (size_hps ?rx)" using s3 by simp ultimately have "log 2 (1 + size_hps hsx + size_hps hsy) - \ \ 2*log 2 (size_hps ?h) - 2*log 2 (size_hps ?ry) - 2" by linarith thus ?thesis by simp qed finally show ?case by (simp) qed simp_all lemma \\_pass1: assumes "hs \ []" "no_Emptys hs" shows "\_hps (pass\<^sub>1 hs) - \_hps hs \ 2 * log 2 (size_hps hs) - length hs + 2" proof - have "sum_ub hs \ 2 * log 2 (size_hps hs) - length hs + 2" using assms by (induct hs rule: sum_ub.induct) (auto dest: no_Empty_ge0) thus ?thesis using \\_pass1_sum_ub[OF assms(2)] by linarith qed lemma size_hps_pass2: "hs \ [] \ no_Emptys hs \ no_Empty(pass\<^sub>2 hs) & size_hps hs = size_hps(hps(pass\<^sub>2 hs))+1" apply(induction hs rule: \_hps.induct) apply (fastforce simp: merge2 split: heap.split)+ done lemma \\_pass2: "hs \ [] \ no_Emptys hs \ \ (pass\<^sub>2 hs) - \_hps hs \ log 2 (size_hps hs)" proof (induction hs) case (Cons h hs) thus ?case proof cases assume "hs = []" thus ?thesis using Cons by (auto simp add: \_hps1 dest: no_Empty_ge0) next assume *: "hs \ []" obtain x hs2 where [simp]: "h = Hp x hs2" using Cons.prems(2)by simp (meson no_Empty.elims(2)) show ?thesis proof (cases "pass\<^sub>2 hs") case Empty thus ?thesis using \_hps_ge0[of hs] by(simp add: add_increasing xt1(3)[OF mult_2, OF add_increasing]) next case (Hp y hs3) with Cons * size_hps_pass2[of hs] show ?thesis by(auto simp: add_mono) qed qed qed simp lemma \\_del_min: assumes "hps h \ []" "no_Empty h" shows "\ (del_min h) - \ h \ 3 * log 2 (size_hps(hps h)) - length(hps h) + 2" proof - obtain x hs where [simp]: "h = Hp x hs" using assms(2) by (cases h) auto let ?\\\<^sub>1 = "\_hps(hps h) - \ h" let ?\\\<^sub>2 = "\(pass\<^sub>2(pass\<^sub>1 (hps h))) - \_hps (hps h)" let ?\\ = "\ (del_min h) - \ h" have "\(pass\<^sub>2(pass\<^sub>1(hps h))) - \_hps (pass\<^sub>1(hps h)) \ log 2 (size_hps(hps h))" using \\_pass2[of "pass\<^sub>1(hps h)"] using assms by (auto simp: pass1_Nil_iff no_Emptys_pass1 dest: no_Emptys_hps) moreover have "\_hps (pass\<^sub>1 (hps h)) - \_hps (hps h) \ 2*\ - length (hps h) + 2" using \\_pass1[OF assms(1) no_Emptys_hps[OF assms(2)]] by blast moreover have "?\\\<^sub>1 \ 0" by simp moreover have "?\\ = ?\\\<^sub>1 + ?\\\<^sub>2" by simp ultimately show ?thesis by linarith qed fun exec :: "'a :: linorder op \ 'a heap list \ 'a heap" where "exec Empty [] = heap.Empty" | "exec Del_min [h] = del_min h" | "exec (Insert x) [h] = Pairing_Heap_List1.insert x h" | "exec Merge [h1,h2] = merge h1 h2" -fun t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 :: "'a heap list \ nat" where - "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [] = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [_] = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (_ # _ # hs) = 1 + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" +fun T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 :: "'a heap list \ nat" where + "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [] = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [_] = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (_ # _ # hs) = 1 + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" -fun t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 :: "'a heap list \ nat" where - "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 [] = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (_ # hs) = 1 + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 hs" +fun T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 :: "'a heap list \ nat" where + "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 [] = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (_ # hs) = 1 + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 hs" fun cost :: "'a :: linorder op \ 'a heap list \ nat" where "cost Empty _ = 1" | "cost Del_min [heap.Empty] = 1" | -"cost Del_min [Hp x hs] = t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" | +"cost Del_min [Hp x hs] = T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" | "cost (Insert a) _ = 1" | "cost Merge _ = 1" fun U :: "'a :: linorder op \ 'a heap list \ real" where "U Empty _ = 1" | "U (Insert a) [h] = log 2 (size_hp h + 1) + 1" | "U Del_min [h] = 3*log 2 (size_hp h + 1) + 4" | "U Merge [h1,h2] = log 2 (size_hp h1 + size_hp h2 + 1) + 2" interpretation pairing: Amortized where arity = arity and exec = exec and cost = cost and inv = "is_root" and \ = \ and U = U proof (standard, goal_cases) case (1 ss f) show ?case proof (cases f) case Empty with 1 show ?thesis by simp next case Insert thus ?thesis using 1 by(auto simp: is_root_merge) next case Merge thus ?thesis using 1 by(auto simp: is_root_merge numeral_eq_Suc) next case [simp]: Del_min then obtain h where [simp]: "ss = [h]" using 1 by auto show ?thesis proof (cases h) case [simp]: (Hp _ hs) show ?thesis proof cases assume "hs = []" thus ?thesis by simp next assume "hs \ []" thus ?thesis using 1(1) no_Emptys_pass1 by (auto intro: is_root_pass2) qed qed simp qed next case (2 s) show ?case by (cases s) (auto simp: \_hps_ge0) next case (3 ss f) show ?case proof (cases f) case Empty with 3 show ?thesis by(auto) next case Insert thus ?thesis using \\_insert 3 by auto next case [simp]: Del_min then obtain h where [simp]: "ss = [h]" using 3 by auto show ?thesis proof (cases h) case [simp]: (Hp x hs) - have "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs \ 2 + length hs" + have "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs \ 2 + length hs" by (induct hs rule: pass\<^sub>1.induct) simp_all hence "cost f ss \ \" by simp moreover have "\ (del_min h) - \ h \ 3*log 2 (size_hp h + 1) - length hs + 2" proof (cases "hs = []") case False hence "\ (del_min h) - \ h \ 3*log 2 (size_hps hs) - length hs + 2" using \\_del_min[of h] 3(1) by simp also have "\ \ 3*log 2 (size_hp h + 1) - length hs + 2" using False 3(1) size_hps_pass2 by fastforce finally show ?thesis . qed simp ultimately show ?thesis by simp qed simp next case [simp]: Merge then obtain h1 h2 where [simp]: "ss = [h1, h2]" using 3 by(auto simp: numeral_eq_Suc) show ?thesis proof (cases "h1 = heap.Empty \ h2 = heap.Empty") case True thus ?thesis by auto next case False then obtain x1 x2 hs1 hs2 where [simp]: "h1 = Hp x1 hs1" "h2 = Hp x2 hs2" by (meson hps.cases) have "\ (merge h1 h2) - \ h1 - \ h2 \ log 2 (size_hp h1 + size_hp h2 + 1) + 1" using \\_merge[of h1 h2] by simp thus ?thesis by(simp) qed qed qed end diff --git a/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis2.thy b/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis2.thy --- a/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis2.thy +++ b/thys/Amortized_Complexity/Pairing_Heap_List1_Analysis2.thy @@ -1,130 +1,130 @@ (* Author: Tobias Nipkow *) subsection \Transfer of Tree Analysis to List Representation\ theory Pairing_Heap_List1_Analysis2 imports Pairing_Heap_List1_Analysis Pairing_Heap_Tree_Analysis begin text\This theory transfers the amortized analysis of the tree-based pairing heaps to Okasaki's pairing heaps.\ abbreviation "is_root' == Pairing_Heap_List1_Analysis.is_root" abbreviation "del_min' == Pairing_Heap_List1.del_min" abbreviation "insert' == Pairing_Heap_List1.insert" abbreviation "merge' == Pairing_Heap_List1.merge" abbreviation "pass\<^sub>1' == Pairing_Heap_List1.pass\<^sub>1" abbreviation "pass\<^sub>2' == Pairing_Heap_List1.pass\<^sub>2" -abbreviation "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1' == Pairing_Heap_List1_Analysis.t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1" -abbreviation "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2' == Pairing_Heap_List1_Analysis.t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2" +abbreviation "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1' == Pairing_Heap_List1_Analysis.T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1" +abbreviation "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2' == Pairing_Heap_List1_Analysis.T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2" fun homs :: "'a heap list \ 'a tree" where "homs [] = Leaf" | "homs (Hp x lhs # rhs) = Node (homs lhs) x (homs rhs)" fun hom :: "'a heap \ 'a tree" where "hom heap.Empty = Leaf" | "hom (Hp x hs) = (Node (homs hs) x Leaf)" lemma homs_pass1': "no_Emptys hs \ homs(pass\<^sub>1' hs) = pass\<^sub>1 (homs hs)" apply(induction hs rule: Pairing_Heap_List1.pass\<^sub>1.induct) apply simp subgoal for h apply(case_tac h) apply (auto) done subgoal for h1 h2 apply(case_tac h1) apply simp apply(case_tac h2) apply (auto) done done lemma hom_merge': "\ no_Emptys lhs; Pairing_Heap_List1_Analysis.is_root h\ \ hom (merge' (Hp x lhs) h) = link \homs lhs, x, hom h\" by(cases h) auto lemma hom_pass2': "no_Emptys hs \ hom(pass\<^sub>2' hs) = pass\<^sub>2 (homs hs)" by(induction hs rule: homs.induct) (auto simp: hom_merge' is_root_pass2) lemma del_min': "is_root' h \ hom(del_min' h) = del_min (hom h)" by(cases h) (auto simp: homs_pass1' hom_pass2' no_Emptys_pass1 is_root_pass2) lemma insert': "is_root' h \ hom(insert' x h) = insert x (hom h)" by(cases h)(auto) lemma merge': "\ is_root' h1; is_root' h2 \ \ hom(merge' h1 h2) = merge (hom h1) (hom h2)" apply(cases h1) apply(simp) apply(cases h2) apply(auto) done -lemma t_pass1': "no_Emptys hs \ t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1' hs = t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1(homs hs)" +lemma T_pass1': "no_Emptys hs \ T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1' hs = T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1(homs hs)" apply(induction hs rule: Pairing_Heap_List1.pass\<^sub>1.induct) apply simp subgoal for h apply(case_tac h) apply (auto) done subgoal for h1 h2 apply(case_tac h1) apply simp apply(case_tac h2) apply (auto) done done -lemma t_pass2': "no_Emptys hs \ t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2' hs = t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2(homs hs)" +lemma T_pass2': "no_Emptys hs \ T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2' hs = T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2(homs hs)" by(induction hs rule: homs.induct) (auto simp: hom_merge' is_root_pass2) lemma size_hp: "is_root' h \ size_hp h = size (hom h)" proof(induction h) case (Hp _ hs) thus ?case apply(induction hs rule: homs.induct) apply simp apply force apply simp done qed simp interpretation Amortized2 where arity = arity and exec = exec and inv = is_root and cost = cost and \ = \ and U = U and hom = hom and exec' = Pairing_Heap_List1_Analysis.exec and cost' = Pairing_Heap_List1_Analysis.cost and inv' = "is_root'" and U' = Pairing_Heap_List1_Analysis.U proof (standard, goal_cases) case (1 _ f) thus ?case by (cases f)(auto simp: merge' del_min' numeral_eq_Suc) next case (2 ts f) show ?case proof(cases f) case [simp]: Del_min then obtain h where [simp]: "ts = [h]" using 2 by auto show ?thesis using 2 by(cases h) (auto simp: is_root_pass2 no_Emptys_pass1) qed (insert 2, auto simp: Pairing_Heap_List1_Analysis.is_root_merge numeral_eq_Suc) next case (3 t) thus ?case by (cases t) (auto) next case (4 ts f) show ?case proof (cases f) case [simp]: Del_min then obtain h where [simp]: "ts = [h]" using 4 by auto show ?thesis using 4 - by (cases h)(auto simp: t_pass1' t_pass2' no_Emptys_pass1 homs_pass1') + by (cases h)(auto simp: T_pass1' T_pass2' no_Emptys_pass1 homs_pass1') qed (insert 4, auto) next case (5 _ f) thus ?case by(cases f) (auto simp: size_hp numeral_eq_Suc) qed end diff --git a/thys/Amortized_Complexity/Pairing_Heap_List2_Analysis.thy b/thys/Amortized_Complexity/Pairing_Heap_List2_Analysis.thy --- a/thys/Amortized_Complexity/Pairing_Heap_List2_Analysis.thy +++ b/thys/Amortized_Complexity/Pairing_Heap_List2_Analysis.thy @@ -1,243 +1,243 @@ (* Author: Tobias Nipkow (based on Hauke Brinkop's tree proofs) *) subsection \Okasaki's Pairing Heap (Modified)\ theory Pairing_Heap_List2_Analysis imports Pairing_Heap.Pairing_Heap_List2 Amortized_Framework Priority_Queue_ops_merge Lemmas_log begin text \Amortized analysis of a modified version of the pairing heaps defined by Okasaki \cite{Okasaki}.\ fun lift_hp :: "'b \ ('a hp \ 'b) \ 'a heap \ 'b" where "lift_hp c f None = c" | "lift_hp c f (Some h) = f h" fun size_hps :: "'a hp list \ nat" where "size_hps(Hp x hsl # hsr) = size_hps hsl + size_hps hsr + 1" | "size_hps [] = 0" definition size_hp :: "'a hp \ nat" where [simp]: "size_hp h = size_hps(hps h) + 1" fun \_hps :: "'a hp list \ real" where "\_hps [] = 0" | "\_hps (Hp x hsl # hsr) = \_hps hsl + \_hps hsr + log 2 (size_hps hsl + size_hps hsr + 1)" definition \_hp :: "'a hp \ real" where [simp]: "\_hp h = \_hps (hps h) + log 2 (size_hps(hps(h))+1)" abbreviation \ :: "'a heap \ real" where "\ \ lift_hp 0 \_hp" abbreviation size_heap :: "'a heap \ nat" where "size_heap \ lift_hp 0 size_hp" lemma \_hps_ge0: "\_hps hs \ 0" by (induction hs rule: size_hps.induct) auto declare algebra_simps[simp] lemma size_hps_Cons[simp]: "size_hps(h # hs) = size_hp h + size_hps hs" by(cases h) simp lemma link2: "link (Hp x lx) h = (case h of (Hp y ly) \ (if x < y then Hp x (Hp y ly # lx) else Hp y (Hp x lx # ly)))" by(simp split: hp.split) lemma size_hps_link: "size_hps(hps (link h1 h2)) = size_hp h1 + size_hp h2 - 1" by (induction rule: link.induct) simp_all lemma pass\<^sub>1_size[simp]: "size_hps (pass\<^sub>1 hs) = size_hps hs" by (induct hs rule: pass\<^sub>1.induct) (simp_all add: size_hps_link) lemma pass\<^sub>2_None[simp]: "pass\<^sub>2 hs = None \ hs = []" by(cases hs) auto lemma \\_insert: "\ (Pairing_Heap_List2.insert x h) - \ h \ log 2 (size_heap h + 1)" by(induct h)(auto simp: link2 split: hp.split) lemma \\_link: "\_hp (link h1 h2) - \_hp h1 - \_hp h2 \ 2 * log 2 (size_hp h1 + size_hp h2)" by (induction h1 h2 rule: link.induct) (simp add: add_increasing) fun sum_ub :: "'a hp list \ real" where "sum_ub [] = 0" | "sum_ub [Hp _ _] = 0" | "sum_ub [Hp _ lx, Hp _ ly] = 2*log 2 (2 + size_hps lx + size_hps ly)" | "sum_ub (Hp _ lx # Hp _ ly # ry) = 2*log 2 (2 + size_hps lx + size_hps ly + size_hps ry) - 2*log 2 (size_hps ry) - 2 + sum_ub ry" lemma \\_pass1_sum_ub: "\_hps (pass\<^sub>1 h) - \_hps h \ sum_ub h" proof (induction h rule: sum_ub.induct) case (3 lx x ly y) have 0: "\x y::real. 0 \ x \ x \ y \ x \ 2*y" by linarith show ?case by (simp add: add_increasing 0) next case (4 x hsx y hsy z hsize_hp) let ?ry = "z # hsize_hp" let ?rx = "Hp y hsy # ?ry" let ?h = "Hp x hsx # ?rx" have "\_hps(pass\<^sub>1 ?h) - \_hps ?h \ log 2 (1 + size_hps hsx + size_hps hsy) - log 2 (1 + size_hps hsy + size_hps ?ry) + sum_ub ?ry" using "4.IH" by simp also have "log 2 (1 + size_hps hsx + size_hps hsy) - log 2 (1 + size_hps hsy + size_hps ?ry) \ 2*log 2 (size_hps ?h) - 2*log 2 (size_hps ?ry) - 2" proof - have "log 2 (1 + size_hps hsx + size_hps hsy) + log 2 (size_hps ?ry) - 2*log 2 (size_hps ?h) = log 2 ((1 + size_hps hsx + size_hps hsy)/(size_hps ?h) ) + log 2 (size_hps ?ry / size_hps ?h)" by (simp add: log_divide) also have "\ \ -2" proof - have "2 + \ \ 2*log 2 ((1 + size_hps hsx + size_hps hsy) / size_hps ?h + size_hps ?ry / size_hps ?h)" using ld_sum_inequality [of "(1 + size_hps hsx + size_hps hsy) / size_hps ?h" "(size_hps ?ry / size_hps ?h)"] by simp also have "\ \ 0" by (simp add: field_simps log_divide add_pos_nonneg) finally show ?thesis by linarith qed finally have "log 2 (1 + size_hps hsx + size_hps hsy) + log 2 (size_hps ?ry) + 2 \ 2*log 2 (size_hps ?h)" by simp moreover have "log 2 (size_hps ?ry) \ log 2 (size_hps ?rx)" by simp ultimately have "log 2 (1 + size_hps hsx + size_hps hsy) - \ \ 2*log 2 (size_hps ?h) - 2*log 2 (size_hps ?ry) - 2" by linarith thus ?thesis by simp qed finally show ?case by (simp) qed simp_all lemma \\_pass1: assumes "hs \ []" shows "\_hps (pass\<^sub>1 hs) - \_hps hs \ 2 * log 2 (size_hps hs) - length hs + 2" proof - have "sum_ub hs \ 2 * log 2 (size_hps hs) - length hs + 2" using assms by (induct hs rule: sum_ub.induct) (simp_all) thus ?thesis using \\_pass1_sum_ub[of hs] by linarith qed lemma size_hps_pass2: "pass\<^sub>2 hs = Some h \ size_hps hs = size_hps(hps h)+1" apply(induction hs arbitrary: h rule: \_hps.induct) apply (auto simp: link2 split: option.split hp.split) done lemma \\_pass2: "hs \ [] \ \ (pass\<^sub>2 hs) - \_hps hs \ log 2 (size_hps hs)" proof (induction hs) case (Cons h hs) thus ?case proof - obtain x hs2 where [simp]: "h = Hp x hs2" by (metis hp.exhaust) show ?thesis proof (cases "pass\<^sub>2 hs") case [simp]: (Some h2) obtain y hs3 where [simp]: "h2 = Hp y hs3" by (metis hp.exhaust) from size_hps_pass2[OF Some] Cons show ?thesis by(cases "hs=[]")(auto simp: add_mono) qed simp qed qed simp lemma \\_del_min: assumes "hps h \ []" shows "\ (del_min (Some h)) - \ (Some h) \ 3 * log 2 (size_hps(hps h)) - length(hps h) + 2" proof - let ?\\\<^sub>1 = "\_hps(hps h) - \_hp h" let ?\\\<^sub>2 = "\(pass\<^sub>2(pass\<^sub>1 (hps h))) - \_hps (hps h)" let ?\\ = "\ (del_min (Some h)) - \ (Some h)" have "\(pass\<^sub>2(pass\<^sub>1(hps h))) - \_hps (pass\<^sub>1(hps h)) \ log 2 (size_hps(hps h))" using \\_pass2[of "pass\<^sub>1(hps h)"] using size_hps.elims assms by force moreover have "\_hps (pass\<^sub>1 (hps h)) - \_hps (hps h) \ 2*\ - length (hps h) + 2" using \\_pass1[OF assms] by blast moreover have "?\\\<^sub>1 \ 0" by (cases h) simp moreover have "?\\ = ?\\\<^sub>1 + ?\\\<^sub>2" by (cases h) simp ultimately show ?thesis by linarith qed fun exec :: "'a :: linorder op \ 'a heap list \ 'a heap" where "exec Empty [] = None" | "exec Del_min [h] = del_min h" | "exec (Insert x) [h] = Pairing_Heap_List2.insert x h" | "exec Merge [h1,h2] = merge h1 h2" -fun t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 :: "'a hp list \ nat" where - "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [] = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [_] = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (_ # _ # hs) = 1 + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" +fun T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 :: "'a hp list \ nat" where + "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [] = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 [_] = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (_ # _ # hs) = 1 + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" -fun t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 :: "'a hp list \ nat" where - "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 [] = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (_ # hs) = 1 + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 hs" +fun T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 :: "'a hp list \ nat" where +"T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 [] = 1" | +"T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (_ # hs) = 1 + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 hs" fun cost :: "'a :: linorder op \ 'a heap list \ nat" where "cost Empty _ = 1" | "cost Del_min [None] = 1" | -"cost Del_min [Some(Hp x hs)] = 1 + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" | +"cost Del_min [Some(Hp x hs)] = 1 + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs" | "cost (Insert a) _ = 1" | "cost Merge _ = 1" fun U :: "'a :: linorder op \ 'a heap list \ real" where "U Empty _ = 1" | "U (Insert a) [h] = log 2 (size_heap h + 1) + 1" | "U Del_min [h] = 3*log 2 (size_heap h + 1) + 5" | "U Merge [h1,h2] = 2*log 2 (size_heap h1 + size_heap h2 + 1) + 1" interpretation pairing: Amortized where arity = arity and exec = exec and cost = cost and inv = "\_. True" and \ = \ and U = U proof (standard, goal_cases) case (2 s) show ?case by (cases s) (auto simp: \_hps_ge0) next case (3 ss f) show ?case proof (cases f) case Empty with 3 show ?thesis by(auto) next case Insert thus ?thesis using Insert \\_insert 3 by auto next case [simp]: Del_min then obtain ho where [simp]: "ss = [ho]" using 3 by auto show ?thesis proof (cases ho) case [simp]: (Some h) show ?thesis proof (cases h) case [simp]: (Hp x hs) - have "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs \ 2 + length hs" + have "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 hs) + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 hs \ 2 + length hs" by (induct hs rule: pass\<^sub>1.induct) simp_all hence "cost f ss \ 1 + \" by simp moreover have "\ (del_min ho) - \ ho \ 3*log 2 (size_heap ho + 1) - length hs + 2" proof (cases "hs = []") case False hence "\ (del_min ho) - \ ho \ 3*log 2 (size_hps hs) - length hs + 2" using \\_del_min[of h] by simp also have "\ \ 3*log 2 (size_heap ho + 1) - length hs + 2" using False size_hps.elims by force finally show ?thesis . qed simp ultimately show ?thesis by simp qed qed simp next case [simp]: Merge then obtain ho1 ho2 where [simp]: "ss = [ho1, ho2]" using 3 by(auto simp: numeral_eq_Suc) show ?thesis proof (cases "ho1 = None \ ho2 = None") case True thus ?thesis by auto next case False then obtain h1 h2 where [simp]: "ho1 = Some h1" "ho2 = Some h2" by auto have "\ (merge ho1 ho2) - \ ho1 - \ ho2 \ 2 * log 2 (size_heap ho1 + size_heap ho2)" using \\_link[of h1 h2] by simp also have "\ \ 2 * log 2 (size_hp h1 + size_hp h2 + 1)" by (simp) finally show ?thesis by(simp) qed qed qed simp end diff --git a/thys/Amortized_Complexity/Pairing_Heap_Tree_Analysis.thy b/thys/Amortized_Complexity/Pairing_Heap_Tree_Analysis.thy --- a/thys/Amortized_Complexity/Pairing_Heap_Tree_Analysis.thy +++ b/thys/Amortized_Complexity/Pairing_Heap_Tree_Analysis.thy @@ -1,268 +1,268 @@ (* Author: Hauke Brinkop and Tobias Nipkow *) section \Pairing Heaps\ subsection \Binary Tree Representation\ theory Pairing_Heap_Tree_Analysis imports Pairing_Heap.Pairing_Heap_Tree Amortized_Framework Priority_Queue_ops_merge Lemmas_log begin text \Verification of logarithmic bounds on the amortized complexity of pairing heaps \cite{FredmanSST86,Brinkop}.\ fun len :: "'a tree \ nat" where "len Leaf = 0" | "len (Node _ _ r) = 1 + len r" fun \ :: "'a tree \ real" where "\ Leaf = 0" | "\ (Node l _ r) = \ l + \ r + log 2 (1 + size l + size r)" lemma link_size[simp]: "size (link h) = size h" by (cases h rule: link.cases) simp_all lemma size_pass\<^sub>1: "size (pass\<^sub>1 h) = size h" by (induct h rule: pass\<^sub>1.induct) simp_all lemma size_pass\<^sub>2: "size (pass\<^sub>2 h) = size h" by (induct h rule: pass\<^sub>2.induct) simp_all lemma size_merge: "is_root h1 \ is_root h2 \ size (merge h1 h2) = size h1 + size h2" by (simp split: tree.splits) lemma \\_insert: "is_root h \ \ (insert x h) - \ h \ log 2 (size h + 1)" by (simp split: tree.splits) lemma \\_merge: assumes "h1 = Node lx x Leaf" "h2 = Node ly y Leaf" shows "\ (merge h1 h2) - \ h1 - \ h2 \ log 2 (size h1 + size h2) + 1" proof - let ?hs = "Node lx x (Node ly y Leaf)" have "\ (merge h1 h2) = \ (link ?hs)" using assms by simp also have "\ = \ lx + \ ly + log 2 (size lx + size ly + 1) + log 2 (size lx + size ly + 2)" by (simp add: algebra_simps) also have "\ = \ lx + \ ly + log 2 (size lx + size ly + 1) + log 2 (size h1 + size h2)" using assms by simp finally have "\ (merge h1 h2) = \" . have "\ (merge h1 h2) - \ h1 - \ h2 = log 2 (size lx + size ly + 1) + log 2 (size h1 + size h2) - log 2 (size lx + 1) - log 2 (size ly + 1)" using assms by (simp add: algebra_simps) also have "\ \ log 2 (size h1 + size h2) + 1" using ld_le_2ld[of "size lx" "size ly"] assms by (simp add: algebra_simps) finally show ?thesis . qed fun upperbound :: "'a tree \ real" where "upperbound Leaf = 0" | "upperbound (Node _ _ Leaf) = 0" | "upperbound (Node lx _ (Node ly _ Leaf)) = 2*log 2 (size lx + size ly + 2)" | "upperbound (Node lx _ (Node ly _ ry)) = 2*log 2 (size lx + size ly + size ry + 2) - 2*log 2 (size ry) - 2 + upperbound ry" lemma \\_pass1_upperbound: "\ (pass\<^sub>1 hs) - \ hs \ upperbound hs" proof (induction hs rule: upperbound.induct) case (3 lx x ly y) have "log 2 (size lx + size ly + 1) - log 2 (size ly + 1) \ log 2 (size lx + size ly + 1)" by simp also have "\ \ log 2 (size lx + size ly + 2)" by simp also have "\ \ 2*\" by simp finally show ?case by (simp add: algebra_simps) next case (4 lx x ly y lz z rz) let ?ry = "Node lz z rz" let ?rx = "Node ly y ?ry" let ?h = "Node lx x ?rx" let ?t ="log 2 (size lx + size ly + 1) - log 2 (size ly + size ?ry + 1)" have "\ (pass\<^sub>1 ?h) - \ ?h \ ?t + upperbound ?ry" using "4.IH" by (simp add: size_pass\<^sub>1 algebra_simps) moreover have "log 2 (size lx + size ly + 1) + 2 * log 2 (size ?ry) + 2 \ 2 * log 2 (size ?h) + log 2 (size ly + size ?ry + 1)" (is "?l \ ?r") proof - have "?l \ 2 * log 2 (size lx + size ly + size ?ry + 1) + log 2 (size ?ry)" using ld_sum_inequality [of "size lx + size ly + 1" "size ?ry"] by simp also have "\ \ 2 * log 2 (size lx + size ly + size ?ry + 2) + log 2 (size ?ry)" by simp also have "\ \ ?r" by simp finally show ?thesis . qed ultimately show ?case by simp qed simp_all lemma \\_pass1: assumes "hs \ Leaf" shows "\ (pass\<^sub>1 hs) - \ hs \ 2*log 2 (size hs) - len hs + 2" proof - from assms have "upperbound hs \ 2*log 2 (size hs) - len hs + 2" by (induct hs rule: upperbound.induct) (simp_all add: algebra_simps) thus ?thesis using \\_pass1_upperbound [of "hs"] order_trans by blast qed lemma \\_pass2: "hs \ Leaf \ \ (pass\<^sub>2 hs) - \ hs \ log 2 (size hs)" proof (induction hs) case (Node lx x rx) thus ?case proof (cases rx) case 1: (Node ly y ry) let ?h = "Node lx x rx" obtain la a where 2: "pass\<^sub>2 rx = Node la a Leaf" using pass\<^sub>2_struct 1 by force hence 3: "size rx = size \" using size_pass\<^sub>2 by metis have link: "\(link(Node lx x (pass\<^sub>2 rx))) - \ lx - \ (pass\<^sub>2 rx) = log 2 (size lx + size rx + 1) + log 2 (size lx + size rx) - log 2 (size rx)" using 2 3 by (simp add: algebra_simps) have "\ (pass\<^sub>2 ?h) - \ ?h = \ (link (Node lx x (pass\<^sub>2 rx))) - \ lx - \ rx - log 2 (size lx + size rx + 1)" by (simp) also have "\ = \ (pass\<^sub>2 rx) - \ rx + log 2 (size lx + size rx) - log 2 (size rx)" using link by linarith also have "\ \ log 2 (size lx + size rx)" using Node.IH 1 by simp also have "\ \ log 2 (size ?h)" using 1 by simp finally show ?thesis . qed simp qed simp lemma \\_mergepairs: assumes "hs \ Leaf" shows "\ (merge_pairs hs) - \ hs \ 3 * log 2 (size hs) - len hs + 2" proof - have "pass\<^sub>1 hs \ Leaf" by (metis assms eq_size_0 size_pass\<^sub>1) with assms \\_pass1[of hs] \\_pass2[of "pass\<^sub>1 hs"] show ?thesis by (auto simp add: size_pass\<^sub>1 pass12_merge_pairs) qed lemma \\_del_min: assumes "lx \ Leaf" shows "\ (del_min (Node lx x Leaf)) - \ (Node lx x Leaf) \ 3*log 2 (size lx) - len lx + 2" proof - let ?h = "Node lx x Leaf" let ?\\\<^sub>1 = "\ lx - \ ?h" let ?\\\<^sub>2 = "\(pass\<^sub>2(pass\<^sub>1 lx)) - \ lx" let ?\\ = "\ (del_min ?h) - \ ?h" have "lx \ Leaf \ \(pass\<^sub>2(pass\<^sub>1 lx)) - \ (pass\<^sub>1 lx) \ log 2 (size lx)" using \\_pass2 [of "pass\<^sub>1 lx"] by(metis eq_size_0 size_pass\<^sub>1) moreover have "lx \ Leaf \ \ (pass\<^sub>1 lx) - \ lx \ 2*\ - len lx + 2" using \\_pass1 by metis moreover have "?\\ \ ?\\\<^sub>2" by simp ultimately show ?thesis using assms by linarith qed lemma is_root_merge: "is_root h1 \ is_root h2 \ is_root (merge h1 h2)" by (simp split: tree.splits) lemma is_root_insert: "is_root h \ is_root (insert x h)" by (simp split: tree.splits) lemma is_root_del_min: assumes "is_root h" shows "is_root (del_min h)" proof (cases h) case [simp]: (Node lx x rx) have "rx = Leaf" using assms by simp thus ?thesis proof (cases lx) case (Node ly y ry) then obtain la a ra where "pass\<^sub>1 lx = Node a la ra" using pass\<^sub>1_struct by blast moreover obtain lb b where "pass\<^sub>2 \ = Node b lb Leaf" using pass\<^sub>2_struct by blast ultimately show ?thesis using assms by simp qed simp qed simp lemma pass\<^sub>1_len: "len (pass\<^sub>1 h) \ len h" by (induct h rule: pass\<^sub>1.induct) simp_all fun exec :: "'a :: linorder op \ 'a tree list \ 'a tree" where "exec Empty [] = Leaf" | "exec Del_min [h] = del_min h" | "exec (Insert x) [h] = insert x h" | "exec Merge [h1,h2] = merge h1 h2" -fun t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 :: "'a tree \ nat" where - "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 Leaf = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (Node _ _ Leaf) = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (Node _ _ (Node _ _ ry)) = t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 ry + 1" +fun T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 :: "'a tree \ nat" where + "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 Leaf = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (Node _ _ Leaf) = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 (Node _ _ (Node _ _ ry)) = T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 ry + 1" -fun t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 :: "'a tree \ nat" where - "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 Leaf = 1" -| "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (Node _ _ rx) = t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 rx + 1" +fun T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 :: "'a tree \ nat" where + "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 Leaf = 1" +| "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (Node _ _ rx) = T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 rx + 1" fun cost :: "'a :: linorder op \ 'a tree list \ nat" where "cost Empty [] = 1" | "cost Del_min [Leaf] = 1" -| "cost Del_min [Node lx _ _] = t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 lx) + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 lx" +| "cost Del_min [Node lx _ _] = T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 lx) + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 lx" | "cost (Insert a) _ = 1" | "cost Merge _ = 1" fun U :: "'a :: linorder op \ 'a tree list \ real" where "U Empty [] = 1" | "U (Insert a) [h] = log 2 (size h + 1) + 1" | "U Del_min [h] = 3*log 2 (size h + 1) + 4" | "U Merge [h1,h2] = log 2 (size h1 + size h2 + 1) + 2" interpretation Amortized where arity = arity and exec = exec and cost = cost and inv = is_root and \ = \ and U = U proof (standard, goal_cases) case (1 _ f) thus ?case using is_root_insert is_root_del_min is_root_merge by (cases f) (auto simp: numeral_eq_Suc) next case (2 s) show ?case by (induct s) simp_all next case (3 ss f) show ?case proof (cases f) case Empty with 3 show ?thesis by(auto) next case (Insert x) then obtain h where "ss = [h]" "is_root h" using 3 by auto thus ?thesis using Insert \\_insert 3 by auto next case [simp]: (Del_min) then obtain h where [simp]: "ss = [h]" using 3 by auto show ?thesis proof (cases h) case [simp]: (Node lx x rx) - have "t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 lx) + t\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 lx \ len lx + 2" + have "T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>2 (pass\<^sub>1 lx) + T\<^sub>p\<^sub>a\<^sub>s\<^sub>s\<^sub>1 lx \ len lx + 2" by (induct lx rule: pass\<^sub>1.induct) simp_all hence "cost f ss \ \" by simp moreover have "\ (del_min h) - \ h \ 3*log 2 (size h + 1) - len lx + 2" proof (cases lx) case [simp]: (Node ly y ry) have "\ (del_min h) - \ h \ 3*log 2 (size lx) - len lx + 2" using \\_del_min[of "lx" "x"] 3 by simp also have "\ \ 3*log 2 (size h + 1) - len lx + 2" by fastforce finally show ?thesis by blast qed (insert 3, simp) ultimately show ?thesis by auto qed simp next case [simp]: Merge then obtain h1 h2 where [simp]: "ss = [h1,h2]" and 1: "is_root h1" "is_root h2" using 3 by (auto simp: numeral_eq_Suc) show ?thesis proof (cases h1) case Leaf thus ?thesis by (cases h2) auto next case h1: Node show ?thesis proof (cases h2) case Leaf thus ?thesis using h1 by simp next case h2: Node have "\ (merge h1 h2) - \ h1 - \ h2 \ log 2 (real (size h1 + size h2)) + 1" apply(rule \\_merge) using h1 h2 1 by auto also have "\ \ log 2 (size h1 + size h2 + 1) + 1" by (simp add: h1) finally show ?thesis by(simp add: algebra_simps) qed qed qed qed end