src/HOL/Data_Structures/Binomial_Heap.thy
changeset 72910 c145be662fbd
parent 72812 caf2fd14e28b
child 72935 aa86651805e0
equal deleted inserted replaced
72907:3883f536d84d 72910:c145be662fbd
   539   "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"
   539   "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"
   540 by (induction ts\<^sub>1 ts\<^sub>2 rule: T_merge.induct)
   540 by (induction ts\<^sub>1 ts\<^sub>2 rule: T_merge.induct)
   541    (auto simp: T_ins_tree_length algebra_simps)
   541    (auto simp: T_ins_tree_length algebra_simps)
   542 
   542 
   543 text \<open>Finally, we get the desired logarithmic bound\<close>
   543 text \<open>Finally, we get the desired logarithmic bound\<close>
   544 lemma T_merge_bound_aux:
   544 lemma T_merge_bound:
   545   fixes ts\<^sub>1 ts\<^sub>2
   545   fixes ts\<^sub>1 ts\<^sub>2
   546   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
   546   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
   547   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
   547   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
   548   assumes BINVARS: "invar ts\<^sub>1" "invar ts\<^sub>2"
   548   assumes "invar ts\<^sub>1" "invar ts\<^sub>2"
   549   shows "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
   549   shows "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
   550 proof -
   550 proof -
   551   define n where "n = n\<^sub>1 + n\<^sub>2"
   551   define n where "n = n\<^sub>1 + n\<^sub>2"
       
   552 
       
   553   note BINVARS = \<open>invar ts\<^sub>1\<close> \<open>invar ts\<^sub>2\<close>
   552 
   554 
   553   from T_merge_length[of ts\<^sub>1 ts\<^sub>2]
   555   from T_merge_length[of ts\<^sub>1 ts\<^sub>2]
   554   have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1" by auto
   556   have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1" by auto
   555   hence "(2::nat)^T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2^(2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1)"
   557   hence "(2::nat)^T_merge ts\<^sub>1 ts\<^sub>2 \<le> 2^(2 * (length ts\<^sub>1 + length ts\<^sub>2) + 1)"
   556     by (rule power_increasing) auto
   558     by (rule power_increasing) auto
   573   also have "log 2 2 \<le> 2" by auto
   575   also have "log 2 2 \<le> 2" by auto
   574   finally have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n + 1) + 2" by auto
   576   finally have "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n + 1) + 2" by auto
   575   thus ?thesis unfolding n_def by (auto simp: algebra_simps)
   577   thus ?thesis unfolding n_def by (auto simp: algebra_simps)
   576 qed
   578 qed
   577 
   579 
   578 lemma T_merge_bound:
       
   579   fixes ts\<^sub>1 ts\<^sub>2
       
   580   defines "n\<^sub>1 \<equiv> size (mset_heap ts\<^sub>1)"
       
   581   defines "n\<^sub>2 \<equiv> size (mset_heap ts\<^sub>2)"
       
   582   assumes "invar ts\<^sub>1" "invar ts\<^sub>2"
       
   583   shows "T_merge ts\<^sub>1 ts\<^sub>2 \<le> 4*log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 2"
       
   584 using assms T_merge_bound_aux unfolding invar_def by blast
       
   585 
       
   586 subsubsection \<open>\<open>T_get_min\<close>\<close>
   580 subsubsection \<open>\<open>T_get_min\<close>\<close>
   587 
   581 
   588 fun T_get_min :: "'a::linorder heap \<Rightarrow> nat" where
   582 fun T_get_min :: "'a::linorder heap \<Rightarrow> nat" where
   589   "T_get_min [t] = 1"
   583   "T_get_min [t] = 1"
   590 | "T_get_min (t#ts) = 1 + T_get_min ts"
   584 | "T_get_min (t#ts) = 1 + T_get_min ts"
   614 | "T_get_min_rest (t#ts) = 1 + T_get_min_rest ts"
   608 | "T_get_min_rest (t#ts) = 1 + T_get_min_rest ts"
   615 
   609 
   616 lemma T_get_min_rest_estimate: "ts\<noteq>[] \<Longrightarrow> T_get_min_rest ts = length ts"
   610 lemma T_get_min_rest_estimate: "ts\<noteq>[] \<Longrightarrow> T_get_min_rest ts = length ts"
   617   by (induction ts rule: T_get_min_rest.induct) auto
   611   by (induction ts rule: T_get_min_rest.induct) auto
   618 
   612 
   619 lemma T_get_min_rest_bound_aux:
   613 lemma T_get_min_rest_bound:
   620   assumes "invar ts"
   614   assumes "invar ts"
   621   assumes "ts\<noteq>[]"
   615   assumes "ts\<noteq>[]"
   622   shows "T_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
   616   shows "T_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
   623 proof -
   617 proof -
   624   have 1: "T_get_min_rest ts = length ts" using assms T_get_min_rest_estimate by auto
   618   have 1: "T_get_min_rest ts = length ts" using assms T_get_min_rest_estimate by auto
   628       by auto
   622       by auto
   629     thus ?thesis using le_log2_of_power by blast
   623     thus ?thesis using le_log2_of_power by blast
   630   qed
   624   qed
   631   finally show ?thesis by auto
   625   finally show ?thesis by auto
   632 qed
   626 qed
   633 
       
   634 lemma T_get_min_rest_bound:
       
   635   assumes "invar ts"
       
   636   assumes "ts\<noteq>[]"
       
   637   shows "T_get_min_rest ts \<le> log 2 (size (mset_heap ts) + 1)"
       
   638 using assms T_get_min_rest_bound_aux unfolding invar_def by blast
       
   639 
   627 
   640 text\<open>Note that although the definition of function \<^const>\<open>rev\<close> has quadratic complexity,
   628 text\<open>Note that although the definition of function \<^const>\<open>rev\<close> has quadratic complexity,
   641 it can and is implemented (via suitable code lemmas) as a linear time function.
   629 it can and is implemented (via suitable code lemmas) as a linear time function.
   642 Thus the following definition is justified:\<close>
   630 Thus the following definition is justified:\<close>
   643 
   631 
   663   also have "\<dots> = 1 + log 2 (n+1)"
   651   also have "\<dots> = 1 + log 2 (n+1)"
   664     by (simp only: of_nat_mult log_mult) auto
   652     by (simp only: of_nat_mult log_mult) auto
   665   finally show ?thesis by (auto simp: algebra_simps)
   653   finally show ?thesis by (auto simp: algebra_simps)
   666 qed
   654 qed
   667 
   655 
   668 lemma T_del_min_bound_aux:
   656 lemma T_del_min_bound:
   669   fixes ts
   657   fixes ts
   670   defines "n \<equiv> size (mset_heap ts)"
   658   defines "n \<equiv> size (mset_heap ts)"
   671   assumes BINVAR: "invar ts"
   659   assumes "invar ts"
   672   assumes "ts\<noteq>[]"
   660   assumes "ts\<noteq>[]"
   673   shows "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   661   shows "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   674 proof -
   662 proof -
   675   obtain r x ts\<^sub>1 ts\<^sub>2 where GM: "get_min_rest ts = (Node r x ts\<^sub>1, ts\<^sub>2)"
   663   obtain r x ts\<^sub>1 ts\<^sub>2 where GM: "get_min_rest ts = (Node r x ts\<^sub>1, ts\<^sub>2)"
   676     by (metis surj_pair tree.exhaust_sel)
   664     by (metis surj_pair tree.exhaust_sel)
   677 
   665 
   678   note BINVAR' = invar_get_min_rest[OF GM \<open>ts\<noteq>[]\<close> BINVAR]
   666   note BINVAR' = invar_get_min_rest[OF GM \<open>ts\<noteq>[]\<close> \<open>invar ts\<close>]
   679   hence BINVAR1: "invar (rev ts\<^sub>1)" by (blast intro: invar_children)
   667   hence BINVAR1: "invar (rev ts\<^sub>1)" by (blast intro: invar_children)
   680 
   668 
   681   define n\<^sub>1 where "n\<^sub>1 = size (mset_heap ts\<^sub>1)"
   669   define n\<^sub>1 where "n\<^sub>1 = size (mset_heap ts\<^sub>1)"
   682   define n\<^sub>2 where "n\<^sub>2 = size (mset_heap ts\<^sub>2)"
   670   define n\<^sub>2 where "n\<^sub>2 = size (mset_heap ts\<^sub>2)"
   683 
   671 
   692   qed
   680   qed
   693 
   681 
   694   have "T_del_min ts = T_get_min_rest ts + T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2"
   682   have "T_del_min ts = T_get_min_rest ts + T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2"
   695     unfolding T_del_min_def by (simp add: GM)
   683     unfolding T_del_min_def by (simp add: GM)
   696   also have "\<dots> \<le> log 2 (n+1) + T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2"
   684   also have "\<dots> \<le> log 2 (n+1) + T_rev ts\<^sub>1 + T_merge (rev ts\<^sub>1) ts\<^sub>2"
   697     using T_get_min_rest_bound_aux[OF assms(2-)] by (auto simp: n_def)
   685     using T_get_min_rest_bound[OF assms(2-)] by (auto simp: n_def)
   698   also have "\<dots> \<le> 2*log 2 (n+1) + T_merge (rev ts\<^sub>1) ts\<^sub>2 + 1"
   686   also have "\<dots> \<le> 2*log 2 (n+1) + T_merge (rev ts\<^sub>1) ts\<^sub>2 + 1"
   699     using T_rev_ts1_bound by auto
   687     using T_rev_ts1_bound by auto
   700   also have "\<dots> \<le> 2*log 2 (n+1) + 4 * log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 3"
   688   also have "\<dots> \<le> 2*log 2 (n+1) + 4 * log 2 (n\<^sub>1 + n\<^sub>2 + 1) + 3"
   701     using T_merge_bound_aux[OF \<open>invar (rev ts\<^sub>1)\<close> \<open>invar ts\<^sub>2\<close>]
   689     using T_merge_bound[OF \<open>invar (rev ts\<^sub>1)\<close> \<open>invar ts\<^sub>2\<close>]
   702     by (auto simp: n\<^sub>1_def n\<^sub>2_def algebra_simps)
   690     by (auto simp: n\<^sub>1_def n\<^sub>2_def algebra_simps)
   703   also have "n\<^sub>1 + n\<^sub>2 \<le> n"
   691   also have "n\<^sub>1 + n\<^sub>2 \<le> n"
   704     unfolding n\<^sub>1_def n\<^sub>2_def n_def
   692     unfolding n\<^sub>1_def n\<^sub>2_def n_def
   705     using mset_get_min_rest[OF GM \<open>ts\<noteq>[]\<close>]
   693     using mset_get_min_rest[OF GM \<open>ts\<noteq>[]\<close>]
   706     by (auto simp: mset_heap_def)
   694     by (auto simp: mset_heap_def)
   707   finally have "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   695   finally have "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
   708     by auto
   696     by auto
   709   thus ?thesis by (simp add: algebra_simps)
   697   thus ?thesis by (simp add: algebra_simps)
   710 qed
   698 qed
   711 
   699 
   712 lemma T_del_min_bound:
       
   713   fixes ts
       
   714   defines "n \<equiv> size (mset_heap ts)"
       
   715   assumes "invar ts"
       
   716   assumes "ts\<noteq>[]"
       
   717   shows "T_del_min ts \<le> 6 * log 2 (n+1) + 3"
       
   718 using assms T_del_min_bound_aux unfolding invar_def by blast
       
   719 
       
   720 end
   700 end