Theory FibProof
theory FibProof
imports
"AutoCorres2_Main.AutoCorres_Main"
begin
fun fibo :: "nat ⇒ nat" where
"fibo 0 = 0" |
"fibo (Suc 0) = Suc 0" |
"fibo (Suc (Suc n)) = fibo n + fibo (Suc n)"
declare fibo.simps [simp del]
lemma fibo_alt_def: "fibo n = (if n = 0 then 0 else if n = 1 then 1 else fibo (n - 1) + fibo (n - 2))"
apply (induct n rule: less_induct)
apply (rename_tac n, case_tac n, simp add: fibo.simps)
apply (rename_tac n1, case_tac n1, simp add: fibo.simps)
apply (simp add: fibo.simps)
done
lemma fibo_mono_Suc: "fibo n ≤ fibo (Suc n)"
by (simp add: fibo_alt_def)
lemma fibo_mono: "a ≤ b ⟹ fibo a ≤ fibo b"
by (metis mono_iff_le_Suc mono_def fibo_mono_Suc)
lemma fibo_mono_strict: "n ≥ 2 ⟹ fibo n < fibo (Suc n)"
apply (case_tac n, simp)
apply (rename_tac n', subgoal_tac "fibo (Suc 0) ≤ fibo n'")
apply (simp add: fibo.simps)
apply (simp add: fibo_mono)
done
lemma fiboI: "⟦ a + 1 = b; b + 1 = c ⟧ ⟹ fibo a + fibo b = fibo c"
by (auto simp: fibo.simps)
function fibo32 :: "word32 ⇒ word32" where
"fibo32 n = (if n = 0 then 0 else if n = 1 then 1 else fibo32 (n - 1) + fibo32 (n - 2))"
apply auto
done
termination fibo32
by (relation "measure (λx. unat x)", (simp|unat_arith)+)
declare fibo32.simps [simp del]
lemma fibo32_0 [simp]: "fibo32 0 = 0"
by (subst fibo32.simps) auto
lemma fibo32_1 [simp]: "fibo32 1 = 1"
by (subst fibo32.simps) auto
lemma fibo_greater: "(6 + n) < fibo (6 + n)"
apply (induct n)
apply eval
apply (subst add_Suc_right)+
apply (subgoal_tac "Suc (6 + n) ≤ fibo (6 + n)")
apply (subgoal_tac "fibo (6 + n) < fibo (Suc (6 + n))")
apply simp
apply (rule fibo_mono_strict)
apply simp
apply simp
done
lemma fibo_greater': "n ≥ 6 ⟹ n < fibo n"
by (metis le_iff_add fibo_greater)
lemma unat_word32_plus: "unat x + unat y < 2^32 ⟹ unat x + unat y = unat (x + y :: word32)"
by (metis len32 unat_of_nat_len word_arith_nat_add)
lemma fibo32_is_fibo: "fibo n < 2^32 ⟹ fibo n = unat (fibo32 (of_nat n))"
apply (induct n rule: less_induct)
apply (subst fibo32.simps)
apply (subst fibo_alt_def)
apply (rename_tac n, case_tac "n = 0", simp)
apply (case_tac "n = 1", simp)
apply (subgoal_tac "n < 2^32"
"fibo (n - 1) + fibo (n - 2) < 2^32"
"of_nat n ≠ (0 :: word32)"
"of_nat n ≠ (1 :: word32)"
"fibo (n - 1) < 2^32"
"fibo (n - 2) < 2^32"
"fibo (n - 1) = unat (fibo32 (of_nat (n - 1)))"
"fibo (n - 2) = unat (fibo32 (of_nat (n - 2)))")
apply (fastforce intro: unat_word32_plus)
apply (metis diff_less gr0I zero_less_numeral)
apply (metis diff_less gr0I zero_less_one)
apply simp
apply simp
apply (metis len32 unat_1 unat_of_nat_len)
apply (metis len32 unat_0 unat_of_nat_len)
apply (metis fibo_alt_def)
apply (case_tac "n < 6")
apply simp
apply (subgoal_tac "n < fibo n")
apply simp
apply (simp add: fibo_greater')
done
lemma fibo32_rec: "⟦ a < a + 2; b = a + 1; c = a + 2 ⟧ ⟹ fibo32 a + fibo32 b = fibo32 c"
apply (subst(3) fibo32.simps)
apply simp
apply safe
apply unat_arith
apply (metis not_le overflow_plus_one_self word_n1_ge word_not_simps(1))
apply (metis word_not_simps(1))
apply (simp add: field_simps)
done