src/HOL/Data_Structures/Binomial_Heap.thy
changeset 70607 b044a06ad0d6
parent 70450 7c2724cefcb8
child 72550 1d0ae7e578a0
equal deleted inserted replaced
70606:4f4ede010687 70607:b044a06ad0d6
    26 type_synonym 'a heap = "'a tree list"
    26 type_synonym 'a heap = "'a tree list"
    27 
    27 
    28 subsubsection \<open>Multiset of elements\<close>
    28 subsubsection \<open>Multiset of elements\<close>
    29 
    29 
    30 fun mset_tree :: "'a::linorder tree \<Rightarrow> 'a multiset" where
    30 fun mset_tree :: "'a::linorder tree \<Rightarrow> 'a multiset" where
    31   "mset_tree (Node _ a c) = {#a#} + (\<Sum>t\<in>#mset c. mset_tree t)"
    31   "mset_tree (Node _ a ts) = {#a#} + (\<Sum>t\<in>#mset ts. mset_tree t)"
    32 
    32 
    33 definition mset_heap :: "'a::linorder heap \<Rightarrow> 'a multiset" where
    33 definition mset_heap :: "'a::linorder heap \<Rightarrow> 'a multiset" where
    34   "mset_heap c = (\<Sum>t\<in>#mset c. mset_tree t)"
    34   "mset_heap ts = (\<Sum>t\<in>#mset ts. mset_tree t)"
    35 
    35 
    36 lemma mset_tree_simp_alt[simp]:
    36 lemma mset_tree_simp_alt[simp]:
    37   "mset_tree (Node r a c) = {#a#} + mset_heap c"
    37   "mset_tree (Node r a ts) = {#a#} + mset_heap ts"
    38   unfolding mset_heap_def by auto
    38   unfolding mset_heap_def by auto
    39 declare mset_tree.simps[simp del]
    39 declare mset_tree.simps[simp del]
    40 
    40 
    41 lemma mset_tree_nonempty[simp]: "mset_tree t \<noteq> {#}"
    41 lemma mset_tree_nonempty[simp]: "mset_tree t \<noteq> {#}"
    42 by (cases t) auto
    42 by (cases t) auto
   179 lemma mset_heap_insert[simp]: "mset_heap (insert x t) = {#x#} + mset_heap t"
   179 lemma mset_heap_insert[simp]: "mset_heap (insert x t) = {#x#} + mset_heap t"
   180 by(auto simp: insert_def)
   180 by(auto simp: insert_def)
   181 
   181 
   182 subsubsection \<open>\<open>merge\<close>\<close>
   182 subsubsection \<open>\<open>merge\<close>\<close>
   183 
   183 
       
   184 context
       
   185 includes pattern_aliases
       
   186 begin
       
   187 
   184 fun merge :: "'a::linorder heap \<Rightarrow> 'a heap \<Rightarrow> 'a heap" where
   188 fun merge :: "'a::linorder heap \<Rightarrow> 'a heap \<Rightarrow> 'a heap" where
   185   "merge ts\<^sub>1 [] = ts\<^sub>1"
   189   "merge ts\<^sub>1 [] = ts\<^sub>1"
   186 | "merge [] ts\<^sub>2 = ts\<^sub>2"
   190 | "merge [] ts\<^sub>2 = ts\<^sub>2"
   187 | "merge (t\<^sub>1#ts\<^sub>1) (t\<^sub>2#ts\<^sub>2) = (
   191 | "merge (t\<^sub>1#ts\<^sub>1 =: h\<^sub>1) (t\<^sub>2#ts\<^sub>2 =: h\<^sub>2) = (
   188     if rank t\<^sub>1 < rank t\<^sub>2 then t\<^sub>1 # merge ts\<^sub>1 (t\<^sub>2#ts\<^sub>2) else
   192     if rank t\<^sub>1 < rank t\<^sub>2 then t\<^sub>1 # merge ts\<^sub>1 h\<^sub>2 else
   189     if rank t\<^sub>2 < rank t\<^sub>1 then t\<^sub>2 # merge (t\<^sub>1#ts\<^sub>1) ts\<^sub>2
   193     if rank t\<^sub>2 < rank t\<^sub>1 then t\<^sub>2 # merge h\<^sub>1 ts\<^sub>2
   190     else ins_tree (link t\<^sub>1 t\<^sub>2) (merge ts\<^sub>1 ts\<^sub>2)
   194     else ins_tree (link t\<^sub>1 t\<^sub>2) (merge ts\<^sub>1 ts\<^sub>2)
   191   )"
   195   )"
   192 
   196 
       
   197 end
       
   198 
   193 lemma merge_simp2[simp]: "merge [] ts\<^sub>2 = ts\<^sub>2"
   199 lemma merge_simp2[simp]: "merge [] ts\<^sub>2 = ts\<^sub>2"
   194 by (cases ts\<^sub>2) auto
   200 by (cases ts\<^sub>2) auto
   195 
   201 
   196 lemma merge_rank_bound:
   202 lemma merge_rank_bound:
   197   assumes "t' \<in> set (merge ts\<^sub>1 ts\<^sub>2)"
   203   assumes "t' \<in> set (merge ts\<^sub>1 ts\<^sub>2)"
   198   assumes "\<forall>t'\<in>set ts\<^sub>1. rank t < rank t'"
   204   assumes "\<forall>t\<^sub>1\<in>set ts\<^sub>1. rank t < rank t\<^sub>1"
   199   assumes "\<forall>t'\<in>set ts\<^sub>2. rank t < rank t'"
   205   assumes "\<forall>t\<^sub>2\<in>set ts\<^sub>2. rank t < rank t\<^sub>2"
   200   shows "rank t < rank t'"
   206   shows "rank t < rank t'"
   201 using assms
   207 using assms
   202 by (induction ts\<^sub>1 ts\<^sub>2 arbitrary: t' rule: merge.induct)
   208 by (induction ts\<^sub>1 ts\<^sub>2 arbitrary: t' rule: merge.induct)
   203    (auto split: if_splits simp: ins_tree_rank_bound)
   209    (auto split: if_splits simp: ins_tree_rank_bound)
   204 
   210 
   513     by (simp only: log_mult of_nat_mult) auto
   519     by (simp only: log_mult of_nat_mult) auto
   514 qed
   520 qed
   515 
   521 
   516 subsubsection \<open>\<open>t_merge\<close>\<close>
   522 subsubsection \<open>\<open>t_merge\<close>\<close>
   517 
   523 
       
   524 context
       
   525 includes pattern_aliases
       
   526 begin
       
   527 
   518 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
   519   "t_merge ts\<^sub>1 [] = 1"
   529   "t_merge ts\<^sub>1 [] = 1"
   520 | "t_merge [] ts\<^sub>2 = 1"
   530 | "t_merge [] ts\<^sub>2 = 1"
   521 | "t_merge (t\<^sub>1#ts\<^sub>1) (t\<^sub>2#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 + (
   522     if rank t\<^sub>1 < rank t\<^sub>2 then t_merge ts\<^sub>1 (t\<^sub>2#ts\<^sub>2)
   532     if rank t\<^sub>1 < rank t\<^sub>2 then t_merge ts\<^sub>1 h\<^sub>2
   523     else if rank t\<^sub>2 < rank t\<^sub>1 then t_merge (t\<^sub>1#ts\<^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
   524     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
   525   )"
   535   )"
       
   536 
       
   537 end
   526 
   538 
   527 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
   528   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>
   529 
   541 
   530 lemma t_ins_tree_length:
   542 lemma t_ins_tree_length: