src/HOL/Data_Structures/Binomial_Heap.thy
changeset 72550 1d0ae7e578a0
parent 70607 b044a06ad0d6
child 72551 729d45c7ff33
equal deleted inserted replaced
72549:726d17b280ea 72550:1d0ae7e578a0
   324   assumes "ts\<noteq>[]"
   324   assumes "ts\<noteq>[]"
   325   shows "mset ts = {#t'#} + mset ts'"
   325   shows "mset ts = {#t'#} + mset ts'"
   326 using assms
   326 using assms
   327 by (induction ts arbitrary: t' ts' rule: get_min.induct) (auto split: prod.splits if_splits)
   327 by (induction ts arbitrary: t' ts' rule: get_min.induct) (auto split: prod.splits if_splits)
   328 
   328 
   329 lemma set_get_min_rest:
   329 lemma seT_get_min_rest:
   330   assumes "get_min_rest ts = (t', ts')"
   330   assumes "get_min_rest ts = (t', ts')"
   331   assumes "ts\<noteq>[]"
   331   assumes "ts\<noteq>[]"
   332   shows "set ts = Set.insert t' (set ts')"
   332   shows "set ts = Set.insert t' (set ts')"
   333 using mset_get_min_rest[OF assms, THEN arg_cong[where f=set_mset]]
   333 using mset_get_min_rest[OF assms, THEN arg_cong[where f=set_mset]]
   334 by auto
   334 by auto
   343     using assms
   343     using assms
   344     proof (induction ts arbitrary: t' ts' rule: get_min.induct)
   344     proof (induction ts arbitrary: t' ts' rule: get_min.induct)
   345       case (2 t v va)
   345       case (2 t v va)
   346       then show ?case
   346       then show ?case
   347         apply (clarsimp split: prod.splits if_splits)
   347         apply (clarsimp split: prod.splits if_splits)
   348         apply (drule set_get_min_rest; fastforce)
   348         apply (drule seT_get_min_rest; fastforce)
   349         done
   349         done
   350     qed auto
   350     qed auto
   351   thus "invar_btree t'" and "invar_bheap ts'" by auto
   351   thus "invar_btree t'" and "invar_bheap ts'" by auto
   352 qed
   352 qed
   353 
   353 
   480 
   480 
   481 text \<open>
   481 text \<open>
   482   We define timing functions for each operation, and provide
   482   We define timing functions for each operation, and provide
   483   estimations of their complexity.
   483   estimations of their complexity.
   484 \<close>
   484 \<close>
   485 definition t_link :: "'a::linorder tree \<Rightarrow> 'a tree \<Rightarrow> nat" where
   485 definition T_link :: "'a::linorder tree \<Rightarrow> 'a tree \<Rightarrow> nat" where
   486 [simp]: "t_link _ _ = 1"
   486 [simp]: "T_link _ _ = 1"
   487 
   487 
   488 fun t_ins_tree :: "'a::linorder tree \<Rightarrow> 'a heap \<Rightarrow> nat" where
   488 fun T_ins_tree :: "'a::linorder tree \<Rightarrow> 'a heap \<Rightarrow> nat" where
   489   "t_ins_tree t [] = 1"
   489   "T_ins_tree t [] = 1"
   490 | "t_ins_tree t\<^sub>1 (t\<^sub>2 # rest) = (
   490 | "T_ins_tree t\<^sub>1 (t\<^sub>2 # rest) = (
   491     (if rank t\<^sub>1 < rank t\<^sub>2 then 1
   491     (if rank t\<^sub>1 < rank t\<^sub>2 then 1
   492      else t_link t\<^sub>1 t\<^sub>2 + t_ins_tree (link t\<^sub>1 t\<^sub>2) rest)
   492      else T_link t\<^sub>1 t\<^sub>2 + T_ins_tree (link t\<^sub>1 t\<^sub>2) rest)
   493   )"
   493   )"
   494 
   494 
   495 definition t_insert :: "'a::linorder \<Rightarrow> 'a heap \<Rightarrow> nat" where
   495 definition T_insert :: "'a::linorder \<Rightarrow> 'a heap \<Rightarrow> nat" where
   496 "t_insert x ts = t_ins_tree (Node 0 x []) ts"
   496 "T_insert x ts = T_ins_tree (Node 0 x []) ts"
   497 
   497 
   498 lemma t_ins_tree_simple_bound: "t_ins_tree t ts \<le> length ts + 1"
   498 lemma T_ins_tree_simple_bound: "T_ins_tree t ts \<le> length ts + 1"
   499 by (induction t ts rule: t_ins_tree.induct) auto
   499 by (induction t ts rule: T_ins_tree.induct) auto
   500 
   500 
   501 subsubsection \<open>\<open>t_insert\<close>\<close>
   501 subsubsection \<open>\<open>T_insert\<close>\<close>
   502 
   502 
   503 lemma t_insert_bound:
   503 lemma T_insert_bound:
   504   assumes "invar ts"
   504   assumes "invar ts"
   505   shows "t_insert x ts \<le> log 2 (size (mset_heap ts) + 1) + 1"
   505   shows "T_insert x ts \<le> log 2 (size (mset_heap ts) + 1) + 1"
   506 proof -
   506 proof -
   507 
   507 
   508   have 1: "t_insert x ts \<le> length ts + 1"
   508   have 1: "T_insert x ts \<le> length ts + 1"
   509     unfolding t_insert_def by (rule t_ins_tree_simple_bound)
   509     unfolding T_insert_def by (rule T_ins_tree_simple_bound)
   510   also have "\<dots> \<le> log 2 (2 * (size (mset_heap ts) + 1))"
   510   also have "\<dots> \<le> log 2 (2 * (size (mset_heap ts) + 1))"
   511   proof -
   511   proof -
   512     from size_mset_bheap[of ts] assms
   512     from size_mset_bheap[of ts] assms
   513     have "2 ^ length ts \<le> size (mset_heap ts) + 1"
   513     have "2 ^ length ts \<le> size (mset_heap ts) + 1"
   514       unfolding invar_def by auto
   514       unfolding invar_def by auto
   517   qed
   517   qed
   518   finally show ?thesis
   518   finally show ?thesis
   519     by (simp only: log_mult of_nat_mult) auto
   519     by (simp only: log_mult of_nat_mult) auto
   520 qed
   520 qed
   521 
   521 
   522 subsubsection \<open>\<open>t_merge\<close>\<close>
   522 subsubsection \<open>\<open>T_merge\<close>\<close>
   523 
   523 
   524 context
   524 context
   525 includes pattern_aliases
   525 includes pattern_aliases
   526 begin
   526 begin
   527 
   527 
   528 fun t_merge :: "'a::linorder heap \<Rightarrow> 'a heap \<Rightarrow> nat" where
   528 fun T_merge :: "'a::linorder heap \<Rightarrow> 'a heap \<Rightarrow> nat" where
   529   "t_merge ts\<^sub>1 [] = 1"
   529   "T_merge ts\<^sub>1 [] = 1"
   530 | "t_merge [] ts\<^sub>2 = 1"
   530 | "T_merge [] ts\<^sub>2 = 1"
   531 | "t_merge (t\<^sub>1#ts\<^sub>1 =: h\<^sub>1) (t\<^sub>2#ts\<^sub>2 =: h\<^sub>2) = 1 + (
   531 | "T_merge (t\<^sub>1#ts\<^sub>1 =: h\<^sub>1) (t\<^sub>2#ts\<^sub>2 =: h\<^sub>2) = 1 + (
   532     if rank t\<^sub>1 < rank t\<^sub>2 then t_merge ts\<^sub>1 h\<^sub>2
   532     if rank t\<^sub>1 < rank t\<^sub>2 then T_merge ts\<^sub>1 h\<^sub>2
   533     else if rank t\<^sub>2 < rank t\<^sub>1 then t_merge h\<^sub>1 ts\<^sub>2
   533     else if rank t\<^sub>2 < rank t\<^sub>1 then T_merge h\<^sub>1 ts\<^sub>2
   534     else t_ins_tree (link t\<^sub>1 t\<^sub>2) (merge ts\<^sub>1 ts\<^sub>2) + t_merge ts\<^sub>1 ts\<^sub>2
   534     else T_ins_tree (link t\<^sub>1 t\<^sub>2) (merge ts\<^sub>1 ts\<^sub>2) + T_merge ts\<^sub>1 ts\<^sub>2
   535   )"
   535   )"
   536 
   536 
   537 end
   537 end
   538 
   538 
   539 text \<open>A crucial idea is to estimate the time in correlation with the
   539 text \<open>A crucial idea is to estimate the time in correlation with the
   540   result length, as each carry reduces the length of the result.\<close>
   540   result length, as each carry reduces the length of the result.\<close>
   541 
   541 
   542 lemma t_ins_tree_length:
   542 lemma T_ins_tree_length:
   543   "t_ins_tree t ts + length (ins_tree t ts) = 2 + length ts"
   543   "T_ins_tree t ts + length (ins_tree t ts) = 2 + length ts"
   544 by (induction t ts rule: ins_tree.induct) auto
   544 by (induction t ts rule: ins_tree.induct) auto
   545 
   545 
   546 lemma t_merge_length:
   546 lemma T_merge_length:
   547   "length (merge ts\<^sub>1 ts\<^sub>2) + t_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1"
   547   "length (merge ts\<^sub>1 ts\<^sub>2) + T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1"
   548 by (induction ts\<^sub>1 ts\<^sub>2 rule: t_merge.induct)
   548 by (induction ts\<^sub>1 ts\<^sub>2 rule: T_merge.induct)
   549    (auto simp: t_ins_tree_length algebra_simps)
   549    (auto simp: T_ins_tree_length algebra_simps)
   550 
   550 
   551 text \<open>Finally, we get the desired logarithmic bound\<close>
   551 text \<open>Finally, we get the desired logarithmic bound\<close>
   552 lemma t_merge_bound_aux:
   552 lemma T_merge_bound_aux:
   553   fixes ts\<^sub>1 ts\<^sub>2
   553   fixes ts\<^sub>1 ts\<^sub>2
   554   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
   554   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
   555   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
   555   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
   556   assumes BINVARS: "invar_bheap ts\<^sub>1" "invar_bheap ts\<^sub>2"
   556   assumes BINVARS: "invar_bheap ts\<^sub>1" "invar_bheap ts\<^sub>2"
   557   shows "t_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
   557   shows "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
   558 proof -
   558 proof -
   559   define n where "n = n\<^sub>1 + n\<^sub>2"
   559   define n where "n = n\<^sub>1 + n\<^sub>2"
   560 
   560 
   561   from t_merge_length[of ts\<^sub>1 ts\<^sub>2]
   561   from T_merge_length[of ts\<^sub>1 ts\<^sub>2]
   562   have "t_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1" by auto
   562   have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1" by auto
   563   hence "(2::nat)^t_merge ts\<^sub>1 ts\<^sub>2 \<le> 2^(2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1)"
   563   hence "(2::nat)^T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2^(2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1)"
   564     by (rule power_increasing) auto
   564     by (rule power_increasing) auto
   565   also have "\<dots> = 2*(2^length ts\<^sub>1)\<^sup>2*(2^length ts\<^sub>2)\<^sup>2"
   565   also have "\<dots> = 2*(2^length ts\<^sub>1)\<^sup>2*(2^length ts\<^sub>2)\<^sup>2"
   566     by (auto simp: algebra_simps power_add power_mult)
   566     by (auto simp: algebra_simps power_add power_mult)
   567   also note BINVARS(1)[THEN size_mset_bheap]
   567   also note BINVARS(1)[THEN size_mset_bheap]
   568   also note BINVARS(2)[THEN size_mset_bheap]
   568   also note BINVARS(2)[THEN size_mset_bheap]
   569   finally have "2 ^ t_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (n\<^sub>1 + 1)\<^sup>2 * (n\<^sub>2 + 1)\<^sup>2"
   569   finally have "2 ^ T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (n\<^sub>1 + 1)\<^sup>2 * (n\<^sub>2 + 1)\<^sup>2"
   570     by (auto simp: power2_nat_le_eq_le n\<^sub>1_def n\<^sub>2_def)
   570     by (auto simp: power2_nat_le_eq_le n\<^sub>1_def n\<^sub>2_def)
   571   from le_log2_of_power[OF this] have "t_merge ts\<^sub>1 ts\<^sub>2 \<le> log 2 \<dots>"
   571   from le_log2_of_power[OF this] have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> log 2 \<dots>"
   572     by simp
   572     by simp
   573   also have "\<dots> = log 2 2 + 2*log 2 (n\<^sub>1 + 1) + 2*log 2 (n\<^sub>2 + 1)"
   573   also have "\<dots> = log 2 2 + 2*log 2 (n\<^sub>1 + 1) + 2*log 2 (n\<^sub>2 + 1)"
   574     by (simp add: log_mult log_nat_power)
   574     by (simp add: log_mult log_nat_power)
   575   also have "n\<^sub>2 \<le> n" by (auto simp: n_def)
   575   also have "n\<^sub>2 \<le> n" by (auto simp: n_def)
   576   finally have "t_merge ts\<^sub>1 ts\<^sub>2 \<le> log 2 2 + 2*log 2 (n\<^sub>1 + 1) + 2*log 2 (n + 1)"
   576   finally have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> log 2 2 + 2*log 2 (n\<^sub>1 + 1) + 2*log 2 (n + 1)"
   577     by auto
   577     by auto
   578   also have "n\<^sub>1 \<le> n" by (auto simp: n_def)
   578   also have "n\<^sub>1 \<le> n" by (auto simp: n_def)
   579   finally have "t_merge ts\<^sub>1 ts\<^sub>2 \<le> log 2 2 + 4*log 2 (n + 1)"
   579   finally have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> log 2 2 + 4*log 2 (n + 1)"
   580     by auto
   580     by auto
   581   also have "log 2 2 \<le> 2" by auto
   581   also have "log 2 2 \<le> 2" by auto
   582   finally have "t_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n + 1) + 2" by auto
   582   finally have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n + 1) + 2" by auto
   583   thus ?thesis unfolding n_def by (auto simp: algebra_simps)
   583   thus ?thesis unfolding n_def by (auto simp: algebra_simps)
   584 qed
   584 qed
   585 
   585 
   586 lemma t_merge_bound:
   586 lemma T_merge_bound:
   587   fixes ts\<^sub>1 ts\<^sub>2
   587   fixes ts\<^sub>1 ts\<^sub>2
   588   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
   588   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
   589   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
   589   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
   590   assumes "invar ts\<^sub>1" "invar ts\<^sub>2"
   590   assumes "invar ts\<^sub>1" "invar ts\<^sub>2"
   591   shows "t_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
   591   shows "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
   592 using assms t_merge_bound_aux unfolding invar_def by blast
   592 using assms T_merge_bound_aux unfolding invar_def by blast
   593 
   593 
   594 subsubsection \<open>\<open>t_get_min\<close>\<close>
   594 subsubsection \<open>\<open>T_get_min\<close>\<close>
   595 
   595 
   596 fun t_get_min :: "'a::linorder heap \<Rightarrow> nat" where
   596 fun T_get_min :: "'a::linorder heap \<Rightarrow> nat" where
   597   "t_get_min [t] = 1"
   597   "T_get_min [t] = 1"
   598 | "t_get_min (t#ts) = 1 + t_get_min ts"
   598 | "T_get_min (t#ts) = 1 + T_get_min ts"
   599 
   599 
   600 lemma t_get_min_estimate: "ts\<noteq>[] \<Longrightarrow> t_get_min ts = length ts"
   600 lemma T_get_min_estimate: "ts\<noteq>[] \<Longrightarrow> T_get_min ts = length ts"
   601 by (induction ts rule: t_get_min.induct) auto
   601 by (induction ts rule: T_get_min.induct) auto
   602 
   602 
   603 lemma t_get_min_bound:
   603 lemma T_get_min_bound:
   604   assumes "invar ts"
   604   assumes "invar ts"
   605   assumes "ts\<noteq>[]"
   605   assumes "ts\<noteq>[]"
   606   shows "t_get_min ts \<le> log 2 (size (mset_heap ts) + 1)"
   606   shows "T_get_min ts \<le> log 2 (size (mset_heap ts) + 1)"
   607 proof -
   607 proof -
   608   have 1: "t_get_min ts = length ts" using assms t_get_min_estimate by auto
   608   have 1: "T_get_min ts = length ts" using assms T_get_min_estimate by auto
   609   also have "\<dots> \<le> log 2 (size (mset_heap ts) + 1)"
   609   also have "\<dots> \<le> log 2 (size (mset_heap ts) + 1)"
   610   proof -
   610   proof -
   611     from size_mset_bheap[of ts] assms have "2 ^ length ts \<le> size (mset_heap ts) + 1"
   611     from size_mset_bheap[of ts] assms have "2 ^ length ts \<le> size (mset_heap ts) + 1"
   612       unfolding invar_def by auto
   612       unfolding invar_def by auto
   613     thus ?thesis using le_log2_of_power by blast
   613     thus ?thesis using le_log2_of_power by blast
   614   qed
   614   qed
   615   finally show ?thesis by auto
   615   finally show ?thesis by auto
   616 qed
   616 qed
   617 
   617 
   618 subsubsection \<open>\<open>t_del_min\<close>\<close>
   618 subsubsection \<open>\<open>T_del_min\<close>\<close>
   619 
   619 
   620 fun t_get_min_rest :: "'a::linorder heap \<Rightarrow> nat" where
   620 fun T_get_min_rest :: "'a::linorder heap \<Rightarrow> nat" where
   621   "t_get_min_rest [t] = 1"
   621   "T_get_min_rest [t] = 1"
   622 | "t_get_min_rest (t#ts) = 1 + t_get_min_rest ts"
   622 | "T_get_min_rest (t#ts) = 1 + T_get_min_rest ts"
   623 
   623 
   624 lemma t_get_min_rest_estimate: "ts\<noteq>[] \<Longrightarrow> t_get_min_rest ts = length ts"
   624 lemma T_get_min_rest_estimate: "ts\<noteq>[] \<Longrightarrow> T_get_min_rest ts = length ts"
   625   by (induction ts rule: t_get_min_rest.induct) auto
   625   by (induction ts rule: T_get_min_rest.induct) auto
   626 
   626 
   627 lemma t_get_min_rest_bound_aux:
   627 lemma T_get_min_rest_bound_aux:
   628   assumes "invar_bheap ts"
   628   assumes "invar_bheap ts"
   629   assumes "ts\<noteq>[]"
   629   assumes "ts\<noteq>[]"
   630   shows "t_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
   630   shows "T_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
   631 proof -
   631 proof -
   632   have 1: "t_get_min_rest ts = length ts" using assms t_get_min_rest_estimate by auto
   632   have 1: "T_get_min_rest ts = length ts" using assms T_get_min_rest_estimate by auto
   633   also have "\<dots> \<le> log 2 (size (mset_heap ts) + 1)"
   633   also have "\<dots> \<le> log 2 (size (mset_heap ts) + 1)"
   634   proof -
   634   proof -
   635     from size_mset_bheap[of ts] assms have "2 ^ length ts \<le> size (mset_heap ts) + 1"
   635     from size_mset_bheap[of ts] assms have "2 ^ length ts \<le> size (mset_heap ts) + 1"
   636       by auto
   636       by auto
   637     thus ?thesis using le_log2_of_power by blast
   637     thus ?thesis using le_log2_of_power by blast
   638   qed
   638   qed
   639   finally show ?thesis by auto
   639   finally show ?thesis by auto
   640 qed
   640 qed
   641 
   641 
   642 lemma t_get_min_rest_bound:
   642 lemma T_get_min_rest_bound:
   643   assumes "invar ts"
   643   assumes "invar ts"
   644   assumes "ts\<noteq>[]"
   644   assumes "ts\<noteq>[]"
   645   shows "t_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
   645   shows "T_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
   646 using assms t_get_min_rest_bound_aux unfolding invar_def by blast
   646 using assms T_get_min_rest_bound_aux unfolding invar_def by blast
   647 
   647 
   648 text\<open>Note that although the definition of function \<^const>\<open>rev\<close> has quadratic complexity,
   648 text\<open>Note that although the definition of function \<^const>\<open>rev\<close> has quadratic complexity,
   649 it can and is implemented (via suitable code lemmas) as a linear time function.
   649 it can and is implemented (via suitable code lemmas) as a linear time function.
   650 Thus the following definition is justified:\<close>
   650 Thus the following definition is justified:\<close>
   651 
   651 
   652 definition "t_rev xs = length xs + 1"
   652 definition "T_rev xs = length xs + 1"
   653 
   653 
   654 definition t_del_min :: "'a::linorder heap \<Rightarrow> nat" where
   654 definition T_del_min :: "'a::linorder heap \<Rightarrow> nat" where
   655   "t_del_min ts = t_get_min_rest ts + (case get_min_rest ts of (Node _ x ts\<^sub>1, ts\<^sub>2)
   655   "T_del_min ts = T_get_min_rest ts + (case get_min_rest ts of (Node _ x ts\<^sub>1, ts\<^sub>2)
   656                     \<Rightarrow> t_rev ts\<^sub>1 + t_merge (rev ts\<^sub>1) ts\<^sub>2
   656                     \<Rightarrow> T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2
   657   )"
   657   )"
   658 
   658 
   659 lemma t_rev_ts1_bound_aux:
   659 lemma T_rev_ts1_bound_aux:
   660   fixes ts
   660   fixes ts
   661   defines "n \<equiv> size (mset_heap ts)"
   661   defines "n \<equiv> size (mset_heap ts)"
   662   assumes BINVAR: "invar_bheap (rev ts)"
   662   assumes BINVAR: "invar_bheap (rev ts)"
   663   shows "t_rev ts \<le> 1 + log 2 (n+1)"
   663   shows "T_rev ts \<le> 1 + log 2 (n+1)"
   664 proof -
   664 proof -
   665   have "t_rev ts = length ts + 1" by (auto simp: t_rev_def)
   665   have "T_rev ts = length ts + 1" by (auto simp: T_rev_def)
   666   hence "2^t_rev ts = 2*2^length ts" by auto
   666   hence "2^T_rev ts = 2*2^length ts" by auto
   667   also have "\<dots> \<le> 2*n+2" using size_mset_bheap[OF BINVAR] by (auto simp: n_def)
   667   also have "\<dots> \<le> 2*n+2" using size_mset_bheap[OF BINVAR] by (auto simp: n_def)
   668   finally have "2 ^ t_rev ts \<le> 2 * n + 2" .
   668   finally have "2 ^ T_rev ts \<le> 2 * n + 2" .
   669   from le_log2_of_power[OF this] have "t_rev ts \<le> log 2 (2 * (n + 1))"
   669   from le_log2_of_power[OF this] have "T_rev ts \<le> log 2 (2 * (n + 1))"
   670     by auto
   670     by auto
   671   also have "\<dots> = 1 + log 2 (n+1)"
   671   also have "\<dots> = 1 + log 2 (n+1)"
   672     by (simp only: of_nat_mult log_mult) auto
   672     by (simp only: of_nat_mult log_mult) auto
   673   finally show ?thesis by (auto simp: algebra_simps)
   673   finally show ?thesis by (auto simp: algebra_simps)
   674 qed
   674 qed
   675 
   675 
   676 lemma t_del_min_bound_aux:
   676 lemma T_del_min_bound_aux:
   677   fixes ts
   677   fixes ts
   678   defines "n \<equiv> size (mset_heap ts)"
   678   defines "n \<equiv> size (mset_heap ts)"
   679   assumes BINVAR: "invar_bheap ts"
   679   assumes BINVAR: "invar_bheap ts"
   680   assumes "ts\<noteq>[]"
   680   assumes "ts\<noteq>[]"
   681   shows "t_del_min ts \<le> 6 * log 2 (n+1) + 3"
   681   shows "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   682 proof -
   682 proof -
   683   obtain r x ts\<^sub>1 ts\<^sub>2 where GM: "get_min_rest ts = (Node r x ts\<^sub>1, ts\<^sub>2)"
   683   obtain r x ts\<^sub>1 ts\<^sub>2 where GM: "get_min_rest ts = (Node r x ts\<^sub>1, ts\<^sub>2)"
   684     by (metis surj_pair tree.exhaust_sel)
   684     by (metis surj_pair tree.exhaust_sel)
   685 
   685 
   686   note BINVAR' = invar_bheap_get_min_rest[OF GM \<open>ts\<noteq>[]\<close> BINVAR]
   686   note BINVAR' = invar_bheap_get_min_rest[OF GM \<open>ts\<noteq>[]\<close> BINVAR]
   687   hence BINVAR1: "invar_bheap (rev ts\<^sub>1)" by (blast intro: invar_bheap_children)
   687   hence BINVAR1: "invar_bheap (rev ts\<^sub>1)" by (blast intro: invar_bheap_children)
   688 
   688 
   689   define n\<^sub>1 where "n\<^sub>1 = size (mset_heap ts\<^sub>1)"
   689   define n\<^sub>1 where "n\<^sub>1 = size (mset_heap ts\<^sub>1)"
   690   define n\<^sub>2 where "n\<^sub>2 = size (mset_heap ts\<^sub>2)"
   690   define n\<^sub>2 where "n\<^sub>2 = size (mset_heap ts\<^sub>2)"
   691 
   691 
   692   have t_rev_ts1_bound: "t_rev ts\<^sub>1 \<le> 1 + log 2 (n+1)"
   692   have T_rev_ts1_bound: "T_rev ts\<^sub>1 \<le> 1 + log 2 (n+1)"
   693   proof -
   693   proof -
   694     note t_rev_ts1_bound_aux[OF BINVAR1, simplified, folded n\<^sub>1_def]
   694     note T_rev_ts1_bound_aux[OF BINVAR1, simplified, folded n\<^sub>1_def]
   695     also have "n\<^sub>1 \<le> n"
   695     also have "n\<^sub>1 \<le> n"
   696       unfolding n\<^sub>1_def n_def
   696       unfolding n\<^sub>1_def n_def
   697       using mset_get_min_rest[OF GM \<open>ts\<noteq>[]\<close>]
   697       using mset_get_min_rest[OF GM \<open>ts\<noteq>[]\<close>]
   698       by (auto simp: mset_heap_def)
   698       by (auto simp: mset_heap_def)
   699     finally show ?thesis by (auto simp: algebra_simps)
   699     finally show ?thesis by (auto simp: algebra_simps)
   700   qed
   700   qed
   701 
   701 
   702   have "t_del_min ts = t_get_min_rest ts + t_rev ts\<^sub>1 + t_merge (rev ts\<^sub>1) ts\<^sub>2"
   702   have "T_del_min ts = T_get_min_rest ts + T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2"
   703     unfolding t_del_min_def by (simp add: GM)
   703     unfolding T_del_min_def by (simp add: GM)
   704   also have "\<dots> \<le> log 2 (n+1) + t_rev ts\<^sub>1 + t_merge (rev ts\<^sub>1) ts\<^sub>2"
   704   also have "\<dots> \<le> log 2 (n+1) + T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2"
   705     using t_get_min_rest_bound_aux[OF assms(2-)] by (auto simp: n_def)
   705     using T_get_min_rest_bound_aux[OF assms(2-)] by (auto simp: n_def)
   706   also have "\<dots> \<le> 2*log 2 (n+1) + t_merge (rev ts\<^sub>1) ts\<^sub>2 + 1"
   706   also have "\<dots> \<le> 2*log 2 (n+1) + T_merge (rev ts\<^sub>1) ts\<^sub>2 + 1"
   707     using t_rev_ts1_bound by auto
   707     using T_rev_ts1_bound by auto
   708   also have "\<dots> \<le> 2*log 2 (n+1) + 4 * log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 3"
   708   also have "\<dots> \<le> 2*log 2 (n+1) + 4 * log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 3"
   709     using t_merge_bound_aux[OF \<open>invar_bheap (rev ts\<^sub>1)\<close> \<open>invar_bheap ts\<^sub>2\<close>]
   709     using T_merge_bound_aux[OF \<open>invar_bheap (rev ts\<^sub>1)\<close> \<open>invar_bheap ts\<^sub>2\<close>]
   710     by (auto simp: n\<^sub>1_def n\<^sub>2_def algebra_simps)
   710     by (auto simp: n\<^sub>1_def n\<^sub>2_def algebra_simps)
   711   also have "n\<^sub>1 + n\<^sub>2 \<le> n"
   711   also have "n\<^sub>1 + n\<^sub>2 \<le> n"
   712     unfolding n\<^sub>1_def n\<^sub>2_def n_def
   712     unfolding n\<^sub>1_def n\<^sub>2_def n_def
   713     using mset_get_min_rest[OF GM \<open>ts\<noteq>[]\<close>]
   713     using mset_get_min_rest[OF GM \<open>ts\<noteq>[]\<close>]
   714     by (auto simp: mset_heap_def)
   714     by (auto simp: mset_heap_def)
   715   finally have "t_del_min ts \<le> 6 * log 2 (n+1) + 3"
   715   finally have "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   716     by auto
   716     by auto
   717   thus ?thesis by (simp add: algebra_simps)
   717   thus ?thesis by (simp add: algebra_simps)
   718 qed
   718 qed
   719 
   719 
   720 lemma t_del_min_bound:
   720 lemma T_del_min_bound:
   721   fixes ts
   721   fixes ts
   722   defines "n \<equiv> size (mset_heap ts)"
   722   defines "n \<equiv> size (mset_heap ts)"
   723   assumes "invar ts"
   723   assumes "invar ts"
   724   assumes "ts\<noteq>[]"
   724   assumes "ts\<noteq>[]"
   725   shows "t_del_min ts \<le> 6 * log 2 (n+1) + 3"
   725   shows "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   726 using assms t_del_min_bound_aux unfolding invar_def by blast
   726 using assms T_del_min_bound_aux unfolding invar_def by blast
   727 
   727 
   728 end
   728 end