514 subsubsection \<open>Converting a Braun Tree into a List of Elements\<close> |
514 subsubsection \<open>Converting a Braun Tree into a List of Elements\<close> |
515 |
515 |
516 text \<open>The code and the proof are originally due to Thomas Sewell (except running time).\<close> |
516 text \<open>The code and the proof are originally due to Thomas Sewell (except running time).\<close> |
517 |
517 |
518 function list_fast_rec :: "'a tree list \<Rightarrow> 'a list" where |
518 function list_fast_rec :: "'a tree list \<Rightarrow> 'a list" where |
519 "list_fast_rec ts = (if ts = [] then [] else |
519 "list_fast_rec ts = (let us = filter (\<lambda>t. t \<noteq> Leaf) ts in |
520 let us = filter (\<lambda>t. t \<noteq> Leaf) ts |
520 if us = [] then [] else |
521 in map value us @ list_fast_rec (map left us @ map right us))" |
521 map value us @ list_fast_rec (map left us @ map right us))" |
522 by (pat_completeness, auto) |
522 by (pat_completeness, auto) |
523 |
523 |
524 lemma list_fast_rec_term: "\<lbrakk> ts \<noteq> []; us = filter (\<lambda>t. t \<noteq> \<langle>\<rangle>) ts \<rbrakk> \<Longrightarrow> |
524 lemma list_fast_rec_term1: "ts \<noteq> [] \<Longrightarrow> Leaf \<notin> set ts \<Longrightarrow> |
525 (map left us @ map right us, ts) \<in> measure (sum_list \<circ> map (\<lambda>t. 2 * size t + 1))" |
525 sum_list (map (size o left) ts) + sum_list (map (size o right) ts) < sum_list (map size ts)" |
526 apply (clarsimp simp: sum_list_addf[symmetric] sum_list_map_filter') |
526 apply (clarsimp simp: sum_list_addf[symmetric] sum_list_map_filter') |
527 apply (rule sum_list_strict_mono; simp) |
527 apply (rule sum_list_strict_mono; clarsimp?) |
528 apply (case_tac x; simp) |
528 apply (case_tac x; simp) |
529 done |
529 done |
|
530 |
|
531 lemma list_fast_rec_term: "us \<noteq> [] \<Longrightarrow> us = filter (\<lambda>t. t \<noteq> \<langle>\<rangle>) ts \<Longrightarrow> |
|
532 sum_list (map (size o left) us) + sum_list (map (size o right) us) < sum_list (map size ts)" |
|
533 apply (rule order_less_le_trans, rule list_fast_rec_term1, simp_all) |
|
534 apply (rule sum_list_filter_le_nat) |
|
535 done |
530 |
536 |
531 termination |
537 termination |
532 apply (relation "measure (sum_list o map (\<lambda>t. 2 * size t + 1))") |
538 apply (relation "measure (sum_list o map size)") |
533 apply simp |
539 apply simp |
534 using list_fast_rec_term by auto |
540 apply (simp add: list_fast_rec_term) |
|
541 done |
535 |
542 |
536 declare list_fast_rec.simps[simp del] |
543 declare list_fast_rec.simps[simp del] |
537 |
544 |
538 definition list_fast :: "'a tree \<Rightarrow> 'a list" where |
545 definition list_fast :: "'a tree \<Rightarrow> 'a list" where |
539 "list_fast t = list_fast_rec [t]" |
546 "list_fast t = list_fast_rec [t]" |
540 |
547 |
541 function t_list_fast_rec :: "'a tree list \<Rightarrow> nat" where |
548 function t_list_fast_rec :: "'a tree list \<Rightarrow> nat" where |
542 "t_list_fast_rec ts = (if ts = [] then 0 else |
549 "t_list_fast_rec ts = (let us = filter (\<lambda>t. t \<noteq> Leaf) ts |
543 let us = filter (\<lambda>t. t \<noteq> Leaf) ts |
550 in if us = [] then 0 else |
544 in length ts + 5 * length us + t_list_fast_rec (map left us @ map right us))" |
551 length ts + 5 * length us + t_list_fast_rec (map left us @ map right us))" |
545 by (pat_completeness, auto) |
552 by (pat_completeness, auto) |
546 |
553 |
547 termination |
554 termination |
548 apply (relation "measure (sum_list o map (\<lambda>t. 2 * size t + 1))") |
555 apply (relation "measure (sum_list o map size)") |
549 apply simp |
556 apply simp |
550 using list_fast_rec_term by auto |
557 apply (simp add: list_fast_rec_term) |
|
558 done |
551 |
559 |
552 declare t_list_fast_rec.simps[simp del] |
560 declare t_list_fast_rec.simps[simp del] |
553 |
|
554 |
561 |
555 paragraph "Functional Correctness" |
562 paragraph "Functional Correctness" |
556 |
563 |
557 lemma list_fast_rec_all_Leaf: |
564 lemma list_fast_rec_all_Leaf: |
558 "\<forall>t \<in> set ts. t = Leaf \<Longrightarrow> list_fast_rec ts = []" |
565 "\<forall>t \<in> set ts. t = Leaf \<Longrightarrow> list_fast_rec ts = []" |
586 apply (rule_tac x="length ts - length xs" in exI) |
593 apply (rule_tac x="length ts - length xs" in exI) |
587 apply (clarsimp simp: list_eq_iff_nth_eq) |
594 apply (clarsimp simp: list_eq_iff_nth_eq) |
588 apply(auto simp: nth_append braun_list_not_Nil take_nths_eq_single braun_list_Nil hd_drop_conv_nth) |
595 apply(auto simp: nth_append braun_list_not_Nil take_nths_eq_single braun_list_Nil hd_drop_conv_nth) |
589 done |
596 done |
590 thus ?thesis |
597 thus ?thesis |
591 by (clarsimp simp: list_fast_rec.simps[of ts] o_def list_fast_rec_all_Leaf) |
598 by (clarsimp simp: list_fast_rec.simps[of ts] o_def list_fast_rec_all_Leaf Let_def) |
592 next |
599 next |
593 case False |
600 case False |
594 with less.prems(2) have *: |
601 with less.prems(2) have *: |
595 "\<forall>i < 2 ^ k. ts ! i \<noteq> Leaf |
602 "\<forall>i < 2 ^ k. ts ! i \<noteq> Leaf |
596 \<and> value (ts ! i) = xs ! i |
603 \<and> value (ts ! i) = xs ! i |
612 |
619 |
613 corollary list_fast_correct: |
620 corollary list_fast_correct: |
614 "braun t \<Longrightarrow> list_fast t = list t" |
621 "braun t \<Longrightarrow> list_fast t = list t" |
615 by (simp add: list_fast_def take_nths_00 braun_list_eq list_fast_rec_correct[where k=0]) |
622 by (simp add: list_fast_def take_nths_00 braun_list_eq list_fast_rec_correct[where k=0]) |
616 |
623 |
617 |
|
618 paragraph "Running Time Analysis" |
624 paragraph "Running Time Analysis" |
619 |
625 |
620 lemma sum_tree_list_children: "\<forall>t \<in> set ts. t \<noteq> Leaf \<Longrightarrow> |
626 lemma sum_tree_list_children: "\<forall>t \<in> set ts. t \<noteq> Leaf \<Longrightarrow> |
621 (\<Sum>t\<leftarrow>ts. k * size t) = (\<Sum>t \<leftarrow> map left ts @ map right ts. k * size t) + k * length ts" |
627 (\<Sum>t\<leftarrow>ts. k * size t) = (\<Sum>t \<leftarrow> map left ts @ map right ts. k * size t) + k * length ts" |
622 by(induction ts)(auto simp add: neq_Leaf_iff algebra_simps) |
628 by(induction ts)(auto simp add: neq_Leaf_iff algebra_simps) |
623 |
629 |
624 theorem t_list_fast_rec_ub: |
630 theorem t_list_fast_rec_ub: |
625 "t_list_fast_rec ts \<le> sum_list (map (\<lambda>t. 7*size t + 1) ts)" |
631 "t_list_fast_rec ts \<le> sum_list (map (\<lambda>t. 7*size t + 1) ts)" |
626 proof (induction ts rule: measure_induct_rule[where f="sum_list o map (\<lambda>t. 2*size t + 1)"]) |
632 proof (induction ts rule: measure_induct_rule[where f="sum_list o map size"]) |
627 case (less ts) |
633 case (less ts) |
|
634 let ?us = "filter (\<lambda>t. t \<noteq> Leaf) ts" |
628 show ?case |
635 show ?case |
629 proof cases |
636 proof cases |
630 assume "ts = []" |
637 assume "?us = []" |
631 thus ?thesis using t_list_fast_rec.simps[of ts] by(simp add: Let_def) |
638 thus ?thesis using t_list_fast_rec.simps[of ts] by(simp add: Let_def) |
632 next |
639 next |
633 assume "ts \<noteq> []" |
640 assume "?us \<noteq> []" |
634 let ?us = "filter (\<lambda>t. t \<noteq> Leaf) ts" |
|
635 let ?children = "map left ?us @ map right ?us" |
641 let ?children = "map left ?us @ map right ?us" |
636 have "t_list_fast_rec ts = t_list_fast_rec ?children + 5 * length ?us + length ts" |
642 have "t_list_fast_rec ts = t_list_fast_rec ?children + 5 * length ?us + length ts" |
637 using \<open>ts \<noteq> []\<close> t_list_fast_rec.simps[of ts] by(simp add: Let_def) |
643 using \<open>?us \<noteq> []\<close> t_list_fast_rec.simps[of ts] by(simp add: Let_def) |
638 also have "\<dots> \<le> (\<Sum>t\<leftarrow>?children. 7 * size t + 1) + 5 * length ?us + length ts" |
644 also have "\<dots> \<le> (\<Sum>t\<leftarrow>?children. 7 * size t + 1) + 5 * length ?us + length ts" |
639 using less[of "map left ?us @ map right ?us"] |
645 using less[of "?children"] list_fast_rec_term[of "?us"] \<open>?us \<noteq> []\<close> |
640 list_fast_rec_term[of ts, OF \<open>ts \<noteq> []\<close>] |
|
641 by (simp) |
646 by (simp) |
642 also have "\<dots> = (\<Sum>t\<leftarrow>?children. 7*size t) + 7 * length ?us + length ts" |
647 also have "\<dots> = (\<Sum>t\<leftarrow>?children. 7*size t) + 7 * length ?us + length ts" |
643 by(simp add: sum_list_Suc o_def) |
648 by(simp add: sum_list_Suc o_def) |
644 also have "\<dots> = (\<Sum>t\<leftarrow>?us. 7*size t) + length ts" |
649 also have "\<dots> = (\<Sum>t\<leftarrow>?us. 7*size t) + length ts" |
645 by(simp add: sum_tree_list_children) |
650 by(simp add: sum_tree_list_children) |