Theory factorial
theory factorial
imports "AutoCorres2.CTranslation" "MachineWords"
begin
declare hrs_simps [simp add]
declare sep_conj_ac [simp add]
consts free_pool :: "nat ⇒ heap_assert"
primrec
fac :: "nat ⇒ machine_word"
where
"fac 0 = 1"
| "fac (Suc n) = of_nat (Suc n) * fac n"
lemma fac_unfold:
"unat n ≠ 0 ⟹ fac (unat n) = n * fac (unat (n - 1))"
apply(case_tac "unat n")
apply simp
apply(subst unat_minus_one)
apply(simp only: unat_simps)
apply(clarify)
apply simp
apply clarsimp
apply(simp only: unat_simps)
apply(subst mod_less)
apply (fold len_of_addr_card)
apply unat_arith
apply (clarsimp simp: distrib_right split: unat_splits)
done
primrec
fac_list :: "nat ⇒ machine_word list"
where
"fac_list 0 = [1]"
| "fac_list (Suc n) = fac (Suc n) # fac_list n"
lemma fac_list_length [simp]:
"length (fac_list n) = n + 1"
by (induct n) auto
lemma fac_list_unfold:
"unat n ≠ 0 ⟹ fac_list (unat n) = fac (unat n) # fac_list (unat (n - 1))"
apply(case_tac "unat n")
apply clarsimp
apply(subst unat_minus_one)
apply force
apply clarsimp
done
primrec
sep_list :: "machine_word list ⇒ machine_word ptr ⇒ heap_assert"
where
"sep_list [] p = (λs. p=NULL ∧ □ s)"
| "sep_list (x#xs) p = (λs. ∃j. ((p ↦ x) ∧⇧* (p +⇩p 1) ↦ j ∧⇧*
sep_list xs (Ptr j)) s)"
lemma sep_list_NULL [simp]:
"sep_list xs NULL = (λs. xs = [] ∧ □ s)"
by (case_tac xs) auto
definition
sep_fac_list :: "machine_word ⇒ machine_word ptr ⇒ heap_assert"
where
"sep_fac_list n p ≡ sep_list (fac_list (unat n)) p"
lemma sep_fac_list_unfold:
"((λs. unat n ≠ 0 ∧ (∃q. (p ↦ fac (unat n) ∧⇧* (p +⇩p 1) ↦ q ∧⇧*
sep_fac_list (n - 1) (Ptr q)) s)) ∧⇧* R) s ⟹
(sep_fac_list n p ∧⇧* R) s"
apply (erule sep_globalise)
apply (simp add: sep_fac_list_def fac_list_unfold)
done
lemma sep_fac_list_points:
"sep_points (sep_fac_list n p) s ⟹ (p ↪ fac (unat n)) s"
apply(unfold sep_points_def)
apply(subst sep_map'_unfold)
apply(erule sep_conj_impl)
apply(unfold sep_fac_list_def)
apply(case_tac "unat n")
apply simp
apply(unfold sep_map'_old)
apply(erule (1) sep_conj_impl)
apply simp
apply clarsimp
apply(subst (asm) sep_conj_assoc [symmetric])+
apply(erule sep_conj_impl)
apply simp+
done
declare [[c_parser_feedback_level = 2]]