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: |