blob: 28b4ba648024c5d3bfdec84014122be5a5c0da1a [file]
(*
* Copyright 2016, NICTA
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(NICTA_GPL)
*)
theory OstoreR
imports
"../spec/OstoreS"
"../spec/OstoreInvS"
"../spec/TransS"
"../impl/BilbyFs_Shallow_Desugar_Tuples"
"../adt/BufferT"
"../spec/SerialS"
"HOL-Library.Sublist"
(* "~~/src/HOL/Word/WordBitwise" *)
"HOL-Library.Multiset"
begin
lemma take_list_update:
"i < length xs
\<Longrightarrow> take n (xs[i := x]) = (if i < n then (take n xs)[i := x] else take n xs)"
by (induct xs arbitrary: n i, simp_all add: take_Cons split: nat.split)
lemma drop_list_update:
"i < length xs
\<Longrightarrow> drop n (xs[i := x]) = (if i < n then drop n xs else (drop n xs)[i - n := x])"
by (induct xs arbitrary: n i, simp_all add: drop_Cons split: nat.split)
lemma is_set_0[simp]:
"\<not>is_set (0, x)"
"\<not>is_set (ostoreWriteNone, x)"
by (simp add: ostoreWriteNone_def is_set_def)+
lemma padding_to_eq_align32_simp:
"\<not> no_summary\<^sub>f mount_st \<Longrightarrow>
padding_to (mount_st, ostore_st, ostoreWriteNone) =
align32 (used\<^sub>f ostore_st, io_size\<^sub>f (super\<^sub>f mount_st))"
unfolding padding_to_def[unfolded tuple_simps sanitizers]
by (simp add: ostoreWriteNone_def Let_def)
lemma padding_to_ret:
"\<lbrakk> P (if is_set(osw,ostoreWriteNewEb) then
if no_summary\<^sub>f mount_st \<or> used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st) then
eb_size\<^sub>f (super\<^sub>f mount_st)
else
eb_size\<^sub>f (super\<^sub>f mount_st) -
serialise_size_summary_Obj_with_extra (summary\<^sub>f ostore_st, 0)
else align32 (used\<^sub>f ostore_st, io_size\<^sub>f (super\<^sub>f mount_st))) \<rbrakk> \<Longrightarrow>
P (padding_to (mount_st, ostore_st, osw))"
unfolding padding_to_def[unfolded sanitizers tuple_simps]
by (fastforce simp: Let_def ostoreWriteNewEb_def)
lemma word_le_diff:
"(a::U32) < a + b \<Longrightarrow>
a + b \<le> c \<Longrightarrow>
a \<le> c - b"
by (unat_arith)
lemma os_sum_sz_simp:
"serialise_size_summary_Obj_with_extra (summary\<^sub>f ostore_st, 0) = os_sum_sz ostore_st"
by (simp add: os_sum_sz_def serialise_size_summary_Obj_def
serialise_size_summary_Obj_with_extra_def bilbyFsObjHeaderSize_def)
lemma padding_to_eb_fullE:
"inv_ostore mount_st ostore_st \<Longrightarrow>
inv_mount_st mount_st \<Longrightarrow>
used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st) \<Longrightarrow>
(used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st) \<Longrightarrow>
P (eb_size\<^sub>f (super\<^sub>f mount_st)))
\<Longrightarrow> P (padding_to (mount_st, ostore_st, osw))"
apply (rule padding_to_ret)
apply (case_tac "is_set (osw, ostoreWriteNewEb)")
apply simp
apply clarsimp
apply (clarsimp simp:inv_mount_st_def Let_def)
apply (simp add: align32_unchanged)
done
lemma sync_offs_le_padding_to:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
shows
"sync_offs\<^sub>f ostore_st \<le> padding_to (mount_st, ostore_st, ostoreWriteNone)"
apply (case_tac "used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st)")
apply (erule padding_to_eb_fullE[OF inv_ostore inv_mount_st])
using inv_ostore apply (fastforce simp: inv_ostore_def)
apply (simp add: padding_to_def)
using inv_ostore_sync_offsD[OF inv_ostore] align32_le[where v="used\<^sub>f ostore_st" and al="io_size\<^sub>f (super\<^sub>f mount_st)"]
inv_mount_st inv_ostore_used_no_overflowD[OF inv_ostore] apply (clarsimp simp: inv_mount_st_def Let_def)
apply unat_arith+
done
lemma used_le_padding_to:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
assumes inv_mount_st: "inv_mount_st mount_st"
shows
"used\<^sub>f ostore_st \<le> padding_to (mount_st, ostore_st, ostoreWriteNone)"
apply (case_tac "used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st)")
apply (erule padding_to_eb_fullE[OF inv_ostore inv_mount_st])
apply (rule inv_ostore_usedD[OF inv_ostore])
apply (simp add: padding_to_def)
apply (rule align32_le)
using inv_mount_st
apply (fastforce simp: inv_mount_st_def Let_def)
using inv_mount_st inv_ostore_used_no_overflowD[OF inv_ostore]
apply (clarsimp simp add: inv_mount_st_def Let_def)
done
lemma padding_to_le_length_wbuf:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
shows
"unat (padding_to (mount_st, ostore_st, ostoreWriteNone)) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
apply (simp add: padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def)
using align32_upper_bound[where bound="eb_size\<^sub>f (super\<^sub>f mount_st)" and v="used\<^sub>f ostore_st" and
al="io_size\<^sub>f (super\<^sub>f mount_st)"]
using inv_mount_st[simplified inv_mount_st_def Let_def] apply clarsimp
using inv_ostore_usedD[OF inv_ostore] apply simp
using inv_ostore_used_no_overflowD[OF inv_ostore] apply simp
using inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
apply unat_arith
done
lemma take_eq_strenghen:
assumes "take m xs = take m ys"
and "n \<le> m"
shows
"take n xs = take n ys"
using assms by (metis min.absorb_iff2 min.commute take_take)
lemma inv_ostore_bound_le_lenD:
"inv_ostore mount_st ostore_st \<Longrightarrow>
unat (bound\<^sub>f (wbuf\<^sub>f ostore_st)) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
apply (clarsimp simp: inv_ostore_def buf_simps wordarray_length_ret)
using wordarray_length_ret[where arr="data\<^sub>f (wbuf\<^sub>f ostore_st)"]
apply simp
done
lemma prepare_memset_get_obj_eq:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
shows
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
ostore_get_obj (ostore_st \<lparr>wbuf\<^sub>f := buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte),
used\<^sub>f := pad_to\<rparr>) v = ostore_get_obj ostore_st v"
apply (clarsimp simp: ostore_get_obj_def)
apply (rule_tac f="\<lambda>x. pObj x (ObjAddr.offs\<^sub>f v)" in arg_cong)
apply (rule_tac m="unat $ used\<^sub>f ostore_st" in take_eq_strenghen)
using wordarray_length_ret[where arr="data\<^sub>f (wbuf\<^sub>f ostore_st)", symmetric]
inv_ostore_wbuf_boundD[OF inv_ostore]
inv_ostore_usedD[OF inv_ostore]
inv_ostore_wbuf_lengthD[OF inv_ostore ]
inv_mount_st[simplified inv_mount_st_def]
unfolding is_valid_addr_def
apply (subst buf_memset_eq[OF inv_ostore_bound_le_lenD[OF inv_ostore]])
using used_le_padding_to[OF inv_ostore inv_mount_st]
apply (simp add: pad_to)
apply (fastforce simp: buf_memset_eq word_le_nat_alt buf_simps wordarray_make
is_valid_addr_def Let_def pad_to min_absorb1)
apply (unat_arith)
done
lemma inv_ostore_index_padding_bytes:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
shows
"inv_ostore_index mount_st
(ostore_st \<lparr>wbuf\<^sub>f := buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte),
used\<^sub>f := pad_to\<rparr>)"
(is "inv_ostore_index mount_st ?ostore_st")
proof -
have index_unchanged:
"index_st\<^sub>f ?ostore_st = index_st\<^sub>f ostore_st" by simp
also have inv_ostore_index:
"inv_ostore_index mount_st ostore_st"
using inv_ostore by (simp add: inv_ostore_def)
moreover have pad_to_ge_used:
"used\<^sub>f ostore_st \<le> pad_to"
by (subst pad_to, rule used_le_padding_to[OF inv_ostore inv_mount_st])
moreover have is_valid_addr:
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
is_valid_addr mount_st ?ostore_st v"
apply (clarsimp simp: is_valid_addr_def pad_to)
apply (case_tac "used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st)")
apply (erule (1) padding_to_eb_fullE[OF inv_ostore inv_mount_st])
apply (cut_tac used_le_padding_to[OF inv_ostore inv_mount_st])
apply (unat_arith)
done
moreover have get_obj_eq:
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
ostore_get_obj ?ostore_st v = ostore_get_obj ostore_st v"
using prepare_memset_get_obj_eq[OF inv_ostore inv_mount_st pad_to] .
ultimately show ?thesis
unfolding inv_ostore_index_def
by (clarsimp simp: Let_def)
qed
lemma map_eq_iff_nth_eq:
"(map f xs = map g ys) = (length xs = length ys \<and> (\<forall>i\<in>{0..<length xs}. f (xs!i) = g (ys!i)))"
by (auto simp: list_eq_iff_nth_eq[where xs="map f xs"] dest: map_eq_imp_length_eq)
text {* Adding padding does not add any object to the ostore_log_objects,
Should probably also have a lemma to prove that the snd part of list_trans on all erase-blocks
is unchanged. That lemma can be used to prove this one almost trivially as ostore_log_objects only used snd
part of the "EbLog list".
*}
lemma length_pollute_buf:
"length (pollute_buf n xs) = length xs"
by (simp add: pollute_buf_def)
lemma buf_slice_buf_memset_is_append_padding:
notes list_trans.simps[simp del]
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and frm: "frm \<in> {0, (sync_offs\<^sub>f ostore_st)}"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
shows
"buf_slice (buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte))
frm pad_to =
buf_slice (wbuf\<^sub>f ostore_st) frm (used\<^sub>f ostore_st) @ padding (unat pad_to - unat (used\<^sub>f ostore_st))"
using inv_ostore_sync_offsD[OF inv_ostore,simplified word_le_nat_alt]
inv_ostore_buf_bound_eqD[OF inv_ostore]
inv_ostore_used_len_wbufD[OF inv_ostore inv_mount_st]
apply (subst buf_memset_eq[OF inv_ostore_bound_le_lenD[OF inv_ostore]])
using used_le_padding_to[OF inv_ostore inv_mount_st]
apply (simp add: pad_to)
apply (subgoal_tac "unat (align32 (used\<^sub>f ostore_st, io_size\<^sub>f (super\<^sub>f mount_st))) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))")
apply (subgoal_tac "0 < io_size\<^sub>f (super\<^sub>f mount_st)")
apply (case_tac "frm = sync_offs\<^sub>f ostore_st")
using inv_mount_st[simplified inv_mount_st_def Let_def] inv_ostore_used_no_overflowD[OF inv_ostore]
apply (clarsimp simp add: pad_to' buf_simps wordarray_make unat_arith_simps(4-5)
min_absorb1 min_absorb2 align32_le[simplified word_le_nat_alt] padding_def)
using frm inv_mount_st[simplified inv_mount_st_def Let_def] inv_ostore_used_no_overflowD[OF inv_ostore]
apply (clarsimp simp add: buf_memset_eq pad_to' buf_simps wordarray_make unat_arith_simps(4-5)
min_absorb1 min_absorb2 align32_le[simplified word_le_nat_alt] padding_def)
using frm inv_mount_st[simplified inv_mount_st_def Let_def]
apply (clarsimp, unat_arith)
using align32_upper_bound inv_ostore_eb_size_wbuf_eqD[OF inv_ostore, symmetric] inv_mount_st
inv_ostore_used_no_overflowD[OF inv_ostore]
apply (simp only: unat_arith_simps, fastforce simp add: inv_mount_st_def Let_def)
done
lemma inv_ostore_valid_list_trans_wbuf:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
assumes used_gt_zero: "0 < used\<^sub>f ostore_st"
assumes sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows
"valid_list_trans (buf_take (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st))"
using inv_bufsD[OF inv_ostore, simplified used_gt_zero sync_lt_used]
apply (clarsimp simp add: valid_list_trans_no_pad_def buf_slice_0_eq_buf_take)
apply (simp add: buf_take_buf_slice_adjacent[OF order.strict_implies_order[OF sync_lt_used],symmetric])
apply (erule (1) valid_list_trans_append)
done
lemma snd_list_trans_memset:
notes list_trans.simps[simp del]
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and frm: "frm \<in> {0, (sync_offs\<^sub>f ostore_st)}"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
shows
"prod.snd (list_trans_no_pad
(buf_slice (buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte))
frm pad_to)) =
prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) frm (used\<^sub>f ostore_st)))"
proof -
have sync_le_used: "sync_offs\<^sub>f ostore_st \<le> used\<^sub>f ostore_st" using sync_lt_used by unat_arith
show ?thesis
using buf_slice_buf_memset_is_append_padding[OF inv_ostore inv_mount_st pad_to, where frm=frm]
apply simp
apply (case_tac "frm = 0")
using frm apply (simp add: buf_slice_0_eq_buf_take)
apply (rule snd_list_trans_no_pad_padding_unchanged)
apply (rule inv_ostore_valid_list_trans_wbuf[OF inv_ostore used_gt_zero sync_lt_used])
using frm apply simp
apply (rule snd_list_trans_no_pad_padding_unchanged)
using inv_bufsD[OF inv_ostore, simplified sync_lt_used]
apply (simp add: valid_list_trans_no_pad_def)
done
qed
lemma ostore_log_objects_padding_bytes:
notes list_trans.simps [simp del]
assumes inv_ostore: "inv_ostore mount_st ostore_st"
assumes inv_mount_st: "inv_mount_st mount_st"
assumes pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
assumes padsz: "padsz = unat (used\<^sub>f ostore_st) - unat pad_to"
assumes used_gt_zero: "0 < used\<^sub>f ostore_st"
assumes sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows
"ostore_log_objects (list_eb_log_wbuf (ostore_st \<lparr>wbuf\<^sub>f :=
buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte), used\<^sub>f := pad_to\<rparr>))
=
ostore_log_objects (list_eb_log_wbuf ostore_st)"
(is "ostore_log_objects (list_eb_log_wbuf ?ostore_st) =
ostore_log_objects (list_eb_log_wbuf ostore_st)")
proof -
have len_eq: "length (list_eb_log_wbuf ?ostore_st) = length (list_eb_log_wbuf ostore_st)"
by (simp add: list_eb_log_wbuf_def list_eb_log_def)
have pad_to_gt_0: "pad_to > 0"
using used_le_padding_to[OF inv_ostore inv_mount_st] pad_to used_gt_zero
by unat_arith
have pad_to': "pad_to = align32 (used\<^sub>f ostore_st, io_size\<^sub>f (super\<^sub>f mount_st))"
using pad_to by (simp add: padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def)
have val_xs: "valid_list_trans (buf_slice (wbuf\<^sub>f ostore_st) 0 (sync_offs\<^sub>f ostore_st))"
using inv_bufsD[OF inv_ostore] used_gt_zero
by (clarsimp simp: buf_slice_0_eq_buf_take valid_list_trans_no_pad_def)
have val_ys: "valid_list_trans (buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st))"
using inv_bufsD[OF inv_ostore] sync_lt_used
by (clarsimp simp: valid_list_trans_no_pad_def)
have sync_le_used: "sync_offs\<^sub>f ostore_st \<le> used\<^sub>f ostore_st" using sync_lt_used by simp
have valid_list_trans_till_used: "valid_list_trans (buf_slice (wbuf\<^sub>f ostore_st) 0 (used\<^sub>f ostore_st))"
using inv_bufsD[OF inv_ostore] used_gt_zero sync_lt_used
apply (clarsimp simp add: unat_arith_simps valid_list_trans_no_pad_def)
using valid_list_trans_append[where xs="buf_take (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st)" and
ys="buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)"]
buf_take_buf_slice_adjacent[OF sync_le_used]
apply (simp add: buf_simps Let_def)
done
have snd_list_trans_no_pad:
"prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) 0 (used\<^sub>f ostore_st))) \<noteq> []"
using inv_bufsD[OF inv_ostore] used_gt_zero sync_lt_used
apply (clarsimp simp add: unat_arith_simps valid_list_trans_no_pad_def del: notI)
apply (drule (1) list_trans_no_pad_append)
apply (simp only: length_greater_0_conv[symmetric] buf_slice_0_eq_buf_take )
using buf_take_buf_slice_adjacent[OF sync_le_used, where b="(wbuf\<^sub>f ostore_st)",symmetric]
apply simp
using list_trans_no_pad_append val_ys by fastforce
have buf_slice_not_Nil: "\<And>xs. buf_slice (wbuf\<^sub>f ostore_st) 0 (used\<^sub>f ostore_st)@ xs \<noteq> []"
using inv_ostore_eb_size_wbuf_eqD[OF inv_ostore] inv_mount_st[simplified inv_mount_st_def Let_def] used_gt_zero
by (clarsimp simp add: buf_slice_def slice_def unat_arith_simps)
have prod_eq: "\<And>x y z. x = (y,z) = (prod.fst x = y \<and> prod.snd x = z)" by auto
have opt_eq: "\<And>i. i < length (list_eb_log_wbuf ostore_st) \<Longrightarrow> (list_eb_log_wbuf ?ostore_st ! i) = [] = ((list_eb_log_wbuf ostore_st ! i) = [])"
apply (simp add: list_eb_log_wbuf_def list_eb_log_def used_gt_zero
buf_slice_buf_memset_is_append_padding[OF inv_ostore
inv_mount_st pad_to, where frm=0, simplified])
apply (case_tac "i \<noteq> unat (wbuf_eb\<^sub>f ostore_st)- unat bilbyFsFirstLogEbNum")
using snd_list_trans_padding_unchanged[OF valid_list_trans_till_used, where n="(unat pad_to - unat (used\<^sub>f ostore_st))"]
snd_list_trans_no_pad
apply (simp add: list_trans_no_pad_def prod.case_eq_if)+
done
{
fix i
assume i_range: "i < length (list_eb_log_wbuf ostore_st)"
and not_none: "list_eb_log_wbuf ostore_st ! i \<noteq> []"
have "list_eb_log_wbuf ?ostore_st ! i = list_eb_log_wbuf ostore_st ! i"
proof -
have "list_eb_log_wbuf ?ostore_st ! i \<noteq> []"
using opt_eq i_range not_none by simp
thus ?thesis
proof cases
assume cur_eb: "i = unat (wbuf_eb\<^sub>f ostore_st) - unat bilbyFsFirstLogEbNum"
have i_in_range: "i < length ((drop (unat bilbyFsFirstLogEbNum) (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st))))"
using inv_ubi_volD[OF inv_ostore, simplified inv_ubi_vol_def] cur_eb
inv_ostore[simplified inv_ostore_def] by unat_arith
show ?thesis
using i_in_range
apply (simp add: list_eb_log_wbuf_def list_eb_log_def cur_eb)
using buf_slice_buf_memset_is_append_padding[OF inv_ostore inv_mount_st pad_to, where frm=0, simplified]
apply simp
apply (rule snd_list_trans_no_pad_padding_unchanged[OF valid_list_trans_till_used])
done
next
assume cur_eb: "i \<noteq> unat (wbuf_eb\<^sub>f ostore_st) - unat bilbyFsFirstLogEbNum"
show ?thesis
using cur_eb len_eq by - (clarsimp simp: buf_memset_eq wordarray_make list_eb_log_wbuf_def list_eb_log_def )
qed
qed
} note list_eb_log_wbuf = this
have "list_eb_log_wbuf ?ostore_st = list_eb_log_wbuf ostore_st"
apply (simp add: list_eb_log_wbuf_def)
using list_eb_log_wbuf
apply (simp add: list_eb_log_wbuf_def)
using snd_list_trans_memset[OF inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used, where frm=0, simplified ]
apply (simp only:)
done
thus ?thesis
unfolding ostore_log_objects_def by simp
qed
lemma inv_ostore_fsm_padding_bytes:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
assumes inv_mount_st: "inv_mount_st mount_st"
assumes pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
assumes used_gt_zero: "0 < used\<^sub>f ostore_st"
assumes sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows
"inv_ostore_fsm mount_st
(ostore_st
\<lparr>wbuf\<^sub>f := buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte),
used\<^sub>f := pad_to\<rparr>)"
(is "inv_ostore_fsm mount_st ?ostore_st")
proof -
obtain padsz::nat where pad_sz: "padsz = unat (used\<^sub>f ostore_st) - unat pad_to" by simp
have inv_fsm:"inv_ostore_fsm mount_st ostore_st" using inv_ostore_fsmD[OF inv_ostore] .
{
fix oid :: ObjId and gimnode :: GimNode\<^sub>T
assume "oid \<in> dom (\<alpha>_fsm_gim (gim\<^sub>f (fsm_st\<^sub>f ?ostore_st)))"
and "(\<alpha>_fsm_gim $ gim\<^sub>f (fsm_st\<^sub>f ?ostore_st)) oid = option.Some gimnode"
hence "unat (GimNode.count\<^sub>f gimnode) = (card {x \<in> set (ostore_log_objects (list_eb_log_wbuf ostore_st)).
oid_is_deleted_by (get_obj_oid x) oid}) = (unat (GimNode.count\<^sub>f gimnode) =
card {x \<in> set (ostore_log_objects (list_eb_log_wbuf ?ostore_st)).
oid_is_deleted_by (get_obj_oid x) oid})
"
using ostore_log_objects_padding_bytes[OF inv_ostore inv_mount_st pad_to pad_sz used_gt_zero sync_lt_used] by simp
} note gim_eq = this
show ?thesis
using inv_fsm unfolding inv_ostore_fsm_def by (fastforce simp: gim_eq dom_def)
qed
lemma prepare_wbuf_memset_\<alpha>_updates_eq:
assumes inv: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and sync_not_eq_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows
"\<alpha>_updates (ostore_st\<lparr>wbuf\<^sub>f := buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte), used\<^sub>f := pad_to\<rparr>) = \<alpha>_updates ostore_st"
apply (simp add: \<alpha>_updates_def del: list_trans.simps)
apply (rule arg_cong[where f="map ostore_update"])
using buf_slice_buf_memset_is_append_padding[OF inv inv_mount_st,folded bilbyFsPadByte_def, where frm="(sync_offs\<^sub>f ostore_st)",simplified]
pad_to[unfolded tuple_simps sanitizers, simplified padding_to_def Let_def ostoreWriteNone_def]
apply (simp add: padding_to_def Let_def ostoreWriteNone_def del: list_trans.simps)
apply (drule meta_spec[where x=pad_to])
apply (simp del: list_trans.simps)
apply (rule snd_list_trans_no_pad_padding_unchanged)
using inv_bufsD[OF inv] sync_not_eq_used
apply (clarsimp simp add: valid_list_trans_no_pad_def)
done
definition
buf_prepared :: "OstoreState\<^sub>T \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> Obj\<^sub>T \<Rightarrow> U8 list"
where
"buf_prepared ostore_st pad_from pad_to pobj \<equiv>
if pad_to - pad_from < bilbyFsObjHeaderSize then
buf_memset' (wbuf\<^sub>f ostore_st) pad_from (pad_to - pad_from) bilbyFsPadByte
else
buf_sub_slice (wbuf\<^sub>f ostore_st) pad_from pad_to (sObj pobj)"
lemma buf_prepared_n_n:
"buf_prepared ostore_st n n pobj = (\<alpha>wa $ data\<^sub>f $ wbuf\<^sub>f ostore_st)"
by (simp add: buf_prepared_def bilbyFsObjHeaderSize_def buf_sub_slice_def buf_simps padding_def)
definition
prepared_pad_obj_no_crc :: "OstoreState\<^sub>T \<Rightarrow> U32 \<Rightarrow> Obj\<^sub>T"
where
"prepared_pad_obj_no_crc ostore_st pad_to \<equiv>
opad\<^sub>f ostore_st
\<lparr>Obj.sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st,
Obj.len\<^sub>f := pad_to - used\<^sub>f ostore_st,
trans\<^sub>f := bilbyFsTransCommit \<rparr>"
definition
prepared_pad_obj :: "OstoreState\<^sub>T \<Rightarrow> U32 \<Rightarrow> U32 \<Rightarrow> Obj\<^sub>T"
where
"prepared_pad_obj ostore_st pad_to crc \<equiv>
let opad = prepared_pad_obj_no_crc ostore_st pad_to
in opad \<lparr> crc\<^sub>f := crc \<rparr>"
lemma padding_to_io_size_no_overflow:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
notes pad_simps = padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def
shows
"padding_to (mount_st, ostore_st, ostoreWriteNone)
< padding_to (mount_st, ostore_st, ostoreWriteNone) + io_size\<^sub>f (super\<^sub>f mount_st)"
proof -
have pad_to_le_max_eb_sz: "padding_to (mount_st, ostore_st, ostoreWriteNone) \<le> bilbyFsMaxEbSize"
using align32_upper_bound[where v="used\<^sub>f ostore_st" and al="io_size\<^sub>f (super\<^sub>f mount_st)" and bound="eb_size\<^sub>f (super\<^sub>f mount_st)"]
inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
inv_mount_st[simplified inv_mount_st_def Let_def]
inv_ostore_usedD[OF inv_ostore]
inv_ostore_used_no_overflowD[OF inv_ostore]
by (clarsimp simp: pad_simps) unat_arith
have iosz_gt_0: "0 < io_size\<^sub>f (super\<^sub>f mount_st)"
and iosz_lt_max_eb_sz: "io_size\<^sub>f (super\<^sub>f mount_st) \<le> bilbyFsMaxEbSize"
using inv_mount_st[simplified inv_mount_st_def Let_def]
by (clarsimp, unat_arith)+
have "bilbyFsMaxEbSize < bilbyFsMaxEbSize + io_size\<^sub>f (super\<^sub>f mount_st)"
using iosz_lt_max_eb_sz and iosz_gt_0
by (simp add: unat_arith_simps bilbyFsMaxEbSize_def)
thus ?thesis
using pad_to_le_max_eb_sz by (simp add: pad_simps) unat_arith
qed
lemma buf_memset_bound_eq:
"unat (buf_bound buf) \<le> length (\<alpha>wa (data\<^sub>f buf)) \<Longrightarrow>
offs \<le> offs + len \<Longrightarrow> buf_bound (buf_memset (buf, offs, len, v)) = buf_bound buf"
apply (subst buf_memset_eq[OF])
apply (simp add: buf_bound_def)+
done
lemma inv_ostore_padding_bytes_preserved:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
assumes inv_mount_st: "inv_mount_st mount_st"
assumes pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
assumes used_gt_zero: "0 < used\<^sub>f ostore_st"
assumes sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows "inv_ostore mount_st (ostore_st \<lparr>wbuf\<^sub>f :=buf_memset(wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte), used\<^sub>f := pad_to\<rparr>)"
(is "inv_ostore mount_st ?ostore_st")
proof -
have pad_to': "pad_to = align32 (used\<^sub>f ostore_st, io_size\<^sub>f (super\<^sub>f mount_st))"
using pad_to by (simp add: padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def)
have "sync_offs\<^sub>f ostore_st \<le> padding_to (mount_st, ostore_st, ostoreWriteNone)"
using sync_offs_le_padding_to[OF inv_ostore inv_mount_st ] .
moreover have "eb_size\<^sub>f (super\<^sub>f mount_st) = buf_length (wbuf\<^sub>f ?ostore_st)"
apply (simp add: pad_to)
apply (subst buf_memset_length_eq[OF inv_ostore_bound_le_lenD[OF inv_ostore]])
apply simp
using used_le_padding_to[OF inv_ostore inv_mount_st] apply simp
using inv_ostore by (fastforce simp: buf_memset_length_eq inv_ostore_def )
moreover have "inv_ostore_summary mount_st ?ostore_st"
by (simp add: inv_ostore_summary_def)
moreover have "inv_ostore_index mount_st ?ostore_st"
by (rule inv_ostore_index_padding_bytes[OF inv_ostore inv_mount_st pad_to])
moreover have "inv_ostore_index_gim_disjoint ?ostore_st"
using inv_ostore by (clarsimp simp: inv_ostore_def inv_ostore_index_gim_disjoint_def)
moreover have "inv_ostore_fsm mount_st ?ostore_st"
using inv_ostore_fsm_padding_bytes[OF inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used] .
moreover hence "buf_bound (wbuf\<^sub>f ?ostore_st) = buf_length (wbuf\<^sub>f ?ostore_st)"
apply (simp add: pad_to)
apply (subst buf_memset_length_eq[OF inv_ostore_bound_le_lenD[OF inv_ostore], simplified ])
using used_le_padding_to[OF inv_ostore inv_mount_st]
apply simp
apply (subst buf_memset_bound_eq)
using inv_ostore_bound_le_lenD[OF inv_ostore] apply (simp add: buf_simps)
apply simp
using used_le_padding_to[OF inv_ostore inv_mount_st]
apply simp
using inv_ostore
by (fastforce simp add: inv_ostore_def buf_simps intro: )
moreover have inv_bufs: "inv_bufs mount_st ?ostore_st"
using inv_ostore apply (clarsimp simp: inv_ostore_def inv_bufs_def Let_def)
apply (rule conjI)
apply (subst buf_memset_eq)
using inv_ostore_bound_le_lenD[OF inv_ostore] apply (simp add: buf_simps)
using used_le_padding_to[OF inv_ostore inv_mount_st] apply (simp add: pad_to)
apply (simp add: buf_simps )
using inv_ostore_sync_offsD[OF inv_ostore,simplified word_le_nat_alt]
inv_ostore_buf_bound_eqD[OF inv_ostore]
inv_ostore_used_len_wbufD[OF inv_ostore inv_mount_st]
inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
apply (simp add: min_absorb1 min_absorb2 inv_mount_st inv_mount_st_def
Let_def wordarray_make)
using buf_slice_buf_memset_is_append_padding[OF inv_ostore inv_mount_st pad_to, where frm="sync_offs\<^sub>f ostore_st"]
using inv_ostore_bound_le_lenD[OF inv_ostore] apply (simp add: )
using used_le_padding_to[OF inv_ostore inv_mount_st]
apply (simp add: pad_to )
apply (rule padding_to_ret, simp add: ostoreWriteNone_def )
using inv_mount_st[simplified Let_def inv_mount_st_def]
apply clarsimp
apply (drule align32_le[where v="used\<^sub>f ostore_st" and al="io_size\<^sub>f (super\<^sub>f mount_st)"])
using inv_ostore_used_no_overflowD[OF inv_ostore] apply simp
apply (rule conjI)
apply (rule impI)
apply (rule valid_list_trans_no_pad_append_padding)
apply (erule (1) impE[OF _ sync_lt_used])
apply (erule impE[OF _ used_gt_zero])
apply (simp only: buf_slice_0_eq_buf_take[symmetric])
apply (subst buf_slice_out_of_buf_memset)
apply simp
apply simp
using used_le_padding_to[OF inv_ostore inv_mount_st] apply fastforce
using inv_ostore_usedD[OF inv_ostore]
inv_ostore_wbuf_boundD[OF inv_ostore]
apply (simp add: buf_simps)
using inv_ostore_usedD[OF inv_ostore]
inv_ostore_wbuf_boundD[OF inv_ostore]
inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
apply (fastforce simp add: buf_simps)
apply simp
apply (clarsimp simp: sync_lt_used valid_list_trans_no_pad_def)
apply (simp add: snd_list_trans_no_pad_padding_unchanged)
done
moreover have get_obj_eq:
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
ostore_get_obj ?ostore_st v = ostore_get_obj ostore_st v"
using prepare_memset_get_obj_eq[OF inv_ostore inv_mount_st pad_to] .
hence runtime_eq: "\<alpha>_ostore_runtime ?ostore_st = \<alpha>_ostore_runtime ostore_st"
using inv_ostore_indexD[OF inv_ostore]
by (fastforce simp add: \<alpha>_ostore_runtime_def option.case_eq_if inv_ostore_index_def Let_def)
have \<alpha>_updates_eq: "\<alpha>_updates ?ostore_st = \<alpha>_updates ostore_st"
using prepare_wbuf_memset_\<alpha>_updates_eq[OF inv_ostore inv_mount_st pad_to sync_lt_used] .
have \<alpha>_ostore_medium_eq: "\<alpha>_ostore_medium ?ostore_st = \<alpha>_ostore_medium ostore_st"
by (simp add: \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def Let_def list_eb_log_def)
then have uptodate_eq: "\<alpha>_ostore_uptodate ?ostore_st = \<alpha>_ostore_uptodate ostore_st"
by (simp add: \<alpha>_ostore_medium_eq \<alpha>_updates_eq \<alpha>_ostore_uptodate_def)
moreover have "\<alpha>_ostore_runtime ?ostore_st = \<alpha>_ostore_uptodate ?ostore_st"
using inv_ostore
by (simp add: runtime_eq uptodate_eq inv_ostore_def)
moreover have "pad_to \<le> buf_length (wbuf\<^sub>f ?ostore_st)"
using inv_mount_st[simplified inv_mount_st_def Let_def]
inv_ostore[simplified inv_ostore_def]
using align32_upper_bound[where v="used\<^sub>f ostore_st" and al="io_size\<^sub>f (super\<^sub>f mount_st)" and bound="eb_size\<^sub>f (super\<^sub>f mount_st)"]
inv_ostore[simplified inv_ostore_def] inv_mount_st[simplified Let_def inv_mount_st_def]
inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
apply (simp add: pad_to')
apply (subst buf_memset_length_eq)
using inv_ostore_bound_le_lenD[OF inv_ostore] apply (simp add: buf_simps)
using used_le_padding_to[OF inv_ostore inv_mount_st] apply (simp add: pad_to' pad_to padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def)
by (clarsimp simp: pad_to' buf_memset_length_eq)
moreover have "inv_log (list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ?ostore_st))) (prod.snd (list_trans_no_pad
(buf_slice (buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte)) (sync_offs\<^sub>f ostore_st) pad_to)))"
using snd_list_trans_no_pad_padding_unchanged
using snd_list_trans_memset[OF inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used, where frm="sync_offs\<^sub>f ostore_st",simplified]
apply simp
using inv_logD[OF inv_ostore, folded inv_log_def] by simp
moreover have "used\<^sub>f ?ostore_st < used\<^sub>f ?ostore_st + io_size\<^sub>f (super\<^sub>f mount_st)"
using padding_to_io_size_no_overflow[OF inv_ostore inv_mount_st]
by (clarsimp simp: inv_ostore_def pad_to)
ultimately show ?thesis
using inv_ostore by (clarsimp simp: pad_to inv_ostore_def inv_bufs inv_flash_def)
qed
lemma take_n_m_padding:
"m \<le> n \<Longrightarrow> n \<le> length xs \<Longrightarrow>
take n (take m xs @ padding (n - m) @ ys) = take m xs @ padding (n - m)"
by (simp add: min_absorb1 min_absorb2 padding_def )
lemma safe_add64:
assumes err: "a > a + b \<Longrightarrow> P (Error ())"
and suc: "a \<le> a+b \<Longrightarrow> P (Success (a+b))"
shows
"P (safe_add64 (a,b))"
unfolding safe_add64_def[unfolded tuple_simps sanitizers]
apply (simp add: Let_def)
apply safe
apply (rule err, simp)
apply (rule err)
(* FIX Cogent code only one check is needed *)
apply (unat_arith)
apply (rule suc)
apply unat_arith
done
lemmas ElemX_simps = ElemA.defs ElemAO.defs ElemB.defs
lemma fsm_mark_ebnum_dirty:
assumes inv_fsm_st: "inv_fsm_st mount_st fsm_st"
and inv_mount_st: "inv_mount_st mount_st"
and ebnum_range: "ebnum \<ge> bilbyFsFirstLogEbNum \<and> ebnum < nb_eb\<^sub>f (super\<^sub>f mount_st)"
and suc: "P (fsm_st
\<lparr>dirty_space\<^sub>f :=
WordArrayT.make
(\<alpha>wa (dirty_space\<^sub>f fsm_st)[unat ebnum := \<alpha>wa (dirty_space\<^sub>f fsm_st) ! unat ebnum + len])\<rparr>)"
shows
"P (fsm_mark_ebnum_dirty (fsm_st, ebnum, len))"
unfolding fsm_mark_ebnum_dirty_def[unfolded tuple_simps sanitizers]
apply (simp add: )
apply (rule wordarray_modify_ret)
using inv_fsm_st[simplified inv_fsm_st_def] ebnum_range apply (clarsimp, unat_arith)
apply (simp add: suc ArrA.make_def wordarray_make
mark_dirty_modifier_def[unfolded tuple_simps sanitizers] ElemX_simps)
done
lemma fsm_mark_dirty_ret: (* This a specialise lemma for fsm_mark_diry when oid = nilObjId
*)
assumes inv_fsm_st: "inv_fsm_st mount_st fsm_st"
and inv_mount_st: "inv_mount_st mount_st"
and ebnum_range: "ebnum\<^sub>f oaddr \<ge> bilbyFsFirstLogEbNum \<and> ebnum\<^sub>f oaddr < nb_eb\<^sub>f (super\<^sub>f mount_st)"
and suc: "\<And>ex. P(ex, fsm_st
\<lparr>dirty_space\<^sub>f :=
WordArrayT.make
(\<alpha>wa (dirty_space\<^sub>f fsm_st)
[unat (ObjAddr.ebnum\<^sub>f oaddr) :=
\<alpha>wa (dirty_space\<^sub>f fsm_st) ! unat (ObjAddr.ebnum\<^sub>f oaddr) + ObjAddr.len\<^sub>f oaddr])\<rparr>,
gimpool)"
shows
"P (fsm_mark_dirty (ex, mount_st, fsm_st, gimpool, nilObjId, oaddr))"
unfolding fsm_mark_dirty_def[unfolded tuple_simps sanitizers]
apply (simp add:)
apply (rule fsm_mark_ebnum_dirty[OF inv_fsm_st inv_mount_st])
using ebnum_range apply (simp)
using ebnum_range apply (simp add: nilObjId_def Let_def suc[where ex=ex])
done
lemma offs_pl_padding_to_le_eb_size:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and sync_neq_used: "sync_offs\<^sub>f ostore_st \<noteq> used\<^sub>f ostore_st"
and var: "var \<in> {sync_offs\<^sub>f ostore_st, used\<^sub>f ostore_st}"
shows
"unat var + unat (padding_to (mount_st, ostore_st, ostoreWriteNone) - var)
\<le> unat (eb_size\<^sub>f (super\<^sub>f mount_st))"
proof -
have pow_of_2: "is_pow_of_2 (io_size\<^sub>f (super\<^sub>f mount_st))"
using inv_mount_st by (simp add: inv_mount_st_def Let_def)
have not_0: "0 < io_size\<^sub>f (super\<^sub>f mount_st)"
using inv_mount_st by (simp add: inv_mount_st_def Let_def) unat_arith
have iosize_dvd_ebsize: "io_size\<^sub>f (super\<^sub>f mount_st) udvd eb_size\<^sub>f (super\<^sub>f mount_st)"
using inv_mount_st by (simp add: inv_mount_st_def Let_def)
show ?thesis
using inv_ostore_usedD[OF inv_ostore] iosize_dvd_ebsize
align32_ge[OF pow_of_2 , where v="used\<^sub>f ostore_st"]
align32_upper_bound[OF _ pow_of_2, where v="used\<^sub>f ostore_st" and bound="eb_size\<^sub>f (super\<^sub>f mount_st)"]
inv_ostore_sync_offsD[OF inv_ostore] inv_ostore_used_no_overflowD[OF inv_ostore]
apply (case_tac "var = sync_offs\<^sub>f ostore_st", simp_all add: var padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def)
using var
by unat_arith+
qed
definition
prepared_fsm_padding_obj :: "OstoreState\<^sub>T \<Rightarrow> U32 \<Rightarrow> FsmState\<^sub>T"
where
"prepared_fsm_padding_obj ostore_st pad_to \<equiv>
if \<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize) then
fsm_st\<^sub>f ostore_st \<lparr>dirty_space\<^sub>f :=
WordArrayT.make (\<alpha>wa (dirty_space\<^sub>f (fsm_st\<^sub>f ostore_st))
[unat (wbuf_eb\<^sub>f ostore_st) := \<alpha>wa (dirty_space\<^sub>f (fsm_st\<^sub>f ostore_st)) ! unat (wbuf_eb\<^sub>f ostore_st)
+ (pad_to - used\<^sub>f ostore_st)])\<rparr>
else fsm_st\<^sub>f ostore_st"
lemma update_obj_pad_ret:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and oaddr_range: "bilbyFsFirstLogEbNum \<le> ObjAddr.ebnum\<^sub>f oaddr \<and> ObjAddr.ebnum\<^sub>f oaddr < nb_eb\<^sub>f (super\<^sub>f mount_st)"
and suc: "\<And>ex v. P (ex, ostore_st
\<lparr>fsm_st\<^sub>f := fsm_st\<^sub>f ostore_st
\<lparr>dirty_space\<^sub>f :=
WordArrayT.make
(\<alpha>wa (dirty_space\<^sub>f (fsm_st\<^sub>f ostore_st))
[unat (ebnum\<^sub>f oaddr) := \<alpha>wa (dirty_space\<^sub>f (fsm_st\<^sub>f ostore_st)) ! unat (ebnum\<^sub>f oaddr) +
ObjAddr.len\<^sub>f oaddr])\<rparr>,
OstoreState.oaddr\<^sub>f :=v\<rparr>)"
shows
"P (update_obj_pad (ex, mount_st, ostore_st, oaddr))"
unfolding update_obj_pad_def[unfolded tuple_simps sanitizers, folded nilObjId_def]
apply (simp add:)
apply (rule fsm_mark_dirty_ret[OF _ inv_mount_st])
using inv_fsm_stD[OF inv_ostore] apply (simp add: inv_fsm_st_def)
using inv_ostore[simplified inv_ostore_def] apply (simp)
using oaddr_range apply simp
apply simp
apply (rule suc)
done
lemma ostore_get_obj_eq_padding_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, osw)"
shows
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
ostore_get_obj (ostore_st \<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj'))\<rparr>,
opad\<^sub>f := obj', used\<^sub>f := pad_to,
OstoreState.next_sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st + 1,
fsm_st\<^sub>f := fsm_st, OstoreState.oaddr\<^sub>f:= oaddr\<rparr>) v = ostore_get_obj ostore_st v"
apply (clarsimp simp: ostore_get_obj_def)
apply (rule_tac f="\<lambda>x. pObj x (ObjAddr.offs\<^sub>f v)" in arg_cong)
apply (rule_tac m="unat $ used\<^sub>f ostore_st" in take_eq_strenghen)
using wordarray_length_ret[where arr="data\<^sub>f (wbuf\<^sub>f ostore_st)", symmetric]
inv_ostore_wbuf_boundD[OF inv_ostore]
inv_ostore_usedD[OF inv_ostore]
inv_ostore_wbuf_lengthD[OF inv_ostore ]
inv_mount_st[simplified inv_mount_st_def]
unfolding is_valid_addr_def
apply (clarsimp simp: wordarray_make pad_to buf_length_def )
apply (subst take_n_buf_sub_slice_n)
apply unat_arith
apply simp
apply unat_arith
done
lemma inv_ostore_index_padding_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
shows
"inv_ostore_index mount_st
(ostore_st \<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj'))\<rparr>,
opad\<^sub>f := obj', used\<^sub>f := pad_to,
OstoreState.next_sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st + 1,
fsm_st\<^sub>f := fsm_st,
OstoreState.oaddr\<^sub>f := oaddr\<rparr>)"
(is "inv_ostore_index mount_st ?ostore_st")
proof -
have index_unchanged:
"index_st\<^sub>f ?ostore_st = index_st\<^sub>f ostore_st" by simp
also have inv_ostore_index:
"inv_ostore_index mount_st ostore_st"
using inv_ostore by (simp add: inv_ostore_def)
moreover have pad_to_ge_used:
"used\<^sub>f ostore_st \<le> pad_to"
by (subst pad_to, rule used_le_padding_to[OF inv_ostore inv_mount_st])
moreover have is_valid_addr:
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
is_valid_addr mount_st ?ostore_st v"
apply (clarsimp simp: is_valid_addr_def pad_to)
apply (case_tac "used\<^sub>f ostore_st = eb_size\<^sub>f (super\<^sub>f mount_st)")
apply (erule (1) padding_to_eb_fullE[OF inv_ostore inv_mount_st])
apply (cut_tac used_le_padding_to[OF inv_ostore inv_mount_st])
apply (unat_arith)
done
moreover have get_obj_eq:
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
ostore_get_obj ?ostore_st v = ostore_get_obj ostore_st v"
using ostore_get_obj_eq_padding_obj[OF inv_ostore inv_mount_st pad_to,
where fsm_st=fsm_st and oaddr=oaddr] by simp
ultimately show ?thesis
unfolding inv_ostore_index_def
by (clarsimp simp: Let_def)
qed
lemmas ostore_update_padding_obj' = ostore_update_padding_obj_def[unfolded tuple_simps sanitizers]
lemma snd_list_trans_sObj_eq_sObj:
assumes valid_obj: "valid_pad_obj obj"
notes Obj_inverse[where xs=Nil, simplified, simp]
shows
"valid_list_trans (sObj obj) \<Longrightarrow>
prod.snd (list_trans (sObj obj)) = [[obj]]"
using valid_obj apply (clarsimp simp: valid_pad_obj_def simp del: list_trans.simps)
apply (erule valid_list_trans.elims)
apply (clarsimp split: if_splits)
apply (erule valid_trans.elims)
apply (rename_tac x xs)
apply (drule sym[where s="sObj obj"], clarsimp simp add: Let_def is_valid_ObjTrans split:if_splits)
using is_valid_ObjHeader_length_sObj[OF valid_obj]
apply (drule_tac t="x#xs" in sym, simp)
apply (drule_tac t="x#xs" in sym, simp)
apply (frule is_valid_ObjHeader_length_sObj[OF valid_obj], simp)
apply (erule valid_trans.elims, clarsimp simp add: is_valid_ObjTrans split: if_splits)
apply (rename_tac x xs)
apply (drule_tac t="x#xs" in sym, simp)
apply (frule is_valid_ObjHeader_length_sObj[OF valid_obj], simp)
apply (rename_tac x xs)
apply (drule_tac t="x#xs" in sym, simp)
apply (frule is_valid_ObjHeader_length_sObj[OF valid_obj], simp)
done
lemma valid_commit_pad_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
shows
"is_valid_ObjCommit obj (sObj obj)"
using obj
apply (clarsimp simp: is_valid_ObjTrans)
apply safe
apply (erule ssubst)
apply (simp add: is_valid_ObjHeader_def )
using inv_opadD[OF inv_ostore]
inv_ostore_eb_size_wbuf_eqD[OF inv_ostore] inv_mount_st[simplified inv_mount_st_def Let_def]
apply (clarsimp simp: ostore_update_padding_obj' buf_sub_slice_length bilbyFsTransCommit_def)
apply (rule conjI)
apply (subst length_sObj)
using obj apply clarsimp
apply (drule arg_cong[ where f=Obj.len\<^sub>f, simplified ostore_update_padding_obj' Let_def prod.case_eq_if])
using padding_obj
apply (simp add: bilbyFsObjHeaderSize_def)
using padding_obj
apply (clarsimp simp add: bilbyFsObjHeaderSize_def)
apply (simp add: is_valid_Obj_def)
apply (simp)
apply (simp add: is_len_and_type_ok_def otype_simps)
using padding_obj apply (simp add: bilbyFsObjHeaderSize_def )
using inv_opadD[OF inv_ostore]
apply (subst Obj_inverse[where xs=Nil, simplified])
apply (clarsimp simp: ostore_update_padding_obj'
Obj_inverse[where xs=Nil, simplified] bilbyFsTransCommit_def is_valid_Obj_def)+
done
lemma snd_list_trans_no_pad_padding_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
and valid_list_trans_pad_obj: "valid_list_trans (sObj obj)"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
shows
"prod.snd (list_trans_no_pad
(buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st) @
sObj obj)) =
prod.snd (list_trans_no_pad
(buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)))"
using obj length_sObj[where obj=obj] apply (simp add: ostore_update_padding_obj' )
apply (erule meta_impE)
apply (fold bilbyFsObjHeaderSize_def)
using padding_obj apply clarsimp
apply (drule arg_cong[where f="Obj.len\<^sub>f"], simp)
apply (subst list_trans_no_pad_append[symmetric])
using inv_bufsD[OF inv_ostore, simplified sync_lt_used] apply (simp add: valid_list_trans_no_pad_def)
using valid_list_trans_pad_obj apply (simp add: obj ostore_update_padding_obj')
using snd_list_trans_sObj_eq_sObj[OF _ valid_list_trans_pad_obj]
inv_opadD[OF inv_ostore]
inv_ostore_valid_pad_objD[OF inv_ostore]
apply (simp add: obj ostore_update_padding_obj' list_trans_no_pad_def
prod.case_eq_if valid_pad_obj_def is_valid_Obj_def
del:list_trans.simps)
apply clarsimp
done
lemma len_sObj:
assumes valid_hdr: "is_valid_ObjHeader obj (sObj obj)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
shows
"unat (pad_to - used\<^sub>f ostore_st) = length (sObj obj)"
using is_valid_ObjHeader_len_facts[OF valid_hdr] valid_pad_obj apply (clarsimp simp: is_valid_ObjHeader_def valid_pad_obj_def length_sObj )
using obj apply clarsimp
apply (drule arg_cong[where f="Obj.len\<^sub>f"])
apply (simp add: ostore_update_padding_obj' bilbyFsObjHeaderSize_def)
done
lemma len_sObj':
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and valid_hdr: "is_valid_ObjHeader obj (sObj obj)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
shows
"unat pad_to - unat (used\<^sub>f ostore_st) = length (sObj obj)"
using len_sObj[OF valid_hdr obj valid_pad_obj] used_le_padding_to[OF inv_ostore inv_mount_st] pad_to
by (clarsimp simp: valid_pad_obj_def) unat_arith
lemma valid_list_trans_pad_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
and invs_pad_to = inv_ostore inv_mount_st pad_to
and padding_obj_unat = padding_obj[simplified word_less_nat_alt]
and valid_commit_pad_obj = valid_commit_pad_obj[OF invs_pad_to obj padding_obj]
and valid_hdr = valid_commit_pad_obj[OF invs_pad_to obj padding_obj, simplified is_valid_ObjTrans, THEN conjunct1]
shows
"valid_list_trans (sObj obj)"
using obj
apply clarify
apply (drule sym[where s=obj], simp)
apply (drule arg_cong[where f=Obj.len\<^sub>f])
apply (simp add: ostore_update_padding_obj')
apply (case_tac "sObj obj")
using is_valid_ObjHeader_length_sObj[OF valid_pad_obj] valid_commit_pad_obj[simplified is_valid_ObjTrans]
padding_obj_unat
apply (clarsimp simp add: bilbyFsObjHeaderSize_def)
apply simp
apply (drule sym[where s="sObj obj" ], simp)
using is_valid_ObjCommit_trans_len[OF valid_pad_obj valid_commit_pad_obj]
using is_valid_ObjHeader_length_sObj[OF valid_pad_obj valid_hdr] obj
apply (clarsimp simp: ostore_update_padding_obj')
apply (drule arg_cong[where f=Obj.len\<^sub>f])
apply simp
apply (simp add: bilbyFsObjHeaderSize_def)
apply (simp add: no_pad_Nil)
apply (drule sym[where t="sObj obj"])
apply (simp only:)
apply (subst valid_trans.simps)
apply (drule sym[where s="sObj obj"])
using valid_pad_obj[simplified valid_pad_obj_def] valid_commit_pad_obj Obj_inverse[where xs=Nil, simplified, where obj=obj, symmetric]
apply (simp add: is_valid_ObjTrans)
done
lemma valid_list_trans_buf_take_sync_offs:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows
"valid_list_trans (buf_take (wbuf\<^sub>f ostore_st \<lparr>data\<^sub>f := WordArrayT.make
(buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>)
(sync_offs\<^sub>f ostore_st))"
apply (simp add: buf_take_def wordarray_make)
apply (subst take_n_buf_sub_slice_m)
using inv_ostore_used_len_wbufD[OF inv_ostore inv_mount_st] apply simp
using sync_lt_used apply simp
using inv_bufsD[OF inv_ostore] used_gt_zero apply (simp add: valid_list_trans_no_pad_def buf_simps)
done
lemma padding_to_le_eb_size:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
shows
"padding_to (mount_st, ostore_st, ostoreWriteNone) \<le> eb_size\<^sub>f (super\<^sub>f mount_st)"
apply (simp add: padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]])
apply (rule align32_upper_bound)
using inv_mount_st[simplified inv_mount_st_def Let_def]
inv_ostore_usedD[OF inv_ostore]
inv_ostore_used_no_overflowD[OF inv_ostore]
apply simp+
done
lemma padding_to_le_len_wbuf:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
notes pad_simps = padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]
shows
"unat pad_to \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
using padding_to_le_eb_size[OF assms(1,2), simplified pad_to pad_simps]
using inv_mount_st apply (clarsimp simp: inv_mount_st_def Let_def pad_to pad_simps)
using inv_ostore_eb_size_wbuf_eqD[OF inv_ostore] apply (unat_arith)
done
lemma valid_list_trans_buf_slice_sync_offs_pad_to:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and valid_hdr: "is_valid_ObjHeader obj (sObj obj)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
notes sync_le_used = order_less_imp_le[OF sync_lt_used]
and invs = inv_ostore inv_mount_st
shows
" valid_list_trans (buf_slice (wbuf\<^sub>f ostore_st \<lparr>data\<^sub>f :=
WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>)
(sync_offs\<^sub>f ostore_st) pad_to)"
apply (simp add: buf_slice_def wordarray_make)
apply (subst slice_buf_sub_slice[OF sync_le_used])
using used_le_padding_to[OF invs] apply (simp add: pad_to)
using padding_to_le_length_wbuf[OF invs] apply (simp add: pad_to)
using len_sObj[OF valid_hdr obj valid_pad_obj] apply simp
apply (rule valid_list_trans_append)
using inv_bufsD[OF inv_ostore] sync_lt_used
apply (simp add: valid_list_trans_no_pad_def)
using len_sObj'[OF invs pad_to valid_hdr obj valid_pad_obj]
valid_list_trans_pad_obj[OF invs pad_to sync_lt_used obj valid_pad_obj padding_obj ]
apply simp
done
lemma snd_list_trans_no_pad_padding_obj_sync_pad_to:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and valid_hdr: "is_valid_ObjHeader obj (sObj obj)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
and sync_le_used = order_less_imp_le[OF sync_lt_used]
and invs = inv_ostore inv_mount_st
and valid_list_trans_pad_obj = valid_list_trans_pad_obj[OF invs pad_to sync_lt_used obj valid_pad_obj padding_obj]
and snd_list_trans_no_pad_padding_obj = snd_list_trans_no_pad_padding_obj[OF invs pad_to sync_lt_used obj padding_obj ]
shows
"prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st \<lparr>data\<^sub>f :=
WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>)
(sync_offs\<^sub>f ostore_st) pad_to)) =
prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)))"
apply (simp add: buf_slice_def wordarray_make)
apply (subst slice_buf_sub_slice[OF sync_le_used])
using used_le_padding_to[OF invs] apply (simp add: pad_to)
using padding_to_le_length_wbuf[OF invs] apply (simp add: pad_to)
using len_sObj[OF valid_hdr obj valid_pad_obj] apply simp
using len_sObj'[OF invs pad_to valid_hdr obj valid_pad_obj] buf_slice_def
using snd_list_trans_no_pad_padding_obj[OF valid_list_trans_pad_obj]
by simp
lemma snd_list_trans_no_pad_all_padding_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and valid_hdr: "is_valid_ObjHeader obj (sObj obj)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
and sync_le_used = order_less_imp_le[OF sync_lt_used]
and invs = inv_ostore inv_mount_st
and valid_list_trans_pad_obj = valid_list_trans_pad_obj[OF invs pad_to sync_lt_used obj valid_pad_obj padding_obj]
and snd_list_trans_no_pad_padding_obj = snd_list_trans_no_pad_padding_obj[OF invs pad_to sync_lt_used obj padding_obj ]
and invs_pad_offs = inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used
shows
"prod.snd (list_trans_no_pad
(buf_slice
(wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>)
0 pad_to)) =
prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) 0 (used\<^sub>f ostore_st)))"
apply (simp add: buf_slice_0_eq_buf_take)
apply (subst buf_take_buf_slice_adjacent[symmetric, where st="sync_offs\<^sub>f ostore_st" and ?end="used\<^sub>f ostore_st"])
using sync_lt_used apply simp
apply (subst buf_take_buf_slice_adjacent[symmetric, where st="sync_offs\<^sub>f ostore_st" and ?end="pad_to"])
using sync_offs_le_padding_to[OF invs] apply (simp add: pad_to)
apply (subst list_trans_no_pad_append[symmetric])
using valid_list_trans_buf_take_sync_offs[OF invs_pad_offs] apply (simp)
using valid_list_trans_buf_slice_sync_offs_pad_to[OF invs_pad_offs valid_hdr obj valid_pad_obj padding_obj]
apply simp
apply (subst list_trans_no_pad_append[symmetric])
using inv_bufsD[OF inv_ostore] used_gt_zero apply (simp add: valid_list_trans_no_pad_def)
using inv_bufsD[OF inv_ostore] sync_lt_used apply (simp add: valid_list_trans_no_pad_def)
apply (simp add: buf_slice_def wordarray_make)
apply (subst slice_buf_sub_slice[OF sync_le_used])
using used_le_padding_to[OF invs] apply (simp add: pad_to)
using padding_to_le_length_wbuf[OF invs] apply (simp add: pad_to)
using len_sObj[OF valid_hdr obj valid_pad_obj] apply simp
apply (subst buf_take_def, simp add: wordarray_make)
apply (subst take_n_buf_sub_slice_m[OF _ sync_le_used])
using inv_ostore_used_len_wbufD[OF inv_ostore inv_mount_st] apply simp
apply (simp add: buf_take_def len_sObj')
using len_sObj'[OF invs pad_to valid_hdr obj valid_pad_obj] snd_list_trans_no_pad_padding_obj [OF valid_list_trans_pad_obj ]
apply (simp add: buf_slice_def)
done
lemma \<alpha>_updates_padding_objeq:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_eq_pad_to: "used = pad_to"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and valid_hdr: "is_valid_ObjHeader obj (sObj obj)"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
notes invs = inv_ostore inv_mount_st
and sync_le_used = order_less_imp_le[OF sync_lt_used]
and snd_list_trans_no_pad_padding_obj = snd_list_trans_no_pad_padding_obj[OF invs pad_to sync_lt_used obj padding_obj ]
and valid_list_trans_pad_obj = valid_list_trans_pad_obj[OF invs pad_to sync_lt_used obj valid_pad_obj padding_obj]
shows
"\<alpha>_updates (ostore_st \<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>,
opad\<^sub>f := obj, used\<^sub>f := used,
OstoreState.next_sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st + 1,
fsm_st\<^sub>f := fsm_st,
OstoreState.oaddr\<^sub>f := oaddr\<rparr>) = \<alpha>_updates ostore_st"
apply (simp add: \<alpha>_updates_def)
apply (rule arg_cong[where f="map ostore_update"])
apply (simp add: buf_slice_def wordarray_make)
apply (simp add: used_eq_pad_to)
apply (subst slice_buf_sub_slice[OF sync_le_used])
using used_le_padding_to[OF invs] apply (simp add: pad_to)
using padding_to_le_length_wbuf[OF invs] apply (simp add: pad_to)
using len_sObj[OF valid_hdr obj valid_pad_obj] apply simp
using len_sObj'[OF invs pad_to valid_hdr obj valid_pad_obj] snd_list_trans_no_pad_padding_obj[OF valid_list_trans_pad_obj]
apply (simp add: len_sObj' buf_slice_def)
done
lemmas Obj_ext_eq_expand = trans[OF _ Obj.ext_inject,
OF arg_cong2[where f="(=)"], OF refl Obj.surjective]
lemma inv_ostore_preserved_padding_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
and used_eq_pad_to: "used = pad_to"
and fsm_st: "fsm_st \<in> {fsm_st\<^sub>f ostore_st, prepared_fsm_padding_obj ostore_st pad_to}"
notes pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
shows "inv_ostore mount_st
(ostore_st \<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>,
opad\<^sub>f := obj, used\<^sub>f := used,
OstoreState.next_sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st + 1,
fsm_st\<^sub>f := fsm_st,
OstoreState.oaddr\<^sub>f := oaddr\<rparr>)"
(is "inv_ostore mount_st ?ostore_st")
proof -
note invs = inv_ostore inv_mount_st
and invs_pad_to = inv_ostore inv_mount_st pad_to
and invs_pad_offs = inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used
and snd_list_trans_no_pad_padding_obj = snd_list_trans_no_pad_padding_obj[OF invs_pad_to sync_lt_used obj padding_obj ]
note valid_hdr = valid_commit_pad_obj[OF invs_pad_to obj padding_obj, simplified is_valid_ObjTrans, THEN conjunct1]
and valid_list_trans_pad_obj = valid_list_trans_pad_obj[OF invs_pad_to sync_lt_used obj valid_pad_obj padding_obj]
note snd_list_trans_no_pad_all_padding_obj = snd_list_trans_no_pad_all_padding_obj[OF invs_pad_offs valid_hdr obj valid_pad_obj padding_obj]
note snd_list_trans_no_pad_padding_obj_sync_pad_to = snd_list_trans_no_pad_padding_obj_sync_pad_to[OF invs_pad_offs valid_hdr obj valid_pad_obj padding_obj]
note \<alpha>_updates_padding_objeq = \<alpha>_updates_padding_objeq[OF invs pad_to used_eq_pad_to sync_lt_used valid_hdr obj valid_pad_obj padding_obj]
note valid_list_trans_buf_slice_sync_offs_pad_to = valid_list_trans_buf_slice_sync_offs_pad_to[OF invs_pad_offs valid_hdr obj valid_pad_obj padding_obj]
and pad_simps = padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]
note len_sObj' = len_sObj'[OF invs pad_to valid_hdr obj ]
have sync_le_pad_to: "sync_offs\<^sub>f ostore_st \<le> pad_to"
using sync_offs_le_padding_to[OF invs] by (simp add: pad_to)
moreover have "wordarray_length (data\<^sub>f (wbuf\<^sub>f ?ostore_st)) = eb_size\<^sub>f (super\<^sub>f mount_st)"
apply (simp)
apply (subst word_unat.Rep_inject [symmetric])
apply (subst wordarray_length_ret)
apply (subst wordarray_make)
apply (subst buf_sub_slice_length)
using inv_ostore_eb_size_wbuf_eqD[OF inv_ostore] by simp
moreover have get_obj_eq:
"\<And>v. is_valid_addr mount_st ostore_st v \<Longrightarrow>
ostore_get_obj ?ostore_st v = ostore_get_obj ostore_st v"
using ostore_get_obj_eq_padding_obj[OF inv_ostore inv_mount_st pad_to] used_eq_pad_to by simp
hence runtime_eq: "\<alpha>_ostore_runtime ?ostore_st = \<alpha>_ostore_runtime ostore_st"
using inv_ostore_indexD[OF inv_ostore]
by (fastforce simp add: \<alpha>_ostore_runtime_def option.case_eq_if inv_ostore_index_def Let_def)
have sync_le_used: "sync_offs\<^sub>f ostore_st \<le> used\<^sub>f ostore_st" using sync_lt_used by simp
have used_le_pad_to: "used\<^sub>f ostore_st \<le> pad_to"
using used_le_padding_to[OF invs] by (simp add: pad_to)
have len_sObj_ge_hdr_size: "unat bilbyFsObjHeaderSize \<le> length (sObj obj)"
using len_sObj
using len_sObj[OF valid_hdr obj valid_pad_obj, symmetric] len_sObj' padding_obj by unat_arith
have \<alpha>_ostore_medium_eq: "\<alpha>_ostore_medium ?ostore_st = \<alpha>_ostore_medium ostore_st"
by (simp add: \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def Let_def list_eb_log_def)
then have uptodate_eq: "\<alpha>_ostore_uptodate ?ostore_st = \<alpha>_ostore_uptodate ostore_st"
by (simp add: \<alpha>_ostore_medium_eq \<alpha>_updates_padding_objeq \<alpha>_ostore_uptodate_def)
moreover have "\<alpha>_ostore_runtime ?ostore_st = \<alpha>_ostore_uptodate ?ostore_st"
using inv_ostore
by (simp add: runtime_eq uptodate_eq inv_ostore_def)
moreover have "inv_ostore_summary mount_st ?ostore_st"
by (simp add: inv_ostore_summary_def)
moreover have "inv_ostore_index mount_st ?ostore_st"
using inv_ostore_index_padding_obj[OF inv_ostore inv_mount_st pad_to] used_eq_pad_to by simp
moreover have "inv_ostore_index_gim_disjoint ?ostore_st"
using inv_ostore fsm_st
by (fastforce simp: prepared_fsm_padding_obj_def inv_ostore_def inv_ostore_index_gim_disjoint_def)
moreover have inv_ostore_fsm: "inv_ostore_fsm mount_st ?ostore_st"
apply (simp add: inv_ostore_fsm_def used_eq_pad_to)
apply (rule conjI)
using inv_ostore_fsmD[OF inv_ostore, simplified inv_ostore_fsm_def]
padding_obj fsm_st
apply (fastforce simp add: prepared_fsm_padding_obj_def)
apply (rule conjI)
using inv_ostore_fsmD[OF inv_ostore, simplified inv_ostore_fsm_def Let_def]
apply (case_tac "fsm_st = fsm_st\<^sub>f ostore_st", simp)
using snd_list_trans_no_pad_all_padding_obj
apply (simp add: list_eb_log_wbuf_def )
using snd_list_trans_no_pad_all_padding_obj fsm_st
apply (clarsimp simp add: padding_obj list_eb_log_wbuf_def prepared_fsm_padding_obj_def)
using inv_ostore_fsmD[OF inv_ostore, simplified inv_ostore_fsm_def] fsm_st
apply (fastforce simp add: padding_obj prepared_fsm_padding_obj_def)
done
moreover have "inv_bufs mount_st ?ostore_st"
using inv_ostore_sync_offsD[OF inv_ostore] inv_ostore_used_len_wbufD[OF invs]
sync_lt_used used_gt_zero
apply (simp add: inv_bufs_def Let_def pad_to' buf_take_def wordarray_make take_n_buf_sub_slice_m used_eq_pad_to)
apply safe
apply (simp_all add: inv_ostore[simplified Let_def inv_ostore_def]inv_bufsD[OF inv_ostore, simplified buf_take_def])
apply (simp add: valid_list_trans_no_pad_def)
apply (rule conjI)
using valid_list_trans_buf_slice_sync_offs_pad_to[simplified pad_to'] apply simp
apply (simp add: buf_slice_def wordarray_make)
apply (subst slice_buf_sub_slice[OF sync_le_used])
using used_le_padding_to[OF invs] apply (simp add: padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]])
using padding_to_le_length_wbuf[OF invs] apply (simp add: pad_simps)
using used_le_padding_to[OF inv_ostore inv_mount_st]
apply (simp add: pad_to' pad_to pad_simps len_sObj'[OF valid_pad_obj, symmetric])
apply unat_arith
apply (subst list_trans_no_pad_append[symmetric])
using inv_bufsD[OF inv_ostore] used_gt_zero len_sObj'[symmetric]
apply (simp add: valid_list_trans_no_pad_def )
using padding_obj len_sObj'[OF valid_pad_obj] pad_to' valid_list_trans_pad_obj apply simp
using inv_bufsD[OF inv_ostore] sync_lt_used apply (simp add: valid_list_trans_no_pad_def)
using inv_bufsD[OF inv_ostore] used_gt_zero apply (simp add: valid_list_trans_no_pad_def buf_take_def)
apply (simp add: buf_slice_def wordarray_make)
apply (subst slice_buf_sub_slice[OF sync_le_used used_le_pad_to[simplified pad_to']])
using padding_to_le_length_wbuf[OF invs, simplified pad_simps] apply simp
using len_sObj[OF valid_hdr obj valid_pad_obj, symmetric] apply (simp add: pad_to')
using len_sObj'[OF valid_pad_obj] apply (simp add: pad_to')
apply (subst slice_buf_sub_slice[OF sync_le_used used_le_pad_to[simplified pad_to']])
using padding_to_le_length_wbuf[OF invs] apply (simp add: pad_simps)
using len_sObj[OF valid_hdr obj valid_pad_obj] apply (simp add: pad_to')
using snd_list_trans_no_pad_padding_obj[OF valid_list_trans_pad_obj] apply simp
using inv_bufsD[OF inv_ostore] apply (clarsimp simp add: valid_list_trans_no_pad_def buf_take_def)
done
moreover have "inv_fsm_st mount_st (fsm_st\<^sub>f ?ostore_st)"
proof cases
assume "fsm_st = fsm_st\<^sub>f ostore_st"
thus ?thesis
using inv_fsm_stD[OF inv_ostore] by(simp add: inv_fsm_st_def)
next
assume "fsm_st \<noteq> fsm_st\<^sub>f ostore_st"
hence "fsm_st = prepared_fsm_padding_obj ostore_st pad_to"
using fsm_st by simp
thus ?thesis
using inv_fsm_stD[OF inv_ostore]
by (simp add: padding_obj prepared_fsm_padding_obj_def
inv_fsm_st_def wordarray_make)
qed
moreover have "inv_flash (list_eb_log_wbuf ?ostore_st) " by (simp add: inv_flash_def)
moreover have "inv_log (list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)))
(prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ?ostore_st) (sync_offs\<^sub>f ostore_st) (pad_to))))"
using snd_list_trans_no_pad_padding_obj_sync_pad_to
inv_logD[OF inv_ostore, folded inv_log_def]
by simp
moreover have "inv_opad obj"
using inv_opadD[OF inv_ostore] obj padding_obj
by clarsimp (simp add: inv_opad_def ostore_update_padding_obj' bilbyFsTransCommit_def
bilbyFsObjHeaderSize_def)
ultimately show ?thesis
using padding_to_io_size_no_overflow[OF inv_ostore inv_mount_st]
inv_ostore inv_opadD[OF inv_ostore]
padding_to_le_eb_size[OF invs]
apply (clarsimp simp add: inv_ostore_def pad_to buf_simps used_eq_pad_to)
done
qed
lemma opad_is_valid_ObjHeader:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and padding_obj: "\<not> pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
notes pad_simps = padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]
notes pad_to' = pad_to[simplified pad_simps]
and ostore_update_padding_obj' = ostore_update_padding_obj_def[unfolded tuple_simps sanitizers]
shows
"is_valid_ObjHeader
(ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize))
(drop (unat (used\<^sub>f ostore_st)) (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st))))"
using inv_opadD[OF inv_ostore] padding_obj inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
inv_ostore_usedD[OF inv_ostore] inv_mount_st[simplified inv_mount_st_def Let_def]
used_le_padding_to[OF inv_ostore inv_mount_st]
apply (clarsimp simp add: is_valid_ObjHeader_def bilbyFsTransCommit_def
ostore_update_padding_obj' bilbyFsObjHeaderSize_def pad_to' word_le_nat_alt)
apply (thin_tac _)+
apply safe
using padding_to_le_length_wbuf[OF inv_ostore inv_mount_st]
inv_ostore_used_len_wbufD[OF inv_ostore inv_mount_st]
used_le_padding_to[OF inv_ostore inv_mount_st]
padding_obj
apply (simp add: bilbyFsObjHeaderSize_def le_def pad_to pad_to'
padding_to_def[unfolded tuple_simps sanitizers], unat_arith)
using pad_to padding_obj apply (simp add: otype_simps is_len_and_type_ok_def
bilbyFsObjHeaderSize_def padding_to_def[unfolded tuple_simps sanitizers])
done
lemma inv_step_padding_obj:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and obj: "\<exists>crc. obj = ostore_update_padding_obj
(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize)
\<lparr>crc\<^sub>f :=crc\<rparr>"
and valid_pad_obj: "valid_pad_obj obj"
and padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
and used_eq_pad_to: "used = pad_to"
and fsm_st: "fsm_st \<in> {fsm_st\<^sub>f ostore_st, prepared_fsm_padding_obj ostore_st pad_to}"
and inv_step: "inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st)"
notes invs = inv_ostore inv_mount_st
and pad_to' = pad_to[simplified padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]]
and valid_hdr = valid_commit_pad_obj[OF invs pad_to obj padding_obj, simplified is_valid_ObjTrans, THEN conjunct1]
shows "inv_\<alpha>_ostore (\<alpha>_ostore_uptodate (ostore_st \<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f := WordArrayT.make (buf_sub_slice (wbuf\<^sub>f ostore_st) (used\<^sub>f ostore_st) pad_to (sObj obj))\<rparr>,
opad\<^sub>f := obj, used\<^sub>f := used,
OstoreState.next_sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st + 1,
fsm_st\<^sub>f := fsm_st,
OstoreState.oaddr\<^sub>f := oaddr\<rparr>))"
apply (clarsimp simp add: inv_\<alpha>_ostore_def \<alpha>_ostore_uptodate_def)
apply (simp add: \<alpha>_updates_padding_objeq[OF inv_ostore inv_mount_st pad_to used_eq_pad_to sync_lt_used valid_hdr obj valid_pad_obj padding_obj])
using inv_step apply (clarsimp simp add: inv_\<alpha>_ostore_def \<alpha>_ostore_uptodate_def)
apply (rename_tac oid obj')
apply (erule_tac x=oid in allE)
apply (erule_tac x=obj' in allE)
apply (simp add: \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def)
done
lemma prepare_wbuf_ret:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and inv_step: "inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st)"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and err:
"\<And>ex'. P ((ex',ostore_st), Error eOverflow)"
and suc:
"\<And>ex' ostore_st'. \<lbrakk>
inv_ostore mount_st ostore_st';
inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st');
\<exists>len sqnum crc oaddr nxtsqnum. ostore_st' =
ostore_st\<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st\<lparr>data\<^sub>f:=WordArrayT.make $
buf_prepared ostore_st (used\<^sub>f ostore_st) pad_to (prepared_pad_obj ostore_st pad_to crc)\<rparr>,
used\<^sub>f := pad_to,
fsm_st\<^sub>f := prepared_fsm_padding_obj ostore_st pad_to,
OstoreState.oaddr\<^sub>f:= oaddr,
OstoreState.next_sqnum\<^sub>f:= nxtsqnum,
opad\<^sub>f:=opad\<^sub>f ostore_st \<lparr>Obj.len\<^sub>f:=len, Obj.sqnum\<^sub>f := sqnum, Obj.crc\<^sub>f := crc\<rparr>\<rparr>;
OstoreState.next_sqnum\<^sub>f ostore_st \<le> OstoreState.next_sqnum\<^sub>f ostore_st'
\<rbrakk>
\<Longrightarrow> P ((ex',ostore_st'), Success ())"
notes pad_simps = padding_to_eq_align32_simp[OF inv_mount_st_no_summaryD[OF inv_mount_st]]
notes pad_to' = pad_to[simplified pad_simps]
and ostore_update_padding_obj' = ostore_update_padding_obj_def[unfolded tuple_simps sanitizers]
shows "P (prepare_wbuf (ex, mount_st, ostore_st, pad_to))"
proof cases
assume no_padding_obj: "pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize"
let ?wbuf = "buf_memset (wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, pad_to - used\<^sub>f ostore_st, bilbyFsPadByte)"
let ?ostore_st = "ostore_st\<lparr>wbuf\<^sub>f := ?wbuf, used\<^sub>f := pad_to\<rparr>"
have bound: "unat (bound\<^sub>f (wbuf\<^sub>f ostore_st)) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
using inv_ostore_bound_le_lenD[OF inv_ostore] by simp
have index_unchanged: "index_st\<^sub>f ?ostore_st = index_st\<^sub>f ostore_st" by simp
have list_eb_log_eq: "list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ?ostore_st)) = list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st))"
by (simp add: list_eb_log_def)
have pad_to_le: "unat pad_to \<le> length (\<alpha>wa $ data\<^sub>f $ wbuf\<^sub>f ostore_st)"
using align32_upper_bound[where v="used\<^sub>f ostore_st" and al="io_size\<^sub>f (super\<^sub>f mount_st)" and bound="eb_size\<^sub>f (super\<^sub>f mount_st)"]
inv_ostore[simplified inv_ostore_def] inv_mount_st[simplified Let_def inv_mount_st_def]
inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
by (simp add : pad_to') unat_arith
have used_le_pad_to: "used\<^sub>f ostore_st \<le> pad_to"
using align32_le[where v="used\<^sub>f ostore_st" and al="io_size\<^sub>f (super\<^sub>f mount_st)"] inv_mount_st[simplified inv_mount_st_def Let_def]
pad_to' inv_ostore_used_no_overflowD[OF inv_ostore]
by simp
have unat_used_le_pad_to: "unat (used\<^sub>f ostore_st) \<le> unat pad_to" using used_le_pad_to by unat_arith
have \<alpha>_updates_eq: "\<alpha>_updates ?ostore_st = \<alpha>_updates ostore_st"
by (rule prepare_wbuf_memset_\<alpha>_updates_eq[OF inv_ostore inv_mount_st pad_to sync_lt_used])
have \<alpha>_medium_eq: "\<alpha>_ostore_medium ?ostore_st = \<alpha>_ostore_medium ostore_st"
by (simp add: \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def list_eb_log_eq)
have inv_step': "inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ?ostore_st)"
using inv_step
by (clarsimp simp add: \<alpha>_ostore_uptodate_def Let_def \<alpha>_medium_eq \<alpha>_updates_eq)
have inv_ostore': "inv_ostore mount_st ?ostore_st"
using inv_ostore_padding_bytes_preserved[OF inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used] .
show ?thesis
unfolding prepare_wbuf_def[unfolded tuple_simps sanitizers]
apply (fold bilbyFsObjHeaderSize_def)
using no_padding_obj apply (simp add: pad_to')
apply (rule suc)
apply (fold bilbyFsPadByte_def)
using inv_ostore' apply (simp add: pad_to padding_to_def ostoreWriteNone_def)
using inv_step' apply (simp add: pad_to padding_to_def ostoreWriteNone_def)
apply (rule_tac x="Obj.len\<^sub>f (opad\<^sub>f ?ostore_st)" in exI)
apply (rule_tac x="Obj.sqnum\<^sub>f (opad\<^sub>f ?ostore_st)" in exI)
apply (rule_tac x="Obj.crc\<^sub>f (opad\<^sub>f ?ostore_st)" in exI)
apply (rule_tac x="(OstoreState.oaddr\<^sub>f ?ostore_st)" in exI)
apply (rule_tac x="(OstoreState.next_sqnum\<^sub>f ?ostore_st)" in exI)
apply (subst buf_memset_eq)
using bound apply simp
using used_le_padding_to[OF inv_ostore inv_mount_st] apply (simp add: pad_to' pad_simps)
apply (fastforce simp add: pad_to padding_to_def
ostoreWriteNone_def buf_prepared_def prepared_fsm_padding_obj_def)
apply simp
done
next
assume padding_obj: "\<not> (pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize)"
have pad_to_upd:
"used\<^sub>f ostore_st +
Obj.len\<^sub>f (ostore_update_padding_obj(opad\<^sub>f ostore_st, OstoreState.next_sqnum\<^sub>f ostore_st,
pad_to - used\<^sub>f ostore_st - bilbyFsObjHeaderSize))
= pad_to"
by (simp add: ostore_update_padding_obj' pad_to pad_simps bilbyFsObjHeaderSize_def)
have dummy_upds: "\<And>x. x = x\<lparr>fsm_st\<^sub>f := fsm_st\<^sub>f x, OstoreState.oaddr\<^sub>f := OstoreState.oaddr\<^sub>f x\<rparr>"
by simp
from padding_obj show ?thesis
unfolding prepare_wbuf_def[unfolded tuple_simps sanitizers, folded bilbyFsObjHeaderSize_def]
apply (simp add: Let_def)
apply (rule safe_add64)
apply (simp add: Let_def, fold eOverflow_def )
apply (simp add: err)
apply (simp add: Let_def )
apply (rule serialise_Obj_ret)
apply (simp add: pad_to' bilbyFsObjHeaderSize_def ostore_update_padding_obj')
using used_le_padding_to[OF inv_ostore inv_mount_st] apply (simp add: pad_simps)
using opad_is_valid_ObjHeader[OF inv_ostore inv_mount_st padding_obj pad_to] apply simp
using inv_opadD[OF inv_ostore] apply (clarsimp simp add: ostore_update_padding_obj' )
using inv_opadD[OF inv_ostore] apply (clarsimp simp add: ostore_update_padding_obj' )
using inv_ostore_eb_size_wbuf_eqD[OF inv_ostore]
inv_ostore_wbuf_boundD[OF inv_ostore]
padding_to_le_eb_size[OF inv_ostore inv_mount_st]
apply (clarsimp simp add: pad_to buf_simps ostore_update_padding_obj' bilbyFsObjHeaderSize_def)
apply (rename_tac buf')
apply (simp add: prod.case_eq_if)
apply (rule update_obj_pad_ret[OF _ inv_mount_st])
apply (subst dummy_upds,rule inv_ostore_preserved_padding_obj[OF inv_ostore
inv_mount_st _ used_gt_zero sync_lt_used])
using pad_to_upd apply (simp add: pad_to)
apply (simp add: ostore_update_padding_obj' pad_to pad_simps bilbyFsObjHeaderSize_def)
apply (rule_tac x="crc\<^sub>f (opad\<^sub>f ostore_st)" in exI)
apply simp
using inv_ostore_valid_pad_objD[OF inv_ostore] apply (clarsimp simp:ostore_update_padding_obj' valid_pad_obj_def is_valid_Obj_def)
apply (simp add: ostore_update_padding_obj' bilbyFsObjHeaderSize_def)
using inv_opadD[OF inv_ostore] apply (clarsimp simp add: ostore_update_padding_obj' bilbyFsObjHeaderSize_def)
using inv_ostore_wbuf_eb_rangeD[OF inv_ostore]
apply (simp add: ostore_update_padding_obj' pad_to pad_simps bilbyFsObjHeaderSize_def)
using inv_ostore_wbuf_eb_rangeD[OF inv_ostore] apply simp
apply (rule suc)
apply simp
apply (rule inv_ostore_preserved_padding_obj[OF inv_ostore
inv_mount_st _ used_gt_zero sync_lt_used])
using pad_to_upd apply (simp add: pad_to)
apply (simp add: ostore_update_padding_obj' pad_to pad_simps bilbyFsObjHeaderSize_def)
apply (rule_tac x="crc\<^sub>f (opad\<^sub>f ostore_st)" in exI)
apply simp
apply (simp add: ostore_update_padding_obj' bilbyFsObjHeaderSize_def)
using inv_ostore_valid_pad_objD[OF inv_ostore] apply (clarsimp simp:ostore_update_padding_obj' valid_pad_obj_def is_valid_Obj_def)
using inv_opadD[OF inv_ostore] apply (clarsimp simp add: ostore_update_padding_obj' bilbyFsObjHeaderSize_def)
using inv_ostore_wbuf_eb_rangeD[OF inv_ostore]
apply (simp add: ostore_update_padding_obj' pad_to pad_simps bilbyFsObjHeaderSize_def)
using padding_obj apply (simp add: prepared_fsm_padding_obj_def pad_simps bilbyFsObjHeaderSize_def pad_to' ostore_update_padding_obj')
apply simp
apply (rule inv_step_padding_obj[OF inv_ostore inv_mount_st _ used_gt_zero sync_lt_used ])
using pad_to_upd apply (simp add: pad_to)
apply (rule_tac x="crc\<^sub>f (opad\<^sub>f ostore_st)" in exI)
using pad_to_upd apply (clarsimp simp add: pad_to ostore_update_padding_obj_def Let\<^sub>d\<^sub>s_def)
using inv_ostore_valid_pad_objD[OF inv_ostore] apply (clarsimp simp: valid_pad_obj_def ostore_update_padding_obj' is_valid_Obj_def)
using pad_to_upd apply (clarsimp simp add: pad_to ostore_update_padding_obj')
using pad_to_upd apply (clarsimp simp add: pad_to ostore_update_padding_obj')
using pad_to_upd apply (clarsimp simp add: pad_to ostore_update_padding_obj' prepared_fsm_padding_obj_def)
using inv_step apply simp
apply simp
using [[goals_limit=1]]
apply (rule_tac x="pad_to - used\<^sub>f ostore_st" in exI)
apply (rule_tac x="OstoreState.next_sqnum\<^sub>f ostore_st" in exI)
apply (rule_tac x="crc\<^sub>f (opad\<^sub>f ostore_st)" in exI)
apply (rule_tac x="v" in exI)
apply (rule_tac x="OstoreState.next_sqnum\<^sub>f ostore_st + 1" in exI)
apply simp
apply (simp add: prepared_fsm_padding_obj_def buf_prepared_def padding_obj pad_to_upd)
apply (simp add: ostore_update_padding_obj' prepared_pad_obj_def Let_def
bilbyFsObjHeaderSize_def prepared_pad_obj_no_crc_def bilbyFsTransCommit_def )
(* FIX Cogent code, currently it updates the otype field but shouldn't because
the type of opad is part of the invariant *)
using inv_opadD[OF inv_ostore] apply (clarsimp simp: bilbyFsTransCommit_def)
using inv_ostore_wbuf_eb_rangeD[OF inv_ostore] apply simp
done
qed
definition
sync_summary_serial :: "OstoreState\<^sub>T \<Rightarrow> (Obj\<^sub>T \<times> Buffer\<^sub>T \<times> U32)"
where
"sync_summary_serial ostore_st \<equiv>
serialise_ObjSummary_crc
(wbuf\<^sub>f ostore_st, used\<^sub>f ostore_st, sum_obj\<^sub>f ostore_st
\<lparr>Obj.sqnum\<^sub>f := OstoreState.next_sqnum\<^sub>f ostore_st, Obj.offs\<^sub>f := used\<^sub>f ostore_st,
trans\<^sub>f := bilbyFsTransCommit,
Obj.len\<^sub>f := serialise_size_summary_Obj_with_extra (summary\<^sub>f ostore_st, 0)\<rparr>,
summary\<^sub>f ostore_st\<lparr>sum_offs\<^sub>f := used\<^sub>f ostore_st\<rparr>)"
lemma ostore_sync_summary_if_eb_new_ret:
"inv_ostore mount_st ostore_st \<Longrightarrow>
inv_mount_st mount_st \<Longrightarrow>
inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st) \<Longrightarrow>
(\<And>ex'. P ((ex', ostore_st), R.Success ())) \<Longrightarrow>
P (ostore_sync_summary_if_eb_new (ex, mount_st, ostore_st, ostoreWriteNone))"
by (simp add: ostore_sync_summary_if_eb_new_def[unfolded tuple_simps sanitizers])
lemma ostore_write_buf_inv_ostore_index:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and ubi_vol:"\<alpha>wubi ubi_vol' = \<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)
[unat (wbuf_eb\<^sub>f ostore_st) :=
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st) @
buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st + nb_bytes)]"
shows
"inv_ostore_index mount_st (ostore_st\<lparr>OstoreState.ubi_vol\<^sub>f := ubi_vol'\<rparr>)"
using inv_ostore inv_mount_st[unfolded inv_mount_st_def]
apply (clarsimp simp: inv_ostore_def Let_def inv_ostore_index_def ostore_get_obj_def )
apply (rename_tac oid addr)
apply (erule_tac x=oid in ballE)
apply (case_tac "ObjAddr.ebnum\<^sub>f addr \<noteq> wbuf_eb\<^sub>f ostore_st")
using ubi_vol apply (clarsimp simp: is_valid_addr_def)+
done
lemma map_list_trans_upd_eq:
"map f (drop m (xs[n:=y'']))[n-m:=y] =
map f (drop m xs)[n-m:=y]"
apply (clarsimp simp: list_eq_iff_nth_eq )
apply (rename_tac i, case_tac "i = n-m")
apply (clarsimp simp del: list_trans.simps)+
done
lemma ostore_write_buf_inv_ostore_fsm:
" inv_ubi_vol mount_st ubi_vol' \<Longrightarrow>
\<alpha>wubi ubi_vol' = \<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)
[unat (wbuf_eb\<^sub>f ostore_st) :=
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st) @
buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st + nb_bytes)] \<Longrightarrow>
inv_ostore_fsm mount_st ostore_st \<Longrightarrow>
inv_ostore_fsm mount_st (ostore_st\<lparr>OstoreState.ubi_vol\<^sub>f := ubi_vol'\<rparr>)"
apply (subgoal_tac "list_eb_log_wbuf (ostore_st\<lparr>OstoreState.ubi_vol\<^sub>f := ubi_vol'\<rparr>) = list_eb_log_wbuf ostore_st")
apply (clarsimp simp add: inv_ostore_fsm_def list_eb_log_wbuf_def list_eb_log_def simp del:list_trans.simps)+
apply (rule map_list_trans_upd_eq)
done
lemma word_not_0_gr_n:
"(\<not> 0 < (n::'a::len0 word)) = (n = 0)"
by (unat_arith, simp add: unat_0_iff)
lemma inv_ostore_sync_offs_agnostic:
"inv_ostore_summary mount_st (ostore_st\<lparr>sync_offs\<^sub>f:=v\<rparr>) = inv_ostore_summary mount_st ostore_st"
"inv_ostore_index mount_st (ostore_st\<lparr>sync_offs\<^sub>f := v\<rparr>)= inv_ostore_index mount_st ostore_st"
"inv_ostore_index_gim_disjoint (ostore_st\<lparr>sync_offs\<^sub>f := v\<rparr>) = inv_ostore_index_gim_disjoint ostore_st"
"inv_ostore_fsm mount_st (ostore_st\<lparr>sync_offs\<^sub>f := v\<rparr>) = inv_ostore_fsm mount_st ostore_st"
"inv_flash (list_eb_log_wbuf (ostore_st\<lparr>sync_offs\<^sub>f := v\<rparr>)) = inv_flash (list_eb_log_wbuf ostore_st)"
apply (clarsimp simp: inv_ostore_summary_def room_for_summary_def
inv_sum_consistent_def os_sum_sz_def)
apply (simp add: inv_ostore_index_def Let_def is_valid_addr_def ostore_get_obj_def)
apply (simp add: inv_ostore_index_gim_disjoint_def)
apply (simp add: inv_ostore_fsm_def list_eb_log_wbuf_def list_eb_log_def del: list_trans.simps)
apply (simp add: inv_flash_def)
done
lemma inv_ostore_medium_buf_prepared:
shows
"\<alpha>_ostore_medium
(ostore_st
\<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone))
(prepared_pad_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)) crc))\<rparr>,
used\<^sub>f := padding_to (mount_st, ostore_st, ostoreWriteNone) \<rparr>) =
\<alpha>_ostore_medium ostore_st"
by (clarsimp simp add: \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def list_eb_log_def)
lemma snd_list_trans_buf_prepared_eq:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
notes invs_pad_ofs = inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used
shows
"prod.snd (list_trans_no_pad
(buf_slice
(wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone))
(prepared_pad_obj ostore_st
(padding_to (mount_st, ostore_st, ostoreWriteNone)) crc))\<rparr>)
(sync_offs\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone)))) =
prod.snd(list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st)
(used\<^sub>f ostore_st)))"
proof -
show ?thesis
proof cases
assume pt: "padding_to (mount_st, ostore_st, ostoreWriteNone) - used\<^sub>f ostore_st < bilbyFsObjHeaderSize"
have bound: "unat (bound\<^sub>f (wbuf\<^sub>f ostore_st)) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
using inv_ostore_bound_le_lenD[OF inv_ostore] by simp
have used_of: "used\<^sub>f ostore_st \<le> used\<^sub>f ostore_st + (pad_to - used\<^sub>f ostore_st)"
apply (simp add: pad_to)
using used_le_padding_to[OF inv_ostore inv_mount_st] by simp
show ?thesis
using pt
using snd_list_trans_memset[OF invs_pad_ofs, where frm="sync_offs\<^sub>f ostore_st"]
by (simp add: buf_prepared_def pad_to buf_memset_eq[where buf="wbuf\<^sub>f ostore_st", OF bound used_of, simplified pad_to])
next
assume "\<not> padding_to (mount_st, ostore_st, ostoreWriteNone) - used\<^sub>f ostore_st < bilbyFsObjHeaderSize"
thus ?thesis
apply (simp add: buf_prepared_def pad_to)
apply (rule snd_list_trans_no_pad_padding_obj_sync_pad_to[OF invs_pad_ofs, simplified pad_to])
apply (simp add: prepared_pad_obj_def)
apply (rule valid_commit_pad_obj[OF inv_ostore inv_mount_st pad_to, simplified is_valid_ObjTrans, THEN conjunct1])
apply (rule_tac x=crc in exI)
apply (simp add: prepared_pad_obj_def prepared_pad_obj_no_crc_def ostore_update_padding_obj' pad_to bilbyFsObjHeaderSize_def bilbyFsTransCommit_def)+
apply (rule_tac x=crc in exI)
apply (simp add: prepared_pad_obj_no_crc_def ostore_update_padding_obj' pad_to bilbyFsObjHeaderSize_def bilbyFsTransCommit_def)
using inv_ostore_valid_pad_objD[OF inv_ostore]
apply (clarsimp simp add: prepared_pad_obj_no_crc_def valid_pad_obj_def prepared_pad_obj_def is_valid_Obj_def)
apply simp
done
qed
qed
lemma valid_list_trans_buf_prepared_eq:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
notes invs_pad = inv_ostore inv_mount_st pad_to
shows
"valid_list_trans
(buf_slice
(wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st) pad_to
(prepared_pad_obj ostore_st pad_to crc))\<rparr>)
(sync_offs\<^sub>f ostore_st) pad_to)"
proof -
have bound: "unat (bound\<^sub>f (wbuf\<^sub>f ostore_st)) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
using inv_ostore_bound_le_lenD[OF inv_ostore] by simp
have used_of: "used\<^sub>f ostore_st \<le> used\<^sub>f ostore_st + (pad_to - used\<^sub>f ostore_st)"
apply (simp add: pad_to)
using used_le_padding_to[OF inv_ostore inv_mount_st] by simp
show ?thesis
apply (simp add: buf_prepared_def prepared_pad_obj_def)
apply (case_tac "pad_to - used\<^sub>f ostore_st < bilbyFsObjHeaderSize")
apply simp
using buf_slice_buf_memset_is_append_padding[OF invs_pad, where frm="sync_offs\<^sub>f ostore_st", simplified buf_memset_eq[OF bound used_of]]
using inv_bufsD[OF inv_ostore] sync_lt_used
apply (simp add: valid_list_trans_append_padding valid_list_trans_no_pad_imp_valid_list_trans)
apply simp
apply (rule valid_list_trans_buf_slice_sync_offs_pad_to[OF invs_pad used_gt_zero sync_lt_used])
apply (rule valid_commit_pad_obj[OF inv_ostore inv_mount_st pad_to, simplified is_valid_ObjTrans, THEN conjunct1])
apply (rule_tac x=crc in exI)
apply (simp add: prepared_pad_obj_def prepared_pad_obj_no_crc_def ostore_update_padding_obj' pad_to bilbyFsObjHeaderSize_def bilbyFsTransCommit_def)+
apply (rule_tac x=crc in exI)
apply (simp add: prepared_pad_obj_def prepared_pad_obj_no_crc_def ostore_update_padding_obj' pad_to bilbyFsObjHeaderSize_def bilbyFsTransCommit_def)+
using inv_ostore_valid_pad_objD[OF inv_ostore]
apply (clarsimp simp add: prepared_pad_obj_no_crc_def valid_pad_obj_def prepared_pad_obj_def is_valid_Obj_def)
apply simp
done
qed
lemma list_trans_no_pad_slice_drop_append:
notes list_trans.simps[simp del]
and pTrans.simps[simp del]
assumes valid_slice: "valid_list_trans (slice frm to xs)"
and valid_drop: "valid_list_trans (drop to xs)"
and "frm \<le> to"
and "to \<le> length xs"
shows
"prod.snd (list_trans_no_pad (slice frm to xs)) @ prod.snd (list_trans_no_pad (drop to xs)) =
prod.snd (list_trans_no_pad (drop frm xs))"
using list_trans_no_pad_append[where xs="slice frm to xs" and ys="drop to xs"]
assms
by (clarsimp simp: slice_drop)
lemma map_ostore_update_append:
"map ostore_update xs @ map ostore_update ys = map ostore_update (xs @ ys)"
by simp
lemma fold_id_append:
"fold id xs (fold id ys Map.empty) = fold id (ys @ xs) Map.empty"
by simp
(* Taken from AFP containers *)
lemma insort_key_append1:
"\<forall>y \<in> set ys. f x < f y \<Longrightarrow> insort_key f x (xs @ ys) = insort_key f x xs @ ys"
proof(induct xs)
case Nil
thus ?case by(cases ys) auto
qed simp
lemma insort_key_append2:
"\<forall>y \<in> set xs. f x > f y \<Longrightarrow> insort_key f x (xs @ ys) = xs @ insort_key f x ys"
by(induct xs) auto
lemma sort_key_append[symmetric]:
"\<forall>x\<in>set xs. \<forall>y\<in>set ys. f x < f y \<Longrightarrow> sort_key f (xs @ ys) = sort_key f xs @ sort_key f ys"
by(induct xs)(simp_all add: insort_key_append1)
(* end of AFP containers *)
lemma inj_on_filter_key_eq:
"inj_on s (insert k (set xs)) \<Longrightarrow> [x\<leftarrow>xs . s k = s x] = filter ((=) k) xs"
apply (induct xs)
apply simp
apply (drule meta_mp, erule subset_inj_on)
apply auto[1]
apply (drule_tac x=k and y=a in inj_on_eq_iff, auto)
done
lemma filter_eq_replicate_count_multiset:
"filter ((=) k) xs = replicate (count (mset xs) k) k"
by (induct xs, auto)
lemma sort_key_multiset_eq:
assumes multiset: "mset xs = mset ys"
and inj_on: "inj_on f (set xs)"
shows "sort_key f xs = sort_key f ys"
proof -
from multiset have set:
"set xs = set ys"
by (rule mset_eq_setD)
note filter = inj_on_filter_key_eq[OF subset_inj_on, OF inj_on]
show ?thesis
apply (rule properties_for_sort_key)
apply (simp add: multiset)
apply (simp add: filter set)
apply (simp add: filter_eq_replicate_count_multiset multiset)
apply simp
done
qed
lemma sort_key_concat_map:
assumes i: "i < length xs" "i \<ge> n"
and f: "f (xs!i@ys) = f (xs!i) @ f ys"
and s: "inj_on s (set (concat (map f (drop n xs@[ys]))))"
shows "sort_key s (concat (map f (drop n (xs[i:=xs!i@ys])))) =
sort_key s (concat (map f ((drop n xs)@[ys])))"
proof -
from i obtain xs1 xi xs2 where xs_split: "xs = xs1 @ [xi] @ xs2"
and xi: "xs ! i = xi" and length_xs1[simp]: "length xs1 = i"
apply (erule_tac x="take i xs" in meta_allE)
apply (erule_tac x="xs ! i" in meta_allE)
apply (erule_tac x="tl (drop i xs)" in meta_allE)
apply (cases "drop i xs", simp_all)
apply (frule_tac f=hd in arg_cong, subst(asm) hd_drop_conv_nth, simp+)
apply (cut_tac n=i and xs=xs in append_take_drop_id, simp)
done
from i have multiset: "mset (concat (map f (drop n xs))) + mset (f ys) =
mset (concat (map f (drop n (xs[i := xs ! i @ ys]))))"
apply (simp add: xs_split drop_list_update)
apply (simp add: list_update_append nth_append f[simplified xi])
done
note set = arg_cong[where f=set_mset, OF multiset[symmetric], simplified]
show ?thesis
apply (rule sort_key_multiset_eq)
apply (simp add: multiset)
apply (rule subset_inj_on[OF s])
apply (simp add: set)
done
qed
lemma sort_key_concat_ignores_order:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
assumes trans_order:
"\<forall>x\<in>set (concat $ list_eb_log (\<alpha>wubi $ OstoreState.ubi_vol\<^sub>f ostore_st)).
\<forall>y\<in>set (prod.snd (list_trans_no_pad xs)).
trans_order x < trans_order y"
assumes inj: "inj_on trans_order
(set (concat
(map (prod.snd \<circ> list_trans_no_pad)
(drop (unat bilbyFsFirstLogEbNum) (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)) @
[xs]))))"
assumes used_gt_0: "0 < used\<^sub>f ostore_st"
assumes valid_xs: "valid_list_trans xs"
shows
"sort_key trans_order
(concat (map (prod.snd \<circ> list_trans_no_pad) (drop (unat bilbyFsFirstLogEbNum)
(\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) [unat (wbuf_eb\<^sub>f ostore_st) :=
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st) @ xs])))) =
sort_key trans_order
(concat (map (prod.snd \<circ> list_trans_no_pad) (drop (unat bilbyFsFirstLogEbNum)
(\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)) @ [xs])))"
apply (rule sort_key_concat_map)
using inv_ostore apply (clarsimp simp: inv_ostore_def inv_bufs_def inv_ubi_vol_def, unat_arith)
using inv_ostore apply (clarsimp simp: inv_ostore_def, unat_arith)
apply (simp)
apply (rule list_trans_no_pad_append[symmetric])
using inv_bufsD[OF inv_ostore] used_gt_0
apply (clarsimp)
apply (drule sym[where t="buf_take (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) "])
apply (simp add: buf_simps valid_list_trans_no_pad_def)
using valid_xs apply simp
using inj apply simp
done
lemma inv_ostore_list_trans_wbuf_sorted[simplified Let_def]:
"inv_ostore mount_st ostore_st \<Longrightarrow>
(let sync_to_used = buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st) in
sort_key trans_order (prod.snd (list_trans_no_pad sync_to_used)) =
prod.snd (list_trans_no_pad sync_to_used))"
by (drule inv_bufsD, clarsimp simp: Let_def)
lemma ostore_sync_\<alpha>_ostore_uptodate:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and pad_to: "pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and wubi: "list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st')) =
list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)
[unat (wbuf_eb\<^sub>f ostore_st) :=
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st) @
buf_slice
(wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone))
(prepared_pad_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)) crc))\<rparr>)
(sync_offs\<^sub>f ostore_st) (padding_to (mount_st, ostore_st, ostoreWriteNone))])"
(is "... = list_eb_log (?ubi[?wbuf_eb:=?old_ubi@?buf_prepared])")
and ostore_m: "ostore_st'\<lparr>OstoreState.ubi_vol\<^sub>f := v\<rparr> = ostore_st
\<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone))
(prepared_pad_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)) crc))\<rparr>,
used\<^sub>f := padding_to (mount_st, ostore_st, ostoreWriteNone),
fsm_st\<^sub>f := prepared_fsm_padding_obj ostore_st (used\<^sub>f ostore_st'), OstoreState.oaddr\<^sub>f := oaddr,
OstoreState.next_sqnum\<^sub>f := nxtsqnum, opad\<^sub>f := opad\<^sub>f ostore_st\<lparr>Obj.len\<^sub>f := len, Obj.sqnum\<^sub>f := sqnum, crc\<^sub>f := crc\<rparr>\<rparr>"
(is "... = ?ostore_st")
notes invs_pad_offs = inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used
shows
"\<alpha>_ostore_medium (ostore_st'\<lparr>sync_offs\<^sub>f := used\<^sub>f ostore_st'\<rparr>) = \<alpha>_ostore_uptodate ostore_st"
proof -
have sort_key_trans_key_eq: "sort_key trans_order (concat (map (prod.snd \<circ> list_trans_no_pad)
(drop (unat bilbyFsFirstLogEbNum) (?ubi
[?wbuf_eb := ?ubi ! ?wbuf_eb @ ?buf_prepared])))) =
sort_key trans_order (concat (map (prod.snd \<circ> list_trans_no_pad)
(drop (unat bilbyFsFirstLogEbNum) ?ubi @ [?buf_prepared])))"
apply (subst sort_key_concat_ignores_order[OF inv_ostore _ _ used_gt_zero])
using snd_list_trans_buf_prepared_eq[OF invs_pad_offs]
apply (simp only: )
using inv_logD[OF inv_ostore]
apply clarsimp
apply (simp only: map_append)
using snd_list_trans_buf_prepared_eq[OF invs_pad_offs]
inv_logD[OF inv_ostore]
apply (fastforce simp: list_eb_log_def)
using sync_lt_used inv_bufsD[OF inv_ostore] apply clarsimp
using valid_list_trans_buf_prepared_eq[OF invs_pad_offs]
apply (simp add: pad_to)+
done
have sort_trans_key_list_eb_log_eq_append_list_trans:
"sort_key trans_order (concat (list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st')))) =
sort_key trans_order (concat (list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st))) @
prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st))))"
apply (simp only: wubi)
apply (simp add: ostore_m list_eb_log_def Let_def)
apply (simp only: sort_key_trans_key_eq)
apply simp
apply (simp only: snd_list_trans_buf_prepared_eq[OF invs_pad_offs])
done
from inv_logD[OF inv_ostore] have trans_order':
"\<forall>x\<in>set (concat $ list_eb_log $ \<alpha>wubi $ OstoreState.ubi_vol\<^sub>f ostore_st).
\<forall>y\<in>set (prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st)
(sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)))).
trans_order x < trans_order y"
by (simp add: snd_list_trans_buf_prepared_eq[OF inv_ostore inv_mount_st])
show ?thesis
apply (simp add: \<alpha>_ostore_uptodate_def \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def
wubi \<alpha>_updates_def del: list_trans.simps)
apply (simp only: fold_id_append map_ostore_update_append)
apply (rule arg_cong[where f="\<lambda>x. fold id x Map.empty"])
apply (rule arg_cong[where f="map ostore_update"])
apply (subst inv_ostore_list_trans_wbuf_sorted[OF inv_ostore, symmetric])
using sort_key_append[OF trans_order'[unfolded fun_app_def] ]
apply (simp add: sort_trans_key_list_eb_log_eq_append_list_trans[simplified wubi])
done
qed
lemma inv_ostore_updated_ubi_preserved:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and nb_bytes_eq_pad_to_minus_sync: "nb_bytes = padding_to (mount_st, ostore_st, ostoreWriteNone) - sync_offs\<^sub>f ostore_st"
and nb_bytes: "0 < nb_bytes"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and inv_ubi_vol: "inv_ubi_vol mount_st ubi_vol'"
and wubi:
"\<alpha>wubi ubi_vol' = \<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)
[unat (wbuf_eb\<^sub>f ostore_st) :=
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st) @
buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st + nb_bytes)]"
and nb_bytes_eq: "sync_offs\<^sub>f ostore_st + nb_bytes = used\<^sub>f ostore_st"
shows
"inv_ostore mount_st (ostore_st\<lparr>OstoreState.ubi_vol\<^sub>f := ubi_vol', sync_offs\<^sub>f := used\<^sub>f ostore_st\<rparr>)"
(is "inv_ostore mount_st ?ostore_st")
proof -
have ostore_upt_Nil: "\<alpha>_updates ?ostore_st = []"
using wubi by (simp add: \<alpha>_updates_def \<alpha>_ostore_uptodate_def buf_slice_n_n)
have wubi_mod_ostore_get_obj_eq:
"\<And>addr. addr \<in> ran (\<alpha>_index (index_st\<^sub>f ostore_st)) \<Longrightarrow> ostore_get_obj ?ostore_st addr = ostore_get_obj ostore_st addr"
using wubi by (simp add: ostore_get_obj_def)
moreover have ostore_rt_eq: "\<alpha>_ostore_runtime ?ostore_st = \<alpha>_ostore_runtime ostore_st"
apply (rule ext)
apply (clarsimp simp: option.case_eq_if \<alpha>_ostore_runtime_def \<alpha>_ostore_medium_def)
using wubi_mod_ostore_get_obj_eq[simplified ran_def] apply fastforce
done
(* copy-paste from proof above should unify them somehow*)
from inv_logD[OF inv_ostore] have trans_order':
"\<forall>x\<in>set (concat ( list_eb_log ( \<alpha>wubi ( OstoreState.ubi_vol\<^sub>f ostore_st)))).
\<forall>y\<in>set (prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st)
(sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)))).
trans_order x < trans_order y"
by (simp add: snd_list_trans_buf_prepared_eq[OF inv_ostore inv_mount_st])
have sort_key_trans_key_eq:
"sort_key trans_order
(concat (map (prod.snd \<circ> list_trans_no_pad)
(drop (unat bilbyFsFirstLogEbNum)
(\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)
[unat (wbuf_eb\<^sub>f ostore_st) :=
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st) @
buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)])))) =
sort_key trans_order
(concat (map (prod.snd \<circ> list_trans_no_pad) (drop (unat bilbyFsFirstLogEbNum) (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)))) @
prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st))))"
apply (subst sort_key_concat_ignores_order[OF inv_ostore _ _ used_gt_zero])
apply (simp add: trans_order')
using inv_logD[OF inv_ostore]
apply (clarsimp simp: list_eb_log_def)
using sync_lt_used inv_bufsD[OF inv_ostore] apply (clarsimp simp: valid_list_trans_no_pad_imp_valid_list_trans)
using valid_list_trans_buf_prepared_eq[OF inv_ostore inv_mount_st, where pad_to="padding_to (mount_st, ostore_st, ostoreWriteNone)"]
apply (simp)+
done
have sort_trans_key_list_eb_log_eq_append_list_trans:
"sort_key trans_order (concat (list_eb_log (\<alpha>wubi ubi_vol'))) =
sort_key trans_order (concat (list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st))) @
prod.snd (list_trans_no_pad (buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st))))"
apply (simp only: wubi nb_bytes_eq)
apply (simp add: list_eb_log_def Let_def)
apply (simp only: sort_key_trans_key_eq)
done
moreover have ostore_uptodate_eq_new_ostore_medium:
"\<alpha>_ostore_medium ?ostore_st = \<alpha>_ostore_uptodate ostore_st"
apply (simp add: \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def wubi)
apply (simp add: \<alpha>_ostore_uptodate_def nb_bytes_eq)
apply (simp add: \<alpha>_ostore_uptodate_def \<alpha>_ostore_medium_def abstract_mount_\<alpha>_ostore_def
wubi \<alpha>_updates_def del: list_trans.simps)
apply (simp only: fold_id_append map_ostore_update_append)
apply (rule arg_cong[where f="\<lambda>x. fold id x Map.empty"])
apply (rule arg_cong[where f="map ostore_update"])
apply (subst inv_ostore_list_trans_wbuf_sorted[OF inv_ostore, symmetric])
apply (rule sym)
apply (rule trans[OF sort_key_append[OF trans_order' ]])
using sort_trans_key_list_eb_log_eq_append_list_trans[simplified wubi,symmetric]
apply (simp add: nb_bytes_eq)
done
moreover have ostore_uptodate_eq:
"\<alpha>_ostore_uptodate ?ostore_st = \<alpha>_ostore_uptodate ostore_st"
using ostore_uptodate_eq_new_ostore_medium ostore_upt_Nil
by (simp add: \<alpha>_ostore_uptodate_def)
moreover have "inv_fsm_st mount_st (fsm_st\<^sub>f ?ostore_st)"
using inv_fsm_stD[OF inv_ostore] by(simp add: inv_fsm_st_def)
moreover have list_eb_log_wbuf_eq:
"list_eb_log_wbuf ?ostore_st = list_eb_log_wbuf ostore_st"
apply (simp add: list_eb_log_wbuf_def wubi list_eb_log_def)
apply (clarsimp simp add: list_eq_iff_nth_eq)
apply (case_tac "i = unat (wbuf_eb\<^sub>f ostore_st) - unat bilbyFsFirstLogEbNum")
apply simp
apply simp
done
moreover have "inv_ostore_fsm mount_st ?ostore_st"
using list_eb_log_wbuf_eq inv_ostore[simplified inv_ostore_def]
by (clarsimp simp add: inv_ostore_fsm_def wubi)
moreover have "inv_ostore_index mount_st ?ostore_st"
using inv_ostore_indexD[OF inv_ostore] wubi_mod_ostore_get_obj_eq[simplified ran_def]
apply (clarsimp simp add: Let_def inv_ostore_index_def)
apply (rename_tac oid oaddr, erule_tac x=oid in ballE)
apply (simp add: is_valid_addr_def)
apply fastforce+
done
moreover have "inv_bufs mount_st ?ostore_st"
using inv_bufsD[OF inv_ostore] inv_ubi_vol apply (clarsimp simp: inv_bufs_def wubi Let_def nb_bytes_eq)
apply (simp add: buf_slice_n_n)
apply (simp add: used_gt_zero )
apply (simp add: sync_lt_used buf_take_buf_slice_adjacent[OF order_less_imp_le[OF sync_lt_used]])
using inv_ostore_wbuf_eb_rangeD[OF inv_ostore ] inv_ubi_vol
apply (clarsimp simp add:inv_ubi_vol_def wubi)
apply (rule conjI)
apply (simp add: unat_arith_simps)
using buf_take_buf_slice_adjacent[OF order_less_imp_le[OF sync_lt_used],symmetric]
valid_list_trans_no_pad_append
by fastforce
moreover have " inv_log (list_eb_log (\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ?ostore_st)))
(prod.snd $ list_trans_no_pad (buf_slice (wbuf\<^sub>f ?ostore_st) (sync_offs\<^sub>f ?ostore_st) (used\<^sub>f ?ostore_st)))"
using inv_logD[OF inv_ostore, THEN conjunct2]
apply (simp add: wubi buf_slice_n_n inv_log_def nb_bytes_eq list_eb_log_def del: set_concat)
using inv_ostore_wbuf_eb_rangeD[OF inv_ostore ] inv_ubi_vol
apply (clarsimp simp add:word_less_nat_alt word_le_nat_alt inv_ubi_vol_def wubi simp del: set_concat)
apply (simp add: drop_list_update)
apply (erule subset_inj_on)
apply (rule order_trans, rule UN_mono, rule set_update_subset_insert, rule subset_refl)
apply simp
apply (subst list_trans_no_pad_append[where xs="\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st) ! unat (wbuf_eb\<^sub>f ostore_st)"
and ys=" buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (used\<^sub>f ostore_st)",symmetric])
prefer 3
apply (simp, simp add: subset_iff)
apply (intro allI impI, rule disjI1, rule rev_bexI,
rule_tac n="unat (wbuf_eb\<^sub>f ostore_st) - unat bilbyFsFirstLogEbNum" in nth_mem, simp)
apply simp
using inv_bufsD[OF inv_ostore] used_gt_zero apply (simp add: inv_ubi_vol_def valid_list_trans_no_pad_imp_valid_list_trans)
using inv_bufsD[OF inv_ostore] sync_lt_used apply (simp add: inv_ubi_vol_def valid_list_trans_no_pad_imp_valid_list_trans)
done
moreover have "io_size\<^sub>f (super\<^sub>f mount_st) udvd used\<^sub>f ostore_st"
using nb_bytes_eq[symmetric] nb_bytes_eq_pad_to_minus_sync
apply simp
apply (thin_tac _)+
(* Why do I need to do this thin_tac nonsense to get this goal? *)
apply (simp add: padding_to_def[unfolded tuple_simps sanitizers])
apply (rule al_dvd_align32)
using inv_mount_st[simplified inv_mount_st_def Let_def] apply clarsimp
using inv_ostore_used_no_overflowD[OF inv_ostore] apply simp
done
ultimately show ?thesis
using inv_ostore apply (simp add: inv_ostore_def ostore_uptodate_eq_new_ostore_medium ostore_rt_eq wubi)
apply (clarsimp simp: inv_ostore_simps Let_def )
done
qed
lemma \<alpha>_updates_buf_prepare_eq:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
shows
"
OstoreState.next_sqnum\<^sub>f ostore_st \<le> next_sqnum \<Longrightarrow>
inv_ostore mount_st
(ostore_st
\<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone))
(prepared_pad_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)) crc))\<rparr>,
used\<^sub>f := padding_to (mount_st, ostore_st, ostoreWriteNone),
fsm_st\<^sub>f := prepared_fsm_padding_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)), OstoreState.oaddr\<^sub>f := oaddr,
OstoreState.next_sqnum\<^sub>f := nxtsqnum, opad\<^sub>f := opad\<^sub>f ostore_st\<lparr>Obj.len\<^sub>f := len, Obj.sqnum\<^sub>f := sqnum, crc\<^sub>f := crc\<rparr>\<rparr>) \<Longrightarrow>
\<alpha>_updates
(ostore_st
\<lparr>wbuf\<^sub>f := wbuf\<^sub>f ostore_st
\<lparr>data\<^sub>f :=
WordArrayT.make
(buf_prepared ostore_st (used\<^sub>f ostore_st)
(padding_to (mount_st, ostore_st, ostoreWriteNone))
(prepared_pad_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)) crc))\<rparr>,
used\<^sub>f := padding_to (mount_st, ostore_st, ostoreWriteNone),
fsm_st\<^sub>f := prepared_fsm_padding_obj ostore_st (padding_to (mount_st, ostore_st, ostoreWriteNone)), OstoreState.oaddr\<^sub>f := oaddr,
OstoreState.next_sqnum\<^sub>f := nxtsqnum, opad\<^sub>f := opad\<^sub>f ostore_st\<lparr>Obj.len\<^sub>f := len, Obj.sqnum\<^sub>f := sqnum, crc\<^sub>f := crc\<rparr>
\<rparr>) = \<alpha>_updates ostore_st"
proof -
obtain pad_to::U32 where pad_to:"pad_to = padding_to (mount_st, ostore_st, ostoreWriteNone)" by simp
have used_gt_zero: "0 < used\<^sub>f ostore_st"
using sync_lt_used by unat_arith
have bound: "unat (bound\<^sub>f (wbuf\<^sub>f ostore_st)) \<le> length (\<alpha>wa (data\<^sub>f (wbuf\<^sub>f ostore_st)))"
using inv_ostore_bound_le_lenD[OF inv_ostore] by simp
have used_of: "used\<^sub>f ostore_st \<le> used\<^sub>f ostore_st + (pad_to - used\<^sub>f ostore_st)"
apply (simp add: pad_to)
using used_le_padding_to[OF inv_ostore inv_mount_st] by simp
show ?thesis
apply (simp add: buf_prepared_def)
apply (case_tac "padding_to (mount_st, ostore_st, ostoreWriteNone) - used\<^sub>f ostore_st
< bilbyFsObjHeaderSize")
apply (simp add: \<alpha>_updates_def)
apply (rule arg_cong[where f="map ostore_update"])
using buf_slice_buf_memset_is_append_padding[OF inv_ostore inv_mount_st pad_to, where frm="sync_offs\<^sub>f ostore_st", simplified pad_to]
using buf_memset_eq[OF bound used_of, simplified pad_to]
apply (simp )
apply (rule snd_list_trans_no_pad_padding_unchanged)
using inv_bufsD[OF inv_ostore] sync_lt_used
apply (simp add: valid_list_trans_no_pad_imp_valid_list_trans)
apply (simp add: \<alpha>_updates_def)
apply (rule arg_cong[where f="map ostore_update"])
apply (rule snd_list_trans_no_pad_padding_obj_sync_pad_to[OF inv_ostore inv_mount_st pad_to used_gt_zero sync_lt_used, simplified pad_to])
apply (rule valid_commit_pad_obj[OF inv_ostore inv_mount_st pad_to, simplified is_valid_ObjTrans, THEN conjunct1])
apply (rule_tac x=crc in exI)
apply (simp add: prepared_pad_obj_def prepared_pad_obj_no_crc_def ostore_update_padding_obj' pad_to bilbyFsObjHeaderSize_def bilbyFsTransCommit_def)+
apply (rule_tac x=crc in exI)
apply (simp add: prepared_pad_obj_def prepared_pad_obj_no_crc_def ostore_update_padding_obj' pad_to bilbyFsObjHeaderSize_def bilbyFsTransCommit_def)+
using inv_ostore_valid_pad_objD[OF inv_ostore]
apply (clarsimp simp add: prepared_pad_obj_no_crc_def valid_pad_obj_def prepared_pad_obj_def is_valid_Obj_def)
apply simp
done
qed
lemma ostore_write_buf_ret:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and inv_step: "inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st)"
and used_gt_zero: "0 < used\<^sub>f ostore_st"
and sync_lt_used: "sync_offs\<^sub>f ostore_st < used\<^sub>f ostore_st"
and offs_ok: "unat (sync_offs\<^sub>f ostore_st) + unat nb_bytes \<le> unat (eb_size\<^sub>f (super\<^sub>f mount_st))"
and nb_bytes_ok: "io_size\<^sub>f (super\<^sub>f mount_st) udvd nb_bytes"
and sync_offs: "sync_offs = sync_offs\<^sub>f ostore_st"
and nb_bytes_eq: "sync_offs\<^sub>f ostore_st + nb_bytes = used\<^sub>f ostore_st"
and nb_bytes_eq_pad_to_minus_sync: "nb_bytes = padding_to (mount_st, ostore_st, ostoreWriteNone) - sync_offs\<^sub>f ostore_st"
and err:
"\<And>ex'. P ((ex',ostore_st), Error eIO)"
and suc:
"\<And>ex' ostore_st'. \<lbrakk>
inv_ostore mount_st (ostore_st' \<lparr> sync_offs\<^sub>f := used\<^sub>f ostore_st\<rparr>);
\<exists>v. ostore_st'\<lparr>OstoreState.ubi_vol\<^sub>f := v\<rparr> = ostore_st;
\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st') = \<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)[(unat (wbuf_eb\<^sub>f ostore_st)):=((\<alpha>wubi (OstoreState.ubi_vol\<^sub>f ostore_st)!(unat (wbuf_eb\<^sub>f ostore_st)))@buf_slice (wbuf\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st) (sync_offs\<^sub>f ostore_st + nb_bytes))] \<rbrakk> \<Longrightarrow>
P ((ex', ostore_st'), Success ())
"
shows
"P (ostore_write_buf(ex, mount_st, ostore_st, sync_offs, nb_bytes, ostoreWriteNone))"
unfolding ostore_write_buf_def[unfolded tuple_simps sanitizers, simplified take\<^sub>c\<^sub>o\<^sub>g\<^sub>e\<^sub>n\<^sub>t_def]
apply (simp add: sync_offs)
apply safe
apply (rule wubi_leb_write_ret[where mount_st=mount_st])
apply (rule length_ubi_buf_eq_sync_offsD[OF inv_ostore inv_mount_st])
apply (rule inv_ostore_wbuf_lengthD[OF inv_ostore])
apply (rule offs_ok)
apply (rule nb_bytes_ok)
using inv_bufsD[OF inv_ostore] apply clarsimp
apply (simp add: err)
apply simp
apply (rule suc)
apply (erule (2) inv_ostore_updated_ubi_preserved[OF inv_ostore inv_mount_st nb_bytes_eq_pad_to_minus_sync _ used_gt_zero sync_lt_used])
apply (simp add: nb_bytes_eq)
apply (rule_tac x="OstoreState.ubi_vol\<^sub>f ostore_st" in exI, fastforce)
apply simp
apply (rule suc)
using sync_lt_used nb_bytes_eq inv_ostore apply (clarsimp simp: word_not_0_gr_n)+
done
lemma extra_padding_is_aligned:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and sync_neq_used: "sync_offs\<^sub>f ostore_st \<noteq> used\<^sub>f ostore_st"
shows
"io_size\<^sub>f (super\<^sub>f mount_st) udvd padding_to (mount_st, ostore_st, ostoreWriteNone) - sync_offs\<^sub>f ostore_st"
proof -
have io_size_dvd_sync_offs: "io_size\<^sub>f (super\<^sub>f mount_st) udvd sync_offs\<^sub>f ostore_st"
using inv_ostore by (clarsimp simp: inv_ostore_def)
show ?thesis
using inv_mount_st[simplified inv_mount_st_def Let_def]
apply clarsimp
apply (drule al_dvd_align32[OF _ inv_ostore_used_no_overflowD[OF inv_ostore]])
using sync_offs_le_padding_to[OF inv_ostore inv_mount_st ]
io_size_dvd_sync_offs
apply (simp add: padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def )
apply (simp add: udvd_iff_dvd word_le_nat_alt unat_sub_if')
done
qed
lemmas OstoreState_ext_eq_expand = trans[OF _ OstoreState.ext_inject,
OF arg_cong2[where f="(=)"], OF refl OstoreState.surjective]
lemma ostore_sync_ret:
assumes inv_ostore: "inv_ostore mount_st ostore_st"
and inv_mount_st: "inv_mount_st mount_st"
and inv_step: "inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st)"
and suc: "\<And>ostore_st' ex'. \<lbrakk> inv_ostore mount_st ostore_st';
inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st');
\<alpha>_ostore_medium ostore_st' = \<alpha>_ostore_uptodate ostore_st;
\<alpha>_updates ostore_st' = []
\<rbrakk> \<Longrightarrow>
P ((ex', ostore_st'), Success ())"
and err: "\<And>e ostore_st' ex' n. \<lbrakk> inv_ostore mount_st ostore_st';
inv_\<alpha>_ostore (\<alpha>_ostore_uptodate ostore_st');
e \<in> {eIO, eNoMem, eNoSpc,eOverflow};
n < length (\<alpha>_updates ostore_st);
\<alpha>_ostore_medium ostore_st' = apply_n_updates n (\<alpha>_ostore_medium ostore_st) (\<alpha>_updates ostore_st);
\<alpha>_updates ostore_st' = (drop n $ \<alpha>_updates ostore_st)
\<rbrakk> \<Longrightarrow>
P ((ex', ostore_st'), Error e)"
notes pad_simps = padding_to_def[unfolded tuple_simps sanitizers] ostoreWriteNone_def
shows "P (ostore_sync (ex, mount_st, ostore_st, ostoreWriteNone))"
using [[goals_limit=2]]
unfolding ostore_sync_def[unfolded tuple_simps sanitizers]
apply (case_tac "sync_offs\<^sub>f ostore_st = used\<^sub>f ostore_st")
apply (simp add: ostoreWriteNone_def Let_def ostoreWriteNewEb_def)
apply (rule suc[OF inv_ostore inv_step])
apply (simp add: \<alpha>_ostore_uptodate_def used_eq_sync_offs_means_no_update)
apply ( simp add: \<alpha>_updates_def buf_simps )
apply (simp add: Let_def)
apply (rule prepare_wbuf_ret[OF inv_ostore inv_mount_st inv_step])
apply (rule refl)
using inv_ostore[simplified inv_ostore_def] apply clarsimp apply unat_arith
using inv_ostore[simplified inv_ostore_def] apply clarsimp apply unat_arith
apply (simp split: prod.split)
apply (rule err[OF inv_ostore inv_step, where e=eOverflow and n=0, simplified])
apply (erule used_neq_sync_offs_means_updates_not_Nil[OF inv_ostore])
apply (simp)
apply (rule ostore_sync_summary_if_eb_new_ret[OF _ inv_mount_st], simp_all)
apply clarsimp
(* apply (subgoal_tac "used\<^sub>f ostore_st' = padding_to (mount_st, ostore_st, ostoreWriteNone)")
apply (subgoal_tac "sync_offs\<^sub>f ostore_st' = sync_offs\<^sub>f ostore_st")*)
apply (rule ostore_write_buf_ret[OF _ inv_mount_st])
apply simp
apply (fastforce)
apply clarsimp
using used_le_padding_to[OF inv_ostore inv_mount_st ]
inv_ostore_sync_offsD[OF inv_ostore] apply unat_arith
using used_le_padding_to[OF inv_ostore inv_mount_st]
inv_ostore_sync_offsD[OF inv_ostore]
apply (simp add: )
apply (clarsimp simp add: OstoreState.splits OstoreState_ext_eq_expand offs_pl_padding_to_le_eb_size[OF inv_ostore inv_mount_st])
apply (clarsimp simp: OstoreState.splits OstoreState_ext_eq_expand extra_padding_is_aligned[OF inv_ostore inv_mount_st])
apply (clarsimp simp: OstoreState.splits OstoreState_ext_eq_expand)
apply (clarsimp simp: OstoreState.splits OstoreState_ext_eq_expand)
apply (clarsimp simp: OstoreState.splits OstoreState_ext_eq_expand)
apply (simp add: pad_simps)
apply (subst align32_idempotence)
using inv_mount_st[simplified inv_mount_st_def] apply (clarsimp simp: Let_def)
using inv_ostore_used_no_overflowD[OF inv_ostore] apply simp
apply simp
apply (clarsimp)
apply (rule err[where e=eIO and n=0, simplified])
apply simp
apply simp
using inv_ostore_sync_offsD[OF inv_ostore]
\<alpha>_updates_buf_prepare_eq[OF inv_ostore inv_mount_st]
used_neq_sync_offs_means_updates_not_Nil[OF inv_ostore]
apply (fastforce)
apply (fastforce simp add: \<alpha>_ostore_medium_def)
using inv_ostore_sync_offsD[OF inv_ostore]
\<alpha>_updates_buf_prepare_eq[OF inv_ostore inv_mount_st]
used_neq_sync_offs_means_updates_not_Nil[OF inv_ostore]
apply (fastforce)
apply simp
apply (rename_tac ex' ostore_st'')
apply (subgoal_tac "padding_to (mount_st, ostore_st, ostoreWriteNone) = used\<^sub>f ostore_st''")
apply (rule suc)
apply clarsimp
apply clarsimp
apply (cut_tac v=v and crc=crc and ostore_st'=ostore_st''
and len=len and oaddr=oaddr and nxtsqnum=nxtsqnum
and sqnum=sqnum in
ostore_sync_\<alpha>_ostore_uptodate[OF inv_ostore inv_mount_st])
apply (rule refl)
using used_le_padding_to[OF inv_ostore inv_mount_st ]
inv_ostore_sync_offsD[OF inv_ostore] apply unat_arith
using [[goals_limit=1]]
using inv_ostore_sync_offsD[OF inv_ostore] apply simp
apply simp
apply simp
apply (rename_tac v)
apply (drule_tac t=" used\<^sub>f ostore_st''" in sym)
using inv_step apply (simp add: \<alpha>_ostore_uptodate_def \<alpha>_updates_def buf_slice_n_n)
apply clarsimp
apply (rename_tac v)
apply (cut_tac v=v and crc=crc and ostore_st'=ostore_st''
and len=len and oaddr=oaddr and nxtsqnum=nxtsqnum
and sqnum=sqnum in
ostore_sync_\<alpha>_ostore_uptodate[OF inv_ostore inv_mount_st])
apply (rule refl)
using inv_ostore_sync_offsD[OF inv_ostore] apply unat_arith
using inv_ostore_sync_offsD[OF inv_ostore] apply unat_arith
using inv_bufsD[OF inv_ostore] apply simp
apply simp
apply (simp add: buf_slice_n_n \<alpha>_updates_def)
apply (simp add: \<alpha>_updates_def buf_slice_n_n)
apply (clarsimp, drule arg_cong[where f=used\<^sub>f], simp)
done
lemma ostore_write_ret:
"\<And>P. \<lbrakk> inv_ostore mount_st ostore_st;
inv_\<alpha>_step_updates ostore_st;
\<And>ex' ostore_st' objs' n. \<lbrakk> inv_ostore mount_st ostore_st';
inv_\<alpha>_step_updates ostore_st' ;
\<alpha>_ostore_medium ostore_st' = apply_n_updates n (\<alpha>_ostore_medium ostore_st) (\<alpha>_updates ostore_st @ [ostore_update (trimNone $ \<alpha>a objs)]);
\<alpha>_updates ostore_st' = drop n (\<alpha>_updates ostore_st @ [ostore_update (trimNone $ \<alpha>a objs)]);
is_set (osw, ostoreWriteForceSync) \<longrightarrow> n = length (\<alpha>_updates ostore_st) + 1
\<rbrakk> \<Longrightarrow>
P ((ex', ostore_st', objs'), Success ());
\<And>e ex' ostore_st' objs' n. \<lbrakk> inv_ostore mount_st ostore_st';
inv_\<alpha>_step_updates ostore_st' ;
e \<in> {eIO, eNoMem, eNoSpc} ;
\<alpha>_ostore_medium ostore_st' = apply_n_updates n (\<alpha>_ostore_medium ostore_st) (\<alpha>_updates ostore_st);
\<alpha>_updates ostore_st' = drop n (\<alpha>_updates ostore_st)
\<rbrakk> \<Longrightarrow>
P ((ex', ostore_st', objs'), Error e)
\<rbrakk> \<Longrightarrow>
P (ostore_write (ex, mount_st, ostore_st, objs, osw))"
oops
end