| author | Fabian Huch <huch@in.tum.de> | 
| Fri, 07 Jun 2024 13:52:25 +0200 | |
| changeset 80277 | 63b83637976a | 
| parent 71805 | 62b17adad0cc | 
| permissions | -rw-r--r-- | 
| 41959 | 1 | (* Title: HOL/Number_Theory/Fib.thy | 
| 2 | Author: Lawrence C. Paulson | |
| 3 | Author: Jeremy Avigad | |
| 64317 | 4 | Author: Manuel Eberl | 
| 31719 | 5 | *) | 
| 6 | ||
| 60527 | 7 | section \<open>The fibonacci function\<close> | 
| 31719 | 8 | |
| 9 | theory Fib | |
| 64317 | 10 | imports Complex_Main | 
| 31719 | 11 | begin | 
| 12 | ||
| 13 | ||
| 60526 | 14 | subsection \<open>Fibonacci numbers\<close> | 
| 31719 | 15 | |
| 54713 | 16 | fun fib :: "nat \<Rightarrow> nat" | 
| 65393 | 17 | where | 
| 18 | fib0: "fib 0 = 0" | |
| 19 | | fib1: "fib (Suc 0) = 1" | |
| 20 | | fib2: "fib (Suc (Suc n)) = fib (Suc n) + fib n" | |
| 60527 | 21 | |
| 31719 | 22 | |
| 60526 | 23 | subsection \<open>Basic Properties\<close> | 
| 31719 | 24 | |
| 65393 | 25 | lemma fib_1 [simp]: "fib 1 = 1" | 
| 54713 | 26 | by (metis One_nat_def fib1) | 
| 31719 | 27 | |
| 65393 | 28 | lemma fib_2 [simp]: "fib 2 = 1" | 
| 29 | using fib.simps(3) [of 0] by (simp add: numeral_2_eq_2) | |
| 31719 | 30 | |
| 54713 | 31 | lemma fib_plus_2: "fib (n + 2) = fib (n + 1) + fib n" | 
| 32 | by (metis Suc_eq_plus1 add_2_eq_Suc' fib.simps(3)) | |
| 31719 | 33 | |
| 65393 | 34 | lemma fib_add: "fib (Suc (n + k)) = fib (Suc k) * fib (Suc n) + fib k * fib n" | 
| 54713 | 35 | by (induct n rule: fib.induct) (auto simp add: field_simps) | 
| 31719 | 36 | |
| 54713 | 37 | lemma fib_neq_0_nat: "n > 0 \<Longrightarrow> fib n > 0" | 
| 65393 | 38 | by (induct n rule: fib.induct) auto | 
| 31719 | 39 | |
| 71805 | 40 | lemma fib_Suc_mono: "fib m \<le> fib (Suc m)" | 
| 41 | by(induction m) auto | |
| 42 | ||
| 43 | lemma fib_mono: "m \<le> n \<Longrightarrow> fib m \<le> fib n" | |
| 44 | by (simp add: fib_Suc_mono lift_Suc_mono_le) | |
| 60527 | 45 | |
| 64317 | 46 | subsection \<open>More efficient code\<close> | 
| 47 | ||
| 48 | text \<open> | |
| 49 | The naive approach is very inefficient since the branching recursion leads to many | |
| 69597 | 50 | values of \<^term>\<open>fib\<close> being computed multiple times. We can avoid this by ``remembering'' | 
| 64317 | 51 | the last two values in the sequence, yielding a tail-recursive version. | 
| 65393 | 52 | This is far from optimal (it takes roughly $O(n\cdot M(n))$ time where $M(n)$ is the | 
| 64317 | 53 | time required to multiply two $n$-bit integers), but much better than the naive version, | 
| 54 | which is exponential. | |
| 55 | \<close> | |
| 56 | ||
| 65393 | 57 | fun gen_fib :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" | 
| 58 | where | |
| 59 | "gen_fib a b 0 = a" | |
| 60 | | "gen_fib a b (Suc 0) = b" | |
| 61 | | "gen_fib a b (Suc (Suc n)) = gen_fib b (a + b) (Suc n)" | |
| 64317 | 62 | |
| 63 | lemma gen_fib_recurrence: "gen_fib a b (Suc (Suc n)) = gen_fib a b n + gen_fib a b (Suc n)" | |
| 65393 | 64 | by (induct a b n rule: gen_fib.induct) simp_all | 
| 65 | ||
| 64317 | 66 | lemma gen_fib_fib: "gen_fib (fib n) (fib (Suc n)) m = fib (n + m)" | 
| 65393 | 67 | by (induct m rule: fib.induct) (simp_all del: gen_fib.simps(3) add: gen_fib_recurrence) | 
| 64317 | 68 | |
| 69 | lemma fib_conv_gen_fib: "fib n = gen_fib 0 1 n" | |
| 70 | using gen_fib_fib[of 0 n] by simp | |
| 71 | ||
| 72 | declare fib_conv_gen_fib [code] | |
| 73 | ||
| 74 | ||
| 60526 | 75 | subsection \<open>A Few Elementary Results\<close> | 
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 76 | |
| 60526 | 77 | text \<open> | 
| 65393 | 78 | \<^medskip> Concrete Mathematics, page 278: Cassini's identity. The proof is | 
| 31719 | 79 | much easier using integers, not natural numbers! | 
| 60526 | 80 | \<close> | 
| 31719 | 81 | |
| 54713 | 82 | lemma fib_Cassini_int: "int (fib (Suc (Suc n)) * fib n) - int((fib (Suc n))\<^sup>2) = - ((-1)^n)" | 
| 65393 | 83 | by (induct n rule: fib.induct) (auto simp add: field_simps power2_eq_square power_add) | 
| 31719 | 84 | |
| 54713 | 85 | lemma fib_Cassini_nat: | 
| 60527 | 86 | "fib (Suc (Suc n)) * fib n = | 
| 87 | (if even n then (fib (Suc n))\<^sup>2 - 1 else (fib (Suc n))\<^sup>2 + 1)" | |
| 65393 | 88 | using fib_Cassini_int [of n] by (auto simp del: of_nat_mult of_nat_power) | 
| 31719 | 89 | |
| 90 | ||
| 60526 | 91 | subsection \<open>Law 6.111 of Concrete Mathematics\<close> | 
| 31719 | 92 | |
| 65393 | 93 | lemma coprime_fib_Suc_nat: "coprime (fib n) (fib (Suc n))" | 
| 54713 | 94 | apply (induct n rule: fib.induct) | 
| 67051 | 95 | apply (simp_all add: coprime_iff_gcd_eq_1 algebra_simps) | 
| 96 | apply (simp add: add.assoc [symmetric]) | |
| 44872 | 97 | done | 
| 31719 | 98 | |
| 67051 | 99 | lemma gcd_fib_add: | 
| 100 | "gcd (fib m) (fib (n + m)) = gcd (fib m) (fib n)" | |
| 101 | proof (cases m) | |
| 102 | case 0 | |
| 103 | then show ?thesis | |
| 104 | by simp | |
| 105 | next | |
| 106 | case (Suc q) | |
| 107 | from coprime_fib_Suc_nat [of q] | |
| 108 | have "coprime (fib (Suc q)) (fib q)" | |
| 109 | by (simp add: ac_simps) | |
| 110 | have "gcd (fib q) (fib (Suc q)) = Suc 0" | |
| 111 | using coprime_fib_Suc_nat [of q] by simp | |
| 112 | then have *: "gcd (fib n * fib q) (fib n * fib (Suc q)) = fib n" | |
| 113 | by (simp add: gcd_mult_distrib_nat [symmetric]) | |
| 114 | moreover have "gcd (fib (Suc q)) (fib n * fib q + fib (Suc n) * fib (Suc q)) = | |
| 115 | gcd (fib (Suc q)) (fib n * fib q)" | |
| 116 | using gcd_add_mult [of "fib (Suc q)"] by (simp add: ac_simps) | |
| 117 | moreover have "gcd (fib (Suc q)) (fib n * fib (Suc q)) = fib (Suc q)" | |
| 118 | by simp | |
| 119 | ultimately show ?thesis | |
| 120 | using Suc \<open>coprime (fib (Suc q)) (fib q)\<close> | |
| 121 | by (auto simp add: fib_add algebra_simps gcd_mult_right_right_cancel) | |
| 122 | qed | |
| 31719 | 123 | |
| 60527 | 124 | lemma gcd_fib_diff: "m \<le> n \<Longrightarrow> gcd (fib m) (fib (n - m)) = gcd (fib m) (fib n)" | 
| 54713 | 125 | by (simp add: gcd_fib_add [symmetric, of _ "n-m"]) | 
| 31719 | 126 | |
| 60527 | 127 | lemma gcd_fib_mod: "0 < m \<Longrightarrow> gcd (fib m) (fib (n mod m)) = gcd (fib m) (fib n)" | 
| 31719 | 128 | proof (induct n rule: less_induct) | 
| 129 | case (less n) | |
| 130 | show "gcd (fib m) (fib (n mod m)) = gcd (fib m) (fib n)" | |
| 131 | proof (cases "m < n") | |
| 44872 | 132 | case True | 
| 133 | then have "m \<le> n" by auto | |
| 65393 | 134 | with \<open>0 < m\<close> have "0 < n" by auto | 
| 135 | with \<open>0 < m\<close> \<open>m < n\<close> have *: "n - m < n" by auto | |
| 31719 | 136 | have "gcd (fib m) (fib (n mod m)) = gcd (fib m) (fib ((n - m) mod m))" | 
| 65393 | 137 | by (simp add: mod_if [of n]) (use \<open>m < n\<close> in auto) | 
| 44872 | 138 | also have "\<dots> = gcd (fib m) (fib (n - m))" | 
| 65393 | 139 | by (simp add: less.hyps * \<open>0 < m\<close>) | 
| 44872 | 140 | also have "\<dots> = gcd (fib m) (fib n)" | 
| 60526 | 141 | by (simp add: gcd_fib_diff \<open>m \<le> n\<close>) | 
| 31719 | 142 | finally show "gcd (fib m) (fib (n mod m)) = gcd (fib m) (fib n)" . | 
| 143 | next | |
| 44872 | 144 | case False | 
| 145 | then show "gcd (fib m) (fib (n mod m)) = gcd (fib m) (fib n)" | |
| 146 | by (cases "m = n") auto | |
| 31719 | 147 | qed | 
| 148 | qed | |
| 149 | ||
| 65393 | 150 | lemma fib_gcd: "fib (gcd m n) = gcd (fib m) (fib n)" \<comment> \<open>Law 6.111\<close> | 
| 62348 | 151 | by (induct m n rule: gcd_nat_induct) (simp_all add: gcd_non_0_nat gcd.commute gcd_fib_mod) | 
| 31719 | 152 | |
| 64267 | 153 | theorem fib_mult_eq_sum_nat: "fib (Suc n) * fib n = (\<Sum>k \<in> {..n}. fib k * fib k)"
 | 
| 54713 | 154 | by (induct n rule: nat.induct) (auto simp add: field_simps) | 
| 31719 | 155 | |
| 60527 | 156 | |
| 64317 | 157 | subsection \<open>Closed form\<close> | 
| 158 | ||
| 159 | lemma fib_closed_form: | |
| 65393 | 160 | fixes \<phi> \<psi> :: real | 
| 161 | defines "\<phi> \<equiv> (1 + sqrt 5) / 2" | |
| 162 | and "\<psi> \<equiv> (1 - sqrt 5) / 2" | |
| 163 | shows "of_nat (fib n) = (\<phi> ^ n - \<psi> ^ n) / sqrt 5" | |
| 164 | proof (induct n rule: fib.induct) | |
| 64317 | 165 | fix n :: nat | 
| 166 | assume IH1: "of_nat (fib n) = (\<phi> ^ n - \<psi> ^ n) / sqrt 5" | |
| 167 | assume IH2: "of_nat (fib (Suc n)) = (\<phi> ^ Suc n - \<psi> ^ Suc n) / sqrt 5" | |
| 168 | have "of_nat (fib (Suc (Suc n))) = of_nat (fib (Suc n)) + of_nat (fib n)" by simp | |
| 65393 | 169 | also have "\<dots> = (\<phi>^n * (\<phi> + 1) - \<psi>^n * (\<psi> + 1)) / sqrt 5" | 
| 64317 | 170 | by (simp add: IH1 IH2 field_simps) | 
| 171 | also have "\<phi> + 1 = \<phi>\<^sup>2" by (simp add: \<phi>_def field_simps power2_eq_square) | |
| 172 | also have "\<psi> + 1 = \<psi>\<^sup>2" by (simp add: \<psi>_def field_simps power2_eq_square) | |
| 65393 | 173 | also have "\<phi>^n * \<phi>\<^sup>2 - \<psi>^n * \<psi>\<^sup>2 = \<phi> ^ Suc (Suc n) - \<psi> ^ Suc (Suc n)" | 
| 64317 | 174 | by (simp add: power2_eq_square) | 
| 175 | finally show "of_nat (fib (Suc (Suc n))) = (\<phi> ^ Suc (Suc n) - \<psi> ^ Suc (Suc n)) / sqrt 5" . | |
| 176 | qed (simp_all add: \<phi>_def \<psi>_def field_simps) | |
| 177 | ||
| 178 | lemma fib_closed_form': | |
| 65393 | 179 | fixes \<phi> \<psi> :: real | 
| 180 | defines "\<phi> \<equiv> (1 + sqrt 5) / 2" | |
| 181 | and "\<psi> \<equiv> (1 - sqrt 5) / 2" | |
| 64317 | 182 | assumes "n > 0" | 
| 65393 | 183 | shows "fib n = round (\<phi> ^ n / sqrt 5)" | 
| 64317 | 184 | proof (rule sym, rule round_unique') | 
| 185 | have "\<bar>\<phi> ^ n / sqrt 5 - of_int (int (fib n))\<bar> = \<bar>\<psi>\<bar> ^ n / sqrt 5" | |
| 186 | by (simp add: fib_closed_form[folded \<phi>_def \<psi>_def] field_simps power_abs) | |
| 187 |   also {
 | |
| 188 | from assms have "\<bar>\<psi>\<bar>^n \<le> \<bar>\<psi>\<bar>^1" | |
| 189 | by (intro power_decreasing) (simp_all add: algebra_simps real_le_lsqrt) | |
| 65393 | 190 | also have "\<dots> < sqrt 5 / 2" by (simp add: \<psi>_def field_simps) | 
| 64317 | 191 | finally have "\<bar>\<psi>\<bar>^n / sqrt 5 < 1/2" by (simp add: field_simps) | 
| 192 | } | |
| 193 | finally show "\<bar>\<phi> ^ n / sqrt 5 - of_int (int (fib n))\<bar> < 1/2" . | |
| 194 | qed | |
| 195 | ||
| 196 | lemma fib_asymptotics: | |
| 65393 | 197 | fixes \<phi> :: real | 
| 198 | defines "\<phi> \<equiv> (1 + sqrt 5) / 2" | |
| 199 | shows "(\<lambda>n. real (fib n) / (\<phi> ^ n / sqrt 5)) \<longlonglongrightarrow> 1" | |
| 64317 | 200 | proof - | 
| 65393 | 201 | define \<psi> :: real where "\<psi> \<equiv> (1 - sqrt 5) / 2" | 
| 64317 | 202 | have "\<phi> > 1" by (simp add: \<phi>_def) | 
| 65393 | 203 | then have *: "\<phi> \<noteq> 0" by auto | 
| 64317 | 204 | have "(\<lambda>n. (\<psi> / \<phi>) ^ n) \<longlonglongrightarrow> 0" | 
| 205 | by (rule LIMSEQ_power_zero) (simp_all add: \<phi>_def \<psi>_def field_simps add_pos_pos) | |
| 65393 | 206 | then have "(\<lambda>n. 1 - (\<psi> / \<phi>) ^ n) \<longlonglongrightarrow> 1 - 0" | 
| 207 | by (intro tendsto_diff tendsto_const) | |
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
69597diff
changeset | 208 | with * have "(\<lambda>n. (\<phi> ^ n - \<psi> ^ n) / \<phi> ^ n) \<longlonglongrightarrow> 1" | 
| 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
69597diff
changeset | 209 | by (simp add: field_simps) | 
| 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
69597diff
changeset | 210 | then show ?thesis | 
| 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
69597diff
changeset | 211 | by (simp add: fib_closed_form \<phi>_def \<psi>_def) | 
| 64317 | 212 | qed | 
| 213 | ||
| 214 | ||
| 215 | subsection \<open>Divide-and-Conquer recurrence\<close> | |
| 216 | ||
| 217 | text \<open> | |
| 65393 | 218 | The following divide-and-conquer recurrence allows for a more efficient computation | 
| 219 | of Fibonacci numbers; however, it requires memoisation of values to be reasonably | |
| 64317 | 220 | efficient, cutting the number of values to be computed to logarithmically many instead of | 
| 65393 | 221 | linearly many. The vast majority of the computation time is then actually spent on the | 
| 64317 | 222 | multiplication, since the output number is exponential in the input number. | 
| 223 | \<close> | |
| 224 | ||
| 225 | lemma fib_rec_odd: | |
| 65393 | 226 | fixes \<phi> \<psi> :: real | 
| 227 | defines "\<phi> \<equiv> (1 + sqrt 5) / 2" | |
| 228 | and "\<psi> \<equiv> (1 - sqrt 5) / 2" | |
| 229 | shows "fib (Suc (2 * n)) = fib n^2 + fib (Suc n)^2" | |
| 64317 | 230 | proof - | 
| 231 | have "of_nat (fib n^2 + fib (Suc n)^2) = ((\<phi> ^ n - \<psi> ^ n)\<^sup>2 + (\<phi> * \<phi> ^ n - \<psi> * \<psi> ^ n)\<^sup>2)/5" | |
| 232 | by (simp add: fib_closed_form[folded \<phi>_def \<psi>_def] field_simps power2_eq_square) | |
| 65393 | 233 | also | 
| 234 | let ?A = "\<phi>^(2 * n) + \<psi>^(2 * n) - 2*(\<phi> * \<psi>)^n + \<phi>^(2 * n + 2) + \<psi>^(2 * n + 2) - 2*(\<phi> * \<psi>)^(n + 1)" | |
| 235 | have "(\<phi> ^ n - \<psi> ^ n)\<^sup>2 + (\<phi> * \<phi> ^ n - \<psi> * \<psi> ^ n)\<^sup>2 = ?A" | |
| 236 | by (simp add: power2_eq_square algebra_simps power_mult power_mult_distrib) | |
| 237 | also have "\<phi> * \<psi> = -1" | |
| 238 | by (simp add: \<phi>_def \<psi>_def field_simps) | |
| 239 | then have "?A = \<phi>^(2 * n + 1) * (\<phi> + inverse \<phi>) + \<psi>^(2 * n + 1) * (\<psi> + inverse \<psi>)" | |
| 64317 | 240 | by (auto simp: field_simps power2_eq_square) | 
| 65393 | 241 | also have "1 + sqrt 5 > 0" | 
| 242 | by (auto intro: add_pos_pos) | |
| 243 | then have "\<phi> + inverse \<phi> = sqrt 5" | |
| 244 | by (simp add: \<phi>_def field_simps) | |
| 245 | also have "\<psi> + inverse \<psi> = -sqrt 5" | |
| 246 | by (simp add: \<psi>_def field_simps) | |
| 247 | also have "(\<phi> ^ (2 * n + 1) * sqrt 5 + \<psi> ^ (2 * n + 1) * - sqrt 5) / 5 = | |
| 248 | (\<phi> ^ (2 * n + 1) - \<psi> ^ (2 * n + 1)) * (sqrt 5 / 5)" | |
| 249 | by (simp add: field_simps) | |
| 250 | also have "sqrt 5 / 5 = inverse (sqrt 5)" | |
| 251 | by (simp add: field_simps) | |
| 252 | also have "(\<phi> ^ (2 * n + 1) - \<psi> ^ (2 * n + 1)) * \<dots> = of_nat (fib (Suc (2 * n)))" | |
| 64317 | 253 | by (simp add: fib_closed_form[folded \<phi>_def \<psi>_def] divide_inverse) | 
| 65393 | 254 | finally show ?thesis | 
| 255 | by (simp only: of_nat_eq_iff) | |
| 64317 | 256 | qed | 
| 257 | ||
| 65393 | 258 | lemma fib_rec_even: "fib (2 * n) = (fib (n - 1) + fib (n + 1)) * fib n" | 
| 259 | proof (induct n) | |
| 260 | case 0 | |
| 261 | then show ?case by simp | |
| 262 | next | |
| 64317 | 263 | case (Suc n) | 
| 264 | let ?rfib = "\<lambda>x. real (fib x)" | |
| 65393 | 265 | have "2 * (Suc n) = Suc (Suc (2 * n))" by simp | 
| 266 | also have "real (fib \<dots>) = ?rfib n^2 + ?rfib (Suc n)^2 + (?rfib (n - 1) + ?rfib (n + 1)) * ?rfib n" | |
| 64317 | 267 | by (simp add: fib_rec_odd Suc) | 
| 268 | also have "(?rfib (n - 1) + ?rfib (n + 1)) * ?rfib n = (2 * ?rfib (n + 1) - ?rfib n) * ?rfib n" | |
| 269 | by (cases n) simp_all | |
| 65393 | 270 | also have "?rfib n^2 + ?rfib (Suc n)^2 + \<dots> = (?rfib (Suc n) + 2 * ?rfib n) * ?rfib (Suc n)" | 
| 64317 | 271 | by (simp add: algebra_simps power2_eq_square) | 
| 65393 | 272 | also have "\<dots> = real ((fib (Suc n - 1) + fib (Suc n + 1)) * fib (Suc n))" by simp | 
| 64317 | 273 | finally show ?case by (simp only: of_nat_eq_iff) | 
| 65393 | 274 | qed | 
| 64317 | 275 | |
| 65393 | 276 | lemma fib_rec_even': "fib (2 * n) = (2 * fib (n - 1) + fib n) * fib n" | 
| 64317 | 277 | by (subst fib_rec_even, cases n) simp_all | 
| 278 | ||
| 279 | lemma fib_rec: | |
| 65393 | 280 | "fib n = | 
| 281 | (if n = 0 then 0 else if n = 1 then 1 | |
| 282 | else if even n then let n' = n div 2; fn = fib n' in (2 * fib (n' - 1) + fn) * fn | |
| 283 | else let n' = n div 2 in fib n' ^ 2 + fib (Suc n') ^ 2)" | |
| 64317 | 284 | by (auto elim: evenE oddE simp: fib_rec_odd fib_rec_even' Let_def) | 
| 285 | ||
| 286 | ||
| 60526 | 287 | subsection \<open>Fibonacci and Binomial Coefficients\<close> | 
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 288 | |
| 64267 | 289 | lemma sum_drop_zero: "(\<Sum>k = 0..Suc n. if 0<k then (f (k - 1)) else 0) = (\<Sum>j = 0..n. f j)" | 
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 290 | by (induct n) auto | 
| 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 291 | |
| 64267 | 292 | lemma sum_choose_drop_zero: | 
| 65393 | 293 | "(\<Sum>k = 0..Suc n. if k = 0 then 0 else (Suc n - k) choose (k - 1)) = | 
| 294 | (\<Sum>j = 0..n. (n-j) choose j)" | |
| 64267 | 295 | by (rule trans [OF sum.cong sum_drop_zero]) auto | 
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 296 | |
| 60527 | 297 | lemma ne_diagonal_fib: "(\<Sum>k = 0..n. (n-k) choose k) = fib (Suc n)" | 
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 298 | proof (induct n rule: fib.induct) | 
| 60527 | 299 | case 1 | 
| 300 | show ?case by simp | |
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 301 | next | 
| 60527 | 302 | case 2 | 
| 303 | show ?case by simp | |
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 304 | next | 
| 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 305 | case (3 n) | 
| 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 306 | have "(\<Sum>k = 0..Suc n. Suc (Suc n) - k choose k) = | 
| 65393 | 307 | (\<Sum>k = 0..Suc n. (Suc n - k choose k) + (if k = 0 then 0 else (Suc n - k choose (k - 1))))" | 
| 64267 | 308 | by (rule sum.cong) (simp_all add: choose_reduce_nat) | 
| 65393 | 309 | also have "\<dots> = | 
| 310 | (\<Sum>k = 0..Suc n. Suc n - k choose k) + | |
| 311 | (\<Sum>k = 0..Suc n. if k=0 then 0 else (Suc n - k choose (k - 1)))" | |
| 64267 | 312 | by (simp add: sum.distrib) | 
| 65393 | 313 | also have "\<dots> = (\<Sum>k = 0..Suc n. Suc n - k choose k) + (\<Sum>j = 0..n. n - j choose j)" | 
| 64267 | 314 | by (metis sum_choose_drop_zero) | 
| 60141 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 315 | finally show ?case using 3 | 
| 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 316 | by simp | 
| 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 317 | qed | 
| 
833adf7db7d8
New material, mostly about limits. Consolidation.
 paulson <lp15@cam.ac.uk> parents: 
59667diff
changeset | 318 | |
| 31719 | 319 | end |