src/HOL/Data_Structures/Array_Braun.thy
changeset 69984 3afa3b25b5e7
parent 69943 deb05b4c48ba
child 69985 8e916ed23d17
equal deleted inserted replaced
69983:4ce5ce3a612b 69984:3afa3b25b5e7
   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)