Theory LLVM_DS_Array
section ‹Arrays›
theory LLVM_DS_Array
imports LLVM_DS_Arith
begin
text ‹Implementing Lists by Arrays›
context begin
interpretation llvm_prim_mem_setup .
definition "array_assn ≡ mk_assn (λxs p.
↿(ll_range {0..<int (length xs)}) ((!) xs o nat) p ** ll_malloc_tag (int (length xs)) p
)"
lemma array_assn_not_null[simp]: "↿array_assn xs null = sep_false"
by (auto simp: array_assn_def)
definition [llvm_inline]: "array_new TYPE('a::llvm_rep) n ≡ ll_malloc TYPE('a) n"
definition [llvm_inline]: "array_free a ≡ ll_free a"
definition [llvm_inline]: "array_nth a i ≡ doM { p ← ll_ofs_ptr a i; ll_load p }"
definition [llvm_inline]: "array_upd a i x ≡ doM { p ← ll_ofs_ptr a i; ll_store x p; return a }"
lemma ll_range_cong: "I=I' ⟹ (⋀i. i∈I' ⟹ f i = f' i) ⟹ p=p'
⟹ ↿(ll_range I) f p = ↿(ll_range I') f' p'"
unfolding ll_range_def
by simp
lemma array_assn_cnv_range_malloc:
"↿array_assn (replicate n init) p = (↿(ll_range {0..<int n}) (λ_. init) p ** ll_malloc_tag (int n) p)"
unfolding array_assn_def
apply (simp add: sep_algebra_simps)
apply (rule sep_conj_trivial_strip2)
apply (rule ll_range_cong)
by auto
lemma array_assn_cnv_range_upd:
"↿array_assn (xs[i:=x]) p = (↿(ll_range {0..<int (length xs)}) (((!) xs ∘ nat)(int i := x)) p ** ll_malloc_tag (int (length xs)) p)"
unfolding array_assn_def
apply (simp add: sep_algebra_simps)
apply (rule sep_conj_trivial_strip2)
apply (rule ll_range_cong)
by auto
lemma pos_sint_to_uint: "0 ≤ sint i ⟹ sint i = uint i"
by (smt Suc_n_not_le_n Suc_pred bintrunc_mod2p int_mod_eq' len_gt_0 power_increasing_iff sint_range' uint_sint)
lemma array_new_rule_sint[vcg_rules]: "llvm_htriple
($$''malloc'' (nat n) ** $$''free'' 1 ** ↿sint.assn n ni ** ↑⇩d(n>0))
(array_new TYPE('a::llvm_rep) ni)
(↿array_assn (replicate (nat n) init))"
unfolding array_new_def array_assn_cnv_range_malloc sint.assn_def
supply [simp] = pos_sint_to_uint unat_def[symmetric]
by vcg
lemma array_new_rule_uint[vcg_rules]: "llvm_htriple
($$''malloc'' (nat n) ** $$''free'' 1 ** ↿uint.assn n ni ** ↑⇩d(n>0))
(array_new TYPE('a::llvm_rep) ni)
(↿array_assn (replicate (nat n) init))"
supply [simp] = unat_def[symmetric]
unfolding array_new_def array_assn_cnv_range_malloc uint.assn_def
by vcg
lemma array_new_rule_unat[vcg_rules]: "llvm_htriple
($$''malloc'' n ** $$''free'' 1 ** ↿unat.assn n ni ** ↑⇩d(n>0))
(array_new TYPE('a::llvm_rep) ni)
(↿array_assn (replicate n init))"
unfolding array_new_def array_assn_cnv_range_malloc unat.assn_def
by vcg
lemma array_new_rule_snat[vcg_rules]: "llvm_htriple
($$''malloc'' n ** $$''free'' 1 ** ↿snat.assn n ni ** ↑⇩d(n>0))
(array_new TYPE('a::llvm_rep) ni)
(↿array_assn (replicate n init))"
unfolding array_new_def array_assn_cnv_range_malloc snat.assn_def
supply [simp] = cnv_snat_to_uint and [simp del] = nat_uint_eq
by vcg
lemma array_free_rule[vcg_rules]: "llvm_htriple (↿array_assn xs p) (array_free p) (λ_. □)"
unfolding array_free_def array_assn_def
by vcg
lemma array_cast_index:
assumes "uint (ii::'a::len word) < max_sint LENGTH('a)"
shows "sint ii = uint ii" "nat (uint ii) < n ⟷ uint ii < int n"
"unat ii < n ⟷ uint ii < int n"
using assms
by (simp_all add: max_sint_def msb_uint_big sint_eq_uint unat_def nat_less_iff del: nat_uint_eq)
abbreviation (input) "in_range_nat i (ii::'a::len word) xs ≡ i<length xs ∧ int i<max_sint LENGTH('a)"
abbreviation (input) "in_range_uint i (ii::'a::len word) xs ≡ i<int (length xs) ∧ i<max_sint LENGTH('a)"
abbreviation "cost_array_nth ≡ $$''ofs_ptr'' 1 ** $$''load'' 1"
abbreviation "cost_array_upd ≡ $$''ofs_ptr'' 1 ** $$''store'' 1"
lemma array_nth_rule_sint[vcg_rules]: "llvm_htriple
(cost_array_nth ** ↿array_assn xs p ** ↿sint.assn i ii ** ↑⇩d(0≤i ∧ i<int (length xs)))
(array_nth p ii)
(λr. ↑(r = xs!nat i) ** ↿array_assn xs p)"
unfolding array_nth_def array_assn_def sint.assn_def
by vcg
lemma array_nth_rule_uint[vcg_rules]: "llvm_htriple
(cost_array_nth ** ↿array_assn xs p ** ↿uint.assn i ii ** ↑⇩d(in_range_uint i ii xs))
(array_nth p ii)
(λr. ↑(r = xs!nat i) ** ↿array_assn xs p)"
unfolding array_nth_def array_assn_def uint.assn_def
supply [simp] = array_cast_index
by vcg
lemma array_nth_rule_unat[vcg_rules]: "llvm_htriple
(cost_array_nth ** ↿array_assn xs p ** ↿unat.assn i ii ** ↑⇩d(in_range_nat i ii xs))
(array_nth p ii)
(λr. ↑(r = xs!i) ** ↿array_assn xs p)"
unfolding array_nth_def array_assn_def unat.assn_def unat_def
supply [simp] = array_cast_index
by vcg
lemma array_nth_rule_snat[vcg_rules]: "llvm_htriple
(cost_array_nth ** ↿array_assn xs p ** ↿snat.assn i ii ** ↑⇩d(i<length xs))
(array_nth p ii)
(λr. ↑(r = xs!i) ** ↿array_assn xs p)"
unfolding array_nth_def array_assn_def snat.assn_def
supply [simp] = cnv_snat_to_uint and [simp del] = nat_uint_eq
by vcg
lemma array_upd_rule_sint[vcg_rules]: "llvm_htriple
(cost_array_upd ** ↿array_assn xs p ** ↿sint.assn i ii ** ↑⇩d(0≤i ∧ i < int (length xs)))
(array_upd p ii x)
(λr. ↑(r=p) ** ↿array_assn (xs[nat i:=x]) p)"
unfolding array_assn_cnv_range_upd
unfolding array_upd_def array_assn_def sint.assn_def
supply [fri_rules] = fri_abs_cong_rl
by vcg
lemma array_upd_rule_uint[vcg_rules]: "llvm_htriple
(cost_array_upd ** ↿array_assn xs p ** ↿uint.assn i ii ** ↑⇩din_range_uint i ii xs)
(array_upd p ii x)
(λr. ↑(r=p) ** ↿array_assn (xs[nat i:=x]) p)"
unfolding array_assn_cnv_range_upd
unfolding array_upd_def array_assn_def uint.assn_def
supply [simp] = array_cast_index
supply [fri_rules] = fri_abs_cong_rl
by vcg
lemma array_upd_rule_nat[vcg_rules]: "llvm_htriple
(cost_array_upd ** ↿array_assn xs p ** ↿unat.assn i ii ** ↑⇩din_range_nat i ii xs)
(array_upd p ii x)
(λr. ↑(r=p) ** ↿array_assn (xs[i:=x]) p)"
unfolding array_assn_cnv_range_upd
unfolding array_upd_def array_assn_def unat.assn_def unat_def
supply [simp] = array_cast_index
supply [fri_rules] = fri_abs_cong_rl
by vcg
lemma array_upd_rule_snat[vcg_rules]: "llvm_htriple
(cost_array_upd ** ↿array_assn xs p ** ↿snat.assn i ii ** ↑⇩d(i<length xs))
(array_upd p ii x)
(λr. ↑(r=p) ** ↿array_assn (xs[i:=x]) p)"
unfolding array_assn_cnv_range_upd
unfolding array_upd_def array_assn_def snat.assn_def
supply [simp] = cnv_snat_to_uint and [simp del] = nat_uint_eq
supply [fri_rules] = fri_abs_cong_rl
apply vcg
done
end
end