Tweak Braun tree list_fast_rec recursion.
authorThomas Sewell <sewell@chalmers.se>
Tue, 26 Mar 2019 16:03:01 +0100
changeset 69984 3afa3b25b5e7
parent 69983 4ce5ce3a612b
child 69985 8e916ed23d17
Tweak Braun tree list_fast_rec recursion. A minor adjustment simplifies the termination argument slightly.
src/HOL/Data_Structures/Array_Braun.thy
--- a/src/HOL/Data_Structures/Array_Braun.thy	Mon Mar 25 21:46:37 2019 +0100
+++ b/src/HOL/Data_Structures/Array_Braun.thy	Tue Mar 26 16:03:01 2019 +0100
@@ -516,22 +516,29 @@
 text \<open>The code and the proof are originally due to Thomas Sewell (except running time).\<close>
 
 function list_fast_rec :: "'a tree list \<Rightarrow> 'a list" where
-"list_fast_rec ts = (if ts = [] then [] else
-  let us = filter (\<lambda>t. t \<noteq> Leaf) ts
-  in map value us @ list_fast_rec (map left us @ map right us))"
+"list_fast_rec ts = (let us = filter (\<lambda>t. t \<noteq> Leaf) ts in
+  if us = [] then [] else
+  map value us @ list_fast_rec (map left us @ map right us))"
 by (pat_completeness, auto)
 
-lemma list_fast_rec_term: "\<lbrakk> ts \<noteq> []; us = filter (\<lambda>t. t \<noteq> \<langle>\<rangle>) ts \<rbrakk> \<Longrightarrow>
-  (map left us @ map right us, ts) \<in> measure (sum_list \<circ> map (\<lambda>t. 2 * size t + 1))"
-apply (clarsimp simp: sum_list_addf[symmetric] sum_list_map_filter')
-apply (rule sum_list_strict_mono; simp)
-apply (case_tac x; simp)
-done
+lemma list_fast_rec_term1: "ts \<noteq> [] \<Longrightarrow> Leaf \<notin> set ts \<Longrightarrow>
+  sum_list (map (size o left) ts) + sum_list (map (size o right) ts) < sum_list (map size ts)"
+  apply (clarsimp simp: sum_list_addf[symmetric] sum_list_map_filter')
+  apply (rule sum_list_strict_mono; clarsimp?)
+  apply (case_tac x; simp)
+  done
+
+lemma list_fast_rec_term: "us \<noteq> [] \<Longrightarrow> us = filter (\<lambda>t. t \<noteq> \<langle>\<rangle>) ts \<Longrightarrow>
+  sum_list (map (size o left) us) + sum_list (map (size o right) us) < sum_list (map size ts)"
+  apply (rule order_less_le_trans, rule list_fast_rec_term1, simp_all)
+  apply (rule sum_list_filter_le_nat)
+  done
 
 termination
-apply (relation "measure (sum_list o map (\<lambda>t. 2 * size t + 1))")
- apply simp
-using list_fast_rec_term by auto
+  apply (relation "measure (sum_list o map size)")
+   apply simp
+  apply (simp add: list_fast_rec_term)
+  done
 
 declare list_fast_rec.simps[simp del]
 
@@ -539,19 +546,19 @@
 "list_fast t = list_fast_rec [t]"
 
 function t_list_fast_rec :: "'a tree list \<Rightarrow> nat" where
-"t_list_fast_rec ts = (if ts = [] then 0 else
-  let us = filter (\<lambda>t. t \<noteq> Leaf) ts
-  in length ts + 5 * length us + t_list_fast_rec (map left us @ map right us))"
+"t_list_fast_rec ts = (let us = filter (\<lambda>t. t \<noteq> Leaf) ts
+  in if us = [] then 0 else
+  length ts + 5 * length us + t_list_fast_rec (map left us @ map right us))"
 by (pat_completeness, auto)
 
 termination
-apply (relation "measure (sum_list o map (\<lambda>t. 2 * size t + 1))")
- apply simp
-using list_fast_rec_term by auto
+  apply (relation "measure (sum_list o map size)")
+   apply simp
+  apply (simp add: list_fast_rec_term)
+  done
 
 declare t_list_fast_rec.simps[simp del]
 
-
 paragraph "Functional Correctness"
 
 lemma list_fast_rec_all_Leaf:
@@ -588,7 +595,7 @@
       apply(auto simp: nth_append braun_list_not_Nil take_nths_eq_single braun_list_Nil hd_drop_conv_nth)
       done
     thus ?thesis
-      by (clarsimp simp: list_fast_rec.simps[of ts] o_def list_fast_rec_all_Leaf)
+      by (clarsimp simp: list_fast_rec.simps[of ts] o_def list_fast_rec_all_Leaf Let_def)
   next
     case False
     with less.prems(2) have *:
@@ -614,7 +621,6 @@
   "braun t \<Longrightarrow> list_fast t = list t"
 by (simp add: list_fast_def take_nths_00 braun_list_eq list_fast_rec_correct[where k=0])
 
-
 paragraph "Running Time Analysis"
 
 lemma sum_tree_list_children: "\<forall>t \<in> set ts. t \<noteq> Leaf \<Longrightarrow>
@@ -623,21 +629,20 @@
 
 theorem t_list_fast_rec_ub:
   "t_list_fast_rec ts \<le> sum_list (map (\<lambda>t. 7*size t + 1) ts)"
-proof (induction ts rule: measure_induct_rule[where f="sum_list o map (\<lambda>t. 2*size t + 1)"])
+proof (induction ts rule: measure_induct_rule[where f="sum_list o map size"])
   case (less ts)
+  let ?us = "filter (\<lambda>t. t \<noteq> Leaf) ts"
   show ?case
   proof cases
-    assume "ts = []"
+    assume "?us = []"
     thus ?thesis using t_list_fast_rec.simps[of ts] by(simp add: Let_def)
   next
-    assume "ts \<noteq> []"
-    let ?us = "filter (\<lambda>t. t \<noteq> Leaf) ts"
+    assume "?us \<noteq> []"
     let ?children = "map left ?us @ map right ?us"
     have "t_list_fast_rec ts = t_list_fast_rec ?children + 5 * length ?us + length ts"
-     using \<open>ts \<noteq> []\<close> t_list_fast_rec.simps[of ts] by(simp add: Let_def)
+     using \<open>?us \<noteq> []\<close> t_list_fast_rec.simps[of ts] by(simp add: Let_def)
     also have "\<dots> \<le> (\<Sum>t\<leftarrow>?children. 7 * size t + 1) + 5 * length ?us + length ts"
-      using less[of "map left ?us @ map right ?us"]
-        list_fast_rec_term[of ts, OF \<open>ts \<noteq> []\<close>]
+      using less[of "?children"] list_fast_rec_term[of "?us"] \<open>?us \<noteq> []\<close>
       by (simp)
     also have "\<dots> = (\<Sum>t\<leftarrow>?children. 7*size t) + 7 * length ?us + length ts"
       by(simp add: sum_list_Suc o_def)