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 |