blob: 430c1362963e16606926b2c49be20f69152ffe33 [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 TransS
imports
"../impl/BilbyFs_Shallow_Desugar_Tuples"
"../impl/BilbyFs_ShallowConsts_Desugar_Tuples"
"../spec/OstoreInvS"
begin
lemma pTrans_remainder:
"prod.fst (pTrans buf) = drop (trans_len buf) buf"
apply (induct buf rule:trans_len.induct)
apply simp
apply (rename_tac v va)
apply (case_tac "trans\<^sub>f (pObj (v # va) 0) = bilbyFsTransIn")
apply (clarsimp simp: Let_def is_valid_ObjTrans)
apply (rule conjI)
apply (fastforce simp: trans_len_Cons bilbyFsObjHeaderSize_def )
apply (clarsimp simp: trans_len_Cons drop_n_ge_0 prod.case_eq_if)
apply (rule_tac f="\<lambda>a. drop a (v#va)" in arg_cong, fastforce)
apply (fastforce simp: Let_def trans_len_Cons bilbyFsObjHeaderSize_def is_valid_ObjTrans)
done
lemma list_trans_not_Nil_Nil:
"xs \<noteq> [] \<Longrightarrow>
list_trans xs \<noteq> ([],[])"
by (simp split: list.splits prod.splits)
lemma prefix_n_takeD:
"prefix xs ys \<Longrightarrow>
n \<le> length xs \<Longrightarrow>
take n ys = take n xs"
by (auto simp: prefix_def)
lemma take_n_eq_simp:
"take len ys = take len xs \<Longrightarrow>
idx < len \<Longrightarrow>
ys !idx = xs !idx"
by (metis elem_take_n)
lemma take_n_and_len'_eq_simp:
"take len ys = take len xs \<Longrightarrow>
idx < len' \<Longrightarrow>
len' \<le> len \<Longrightarrow>
ys !idx = xs !idx"
by (erule take_n_eq_simp) simp
lemma take_length_eq:
"\<lbrakk>take n xs = take n ys; length xs \<ge> n\<rbrakk> \<Longrightarrow> length ys \<ge> n"
by (fastforce dest!: arg_cong[where f=length])
lemma take_drop_eq_bounded:
"\<lbrakk>take n xs = take n ys; j + k < n\<rbrakk>
\<Longrightarrow> take j (drop k xs) = take j (drop k ys)"
apply (case_tac "length xs \<ge> n")
apply (subgoal_tac "length ys \<ge> n")
prefer 2
apply (erule (1) take_length_eq)
apply (rule nth_equalityI)
apply simp
apply clarsimp
apply (simp add: take_n_eq_simp[where xs=ys])
apply (simp add: not_less_eq_eq)
done
lemma pObjI:
"P(pObj ys 0) \<Longrightarrow>
unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj xs 0)) \<Longrightarrow>
take (unat (Obj.len\<^sub>f (pObj xs 0))) xs = take (unat (Obj.len\<^sub>f (pObj xs 0))) ys \<Longrightarrow>
P(pObj xs 0)"
apply (erule subst[where P=P,rotated])
apply (simp add: pObj_def pObjHeader_simp)
apply (subgoal_tac "\<forall>n<bilbyFsObjHeaderSize - 4. ple32 ys n = ple32 xs n")
apply (subgoal_tac "\<forall>n<bilbyFsObjHeaderSize - 8. ple64 ys n = ple64 xs n")
apply (simp add: pObj_def pObjHeader_simp
take_n_and_len'_eq_simp[where xs=ys and ys=xs and len'="unat bilbyFsObjHeaderSize"])
apply (clarsimp simp: ple64_def bilbyFsObjHeaderSize_def)
apply (subst take_drop_eq_bounded[where xs=xs and ys=ys and n="unat (ple32 xs 0x10)"])
apply ((simp | unat_arith)+)[3]
apply clarsimp
apply (subst ple32_def)+
apply (clarsimp simp: bilbyFsObjHeaderSize_def)
apply (subst take_drop_eq_bounded[where xs=xs and ys=ys and n="unat (ple32 xs 0x10)"])
apply ((simp | unat_arith)+)
done
lemma pObjD:
"take (unat (Obj.len\<^sub>f (pObj xs 0))) ys = take (unat (Obj.len\<^sub>f (pObj xs 0))) xs \<Longrightarrow>
unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj xs 0)) \<Longrightarrow>
pObj ys 0 = pObj xs 0"
by (auto intro: pObjI)
lemma length_bilbyFsObjHeaderSize_le_trans:
"unat len \<le> length xs \<Longrightarrow>
length xs \<le> length ys \<Longrightarrow>
unat bilbyFsObjHeaderSize \<le> length ys \<Longrightarrow>
bilbyFsObjHeaderSize \<le> len \<Longrightarrow>
unat bilbyFsObjHeaderSize \<le> length xs"
by unat_arith
lemma is_valid_ObjHeader_prefix_eq:
"prefix xs ys \<Longrightarrow>
unat (Obj.len\<^sub>f (pObj xs 0)) \<le> length xs \<Longrightarrow>
unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj xs 0)) \<Longrightarrow>
is_valid_ObjHeader (pObj ys 0) ys = is_valid_ObjHeader (pObj xs 0) xs"
apply (frule (1) prefix_n_takeD[where n="unat (Obj.len\<^sub>f (pObj xs 0))"])
apply (drule (1) pObjD)
apply (frule prefix_n_takeD[where n="length xs" and xs=xs and ys=ys], fastforce)
apply (subgoal_tac "take (unat $ Obj.len\<^sub>f $ pObj xs 0) xs = take (unat $ Obj.len\<^sub>f $ pObj xs 0) ys")
prefer 2
apply (drule (1) prefix_n_takeD, fastforce)
apply (frule prefix_length_le)
apply (auto simp: is_valid_ObjHeader_def length_bilbyFsObjHeaderSize_le_trans)
done
lemma is_valid_ObjHeader_prefix:
"is_valid_ObjHeader (pObj xs 0) xs \<Longrightarrow>
prefix xs ys \<Longrightarrow>
is_valid_ObjHeader (pObj ys 0) ys"
apply (frule is_valid_ObjHeader_buf_len)
apply (frule is_valid_ObjHeader_len)
apply (drule is_valid_ObjHeader_prefix_eq)
apply (clarsimp , unat_arith?)+
done
lemma is_valid_ObjHeader_prefix_rev:
"is_valid_ObjHeader (pObj ys 0) ys \<Longrightarrow>
prefix xs ys \<Longrightarrow>
unat (Obj.len\<^sub>f (pObj xs 0)) \<le> length xs \<Longrightarrow>
unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj xs 0)) \<Longrightarrow>
is_valid_ObjHeader (pObj xs 0) xs"
by (drule is_valid_ObjHeader_prefix_eq, auto)
lemma is_valid_ObjHeader_data_len:
"is_valid_ObjHeader (pObj xs n) (take nb ys) \<Longrightarrow>
is_valid_ObjHeader (pObj xs n) ys"
by (clarsimp simp: is_valid_ObjHeader_def)
lemma is_valid_ObjHeader_trans_len:
"is_valid_ObjHeader (pObj xs 0) xs \<Longrightarrow>
unat (Obj.len\<^sub>f (pObj xs 0)) \<le> trans_len xs"
by (case_tac "xs")
(clarsimp split:if_splits simp: trans_len_Cons)+
lemma valid_trans_valid_ObjHeaderD:
"valid_trans ys \<Longrightarrow> is_valid_ObjHeader (pObj ys 0) ys"
apply (erule valid_trans.elims)
apply (clarsimp split:if_splits simp: is_valid_ObjTrans)
done
lemma valid_trans_pObj_trans_len:
"valid_trans xs \<Longrightarrow>
unat (Obj.len\<^sub>f (pObj xs 0)) \<le> trans_len xs"
apply (case_tac "xs")
apply (simp)
apply (erule valid_trans.elims)
apply (clarsimp split:if_splits)
done
lemma valid_trans_pObj_take_trans_len:
"valid_trans (take (trans_len ys) ys) \<Longrightarrow>
unat (Obj.len\<^sub>f (pObj (take (trans_len ys) ys) 0)) \<le> trans_len ys"
apply (case_tac "(take (trans_len ys) ys)")
apply (clarsimp)
apply (erule valid_trans.elims)
apply (clarsimp simp:is_valid_ObjTrans split:if_splits )
apply (drule sym, simp only:)
apply (drule is_valid_ObjHeader_buf_len)
apply simp
apply (drule sym, simp only:)
apply (drule is_valid_ObjHeader_buf_len)
apply simp
done
lemma valid_trans_take_trans_len_valid_ObjHeaderD:
assumes "valid_trans (take (trans_len ys) ys)"
shows "is_valid_ObjHeader (pObj ys 0) ys"
proof -
have tl_take_bound: "unat (Obj.len\<^sub>f (pObj (take (trans_len ys) ys) 0)) \<le> trans_len ys"
by (rule valid_trans_pObj_take_trans_len[OF assms])
have "unat bilbyFsObjHeaderSize \<le> length (take (trans_len ys) ys)"
using is_valid_ObjHeader_len_facts[OF valid_trans_valid_ObjHeaderD[OF assms]]
by (clarsimp simp: is_valid_ObjHeader_def)
moreover have "length (take (trans_len ys) ys) \<le> length ys"
by simp
ultimately have len_eq: "Obj.len\<^sub>f (pObj ys 0) = (Obj.len\<^sub>f (pObj (take (trans_len ys) ys) 0))"
by (clarsimp simp: pObj_def pObjHeader_def Let_def Obj.make_def bilbyFsObjHeaderSize_def ple32_take)
from tl_take_bound and len_eq
have tl_bound: "unat (Obj.len\<^sub>f (pObj ys 0)) \<le> trans_len ys"
by simp
have valid: "is_valid_ObjHeader (pObj (take (trans_len ys) ys) 0) (take (trans_len ys) ys)"
by (rule valid_trans_valid_ObjHeaderD[OF assms])
have len_lower_bound: "unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj ys 0))"
using len_eq[symmetric] is_valid_ObjHeader_len[OF valid] by simp unat_arith
show ?thesis
using tl_bound valid len_eq
by - (rule pObjI[where ys="(take (trans_len ys) ys)", OF _ len_lower_bound], simp_all add: is_valid_ObjHeader_def min_absorb1)
qed
lemma valid_log_buf_fun_imp_valid_ObjHeader:
"valid_list_trans ys \<Longrightarrow> is_valid_ObjHeader (pObj ys 0) ys"
apply (erule valid_list_trans.elims)
apply (clarsimp simp: is_valid_ObjTrans)
apply (drule sym[where s=ys], simp)
apply (erule valid_trans.elims)
apply (rename_tac v va)
apply (subgoal_tac "is_valid_ObjHeader (pObj (v#va) 0) (v#va)")
apply (erule is_valid_ObjHeader_prefix)
apply (drule_tac t="v # va" in sym, fastforce)
apply (fastforce simp: is_valid_ObjTrans split: if_splits dest: is_valid_ObjHeader_buf_len)+
done
lemma n_idx_in_range:
"n < length xs \<Longrightarrow> (xs @ ys) ! n = xs ! n"
by (metis nth_append)
lemma is_down_32_8[simp]:
"is_down (c::(U32 \<Rightarrow> U8))"
by (simp add: is_down_def word_size target_size source_size)
lemma u32_to_u8_ignored[simp]:
"u32_to_u8 (ucast x) = x"
by (simp add: u32_to_u8_is_ucast ucast_down_ucast_id)
lemma word_rcat_8_32_ucast_last:
"list \<noteq> [] \<Longrightarrow> ucast (word_rcat list :: word32) = (last list :: word8)"
apply (cases list rule: rev_cases, simp_all)
apply (rule word_eqI)
apply (simp add: word_size test_bit_rcat[OF _ refl] nth_ucast)
done
lemma is_valid_ObjHeader_first_byte:
assumes "is_valid_ObjHeader (pObj data 0) data"
shows
"hd data = u32_to_u8 bilbyFsMagic"
proof -
have len_data: "length data > 4"
using is_valid_ObjHeader_len_facts[OF assms]
by (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def)
have "magic\<^sub>f (pObj data 0) = bilbyFsMagic"
using assms unfolding is_valid_ObjHeader_def by simp
hence "ple32 data 0 = bilbyFsMagic"
by (simp add: pObj_def pObjHeader_def Let_def Obj.make_def)
hence "u32_to_u8 (ple32 data 0) = u32_to_u8 bilbyFsMagic"
by (simp)
thus ?thesis
using len_data
by (case_tac data)
(clarsimp simp: ple32_def u32_to_u8_is_ucast word_rcat_8_32_ucast_last)+
qed
lemma is_valid_ObjHeader_not_pad:
"is_valid_ObjHeader (pObj data 0) data \<Longrightarrow> hd data \<noteq> bilbyFsPadByte"
by (drule is_valid_ObjHeader_first_byte)
(simp add: bilbyFsMagic_def bilbyFsPadByte_def u32_to_u8_is_ucast)
lemma valid_list_trans_non_empty:
"valid_list_trans ys \<Longrightarrow> ys \<noteq> []"
by (erule valid_list_trans.elims, simp_all)
lemma nopad_not_Nil:
"nopad xs \<noteq> [] \<Longrightarrow> xs \<noteq> []"
by (case_tac xs) (simp_all add: nopad_def)
lemma valid_trans_imp_valid_trans_trans_len:
"valid_trans xs \<Longrightarrow> trans_len xs \<le> length xs"
apply (induct xs rule: trans_len.induct)
apply (simp)
apply (erule valid_trans.elims)
apply (clarsimp split: if_splits simp add: is_valid_ObjTrans)
apply (rename_tac v vs)
apply (subgoal_tac "Suc (length vs) \<ge> unat (Obj.len\<^sub>f (pObj (v#vs) 0))")
apply (fastforce simp: is_valid_ObjHeader_def)+
done
lemma validObjIn_imp_validObjHeader:
"is_valid_ObjIn obj buf \<Longrightarrow> is_valid_ObjHeader obj buf"
by (simp add: is_valid_ObjTrans)
lemma trans_len_induct:
"P [] \<Longrightarrow>
(\<And>v vs. (is_valid_ObjIn (pObj (v#vs) 0) (v#vs) \<Longrightarrow>
P (drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v#vs))) \<Longrightarrow>
P (v#vs)) \<Longrightarrow> P a0"
by (erule trans_len.induct)
(fastforce intro: validObjIn_imp_validObjHeader)
lemma not_is_valid_ObjHeader_trans_len:
"\<not>is_valid_ObjHeader (pObj xs 0) xs \<Longrightarrow> trans_len xs = max (unat bilbyFsObjHeaderSize) (unat (Obj.len\<^sub>f (pObj xs 0)))"
by (case_tac xs, simp_all add: trans_len_Cons)
lemma trans_len_idempotence:
notes notI [rule del]
shows
"trans_len (take (trans_len xs) xs) = trans_len xs"
proof (induction xs rule: trans_len_induct)
show "trans_len (take (trans_len []) []) = trans_len []"
by simp
next
fix v vs
assume IH: "is_valid_ObjIn (pObj (v#vs) 0) (v#vs) \<Longrightarrow>
trans_len (take (trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs)))
(drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v # vs))) =
trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))"
have hdr_sz_le_tl: "unat bilbyFsObjHeaderSize \<le> trans_len (v#vs)"
using hdr_sz_le_trans_len[where xs="v#vs"] .
hence hdr_eq: "pObjHeader (take (trans_len (v#vs)) (v#vs)) 0 = pObjHeader (v#vs) 0"
by (simp add: pObjHeader_simp ple32_take ple64_take)
have len_eq: "unat (Obj.len\<^sub>f (pObj (take (trans_len (v # vs)) (v # vs)) 0)) = unat (Obj.len\<^sub>f (pObj (v # vs) 0))"
using hdr_sz_le_trans_len[where xs="v#vs"] ple32_take[where ys="v#vs"]
by (simp add: pObjHeader_simp pObj_def)
have trans_otype_eq: "\<And>f. f \<in> {Obj.trans\<^sub>f, Obj.otype\<^sub>f} \<Longrightarrow> (f (pObj (take (trans_len (v # vs)) (v # vs)) 0)) = f (pObj (v # vs) 0)"
using hdr_sz_le_trans_len[where xs="v#vs"]
by (fastforce simp: pObjHeader_simp pObj_def)
have magic_eq: "\<And>f. f \<in> {Obj.magic\<^sub>f, Obj.offs\<^sub>f} \<Longrightarrow> (f (pObj (take (trans_len (v # vs)) (v # vs)) 0)) = f (pObj (v # vs) 0)"
using hdr_sz_le_trans_len[where xs="v#vs"] ple32_take[where ys="v#vs"]
by (fastforce simp: pObjHeader_simp pObj_def)
show "trans_len (take (trans_len (v#vs)) (v#vs)) = trans_len (v#vs)"
proof (cases)
assume valid_in: "is_valid_ObjIn (pObj (v#vs) 0) (v#vs)"
hence valid_hdr: "is_valid_ObjHeader (pObj (v#vs) 0) (v#vs)"
by (simp add: is_valid_ObjTrans)
have valid_in': "is_valid_ObjIn (pObj (take (trans_len (v#vs)) (v#vs)) 0) (take (trans_len (v#vs)) (v#vs))"
using hdr_eq hdr_sz_le_trans_len[where xs="v#vs"] hdr_sz_le_tl valid_in
by (simp add: is_valid_ObjTrans is_valid_ObjHeader_def pObj_def Obj.make_def Let_def
ple32_take[where ys="v#vs"] ple64_take[where ys="v#vs"] pObjHeader_def
bilbyFsObjHeaderSize_def min_absorb1) (* this takes ages *)
let ?olen = "unat (Obj.len\<^sub>f (pObj (v # vs) 0))"
let ?dropolen = "drop ?olen (v # vs)"
have tl: "trans_len (v#vs) = ?olen + trans_len ?dropolen"
using valid_in trans_len_Cons by (simp add: is_valid_ObjTrans)
have tl': "trans_len (take (trans_len (v # vs)) (v # vs)) = (unat $ Obj.len\<^sub>f $ pObj (take (trans_len (v # vs)) (v # vs)) 0) +
trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (take (trans_len (v # vs)) (v # vs)) 0) (take (trans_len (v # vs)) (v # vs)))"
using valid_in' trans_len_Cons by (simp add: is_valid_ObjTrans)
have olen_assoc: "?olen + trans_len ?dropolen = trans_len ?dropolen + ?olen"
by simp
have tl_plus_eq: "trans_len (drop ?olen (take (?olen + trans_len ?dropolen) (v # vs))) =
trans_len (take (trans_len ?dropolen) ?dropolen)"
by (rule arg_cong[where f="trans_len"]) (simp add: take_drop olen_assoc)
have "?olen + trans_len ?dropolen = (unat $ Obj.len\<^sub>f $ pObj (take (trans_len (v # vs)) (v # vs)) 0) +
trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (take (trans_len (v # vs)) (v # vs)) 0)
(take (trans_len (v # vs)) (v # vs)))"
using len_eq IH[OF valid_in,simplified] tl_plus_eq
by (simp add: len_eq valid_in valid_hdr trans_len_Cons)
thus ?thesis
by (simp add: tl[symmetric] tl')
next
assume not_in: "\<not>is_valid_ObjIn (pObj (v#vs) 0) (v#vs)"
thus ?thesis
proof (cases)
assume valid: "is_valid_ObjHeader (pObj (v#vs) 0) (v#vs)"
have valid': "is_valid_ObjHeader (pObj (take (trans_len (v#vs)) (v#vs)) 0) (take (trans_len (v#vs)) (v#vs))"
using hdr_eq len_eq hdr_sz_le_trans_len[where xs="v#vs"] valid apply (simp only: is_valid_ObjTrans is_valid_ObjHeader_def pObj_def Obj.make_def Let_def
pObjHeader_def )
using is_valid_ObjHeader_trans_len[OF valid, simplified pObjHeader_simp pObj_def]
by (simp add: ple32_take[where ys="v#vs"] ple64_take[where ys="v#vs"] bilbyFsObjHeaderSize_def
min_absorb1)
hence not_in': "\<not>is_valid_ObjIn (pObj (take (trans_len (v#vs)) (v#vs)) 0) (take (trans_len (v#vs)) (v#vs))"
using valid' valid not_in apply (simp add: is_valid_ObjTrans)
apply (drule is_valid_ObjHeader_buf_len)+
apply (simp only: pObjHeader_simp pObj_def)
apply clarsimp
done
thus ?thesis
using valid valid' not_in not_in' apply (simp add: trans_len_Cons)
apply (case_tac "take (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs)", fastforce)
using len_eq apply (clarsimp simp: trans_len_Cons bilbyFsObjHeaderSize_def)
done
next
assume not_valid: "\<not>is_valid_ObjHeader (pObj (v#vs) 0) (v#vs)"
hence not_valid': "\<not>is_valid_ObjHeader (pObj (take (trans_len (v#vs)) (v#vs)) 0) (take (trans_len (v#vs)) (v#vs))"
using len_eq
by (fastforce simp: is_valid_ObjHeader_def magic_eq trans_otype_eq)+
have "unat (Obj.len\<^sub>f
(pObj (take (max (unat bilbyFsObjHeaderSize) (unat (Obj.len\<^sub>f (pObj (v # vs) 0))))
(v # vs))
0)) = (unat (Obj.len\<^sub>f (pObj (v # vs) 0)))"
using ple32_take[where ys="(v # vs)" and ntake="(max (unat bilbyFsObjHeaderSize) (unat (Obj.len\<^sub>f (pObj (v # vs) 0))))"]
by (simp add: pObj_def pObjHeader_simp)
thus ?thesis
apply (simp add: trans_len_Cons)
using not_valid and not_valid' apply simp
apply (case_tac "(take (max (unat bilbyFsObjHeaderSize) (unat (Obj.len\<^sub>f (pObj (v # vs) 0)))) (v # vs))")
apply (simp add: bilbyFsObjHeaderSize_def)
apply (simp add: trans_len_Cons)
done
qed
qed
qed
lemma trans_len_take_drop_eq:
assumes is_in:"is_valid_ObjIn (pObj (v # vs) 0) (v # vs)"
and valid_trans: "valid_trans (v#vs)"
shows
"take (trans_len (drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs)))
(drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs)) =
drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (take (trans_len (v # vs)) (v # vs))"
proof -
have "valid_trans (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))"
using valid_trans is_in by - (erule valid_trans.elims, fastforce)
let ?lenobj = "unat (Obj.len\<^sub>f (pObj (v # vs) 0))"
have "trans_len (drop ?lenobj (v#vs)) + ?lenobj = trans_len (v#vs)"
using is_in by (subst trans_len.simps) (clarsimp simp: is_valid_ObjTrans)
thus ?thesis
by (simp add: take_drop)
qed
lemma trans_len_take_drop_eq':
assumes yys_eq: "y#ys = take (trans_len (v#vs)) (v#vs)"
and is_in': "is_valid_ObjIn (pObj (v#vs) 0) (v#vs)"
and len_eq: "(unat (Obj.len\<^sub>f (pObj (y#ys) 0))) = (unat (Obj.len\<^sub>f (pObj (v#vs) 0)))"
shows
"take (trans_len (drop (unat (Obj.len\<^sub>f (pObj (v#vs) 0))) (v#vs)))
(drop (unat (Obj.len\<^sub>f (pObj (v#vs) 0))) (v#vs)) =
drop (unat (Obj.len\<^sub>f (pObj (v#vs) 0))) (y#ys)"
apply (simp add: yys_eq)
apply (subst trans_len_Cons)
using is_in' apply (clarsimp simp: is_valid_ObjTrans)
apply (simp add: take_drop len_eq[simplified yys_eq])
apply (case_tac "(drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs))")
apply simp
apply (rename_tac x xs)
apply (drule_tac t="x#xs" in sym)
apply (subgoal_tac "(trans_len (drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs)) +
unat (Obj.len\<^sub>f (pObj (v # vs) 0))) = ( unat (Obj.len\<^sub>f (pObj (v # vs) 0)) +
trans_len (drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs)))")
apply (simp only:)+
done
lemma take_trans_len_is_valid_ObjHeader_preserved:
assumes hdr: "is_valid_ObjHeader (pObj (v#vs) 0) (v#vs)"
and trans: "Obj.trans\<^sub>f (pObj (v#vs) 0) = tr"
and valid: "valid_trans (v # vs)"
and yys_eq:"take (trans_len (v#vs)) (v#vs) = y#ys"
shows
"is_valid_ObjHeader (pObj (y#ys) 0) (y#ys) \<and>
Obj.trans\<^sub>f (pObj (y#ys) 0) = tr \<and>
unat (Obj.len\<^sub>f (pObj (y#ys) 0)) = unat (Obj.len\<^sub>f (pObj (v#vs) 0))"
proof -
have prefix: "prefix (y#ys) (v#vs)"
using yys_eq by (metis take_is_prefix)
have len_eq: "unat (Obj.len\<^sub>f (pObj (y#ys) 0)) = unat (Obj.len\<^sub>f (pObj (v#vs) 0))"
using hdr_sz_le_trans_len[where xs="v#vs"]
by (simp only: yys_eq[symmetric] bilbyFsObjHeaderSize_def
pObj_def pObjHeader_def Obj.make_def Let_def ple32_take)
(simp add: ple32_take)
moreover hence len_obj: "unat (Obj.len\<^sub>f (pObj (y#ys) 0)) \<le> length (y#ys)"
using yys_eq[symmetric] is_valid_ObjHeader_buf_len[OF hdr] is_valid_ObjHeader_trans_len[OF hdr]
by clarsimp
have lower_bound: "unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj (y#ys) 0))"
using is_valid_ObjHeader_len[OF hdr] len_eq by unat_arith
have hdr_yys: "is_valid_ObjHeader (pObj (y # ys) 0) (y # ys)"
using is_valid_ObjHeader_prefix_rev[OF hdr prefix len_obj lower_bound] .
moreover have "unat bilbyFsObjHeaderSize \<le> length (y#ys)"
using is_valid_ObjHeader_buf_len[OF hdr_yys] by clarsimp
hence "Obj.trans\<^sub>f (pObj (y#ys) 0) = Obj.trans\<^sub>f (pObj (v#vs) 0)"
by (simp only: yys_eq[symmetric] bilbyFsObjHeaderSize_def
pObj_def pObjHeader_def Obj.make_def Let_def ple32_def)
simp
ultimately show "?thesis"
using trans by simp
qed
lemma valid_trans_imp_valid_trans_take_trans_len:
assumes valid: "valid_trans xs"
shows
"valid_trans (take (trans_len xs) xs)"
using valid_trans_imp_valid_trans_trans_len[OF valid] valid
proof (induction xs rule: trans_len_induct)
assume "valid_trans []"
hence False by simp
thus "valid_trans (take (trans_len []) [])" by simp
next
fix v vs
assume valid: "valid_trans (v # vs)"
and tllen: "trans_len (v # vs) \<le> length (v # vs)"
and IH:"\<lbrakk> is_valid_ObjIn (pObj (v#vs) 0) (v#vs);
trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))
\<le> length (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs));
valid_trans (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs)) \<rbrakk> \<Longrightarrow>
valid_trans (take (trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v#vs))) (drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v#vs)))"
thus "valid_trans (take (trans_len (v # vs)) (v # vs))"
proof (cases "is_valid_ObjIn (pObj (v#vs) 0) (v#vs)")
case True
obtain y ys where yys_eq:"take (trans_len (v#vs)) (v#vs) = y#ys"
using trans_len_non_zero[where xs="v#vs"]
by (drule_tac x=v and y="take (trans_len (v#vs) - 1) vs" in meta_spec2)
(case_tac "trans_len (v # vs)", fastforce+)
have trans_len_le: "trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))
\<le> length (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))"
using valid True
by - (fastforce split: if_splits dest: valid_trans_imp_valid_trans_trans_len)
have valid_nxt: "valid_trans (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))"
using valid True by - fastforce
have valid_trans_len: "valid_trans (take (trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v#vs))) (drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v#vs)))"
using IH[OF True trans_len_le valid_nxt] .
have "is_valid_ObjHeader (pObj (v#vs) 0) (v#vs)"
and "Obj.trans\<^sub>f (pObj (v#vs) 0) = bilbyFsTransIn"
using True by (simp add: is_valid_ObjTrans)+
hence "is_valid_ObjIn (pObj (y#ys) 0) (y#ys)"
and "unat (Obj.len\<^sub>f (pObj (y#ys) 0)) = unat (Obj.len\<^sub>f (pObj (v#vs) 0))"
using take_trans_len_is_valid_ObjHeader_preserved[OF _ _ valid yys_eq]
by (simp add: is_valid_ObjTrans)+
thus ?thesis
using valid_trans_len trans_len_take_drop_eq[OF True valid]
by (auto simp: yys_eq[symmetric])
next
case False
hence validCommit: "is_valid_ObjCommit (pObj (v#vs) 0) (v#vs)"
using valid by - (erule valid_trans.elims, simp)
thus ?thesis
proof (cases "take (trans_len (v # vs)) (v # vs)")
case Nil
hence False using trans_len_non_zero[where xs="v#vs"] by simp
thus ?thesis by simp
next
case (Cons y ys)
have "is_valid_ObjHeader (pObj (v#vs) 0) (v#vs)"
and "Obj.trans\<^sub>f (pObj (v#vs) 0) = bilbyFsTransCommit"
using validCommit by (simp add: is_valid_ObjTrans)+
hence "is_valid_ObjCommit (pObj (y#ys) 0) (y#ys)"
using take_trans_len_is_valid_ObjHeader_preserved[OF _ _ valid Cons]
by (simp add: is_valid_ObjTrans)
thus ?thesis
using Cons by simp
qed
qed
qed
lemma drop_append':
"drop n (x#xs @ ys) = drop n (x#xs) @ drop (n - length (x#xs)) ys"
by (metis append_Cons drop_append)
lemma obj_len_append:
assumes "unat bilbyFsObjHeaderSize \<le> Suc (length vs)"
shows " (Obj.len\<^sub>f (pObj (v # vs @ zs) 0)) = Obj.len\<^sub>f (pObj (v # vs) 0)"
using assms by (auto simp: pObj_def pObjHeader_simp n_idx_in_range ple32_def)
lemma valid_trans_take_trans_len_imp_valid_trans:
assumes valid: "valid_trans (take (trans_len xs) xs)"
shows "valid_trans xs"
using valid
proof (induction "xs" rule: valid_trans.induct)
assume "valid_trans (take (trans_len []) [])"
hence "False" by simp
thus "valid_trans []" by simp
next
fix v vs
assume valid: "valid_trans (take (trans_len (v # vs)) (v # vs))"
and IH: "is_valid_ObjIn (pObj (v # vs) 0) (v # vs) \<Longrightarrow>
valid_trans (take (trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs)))
(drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))) \<Longrightarrow>
valid_trans (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs))"
obtain y ys where yys_eq: "y#ys = take (trans_len (v#vs)) (v#vs)"
using trans_len_non_zero[where xs="v#vs"] by (cases "take (trans_len (v # vs)) (v # vs)" ,simp+)
have len_le_trans_len: "unat (Obj.len\<^sub>f (pObj (y#ys) 0)) \<le> trans_len (y#ys)"
using valid_trans_pObj_trans_len[OF valid] yys_eq by simp
have valid_obj_xs: "is_valid_ObjHeader (pObj (y#ys) 0) (y#ys)"
using valid yys_eq by - (erule valid_trans.elims, clarsimp simp: is_valid_ObjTrans split:if_splits)
have trans_len_eq: "trans_len (y#ys) = trans_len (v#vs)"
using trans_len_idempotence yys_eq by simp
have len_yys: "unat bilbyFsObjHeaderSize \<le> length (y#ys)"
using hdr_sz_le_trans_len[where xs="y#ys"] yys_eq[symmetric]
valid_trans_imp_valid_trans_trans_len[OF valid] by simp
have len_eq: "Obj.len\<^sub>f (pObj (y#ys) 0) = Obj.len\<^sub>f (pObj (v#vs) 0)"
using len_yys
by (simp add: pObj_def pObjHeader_def Obj.make_def yys_eq
ple32_take bilbyFsObjHeaderSize_def Let_def)
have min_obj_len_trans_len:"min (unat (Obj.len\<^sub>f (pObj (v#vs) 0))) (trans_len (v#vs)) = unat (Obj.len\<^sub>f (pObj (v#vs) 0))"
using len_le_trans_len[simplified trans_len_eq len_eq] by simp
have len_lower_bound: "unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj (v#vs) 0))"
using is_valid_ObjHeader_len[OF valid_obj_xs] by (simp add: len_eq yys_eq[symmetric]) unat_arith
show "valid_trans (v # vs)"
proof cases
assume is_in: "is_valid_ObjIn (pObj (y#ys) 0) (y#ys)"
hence is_in': "is_valid_ObjIn (pObj (v#vs) 0) (v#vs)"
apply (clarsimp simp: is_valid_ObjTrans yys_eq )
apply (drule is_valid_ObjHeader_data_len[where ys="v#vs"])
apply (frule is_valid_ObjHeader_len)
using len_eq min_obj_len_trans_len
by (auto elim: pObjI[OF _ len_lower_bound] simp: bilbyFsObjHeaderSize_def)
have "valid_trans (drop (unat $ Obj.len\<^sub>f $ pObj (y#ys) 0) (y#ys))"
using valid yys_eq[symmetric] by - (erule valid_trans.elims,simp add: is_in)
hence valid_take_trans_len_nxt:
"valid_trans (take (trans_len (drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs)))
(drop (unat $ Obj.len\<^sub>f $ pObj (v # vs) 0) (v # vs)))"
apply (simp add: yys_eq len_eq[simplified yys_eq])
apply (erule subst[rotated,where P=valid_trans])
using trans_len_take_drop_eq'[OF yys_eq is_in'] len_eq
by (simp add: yys_eq)
have "valid_trans (drop (unat $ Obj.len\<^sub>f $ pObj (v#vs) 0) (v#vs))"
using IH[OF is_in' valid_take_trans_len_nxt] .
thus ?thesis
using is_in' by (simp add: valid_trans_Cons)
next
assume is_not_in: "\<not>is_valid_ObjIn (pObj (y#ys) 0) (y#ys)"
hence is_commit: "is_valid_ObjCommit (pObj (y#ys) 0) (y#ys)"
using valid by - (erule valid_trans.elims, simp add: yys_eq)
hence is_commit':"is_valid_ObjCommit (pObj (v#vs) 0) (v#vs)"
apply (clarsimp simp: is_valid_ObjTrans yys_eq)
apply (drule is_valid_ObjHeader_data_len[where ys="v#vs"])
apply (frule is_valid_ObjHeader_len)
using len_eq min_obj_len_trans_len
apply (auto elim: pObjI[OF _ len_lower_bound] simp: bilbyFsObjHeaderSize_def)
done
thus ?thesis
using is_commit' by (simp add: valid_trans_Cons is_valid_Obj_diff)
qed
qed
lemma valid_trans_eq_valid_trans_take_trans_len:
"valid_trans xs = valid_trans (take (trans_len xs) xs)"
apply (rule iffI)
apply (erule valid_trans_imp_valid_trans_take_trans_len)
apply (erule valid_trans_take_trans_len_imp_valid_trans)
done
lemma valid_trans_prefixD:
"valid_trans xs \<Longrightarrow>
prefix xs ys \<Longrightarrow>
trans_len ys = trans_len xs"
apply (clarsimp simp: prefix_def)
apply (rename_tac zs)
apply (thin_tac "ys = xs @ zs")
apply (induct xs rule: trans_len_induct)
apply simp
apply (erule valid_trans.elims)
apply (rename_tac v vs)
apply (case_tac "is_valid_ObjIn (pObj (v#vs) 0) (v#vs)")
apply simp
apply (case_tac "(v # vs @ zs)")
apply (simp add: trans_len_Cons)
apply (subst trans_len_Cons)
apply (clarsimp simp: is_valid_ObjTrans)
apply (rename_tac v)
apply (frule_tac ys="(v # vs @ zs)" in is_valid_ObjHeader_prefix)
apply (simp)
apply simp
apply (frule_tac data="(v # vs @ zs)" in is_valid_ObjHeader_len_unat)
apply (drule_tac xs="(v # vs @ zs)" and ys="v#vs" in pObjD[rotated])
apply (drule_tac data="(v # vs )" in is_valid_ObjHeader_buf_len)
apply clarsimp
apply (rule nth_take_lemma)
apply (drule_tac is_valid_ObjHeader_buf_len)
apply (simp add: pObj_def pObjHeader_simp ple32_append_Cons)
apply (simp add: pObj_def pObjHeader_simp ple32_append_Cons)
apply (subgoal_tac "unat (Obj.len\<^sub>f (pObj (v # vs @ zs) 0)) = unat (Obj.len\<^sub>f (pObj (v#vs) 0)) ")
apply (simp)
apply (rename_tac i)
apply (case_tac i, simp_all add: nth_append)
apply (simp add: pObj_def pObjHeader_simp ple32_append_Cons)
apply (drule_tac x=zs in meta_spec)
apply (erule_tac P="\<lambda>xs. trans_len xs =
trans_len (drop (unat (Obj.len\<^sub>f (pObj (v # vs @ zs) 0))) (v # vs))" in subst[rotated])
apply (subgoal_tac " (unat (Obj.len\<^sub>f (pObj (v # vs @ zs) 0))) \<le> length (v#vs)")
apply (simp add: )
apply (subgoal_tac "unat bilbyFsObjHeaderSize \<le> unat (Obj.len\<^sub>f (pObj (v # vs @ zs) 0)) ")
apply (simp add: bilbyFsObjHeaderSize_def drop_n_ge_0)
apply (drule is_valid_ObjHeader_len, unat_arith)
apply (drule is_valid_ObjHeader_buf_len, simp)
apply (clarsimp simp: trans_len_Cons is_valid_ObjTrans split: if_splits)
apply (frule is_valid_ObjHeader_len)
apply (drule is_valid_ObjHeader_buf_len, simp)+
apply (clarsimp simp: pObj_def pObjHeader_simp ple32_append_Cons nth_append max_absorb2)
apply unat_arith
done
lemma valid_trans_prefix_imp:
"valid_trans xs \<Longrightarrow>
prefix xs ys \<Longrightarrow>
valid_trans ys"
apply (frule valid_trans_imp_valid_trans_take_trans_len)
apply (frule valid_trans_imp_valid_trans_trans_len)
apply (subgoal_tac "take (trans_len xs) xs = take (trans_len xs) ys")
apply simp
apply (frule valid_trans_imp_valid_trans_take_trans_len)
apply (drule (1) valid_trans_prefixD[THEN sym])
apply simp
apply (drule (1) valid_trans_take_trans_len_imp_valid_trans)
apply (fastforce simp: prefix_def)
done
lemma drop_prefixI:
"prefix xs ys \<Longrightarrow>
prefix (drop n xs) (drop n ys)"
by (auto simp: prefix_def)
lemma drop_Nil_prefixD:
"prefix xs ys \<Longrightarrow>
drop n xs \<noteq> [] \<Longrightarrow> (drop n ys) \<noteq> []"
by (auto simp: prefix_def)
lemma drop_length_append:
"drop (length xs) (xs@ys) = ys"
by auto
lemma drop_trans_len_Nil_eq_length:
"drop (trans_len xs) xs = [] \<Longrightarrow>
valid_trans xs \<Longrightarrow>
trans_len xs = length xs"
apply (induct xs rule: trans_len.induct)
apply fastforce
apply (simp)
apply (subst (asm) valid_trans.simps)
apply (clarsimp split:if_splits simp:is_valid_ObjTrans)
apply (fastforce dest: is_valid_ObjHeader_buf_len)+
done
definition valid_obj :: "U8 list \<Rightarrow> bool"
where
"valid_obj xs \<equiv> is_valid_ObjHeader (pObj xs 0) xs"
lemma not_valid_obj_list_trans:
"\<not>valid_obj xs \<Longrightarrow>
prod.fst (list_trans xs) = xs"
by (case_tac xs)
(simp add: Let_def valid_obj_def split: list.splits)+
lemma valid_obj_imp_no_pad_byte:
"valid_obj xs \<Longrightarrow> xs!0 \<noteq> bilbyFsPadByte"
using is_valid_ObjHeader_not_pad[where data=xs]
apply (simp add: valid_obj_def)
apply (drule is_valid_ObjHeader_buf_len)
apply (case_tac xs, simp_all add: bilbyFsObjHeaderSize_def)
done
lemma valid_trans_imp_valid_obj:
"valid_trans xs \<Longrightarrow> valid_obj xs"
by (erule valid_trans.elims)
(simp add: is_valid_ObjTrans valid_obj_def split:if_splits)
lemma nopad_Nil:
"\<And>n. nopad xs = [] \<Longrightarrow> nopad (xs@(replicate n bilbyFsPadByte)) = []"
by (simp add:nopad_def)
lemma list_Cons_append_simp:
"b # buf = xs \<Longrightarrow>
(b # buf @ ys) = xs @ ys"
by simp
definition
padding :: "nat \<Rightarrow> U8 list"
where
"padding n = replicate n bilbyFsPadByte"
lemma Cons_append: "x # xs @ ys = (x#xs) @ ys"
by simp
lemma slice_Cons_append: "slice f t (x #xs @ ys) = slice f t (x#xs) @ slice (f - min (length (x#xs)) t) (t - length (x#xs)) ys"
by (simp only: Cons_append slice_append )
lemma is_valid_ObjHeader_pObj_eq:
"is_valid_ObjHeader (pObj (b # buf @ xs) 0) (b # buf @xs) \<Longrightarrow>
is_valid_ObjHeader (pObj (b # buf) 0) (b # buf) \<Longrightarrow>
pObj (b # buf @ xs) 0 = pObj (b # buf) 0 "
apply (frule is_valid_ObjHeader_len_facts[where data="b # buf"])
apply (frule is_valid_ObjHeader_len_facts[where data="b # buf@xs"])
apply (clarsimp simp: is_valid_ObjHeader_def bilbyFsObjHeaderSize_def pObj_def Let_def pObjHeader_def Obj.make_def)
apply (simp add: ple32_eq_slice4 ple64_eq_slice8 slice_Cons_append slice_n_n )
apply (simp only: Cons_append take_append nth_append)
apply simp
done
lemma pTrans_remainderD:
"P (prod.fst (pTrans buf)) \<Longrightarrow> P (drop (trans_len buf) buf)"
by (simp add: pTrans_remainder)
lemma is_valid_ObjHeader_trans_len_le_buf_len:
"is_valid_ObjHeader (pObj xs 0) xs \<Longrightarrow>
unat (Obj.len\<^sub>f (pObj xs 0)) \<le> length xs"
by (clarsimp simp: is_valid_ObjHeader_def)
lemma snd_pTrans_append:
"valid_trans xs \<Longrightarrow> prod.snd (pTrans (xs @ ys)) = prod.snd (pTrans xs)"
apply (induct rule:pTrans.induct)
apply simp
apply (erule valid_trans.elims)
apply (clarsimp split:if_splits simp: is_valid_ObjTrans simp: Let_def)
apply (frule is_valid_ObjHeader_pObj_eq[rotated, where xs="ys"])
apply (clarsimp simp: prefix_def is_valid_ObjHeader_prefix)
apply (rename_tac v vs)
apply (frule_tac ys="(v # vs @ ys)" in is_valid_ObjHeader_prefix)
apply simp
apply (simp add: prod.case_eq_if)
apply (subgoal_tac "(drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs) @ ys) = (drop (unat (Obj.len\<^sub>f (pObj (v # vs) 0))) (v # vs @ ys))")
apply simp
apply (drule is_valid_ObjHeader_trans_len_le_buf_len)
apply (simp add: drop_append' prod.case_eq_if)
apply (frule is_valid_ObjHeader_pObj_eq[rotated, where xs="ys"])
apply (clarsimp simp: prefix_def is_valid_ObjHeader_prefix)
apply (frule_tac ys="(vb # vaa @ ys)" in is_valid_ObjHeader_prefix, simp)
apply (drule is_valid_ObjHeader_trans_len_le_buf_len)
apply (simp)
done
text {* @{term pTrans_valid_non_empty} says that pTrans cannot fail if valid_trans holds *}
lemma pTrans_valid_non_empty:
"valid_trans xs \<Longrightarrow> prod.snd (pTrans (xs@ys)) \<noteq> []"
apply (case_tac "xs@ys")
apply simp
apply (rename_tac v va )
apply (simp add: Let_def, drule sym, simp)
apply (erule valid_trans.elims)
apply (rename_tac vb vaa)
apply (drule_tac t="vb # vaa" in sym)
apply (simp only:)
apply (subgoal_tac "is_valid_ObjHeader (pObj (xs @ ys) 0) (xs @ ys)")
apply (clarsimp simp: is_valid_ObjTrans split:if_splits)
apply (fastforce simp: prod.case_eq_if)+
apply (clarsimp simp: is_valid_ObjTrans split:if_splits)
apply (erule is_valid_ObjHeader_prefix, simp_all)+
done
lemma valid_trans_pTrans_non_empty_trans:
notes notI [rule del]
shows
"valid_trans xs \<Longrightarrow>
prod.snd (pTrans xs) \<noteq> []"
using pTrans_valid_non_empty[where ys=Nil]
by fastforce
text {* Nicer induction lemma (variable renamed) *}
lemma list_trans_induct:
"(\<And>data. (\<And>data' tx. (data', tx) = pTrans data \<Longrightarrow> data' \<noteq>[] \<Longrightarrow> tx \<noteq> [] \<Longrightarrow> P (nopad data')) \<Longrightarrow> P data) \<Longrightarrow> P a0"
apply (rule list_trans.induct)
apply (drule_tac x=data in meta_spec)
apply (drule meta_mp)
apply (drule_tac x=data' and y=tx in meta_spec2)
apply (drule_tac x="hd data'" and y="tl data'" in meta_spec2)
apply (drule_tac x="hd tx" and y="tl tx" in meta_spec2)
apply fastforce
apply assumption
done
lemma snd_list_trans_Nil:
"prod.snd (list_trans []) = []"
by simp
lemma no_pad_Nil:
"nopad [] = []"
unfolding nopad_def
by simp
lemma nopad_padding_drop_eq_Nil:
"(nopad (drop n (xs @ padding m)) = []) = (nopad (drop n xs) = [])"
by (auto simp add: drop_append' nopad_def padding_def)
lemma nopad_padding_drop_eq_NilD:
"(nopad (drop n xs) = []) \<Longrightarrow> ( nopad (drop n (xs @ padding m)) = [])"
using nopad_padding_drop_eq_Nil
by auto
lemma nopad_padding_drop_eq_Nil':
"( nopad (drop n (x # xs @ padding m)) = []) = (nopad (drop n (x # xs)) = [])"
using nopad_padding_drop_eq_Nil[where xs="(x # xs)" and n=n and m=m]
by (subst Cons_append) auto
lemma nopad_padding_append:
"nopad xs \<noteq> [] \<Longrightarrow>
nopad (xs @ padding m) = nopad xs @ padding m"
by (clarsimp simp add: nopad_def padding_def)
lemma valid_list_trans_append_padding:
"valid_list_trans xs \<Longrightarrow>
valid_list_trans (xs @ padding n)"
apply (induct xs rule: valid_list_trans.induct)
apply simp
apply (erule valid_list_trans.elims)
apply simp
apply (rename_tac b' buf' b buf)
apply (clarsimp)
apply (frule_tac ys="(b # buf @ padding n)" in valid_trans_prefixD, simp)
apply (clarsimp simp add: nopad_padding_drop_eq_Nil' split:if_splits)
apply (frule_tac ys="(b # buf @ padding n)" in valid_trans_prefix_imp, simp)
apply assumption
apply (frule_tac ys="(b # buf @ padding n)" in valid_trans_prefix_imp, simp)
apply simp
apply (subgoal_tac "(nopad (drop (trans_len (b # buf)) (b # buf)) @ padding n) = (nopad (drop (trans_len (b # buf)) (b # buf @ padding n)))")
apply simp
apply (frule valid_trans_imp_valid_trans_trans_len)
apply (simp add: drop_append')
apply (case_tac "nopad (drop (trans_len (b # buf)) (b # buf))")
apply (simp add: nopad_padding_drop_eq_Nil' nopad_padding_append)+
done
lemma snd_list_trans_padding_unchanged:
notes list_trans.simps[simp del]
and length_drop[simp del]
and pTrans.simps[simp del]
shows
"valid_list_trans xs \<Longrightarrow>
prod.snd (list_trans (xs @ padding n)) = prod.snd (list_trans xs)"
apply (case_tac n, simp add: padding_def)
apply (induct xs rule: list_trans_induct)
apply (frule valid_list_trans_append_padding[where n=n])
apply (erule valid_list_trans.elims)
apply (erule valid_list_trans.elims)
apply clarsimp
apply (rename_tac pad_len buf b)
apply (clarsimp split: if_splits)
apply (subgoal_tac "nopad (drop (trans_len (b # buf @ padding (Suc pad_len))) (b # buf @ padding (Suc pad_len))) = nopad (drop (trans_len (b # buf)) (b # buf))")
prefer 2
apply (drule valid_trans_valid_ObjHeaderD,drule is_valid_ObjHeader_trans_len_le_buf_len)
apply (simp add: drop_append')
apply (subst list_trans.simps)
apply (rule sym, subst list_trans.simps, rule sym)
apply (frule_tac xs="(b # buf)" and ys="padding (Suc pad_len)" in snd_pTrans_append)
apply (simp only: prod.case_eq_if list.case_eq_if pTrans_remainder)
apply (case_tac "drop (trans_len (b # buf)) (b # buf)")
apply (simp add: snd_list_trans_Nil)+
apply (subst list_trans.simps)
apply (rule sym, subst list_trans.simps, rule sym)
apply (frule_tac xs="(b # buf)" and ys="padding (Suc pad_len)" in snd_pTrans_append)
apply (simp only: prod.case_eq_if list.case_eq_if pTrans_remainder)
apply (subgoal_tac "drop (trans_len (b # buf @ padding (Suc pad_len))) (b # buf @ padding (Suc pad_len)) \<noteq> []")
prefer 2
apply (frule_tac ys="b # buf @ padding (Suc pad_len)" in valid_trans_prefixD, simp)
apply (drule valid_trans_imp_valid_trans_trans_len)
apply (simp add: drop_append' padding_def)
apply simp
apply (frule valid_trans_imp_valid_trans_trans_len)
apply (simp add: valid_trans_pTrans_non_empty_trans snd_list_trans_Nil)
apply (frule_tac ys="(b # buf @ padding (Suc pad_len))" in valid_trans_prefixD, simp)
apply (simp add: )
apply (frule_tac m="(Suc pad_len)" in nopad_padding_drop_eq_NilD)
apply simp
apply (frule_tac ys="(b # buf @ padding (Suc pad_len))" in valid_trans_prefixD, simp)
apply (simp add: nopad_padding_drop_eq_Nil')
(* last subgoal uses the induction hypothesis *)
apply (subst list_trans.simps)
apply (rule sym, subst list_trans.simps, rule sym)
apply (frule_tac xs="b # buf @ padding (Suc pad_len)" in valid_trans_pTrans_non_empty_trans)
apply (frule_tac xs="b # buf" in valid_trans_pTrans_non_empty_trans)
apply (frule_tac ys="padding (Suc pad_len)" in snd_pTrans_append)
apply (frule nopad_not_Nil)
apply (frule_tac ys="(b # buf @ padding (Suc pad_len))" in valid_trans_prefixD, simp)
apply (simp add: prod.case_eq_if list.case_eq_if del: drop_eq_Nil)
apply (simp add: pTrans_remainder nopad_padding_drop_eq_Nil' drop_append')
apply (drule_tac x="prod.fst $ pTrans (b#buf)" and y="prod.snd $ pTrans (b#buf)" in meta_spec2)
apply (drule_tac x=pad_len in meta_spec)
apply (simp add: pTrans_remainder)
apply (erule meta_impE)
apply (simp add: prod_eq[symmetric] pTrans_remainder)
apply (erule trans[rotated])
apply (rule arg_cong[where f="\<lambda>xs. prod.snd (list_trans xs)"])
apply (simp add: nopad_padding_append)
done
lemma snd_list_trans_no_pad_padding_unchanged:
"valid_list_trans xs \<Longrightarrow>
prod.snd (list_trans_no_pad (xs @ padding n)) = prod.snd (list_trans_no_pad xs)"
by (fastforce dest: snd_list_trans_padding_unchanged[where n=n] simp: list_trans_no_pad_def prod.case_eq_if simp del: list_trans.simps)
lemma valid_list_trans_no_pad_append_padding:
"valid_list_trans_no_pad xs \<Longrightarrow>
valid_list_trans_no_pad (xs @ padding n)"
by (clarsimp simp add: valid_list_trans_no_pad_def
valid_list_trans_append_padding[where n=n]
snd_list_trans_no_pad_padding_unchanged)
lemma snd_list_trans_not_Nil:
"valid_list_trans xs \<Longrightarrow>
prod.snd (list_trans xs) \<noteq> []"
apply (erule valid_list_trans.elims)
apply (clarsimp simp del: pTrans.simps)
apply (frule valid_trans_pTrans_non_empty_trans)
apply (clarsimp simp: prod.case_eq_if simp del: pTrans.simps split:list.splits)
done
lemma snd_list_trans_nopad_not_Nil:
"valid_list_trans_no_pad xs \<Longrightarrow>
prod.snd (list_trans_no_pad xs) \<noteq> []"
by (simp add: valid_list_trans_no_pad_def)
lemma valid_trans_nth_0_neq_pad_byte:
"valid_trans xs \<Longrightarrow> xs!0 \<noteq> bilbyFsPadByte"
by (fastforce elim: valid_trans.elims dest: is_valid_ObjHeader_not_pad
simp: is_valid_ObjTrans split:if_splits)
lemma valid_list_trans_nth_0_neq_pad_byte:
"valid_list_trans ys \<Longrightarrow> ys!0 \<noteq> bilbyFsPadByte"
by (fastforce elim: valid_list_trans.elims dest: valid_trans_nth_0_neq_pad_byte)
lemma nopad_drop_trans_len_Nil_append:
"valid_list_trans ys \<Longrightarrow>
nopad (drop (trans_len xs) xs) = [] \<Longrightarrow>
valid_trans xs \<Longrightarrow>
nopad (drop (trans_len (xs @ ys)) (xs @ ys)) = ys"
apply (frule valid_trans_prefixD[where ys="(xs @ ys)"], simp)
apply (frule valid_trans_imp_valid_trans_trans_len)
apply (simp add: nopad_def)
apply (frule valid_list_trans_nth_0_neq_pad_byte)
apply (case_tac ys, fastforce+)
done
lemma nopad_drop_trans_len_Nil_append':
"valid_list_trans ys \<Longrightarrow>
nopad (drop (trans_len xs) xs) = [] \<Longrightarrow>
valid_trans xs \<Longrightarrow>
nopad (drop (trans_len xs) (xs @ ys)) = ys"
apply (frule valid_trans_prefixD[where ys="(xs @ ys)"], simp)
apply (frule valid_trans_imp_valid_trans_trans_len)
apply (simp add: nopad_def)
apply (frule valid_list_trans_nth_0_neq_pad_byte)
apply (case_tac ys, fastforce+)
done
lemma nopad_drop_trans_len_not_Nil_append:
"nopad (drop (trans_len xs) xs) \<noteq> [] \<Longrightarrow>
valid_trans xs \<Longrightarrow>
nopad (drop (trans_len (xs @ ys)) (xs @ ys)) \<noteq> []"
apply (frule valid_trans_prefixD[where ys="xs@ys"], simp)
apply (frule valid_trans_imp_valid_trans_trans_len)
apply (fastforce simp add: nopad_def)
done
lemma nopad_ys_eq_ys_nopad_append:
"nopad ys = ys \<Longrightarrow>
nopad (xs @ ys) = nopad xs @ ys"
by (metis (no_types, hide_lams) nopad_def append_self_conv dropWhile_append3
dropWhile_eq_Cons_conv valid_list_trans.cases)
lemma valid_list_trans_nopad_eq_id:
"valid_list_trans xs \<Longrightarrow> nopad xs = xs"
by (cases xs) (frule valid_list_trans_nth_0_neq_pad_byte, simp add: nopad_def)+
lemma valid_list_trans_append:
assumes val_xs: "valid_list_trans xs"
and val_ys: "valid_list_trans ys"
shows
"valid_list_trans (xs@ys)"
proof -
obtain y' ys' where ys_cons: "ys = y'#ys'" using val_ys by (case_tac ys, simp)
show ?thesis
using assms
apply (induct xs rule: valid_list_trans.induct)
apply simp
apply (rename_tac x' xs')
apply (clarsimp simp add: split: if_splits)
apply (case_tac "nopad (drop (trans_len (x' # xs' @ ys)) (x' # xs' @ ys)) = []")
apply simp
apply (erule valid_trans_prefix_imp, simp)
apply simp
apply (frule_tac ys="x'#xs'@ys" in valid_trans_prefix_imp)
apply simp
apply (simp only: Cons_append)
apply (frule (2) nopad_drop_trans_len_Nil_append)
apply simp
apply (simp only: Cons_append)
apply (frule (1) nopad_drop_trans_len_not_Nil_append[where ys="ys"])
apply clarsimp
apply (frule_tac ys="x'#xs' @ ys" in valid_trans_prefix_imp, simp)
apply (simp)
apply (frule_tac ys="(x' # xs' @ ys)" in valid_trans_prefixD, simp)
apply simp
apply (simp add: drop_append')
apply (frule_tac xs="x'#xs'" in valid_trans_imp_valid_trans_trans_len)
apply simp
apply (frule valid_list_trans_nopad_eq_id)
apply (simp add: nopad_ys_eq_ys_nopad_append)
done
qed
lemma trans_len_append:
"valid_trans xs \<Longrightarrow>
trans_len (xs @ ys) = trans_len xs"
apply (induct xs rule:trans_len.induct)
apply simp
apply (erule valid_trans.elims)
apply (simp add: is_valid_ObjTrans)
apply (clarsimp split: if_splits)
apply (subst trans_len.simps)
apply (rename_tac v vs)
apply (frule_tac ys="(v#vs @ ys)" in is_valid_ObjHeader_prefix, simp)
apply (simp add: is_valid_ObjTrans)
apply (frule (1) is_valid_ObjHeader_pObj_eq[where xs=ys] )
apply (simp add: )
apply (erule trans[rotated])
apply (rule arg_cong[where f=trans_len])
apply (frule is_valid_ObjHeader_trans_len_le_buf_len)
apply (simp add: drop_append')
apply (clarsimp simp add: is_valid_ObjTrans)
apply (subst trans_len.simps)
apply (simp add: is_valid_ObjTrans)
apply (rename_tac v vs)
apply (frule_tac ys="(v#vs @ ys)" in is_valid_ObjHeader_prefix, simp)
apply (simp add: is_valid_ObjTrans)
apply (frule (1) is_valid_ObjHeader_pObj_eq[where xs=ys] )
apply simp
done
lemma fst_pTrans_append_valid_trans_not_Nil:
shows
"valid_trans xs \<Longrightarrow> ys \<noteq> [] \<Longrightarrow>
prod.fst (pTrans (xs @ ys)) \<noteq> []"
apply (subgoal_tac "valid_trans (take (trans_len xs) xs)")
prefer 2
apply (simp add: valid_trans_eq_valid_trans_take_trans_len[symmetric])
apply (simp add: pTrans_remainder)
apply (subgoal_tac "trans_len (xs @ ys) = trans_len xs \<and> trans_len xs \<le> length xs")
apply simp
apply (frule valid_trans_imp_valid_trans_trans_len, simp)
apply (simp add: trans_len_append)
done
lemma no_pad_byte_nopad_append:
"ys ! 0 \<noteq> bilbyFsPadByte \<Longrightarrow>
nopad xs @ ys = nopad (xs @ ys)"
apply (simp add: nopad_def)
apply (case_tac ys)
apply simp
apply simp
apply (simp add: dropWhile_append3)
done
lemma list_trans_append:
notes list_trans.simps[simp del]
and pTrans.simps[simp del]
assumes valid_xs: "valid_list_trans xs"
and valid_ys: "valid_list_trans ys"
shows
"prod.snd (list_trans xs) @ prod.snd (list_trans ys) =
prod.snd (list_trans (xs@ys))"
proof -
obtain y' ys' where ys_cons: "ys = y'#ys'" using valid_ys by (case_tac ys, simp)
have ys_not_Nil: "ys \<noteq> []" using valid_ys by auto
show ?thesis
using assms
proof (induction xs rule: list_trans_induct)
fix data
assume IH:
"(\<And>data' tx.
(data', tx) = pTrans data \<Longrightarrow>
data' \<noteq> [] \<Longrightarrow>
tx \<noteq> [] \<Longrightarrow>
valid_list_trans (nopad data') \<Longrightarrow>
valid_list_trans ys \<Longrightarrow>
prod.snd (list_trans (nopad data')) @ prod.snd (list_trans ys) =
prod.snd (list_trans (nopad data' @ ys)))"
and valid_data: "valid_list_trans data"
obtain d ds where data_cons: "data = d#ds" using valid_data by (case_tac data, simp)
have val_trans_ys: "valid_trans ys"
using valid_ys by (simp add: ys_cons)
have val_trans_data: "valid_trans data"
using valid_data by (simp add: data_cons)
show "prod.snd (list_trans data) @ prod.snd (list_trans ys) = prod.snd (list_trans (data @ ys))"
proof (cases "nopad (drop (trans_len data) data)")
case Nil
show ?thesis
using Nil
apply -
apply (subst data_cons, subst list_trans.simps, simp only:data_cons[symmetric])
apply (simp add: prod.case_eq_if)
apply (simp add: pTrans_remainder)
apply (simp add: list.case_eq_if)
using valid_trans_pTrans_non_empty_trans[OF val_trans_data]
apply simp
using valid_trans_imp_valid_trans_trans_len[OF val_trans_data]
apply (simp add: prod.case_eq_if snd_list_trans_Nil)
apply (subst list_trans.simps[where data="data@ys"])
apply (simp add: prod.case_eq_if list.case_eq_if)
using fst_pTrans_append_valid_trans_not_Nil[OF val_trans_data ys_not_Nil]
apply (simp add: pTrans_valid_non_empty[OF val_trans_data] snd_pTrans_append[OF val_trans_data])
apply (simp add: pTrans_remainder trans_len_append[OF val_trans_data] )
using valid_trans_nth_0_neq_pad_byte[OF val_trans_ys]
apply (simp add: nopad_def)
apply (rule arg_cong[where f=prod.snd])
apply (rule arg_cong[where f=list_trans])
apply (case_tac ys, simp_all)
done
next
case (Cons v vs)
show ?thesis
using Cons
apply (subst list_trans.simps)
apply (simp add: prod.case_eq_if list.case_eq_if)
apply (simp add: pTrans_remainder)
apply (simp add: valid_trans_pTrans_non_empty_trans[OF val_trans_data])
using valid_trans_pTrans_non_empty_trans[OF val_trans_data]
apply (case_tac "length data \<le> trans_len data")
apply (simp add: nopad_def)
apply (simp add: )
using IH[where data'="prod.fst (pTrans data)" and tx="prod.snd (pTrans data)"]
apply simp
apply (erule meta_impE)
apply (simp add: pTrans_remainder nopad_def)
apply (simp add: valid_ys)
apply (erule meta_impE)
apply (simp only: pTrans_remainder)
apply (drule sym[where t="v#vs"], simp)
apply (cut_tac valid_data[simplified data_cons valid_list_trans.simps, THEN conjunct2])
apply (clarsimp simp add: data_cons[symmetric] split:if_splits)
apply (drule sym[where t="v#vs"])
apply simp
apply (simp only: pTrans_remainder)
apply (thin_tac _)+
apply (rule sym, subst list_trans.simps, rule sym)
apply (simp only: prod.case_eq_if)
apply (simp only: list.case_eq_if)
apply (simp add: fst_pTrans_append_valid_trans_not_Nil[OF val_trans_data ys_not_Nil])
apply (simp add: pTrans_valid_non_empty[OF val_trans_data])
apply (simp add: snd_pTrans_append[OF val_trans_data])
apply (simp only: pTrans_remainder)
apply (simp add: valid_trans_prefixD[OF val_trans_data, where ys="data@ys"])
apply (simp add: valid_trans_imp_valid_trans_trans_len[OF val_trans_data])
apply (rule arg_cong[where f=prod.snd])
apply (rule arg_cong[where f=list_trans])
using valid_trans_nth_0_neq_pad_byte[OF val_trans_ys]
using valid_trans_imp_valid_trans_trans_len[OF val_trans_data]
apply (simp add: no_pad_byte_nopad_append )
done
qed
qed
qed
lemma valid_list_trans_no_pad_append:
"valid_list_trans_no_pad xs \<Longrightarrow>
valid_list_trans_no_pad ys \<Longrightarrow>
valid_list_trans_no_pad (xs@ys)"
using valid_list_trans_append[where xs=xs and ys=ys]
snd_list_trans_not_Nil[where xs=xs] snd_list_trans_not_Nil[where xs=ys]
list_trans_append[where xs=xs and ys=ys, symmetric]
by (clarsimp simp add: prod.case_eq_if valid_list_trans_no_pad_def
list_trans_no_pad_def simp del:list_trans.simps)
lemma valid_list_trans_no_pad_imp_valid_list_trans:
"valid_list_trans_no_pad xs \<Longrightarrow> valid_list_trans xs"
by (simp add: valid_list_trans_no_pad_def)
lemma slice_drop:
"to \<le> length xs \<Longrightarrow> frm \<le> to \<Longrightarrow> slice frm to xs @ drop to xs = drop frm xs"
using drop_append[where xs="take to xs" and ys="drop to xs" and n=frm]
by (simp add: slice_def min_absorb1 min_absorb2 unat_arith_simps)
lemma list_trans_no_pad_append:
notes list_trans.simps[simp del]
and pTrans.simps[simp del]
assumes valid_slice: "valid_list_trans xs"
and valid_drop: "valid_list_trans ys"
shows
"prod.snd (list_trans_no_pad xs) @ prod.snd (list_trans_no_pad ys) =
prod.snd (list_trans_no_pad (xs@ys))"
using list_trans_append assms
by (clarsimp simp: valid_list_trans_no_pad_def list_trans_no_pad_def
prod.case_eq_if filter_append[symmetric] slice_drop min_absorb2)
(* Do I need this lemma?
It seems that it's not needed it until I start reasoning about pollute_buf. *)
(*
lemma fst_list_trans:
assumes prefixeq: "prefixeq xs ys"
and valid_list: "valid_list_trans xs"
and no_valid_obj: "\<not>valid_obj (drop (length xs) ys)"
(*nopad (drop (length xs) ys) \<noteq> [] \<Longrightarrow>*)
shows
"fst (list_trans ys) = drop (length xs) ys"
proof -
from valid_list have "valid_trans xs"
by - (erule valid_list_trans.elims, simp)
hence valid_ys: "valid_trans ys"
using prefixeq by (rule valid_trans_prefixeq_imp)
have "snd (pTrans ys) \<noteq> []"
using valid_trans_pTrans_non_empty_trans[OF valid_ys] .
thus ?thesis
using assms
proof (induction "ys" arbitrary:xs rule: list_trans_induct)
fix xs ys
assume snd_pTrans: "snd (pTrans ys) \<noteq> []"
and prefixeq: "prefixeq xs ys"
and valid_list: "valid_list_trans xs"
and not_valid_obj: "\<not> valid_obj (drop (length xs) ys)"
and IH:
"\<And>data' tx xs.
(data', tx) = pTrans ys \<Longrightarrow>
data' \<noteq> [] \<Longrightarrow>
tx \<noteq> [] \<Longrightarrow>
snd (pTrans (nopad data')) \<noteq> [] \<Longrightarrow>
prefixeq xs (nopad data') \<Longrightarrow>
valid_list_trans xs \<Longrightarrow>
\<not> valid_obj (drop (length xs) (nopad data')) \<Longrightarrow>
fst (list_trans (nopad data')) = drop (length xs) (nopad data')"
show "fst (list_trans ys) = drop (length xs) ys"
proof -
obtain zs where zsimp: "ys = xs @ zs"
using prefixeq by (fastforce simp : prefixeq_def)
have valid_trans_xs: "valid_trans xs"
using valid_list by - (erule valid_list_trans.elims, simp)
hence xs_not_nil: "xs \<noteq> []"
using valid_trans_xs by (case_tac xs, simp_all)
have valid_trans_ys: "valid_trans (xs@zs)"
using valid_trans_prefixeq_imp[OF valid_trans_xs prefixeq, simplified zsimp] .
hence ys_not_nil: "(xs@zs) \<noteq> []"
using valid_trans_xs by (case_tac "xs@zs", simp_all)
have trans_len_eq: "trans_len (xs@zs) = trans_len xs"
using valid_trans_prefixeqD[OF valid_trans_xs prefixeq, simplified zsimp] .
have trans_len_le_length_xs: "trans_len xs \<le> length xs"
using valid_trans_imp_valid_trans_trans_len[OF valid_trans_xs] .
have xs_remainder: "fst (pTrans xs) = drop (trans_len xs) xs"
using pTrans_remainder[where buf="xs"] .
have ys_remainder: "fst (pTrans (xs @ zs)) = drop (trans_len (xs @ zs)) (xs @ zs)"
using pTrans_remainder[where buf="xs@zs"] .
thus ?thesis
proof cases
assume length_xs: "trans_len xs = length xs"
hence fst_pTrans_ys:"fst (pTrans (xs@zs)) = zs"
using ys_remainder trans_len_eq by simp
thus ?thesis
using snd_pTrans apply (case_tac ys, simp, simp del:pTrans.simps)
apply (drule sym[where s=ys], simp add: zsimp prod.case_eq_if)
apply (case_tac zs, simp split:list.splits)
apply (simp)
apply (case_tac " snd (pTrans (xs @ zs))", fastforce)
using not_valid_obj_list_trans[OF not_valid_obj[simplified zsimp drop_length_append]]
apply (simp del:pTrans.simps list_trans.simps add: prod.case_eq_if)
oops
next
fix tx
let ?vs = "drop (trans_len xs) xs"
assume length_xs: "trans_len xs \<noteq> length xs"
hence vs_not_nil: "?vs \<noteq> []"
using trans_len_eq trans_len_le_length_xs by simp
obtain data' where data'_pTrans: "data' = fst (pTrans ys)"
by simp
hence data_eq: "data' = drop (trans_len ys) ys"
using zsimp ys_remainder by simp
hence data'_not_nil: "data' \<noteq> []"
using ys_remainder zsimp trans_len_eq trans_len_le_length_xs length_xs by simp
obtain tx where tx_facts: "tx = snd (pTrans ys) \<and> tx \<noteq> []"
using snd_pTrans by fastforce
hence a1: "(data', tx) = pTrans ys"
using data'_pTrans tx_facts by fastforce
have a5: "prefixeq ?vs (nopad data')"
by (simp add: data_eq trans_len_eq zsimp)
have a6: "valid_list_trans ?vs"
using valid_list trans_len_le_length_xs length_xs
by - (erule valid_list_trans.elims, fastforce)
have a4: "snd (pTrans (nopad data')) \<noteq> []"
proof -
have "valid_trans ?vs"
using valid_list a6 length_xs trans_len_le_length_xs
by - (fastforce elim: valid_list_trans.elims)
hence "valid_trans data'"
using a5 by - (drule valid_trans_prefixeq_imp)
thus ?thesis
by - (drule valid_trans_pTrans_non_empty_trans)
qed
have a7: "\<not> valid_obj (drop (length ?vs) data')"
using trans_len_le_length_xs trans_len_eq not_valid_obj
by (simp add: zsimp data_eq)
have "fst (list_trans data') = drop (length ?vs) data'"
using IH[OF a1 data'_not_nil conjunct2[OF tx_facts] a4 ]
using IH[OF a1 data'_not_nil conjunct2[OF tx_facts] a4 a5 a6 a7] oops
thus ?thesis
apply (simp only:zsimp data_eq)
apply (subst list_trans.simps)
using ys_remainder snd_pTrans[simplified zsimp] length_xs trans_len_eq
apply (simp add: prod.case_eq_if del: list_trans.simps)
apply (subgoal_tac "drop (trans_len xs) xs @ drop (trans_len xs - length xs) zs \<noteq> []")
using trans_len_le_length_xs
apply (clarsimp simp: prod.case_eq_if simp del: list_trans.simps split: list.splits)+
done
qed
qed
qed
qed
*)
end