src/HOL/Library/Tree.thy
changeset 63755 182c111190e5
parent 63665 15f48ce7ec23
child 63765 e60020520b15
equal deleted inserted replaced
63729:89b6d339c6c4 63755:182c111190e5
     1 (* Author: Tobias Nipkow *)
     1 (* Author: Tobias Nipkow *)
       
     2 (* Todo:
       
     3  size t = 2^h - 1 \<Longrightarrow> complete t
       
     4  (min_)height of balanced trees via floorlog
       
     5 *)
     2 
     6 
     3 section \<open>Binary Tree\<close>
     7 section \<open>Binary Tree\<close>
     4 
     8 
     5 theory Tree
     9 theory Tree
     6 imports Main
    10 imports Main
    83     also have "(2::nat) ^ height r \<le> 2 ^ height l" using False by simp
    87     also have "(2::nat) ^ height r \<le> 2 ^ height l" using False by simp
    84     finally show ?thesis using False by (auto simp: max_def mult_2)
    88     finally show ?thesis using False by (auto simp: max_def mult_2)
    85   qed
    89   qed
    86 qed simp
    90 qed simp
    87 
    91 
       
    92 corollary size_height: "size t \<le> 2 ^ height (t::'a tree) - 1"
       
    93 using size1_height[of t] by(arith)
       
    94 
    88 
    95 
    89 fun min_height :: "'a tree \<Rightarrow> nat" where
    96 fun min_height :: "'a tree \<Rightarrow> nat" where
    90 "min_height Leaf = 0" |
    97 "min_height Leaf = 0" |
    91 "min_height (Node l _ r) = min (min_height l) (min_height r) + 1"
    98 "min_height (Node l _ r) = min (min_height l) (min_height r) + 1"
    92 
    99 
   104   also have "\<dots> \<le> size(Node l a r) + 1" using Node.IH by simp
   111   also have "\<dots> \<le> size(Node l a r) + 1" using Node.IH by simp
   105   finally show ?case .
   112   finally show ?case .
   106 qed simp
   113 qed simp
   107 
   114 
   108 
   115 
   109 subsection "Balanced"
   116 subsection \<open>Complete\<close>
   110 
   117 
   111 fun balanced :: "'a tree \<Rightarrow> bool" where
   118 fun complete :: "'a tree \<Rightarrow> bool" where
   112 "balanced Leaf = True" |
   119 "complete Leaf = True" |
   113 "balanced (Node l x r) = (balanced l \<and> balanced r \<and> height l = height r)"
   120 "complete (Node l x r) = (complete l \<and> complete r \<and> height l = height r)"
   114 
   121 
   115 lemma balanced_iff_min_height: "balanced t \<longleftrightarrow> (min_height t = height t)"
   122 lemma complete_iff_height: "complete t \<longleftrightarrow> (min_height t = height t)"
   116 apply(induction t)
   123 apply(induction t)
   117  apply simp
   124  apply simp
   118 apply (simp add: min_def max_def)
   125 apply (simp add: min_def max_def)
   119 by (metis le_antisym le_trans min_hight_le_height)
   126 by (metis le_antisym le_trans min_hight_le_height)
   120 
   127 
   121 lemma balanced_size1: "balanced t \<Longrightarrow> size1 t = 2 ^ height t"
   128 lemma complete_size1: "complete t \<Longrightarrow> size1 t = 2 ^ height t"
   122 by (induction t) auto
   129 by (induction t) auto
   123 
   130 
   124 lemma balanced_size: "balanced t \<Longrightarrow> size t = 2 ^ height t - 1"
   131 lemma size_if_complete: "complete t \<Longrightarrow> size t = 2 ^ height t - 1"
   125 using balanced_size1[simplified size1_def] by fastforce
   132 using complete_size1[simplified size1_def] by fastforce
       
   133 
       
   134 text\<open>A better lower bound for incomplete trees:\<close>
       
   135 
       
   136 lemma min_height_le_size_if_incomplete:
       
   137   "\<not> complete t \<Longrightarrow> 2 ^ min_height t \<le> size t"
       
   138 proof(induction t)
       
   139   case Leaf thus ?case by simp
       
   140 next
       
   141   case (Node l a r)
       
   142   show ?case (is "?l \<le> ?r")
       
   143   proof (cases "complete l")
       
   144     case l: True thus ?thesis
       
   145     proof (cases "complete r")
       
   146       case r: True
       
   147       have "height l \<noteq> height r" using Node.prems l r by simp
       
   148       hence "?l < 2 ^ min_height l + 2 ^ min_height r"
       
   149         using l r by (simp add: min_def complete_iff_height)
       
   150       also have "\<dots> = (size l + 1) + (size r + 1)"
       
   151         using l r size_if_complete[where ?'a = 'a]
       
   152         by (simp add: complete_iff_height)
       
   153       also have "\<dots> \<le> ?r + 1" by simp
       
   154       finally show ?thesis by arith
       
   155     next
       
   156       case r: False
       
   157       have "?l \<le> 2 ^ min_height l + 2 ^ min_height r" by (simp add: min_def)
       
   158       also have "\<dots> \<le> size l + 1 + size r"
       
   159         using Node.IH(2)[OF r] l size_if_complete[where ?'a = 'a]
       
   160         by (simp add: complete_iff_height)
       
   161       also have "\<dots> = ?r" by simp
       
   162       finally show ?thesis .
       
   163     qed
       
   164   next
       
   165     case l: False thus ?thesis
       
   166     proof (cases "complete r")
       
   167       case r: True
       
   168       have "?l \<le> 2 ^ min_height l + 2 ^ min_height r" by (simp add: min_def)
       
   169       also have "\<dots> \<le> size l + (size r + 1)"
       
   170         using Node.IH(1)[OF l] r size_if_complete[where ?'a = 'a]
       
   171         by (simp add: complete_iff_height)
       
   172       also have "\<dots> = ?r" by simp
       
   173       finally show ?thesis .
       
   174     next
       
   175       case r: False
       
   176       have "?l \<le> 2 ^ min_height l + 2 ^ min_height r"
       
   177         by (simp add: min_def)
       
   178       also have "\<dots> \<le> size l + size r"
       
   179         using Node.IH(1)[OF l] Node.IH(2)[OF r] by (simp)
       
   180       also have "\<dots> \<le> ?r" by simp
       
   181       finally show ?thesis .
       
   182     qed
       
   183   qed
       
   184 qed
       
   185 
       
   186 
       
   187 subsection \<open>Balanced\<close>
       
   188 
       
   189 abbreviation "balanced t \<equiv> (height t - min_height t \<le> 1)"
       
   190 
       
   191 text\<open>Balanced trees have optimal height:\<close>
       
   192 
       
   193 lemma balanced_optimal:
       
   194 fixes t :: "'a tree" and t' :: "'b tree"
       
   195 assumes "balanced t" "size t \<le> size t'" shows "height t \<le> height t'"
       
   196 proof (cases "complete t")
       
   197   case True
       
   198   have "(2::nat) ^ height t - 1 \<le> 2 ^ height t' - 1"
       
   199   proof -
       
   200     have "(2::nat) ^ height t - 1 = size t"
       
   201       using True by (simp add: complete_iff_height size_if_complete)
       
   202     also note assms(2)
       
   203     also have "size t' \<le> 2 ^ height t' - 1" by (rule size_height)
       
   204     finally show ?thesis .
       
   205   qed
       
   206   thus ?thesis by (simp add: le_diff_iff)
       
   207 next
       
   208   case False
       
   209   have "(2::nat) ^ min_height t < 2 ^ height t'"
       
   210   proof -
       
   211     have "(2::nat) ^ min_height t \<le> size t"
       
   212       by(rule min_height_le_size_if_incomplete[OF False])
       
   213     also note assms(2)
       
   214     also have "size t' \<le> 2 ^ height t' - 1"  by(rule size_height)
       
   215     finally show ?thesis
       
   216       using power_eq_0_iff[of "2::nat" "height t'"] by linarith
       
   217   qed
       
   218   hence *: "min_height t < height t'" by simp
       
   219   have "min_height t + 1 = height t"
       
   220     using min_hight_le_height[of t] assms(1) False
       
   221     by (simp add: complete_iff_height)
       
   222   with * show ?thesis by arith
       
   223 qed
   126 
   224 
   127 
   225 
   128 subsection \<open>Path length\<close>
   226 subsection \<open>Path length\<close>
   129 
   227 
   130 text \<open>The internal path length of a tree:\<close>
   228 text \<open>The internal path length of a tree:\<close>
   131 
   229 
   132 fun path_len :: "'a tree \<Rightarrow> nat" where
   230 fun path_len :: "'a tree \<Rightarrow> nat" where
   133 "path_len Leaf = 0 " |
   231 "path_len Leaf = 0 " |
   134 "path_len (Node l _ r) = path_len l + size l + path_len r + size r"
   232 "path_len (Node l _ r) = path_len l + size l + path_len r + size r"
   135 
   233 
   136 lemma path_len_if_bal: "balanced t
   234 lemma path_len_if_bal: "complete t
   137   \<Longrightarrow> path_len t = (let n = height t in 2 + n*2^n - 2^(n+1))"
   235   \<Longrightarrow> path_len t = (let n = height t in 2 + n*2^n - 2^(n+1))"
   138 proof(induction t)
   236 proof(induction t)
   139   case (Node l x r)
   237   case (Node l x r)
   140   have *: "2^(n+1) \<le> 2 + n*2^n" for n :: nat
   238   have *: "2^(n+1) \<le> 2 + n*2^n" for n :: nat
   141     by(induction n) auto
   239     by(induction n) auto
   142   have **: "(0::nat) < 2^n" for n :: nat by simp
   240   have **: "(0::nat) < 2^n" for n :: nat by simp
   143   let ?h = "height r"
   241   let ?h = "height r"
   144   show ?case using Node *[of ?h] **[of ?h] by (simp add: balanced_size Let_def)
   242   show ?case using Node *[of ?h] **[of ?h] by (simp add: size_if_complete Let_def)
   145 qed simp
   243 qed simp
   146 
   244 
   147 
   245 
   148 subsection "The set of subtrees"
   246 subsection "The set of subtrees"
   149 
   247