| author | wenzelm | 
| Sat, 25 Nov 2023 17:11:32 +0100 | |
| changeset 79060 | 9f2040e5e2d6 | 
| 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: 
59667 
diff
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: 
69597 
diff
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: 
69597 
diff
changeset
 | 
209  | 
by (simp add: field_simps)  | 
| 
 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 
haftmann 
parents: 
69597 
diff
changeset
 | 
210  | 
then show ?thesis  | 
| 
 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 
haftmann 
parents: 
69597 
diff
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: 
59667 
diff
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: 
59667 
diff
changeset
 | 
290  | 
by (induct n) auto  | 
| 
 
833adf7db7d8
New material, mostly about limits. Consolidation.
 
paulson <lp15@cam.ac.uk> 
parents: 
59667 
diff
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: 
59667 
diff
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: 
59667 
diff
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: 
59667 
diff
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: 
59667 
diff
changeset
 | 
304  | 
next  | 
| 
 
833adf7db7d8
New material, mostly about limits. Consolidation.
 
paulson <lp15@cam.ac.uk> 
parents: 
59667 
diff
changeset
 | 
305  | 
case (3 n)  | 
| 
 
833adf7db7d8
New material, mostly about limits. Consolidation.
 
paulson <lp15@cam.ac.uk> 
parents: 
59667 
diff
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: 
59667 
diff
changeset
 | 
315  | 
finally show ?case using 3  | 
| 
 
833adf7db7d8
New material, mostly about limits. Consolidation.
 
paulson <lp15@cam.ac.uk> 
parents: 
59667 
diff
changeset
 | 
316  | 
by simp  | 
| 
 
833adf7db7d8
New material, mostly about limits. Consolidation.
 
paulson <lp15@cam.ac.uk> 
parents: 
59667 
diff
changeset
 | 
317  | 
qed  | 
| 
 
833adf7db7d8
New material, mostly about limits. Consolidation.
 
paulson <lp15@cam.ac.uk> 
parents: 
59667 
diff
changeset
 | 
318  | 
|
| 31719 | 319  | 
end  |