Up to index of Isabelle/HOL/SafeImp
theory dem_translation(*
Title: Lemmas on the static properties of the translation SVM to JVM
Author: Ricardo Pe~na and Javier de Dios
Copyright: January 2009, Universidad Complutense de Madrid
*)
header {* Lemmas on the static properties of the translation SVM to JVM *}
theory dem_translation
imports "../JVMSAFE/JVMExec" SVM2JVM SVMSemantics CertifSVM2JVM
begin
declare trInstr.simps [simp del]
declare equivS.simps [simp del]
declare drop_append [simp del]
lemma fun_trInstr1_aux [rule_format]:
"(∀ pc i cdm pc' i' cdm' insts .
(∀ j ≥ i . (p,j) ∉ dom cdm) -->
((pc',i',cdm'),insts) = mapAccumL (trInstrAux p ctm com pcc) (pc,i,cdm) svms
--> cdm ⊆m cdm'∧ (∀ j ≥ i'. (p,j) ∉ dom cdm'))"
(* we make induction on the list of instructions *)
apply (induct svms)
(* empty list *)
apply simp
(* non-empty list *)
apply (rule allI)+
apply (rename_tac inst svms pc1 i1 cdm1 pc2 i2 cdm2 insts2)
apply (unfold mapAccumL.simps)
apply (case_tac "trInstrAux p ctm com pcc (pc1, i1, cdm1) inst")
apply (rename_tac state bc)
apply (case_tac state, rename_tac pc3 rest)
apply (case_tac rest, rename_tac i3 cdm3, simp)
apply (case_tac "mapAccumL (trInstrAux p ctm com pcc) (pc3, i3, cdm3) svms")
apply (rename_tac state4 insts4)
apply (case_tac state4,rename_tac pc4 rest4)
apply (case_tac rest4, rename_tac i4 cdm4,clarsimp)
apply (subgoal_tac "((pc4, i4, cdm4), insts4)
= mapAccumL (trInstrAux p ctm com pcc) (pc3, i3, cdm3) svms")
prefer 2 apply simp
(* we instantiate the universal vars of the induction hypothesis *)
apply (erule_tac x="pc3" in allE)
apply (rotate_tac -1)
apply (erule_tac x="i3" in allE)
apply (rotate_tac -1)
apply (erule_tac x="cdm3" in allE)
(* we eliminate the implication in the premises *)
apply (erule impE)
prefer 2
apply (rotate_tac -1)
apply (erule_tac x="pc4" in allE)
apply (rotate_tac -1)
apply (erule_tac x="i4" in allE)
apply (rotate_tac -1)
apply (erule_tac x="cdm4" in allE)
apply (erule impE)
apply (rule_tac x=insts4 in exI,assumption)
(* we unfold the definition of trInstrAux *)
apply (elim conjE)
apply (rule conjI)
apply (unfold trInstrAux_def) apply (simp)
apply (elim conjE)
apply (subgoal_tac "cdm1 ⊆m cdm1((p, i1) \<mapsto> pc1)")
apply (erule map_le_trans,simp)
(* we prove that (p,i1) was not in the domain of cdm1 *)
apply (erule_tac x=i1 in allE)
apply (erule impE,simp)
apply (unfold map_le_def) apply(force)
apply assumption
apply simp
apply (elim conjE)
apply clarify
apply (erule_tac x=j in allE)
apply (drule mp)
by auto
lemma fun_trInstr1 [rule_format]:
"(∀ pc i cdm pc' i' cdm' insts .
(∀ j ≥ i . (p,j) ∉ dom cdm) -->
((pc',i',cdm'),insts) = mapAccumL (trInstrAux p ctm com pcc) (pc,i,cdm) svms
--> cdm ⊆m cdm')"
apply (rule allI)+
apply (rule impI)+
thm fun_trInstr1_aux
apply (subgoal_tac "cdm ⊆m cdm'∧ (∀ j ≥ i'. (p,j) ∉ dom cdm')")
prefer 2 apply (rule fun_trInstr1_aux)
apply (erule_tac x=j in allE) apply (drule mp)
by auto
lemma fun_trInstrAux:
"((pc',cdm'),bc') = trSeq ctm com pcc (pc,cdm) (p,svms,fn) -->
svms = is # iss -->
(∀ j≥0 . (p,j) ∉ dom cdm) -->
drop pc bc = bc' @ rest -->
(∀ i . i < length svms -->
(∃ pc'' cdm'' bc'' rest' insts1.
((pc''+length bc'',i+1,cdm''((p,i)\<mapsto> pc'')),bc'') =
trInstrAux p ctm com pcc (pc'',i,cdm'') (svms!i)
∧ drop (pc''-pc) bc' = bc'' @ rest'
∧ ((pc'',i,cdm''),insts1)=
mapAccumL (trInstrAux p ctm com pcc) (pc,0,cdm) (take i svms)
∧ cdm''((p,i)\<mapsto> pc'') ⊆m cdm'))"
apply (rule impI)+
apply (rule allI)
(* we make induction on the position i of the svm instruction *)
apply (induct_tac i)
(* i= 0 *)
apply (rule impI)
apply (unfold trSeq_def)
apply clarify
apply (case_tac "(pc,cdm)")
apply (case_tac "(p, is # iss, fn)")
apply (rename_tac pc2 cdm2 p2 rest2)
apply (case_tac "rest2")
apply (rename_tac instr ff)
apply (simp del: mapAccumL.simps)
apply (case_tac "mapAccumL (trInstrAux p2 ctm com pcc) (pc2, 0, cdm2) instr")
apply (rename_tac result instss2)
apply (case_tac result)
apply (rename_tac pc3 rest2)
apply (case_tac rest2)
apply (simp del: mapAccumL.simps)
apply clarify
(* we apply the lemma mapAccumL_non_empty *)
apply (rename_tac nn bca)
apply (subgoal_tac "(∃ s' y ys'.
(s',y) = trInstrAux p ctm com pcc (pc, 0, cdm) is
∧ ((pc',nn,cdm'),ys')=mapAccumL (trInstrAux p ctm com pcc) s' iss
∧ instss2 = y # ys')")
prefer 2
apply (subgoal_tac "((pc', nn, cdm'), instss2)=
mapAccumL (trInstrAux p ctm com pcc) (pc, 0, cdm) (is # iss)")
prefer 2 apply simp
apply (erule mapAccumL_non_empty2,simp)
apply (elim exE,elim conjE)
apply clarify
apply (rename_tac pc4 nn4 cdm4 bc0 ys')
(* we instantiate the existential vars: pc and cdm are the inital ones *)
apply (rule_tac x=pc in exI)
apply (rule_tac x=cdm in exI)
apply (rule_tac x=bc0 in exI)
apply (subgoal_tac "(pc4, nn4, cdm4)=
(pc + length bc0, Suc 0, λ a. if a = (p, 0) then Some pc else cdm a)")
apply (rule conjI)
apply simp
apply (rule conjI)
apply (rule_tac x="concat ys'" in exI)
apply force
apply (rule conjI)
apply (rule_tac x="[]" in exI,simp)
apply (simp del: mapAccumL.simps add: trInstrAux_def)
apply (fold fun_upd_apply)
apply (elim conjE)
apply clarify
thm fun_trInstr1
apply (rule_tac i="Suc 0" and p="p" in fun_trInstr1)
apply (erule_tac x=j in allE)
apply force
apply simp
apply (simp del: mapAccumL.simps add: trInstrAux_def)
apply (fold fun_upd_apply)
apply force
(* inductive step i > 0 *)
apply clarify
apply (case_tac "(pc,cdm)")
apply (case_tac "(p, is # iss, fn)")
apply (rename_tac pc2 cdm2 p2 rest2)
apply (case_tac "rest2")
apply (rename_tac instr ff)
apply (simp del: mapAccumL.simps)
apply (case_tac "mapAccumL (trInstrAux p2 ctm com pcc) (pc2, 0, cdm2) instr")
apply (rename_tac result instss)
apply (case_tac result)
apply (rename_tac pc3 rest3)
apply (case_tac rest3)
apply (rename_tac n3 cdm3)
apply (simp del: mapAccumL.simps)
apply clarify
(* we split the input list into the n first ones and the rest *)
apply (subgoal_tac "(take n (is#iss)) @ (drop n (is#iss))=is#iss")
prefer 2
apply (rule append_take_drop_id)
apply (subgoal_tac "∃ s1 insts1 insts2 . (s1,insts1) =
mapAccumL (trInstrAux p ctm com pcc) (pc, 0, cdm) (take n (is # iss))
∧ ((pc', n3, cdm'), insts2)=
mapAccumL (trInstrAux p ctm com pcc) s1 (drop n (is # iss))
∧ instss= insts1 @ insts2")
prefer 2
apply (rule mapAccumL_split [where xs="is # iss"]) apply(simp,simp)
apply (elim exE, elim conjE)
apply (case_tac s1)
apply (rename_tac pc1 rest1)
apply (case_tac rest1)
apply (rename_tac nn1 cdm1)
apply clarify
apply (subgoal_tac " ((pc'', n, cdm''), insts1)=((pc1, nn1, cdm1), insts1a)")
prefer 2
apply simp
apply clarify
apply (thin_tac "?x=mapAccumL ?f (pc,0,cdm) ?xs")
(* we execute one mapAccumL step *)
(* non empty list after dropping nn1 instructions *)
apply (subgoal_tac "nn1 < length (is#iss)")
apply (subgoal_tac "(∃ is2 iss2 . drop nn1 (is # iss) = is2#iss2
∧ (is # iss) ! nn1 = is2)")
prefer 2
apply (erule drop_nth)
prefer 2
apply simp
apply (elim exE)
apply clarify
(* now, instruction nn1 is the first one of the remaining list *)
apply (subgoal_tac "(∃ s' y ys'.
(s',y) = trInstrAux p ctm com pcc (pc1, nn1, cdm1) ((is # iss) ! nn1)
∧ ((pc', n3, cdm'),ys') = mapAccumL (trInstrAux p ctm com pcc) s' iss2
∧ insts2 = y # ys')")
prefer 2
apply (erule mapAccumL_non_empty2,simp)
apply (elim exE)
apply (elim conjE)
apply (simp del: mapAccumL.simps drop_append)
apply (rename_tac s' bc2 ys')
apply (case_tac s')
apply (rename_tac pc2 rest2)
apply (case_tac rest2, rename_tac nn2 cdm2,clarify)
apply (subgoal_tac "((pc1 + length bc'', Suc nn1,
% a. if a = (p, nn1) then Some pc1 else cdm1 a), bc'')
=((pc2, nn2, cdm2), bc2)")
prefer 2
apply simp
apply (clarify, thin_tac "?x=trInstrAux p ctm com pcc ?y ?z")
(* we execute two steps of mapAccumL *)
apply (subgoal_tac "∃ iss3. iss2=(iss ! nn1)#iss3")
apply (elim exE,clarify)
apply (subgoal_tac "(∃ s1 s2 y1 y2 ys3 .
(s1,y1)=trInstrAux p ctm com pcc (pc1, nn1, cdm1) ((is # iss) ! nn1)
∧ (s2,y2)=trInstrAux p ctm com pcc s1 (iss!nn1)
∧ ((pc', n3, cdm'), ys3)=mapAccumL (trInstrAux p ctm com pcc) s2 iss3
∧ bc2#ys'=y1#y2#ys3)")
prefer 2
apply (erule mapAccumL_two_elements)
apply simp
apply (elim exE)
apply (case_tac s1, rename_tac pc3 rest3,clarify)
apply (rename_tac nn3 cdm3)
apply (subgoal_tac "((pc3, nn3, cdm3), y1)=
((pc1 + length y1, Suc nn1,
% a. if a = (p, nn1) then Some pc1 else cdm1 a), y1)")
prefer 2
apply simp
apply (clarify,thin_tac "?x=trInstrAux p ctm com pcc ?y ?z")
apply (rename_tac pc4 nn4 cdm4 y1 y2 ys3 pc3 nn3 cdm3)
prefer 2
apply (rule_tac x="tl iss2" in exI)
apply (subgoal_tac "drop (Suc nn1) (is#iss) = iss2")
prefer 2
apply (subgoal_tac "drop (Suc nn1) (is # iss)=drop nn1 (tl (is#iss))")
prefer 2
apply (rule drop_Suc)
apply (subgoal_tac "is # iss=take nn1 (is # iss) @ (is # iss) ! nn1 # iss2")
prefer 2
apply simp
apply (erule drop_take_Suc)
apply (rule drop_nth2,assumption,simp)
(* finally we instantiate the existential vars *)
apply (rule_tac x="pc1 + length y1" in exI)
apply (rule_tac x=" % a. if a = (p, nn1) then Some pc1 else cdm1 a" in exI)
apply (rule_tac x="y2" in exI)
apply (rule conjI)
(* first conclusion *)
apply (thin_tac "mapAccumL ?x ?y ?z = ?w")
apply (thin_tac "?w=mapAccumL ?x ?y ?z")
apply (thin_tac "?w=mapAccumL ?x ?y ?z")
apply (thin_tac "?x=trInstrAux ?x1 ?x2 ?x3 ?x4 ?x5 ?x6")
apply (simp add: trInstrAux_def)
apply clarify
apply (fold fun_upd_apply)
apply force
(* second conclusion *)
apply (rule conjI)
apply (rule_tac x="concat ys3" in exI)
apply (simp only: concat.simps)
apply (rule drop_append2,simp,simp)
(* third conclusion *)
apply (rule conjI)
apply (rule_tac x="insts1a @ [y1]" in exI)
apply (subgoal_tac "is # take nn1 iss=(take nn1 (is # iss)) @ [(is # iss) ! nn1]")
apply (erule_tac t="is # take nn1 iss" in ssubst)
prefer 2
apply (erule take_append2)
apply (rule mapAccumL_one_more,simp,assumption)
(* fourth conclusion *)
apply (thin_tac "drop ?n ?x = ?y")
apply (thin_tac "drop ?n ?x = ?y")
apply (thin_tac "drop ?n ?x = ?y")
apply (thin_tac "(take ?n ?x)@?z = ?y")
apply (thin_tac "?x < ?y")
apply (subgoal_tac "cdm4 = cdm1((p, nn1) \<mapsto> pc1,
(p, Suc nn1) \<mapsto> pc1 + length y1)")
prefer 2 apply (unfold trInstrAux_def)
apply force
apply (simp del:mapAccumL.simps trInstr.simps)
apply (fold fun_upd_apply)
apply (elim conjE)
apply (thin_tac "mapAccumL ?f ?s ?x = ?y")
apply (subgoal_tac "cdm1 ((p, nn1) \<mapsto> pc1, (p, Suc nn1) \<mapsto> pc1 + length
(trInstr pc1 (cdm1((p, nn1) \<mapsto> pc1)) ctm com pcc ((is # iss) ! nn1)))
⊆m cdm' ∧ (∀ j≥ n3.(p,j)∉ dom cdm')")
prefer 2
apply (rule fun_trInstr1_aux)
prefer 2 apply simp
prefer 2 apply (elim conjE,assumption)
apply (subgoal_tac "cdm ⊆m cdm1 ∧ (∀ j≥ nn1.(p,j)∉ dom cdm1)")
prefer 2
apply (rule fun_trInstr1_aux)
prefer 2 apply simp
apply (erule_tac x=ja in allE,assumption)
apply (thin_tac "?y = mapAccumL ?f ?s ?x")
apply (thin_tac "?y = mapAccumL ?f ?s ?x")
apply (thin_tac "?y = mapAccumL ?f ?s ?x")
apply (thin_tac "?mapAccumL ?f ?s ?x = ?y")
apply (elim conjE)
apply clarify
apply (unfold fun_upd_apply)
apply (rotate_tac 1)
apply (erule_tac x=j in allE)
apply (drule mp,simp)
apply force
done
lemma fun_trInstr :
"[| ((pc',cdm'),bc') = trSeq ctm com pcc (pc,cdm) (p,svms,fn);
svms = is1 # iss;
(∀ j≥0 . (p,j) ∉ dom cdm);
drop pc bc = bc' @ rest;
svm = svms ! i;
i < length svms
|] ==> (∃ pc'' cdm'' bc'' rest .
bc'' = trInstr pc'' cdm'' ctm com pcc svm
∧ drop pc'' bc = bc'' @ rest
∧ cdm'' (p,i) = Some pc''
∧ cdm'' ⊆m cdm')"
(* this is a more or less direct consequence of lemma fun_trInstrAux *)
apply (insert fun_trInstrAux [of pc' cdm' bc' ctm com pcc pc cdm
p svms fn is1 iss bc rest])
apply (drule mp,assumption)+
apply (rotate_tac -1)
apply (erule_tac x=i in allE)
apply (drule mp,assumption)
apply (elim exE, elim conjE)
(* the pc, an bc are the same than those of trInstrAux, but
rest is the appending of the two rests and
the cdm is the one returned by trInstrAux *)
apply (rule_tac x="pc''" in exI)
apply (rule_tac x="cdm''((p, i) \<mapsto> pc'')" in exI)
apply (rule_tac x="bc''" in exI)
apply (rule_tac x="rest' @ rest" in exI)
(* first conclusion *)
apply (rule conjI)
apply (unfold trInstrAux_def)
apply simp
(* second and third conclusions *)
apply (rule conjI)
apply clarsimp
apply (erule drop_append3,assumption)
apply (rule conjI,simp)
(* fourth conclusion *)
by assumption
axioms fun_trSeq1:
"(∃ pc2 cdm2 bc2 . ((pc2,cdm2),bc2) = trSeq ctm com pcc (pc1,cdm1) svm
∧ pc2-pc1=length bc2)"
axioms fun_trSeq2:
"((pc2,cdm2),bc2) = trSeq ctm com pcc (pc1,cdm1) seq
==> cdm1 ⊆m cdm2"
lemma fun_trSeq3 [rule_format]:
"(∀ pc1 cdm1 pc2 cdm2 bcs .
((pc2,cdm2),bcs) = mapAccumL (trSeq ctm com pcc) (pc1,cdm1) svms -->
cdm1 ⊆m cdm2)"
(* we make induction on the list of sequences *)
apply (induct svms)
(* empty list *)
apply simp
(* non-empty list *)
apply (rule allI)+
apply (rename_tac seq svms pc1 cdm1 pc2 cdm2 bcs)
apply (unfold mapAccumL.simps)
apply (case_tac "trSeq ctm com pcc (pc1, cdm1) seq")
apply (rename_tac state bc)
apply (case_tac state, rename_tac pc3 cdm3,simp)
apply (case_tac "mapAccumL (trSeq ctm com pcc) (pc3, cdm3) svms",rename_tac state4 bcs4)
apply (case_tac state4,rename_tac pc4 cdm4,clarsimp)
apply (subgoal_tac "((pc4, cdm4), bcs4)
= mapAccumL (trSeq ctm com pcc) (pc3, cdm3) svms")
prefer 2 apply simp
apply (erule_tac x="pc3" in allE)
apply (erule_tac x="cdm3" in allE)
apply (erule_tac x="pc4" in allE)
apply (erule_tac x="cdm4" in allE)
apply (erule impE)
apply (rule_tac x=bcs4 in exI,assumption)
apply (subgoal_tac "cdm1 ⊆m cdm3")
prefer 2 apply (rule fun_trSeq2,rule sym,simp)
by (erule map_le_trans,assumption)
lemma fun_trSeq_aux :
"((pc,cdm),bcs) = mapAccumL (trSeq ctm com pcc) (pcini,cdini) svms -->
drop pcini bc = concat bcs -->
(∀ i . i < length svms -->
(∃ pc1 cdm1 pc2 cdm2 bcs1 bcs2 bc2 .
((pc1,cdm1),bcs1) = mapAccumL (trSeq ctm com pcc) (pcini,cdini) (take i svms)
∧ ((pc2,cdm2),bc2) = trSeq ctm com pcc (pc1,cdm1) (svms ! i)
∧ ((pc,cdm),bcs2) = mapAccumL (trSeq ctm com pcc) (pc1,cdm1) (drop i svms)
∧ bcs = bcs1 @ bcs2
∧ (pc1-pcini) = length (concat bcs1)
∧ cdm2 ⊆m cdm))"
apply (rule impI)+
apply (rule allI)
(* we make induction on the position i of the sequence *)
apply (induct_tac i)
(* i= 0 *)
apply (rule impI)
apply (rule_tac x="pcini" in exI)
apply (rule_tac x="cdini" in exI)
apply (subgoal_tac "(∃ pc2 cdm2 bc2 .
((pc2,cdm2),bc2) = trSeq ctm com pcc (pcini,cdini) (svms ! 0)
∧ pc2-pcini=length bc2)")
prefer 2
apply (rule fun_trSeq1)
apply (elim exE, elim conjE)
apply (rule_tac x="pc2" in exI)
apply (rule_tac x="cdm2" in exI)
apply (rule_tac x="[]" in exI)
apply (rule_tac x="bcs" in exI)
apply (rule_tac x="bc2" in exI)
apply (rule conjI,simp)
apply (rule conjI,assumption)
apply (rule conjI,simp)
apply (rule conjI,simp)
apply (rule conjI,simp)
apply (subgoal_tac "∃ s' y ys'.
(s',y) = trSeq ctm com pcc (pcini, cdini) (svms!0)
∧ ((pc, cdm),ys') = mapAccumL (trSeq ctm com pcc) s' (tl svms)")
prefer 2 apply (erule mapAccumL_non_empty3,assumption)
apply (elim exE,elim conjE)
apply clarify apply (rename_tac pc2' cdm2' bc2' bcs')
apply (subgoal_tac "((pc2', cdm2'), bc2')=((pc2, cdm2), bc2)")
prefer 2 apply simp
apply clarify
apply (erule fun_trSeq3)
(* i > 0*)
apply (rule impI, drule mp, simp)
apply (elim exE,elim conjE)
(* we unfold the second occurrence of mapAccumL *)
apply (subgoal_tac "drop n svms = (svms ! n) # drop (Suc n) svms")
apply clarify
prefer 2 apply (rule drop_nth3, simp)
apply (subgoal_tac "∃ s' y ys'.
(s',y) = trSeq ctm com pcc (pc1, cdm1) (svms ! n)
∧ ((pc, cdm),ys') = mapAccumL (trSeq ctm com pcc) s' (drop (Suc n) svms)
∧ bcs2 = y # ys'")
prefer 2
apply (rule mapAccumL_non_empty2 [where f="trSeq ctm com pcc"])
apply (blast,simp)
apply (elim exE,elim conjE)
apply (case_tac s')
apply clarify
apply (rename_tac bc2' bcs3 pc2' cdm2')
apply (subgoal_tac "((pc2', cdm2'), bc2')=((pc2, cdm2), bc2)")
prefer 2 apply simp
apply clarify
apply (thin_tac "?x=trSeq ?x1 ?x2 ?x3 ?x4 ?x5")
(* we instantiate the initial pc and cdm of svms ! Suc n *)
apply (rule_tac x="pc2" in exI)
apply (rule_tac x="cdm2" in exI)
apply (subgoal_tac "∃ pc2a cdm2a bc2a .
((pc2a, cdm2a), bc2a) = trSeq ctm com pcc (pc2, cdm2) (svms ! Suc n)
∧ pc2a - pc2 = length bc2a")
prefer 2 apply (rule fun_trSeq1)
apply (elim exE,elim conjE)
(* we instantiate the rest of existential vars *)
apply (rule_tac x="pc2a" in exI)
apply (rule_tac x="cdm2a" in exI)
apply (rule_tac x="bcs1 @ [bc2]" in exI)
apply (rule_tac x="bcs3" in exI)
apply (rule_tac x="bc2a" in exI)
(* first conclusion *)
apply (rule conjI)
apply (subgoal_tac "take (Suc n) svms=(take n svms)@[svms ! n]")
prefer 2
apply (rule take_append3,simp)
apply (erule_tac t="take (Suc n) svms" in ssubst)
apply (erule mapAccumL_one_more,assumption)
(* second conclusion *)
apply (rule conjI,assumption)
(* third conclusion *)
apply (rule conjI,assumption)
(* fourth conclusion *)
apply (rule conjI, simp)
(* fifth conclusion *)
apply (subgoal_tac "∃ pc2b cdm2b bc2b .
((pc2b, cdm2b), bc2b) = trSeq ctm com pcc (pc1, cdm1) (svms ! n)
∧ pc2b - pc1 = length bc2b")
prefer 2
apply (rule fun_trSeq1)
apply (elim exE,elim conjE)
apply (subgoal_tac "((pc2, cdm2), bc2)=((pc2b, cdm2b), bc2b)")
prefer 2 apply simp
apply clarify
apply simp
apply (subgoal_tac "(pc1 - pcini)+(pc2b - pc1)=
(length (concat bcs1))+(length bc2b)")
prefer 2
apply (erule sum_nat,assumption)
apply (rule conjI)
apply (rule sym)
apply (subgoal_tac "length (concat bcs1) + length bc2b
= pc1 - pcini + (pc2b - pc1)")
prefer 2 apply simp
apply (erule_tac t="length (concat bcs1) + length bc2b" in ssubst)
apply (rule sum_substract)
apply (rename_tac cdm3 bc3 pc2 cdm2 bc2)
(* sixth conclusion *)
apply (subgoal_tac "∃ s' y ys'.
(s',y) = trSeq ctm com pcc (pc2, cdm2) ((drop (Suc n) svms)!0)
∧ ((pc, cdm),ys') =
mapAccumL (trSeq ctm com pcc) s' (tl (drop (Suc n) svms))")
prefer 2 apply (erule mapAccumL_non_empty3)
apply force
apply (elim exE,elim conjE)
apply clarify apply (rename_tac pc2' cdm3' bc3' bcs')
apply (subgoal_tac "((pc2', cdm3'), bc3')=((pc2a, cdm3), bc3)")
prefer 2 apply simp
apply clarify
apply (erule fun_trSeq3)
done
lemma fun_trSeq :
"[| ((pc,cdm),bcs) = mapAccumL (trSeq ctm com pcc) (pcini,cdini) svms;
drop pcini bc = concat bcs;
l < length svms;
seq = svms ! l
|] ==> (∃ pc' cdm' pc'' cdm'' bc' rest .
((pc'',cdm''),bc') = trSeq ctm com pcc (pc',cdm') seq
∧ drop pc' bc = bc' @ rest
∧ cdm'' ⊆m cdm)"
(* this is a consequence of lemma fun_trSeq_aux *)
apply (insert fun_trSeq_aux [of pc cdm bcs ctm com pcc pcini cdini svms bc])
apply (drule mp,assumption)+
apply (erule_tac x=l in allE)
apply (drule mp,assumption)
apply (elim exE, elim conjE)
(* we instantiate the existential vars *)
apply (rule_tac x="pc1" in exI)
apply (rule_tac x="cdm1" in exI)
apply (rule_tac x="pc2" in exI)
apply (rule_tac x="cdm2" in exI)
apply (rule_tac x="bc2" in exI)
apply (rule_tac x="drop (pc2-pc1) (concat bcs2)" in exI)
(* first conclusion *)
apply (rule conjI, simp)
(* second and third conclusions *)
apply (rule conjI)
apply (thin_tac "?x=mapAccumL ?y ?z ?u")
apply (thin_tac "?x=mapAccumL ?y ?z ?u")
apply (subgoal_tac "drop l svms=(svms!l) # drop (Suc l) svms")
prefer 2
apply (erule drop_nth3, clarify)
apply (case_tac "trSeq ctm com pcc (pc1, cdm1) (svms ! l)", clarsimp)
apply (rename_tac pc2 cdm2 bc2)
apply (case_tac "mapAccumL (trSeq ctm com pcc) (pc2,cdm2) (drop (Suc l) svms)",clarsimp)
apply (rename_tac bcs3)
apply (subgoal_tac "∃ pc2' cdm2' bc2' .
((pc2',cdm2'),bc2') = trSeq ctm com pcc (pc1, cdm1) (svms ! l)
∧ pc2'-pc1 = length bc2'")
prefer 2 apply (rule fun_trSeq1, clarify)
apply (subgoal_tac "((pc2', cdm2'), bc2')=((pc2, cdm2), bc2)")
prefer 2 apply simp
apply clarify
apply auto
apply (subgoal_tac "drop pc1 bc = [] @ [] @ (bc2 @ concat bcs3)")
prefer 2 apply (rule drop_append3)
apply (simp,simp,simp add: drop_append)
done
lemma fun_trCodeStore:
"(P',cdm,ctm,com) = trSVM2JVM ((svms, ctmap), ini, ct, st) -->
bc = extractBytecode P' -->
(∃ cdm' ctm' pcc pcini cdini pc bcs .
((pc,cdm),bcs) = mapAccumL (trSeq ctm' com pcc) (pcini,cdini) svms
∧ drop pcini bc = concat bcs)"
(* First we unfold some definitions and tuples *)
apply (rule impI)+
apply (unfold trSVM2JVM_def)
apply clarsimp
apply (case_tac "trCodeStore ini (length (initConsTable ct) +
length (initSizeTable st)) ctmap (trConsTable ct) svms")
apply (rename_tac instrs1 rest)
apply (case_tac rest)
apply (rename_tac cdm1 ctm1)
apply clarsimp
apply (subgoal_tac "extractBytecode
((safeP, objectC, [], [(sigSafeMain, PrimT Void, 10, 10,
initConsTable ct @ initSizeTable st @ instrs1, [])]) # Prog_RTS) =
initConsTable ct @ initSizeTable st @ instrs1")
apply simp
apply (thin_tac "extractBytecode ?x=?y")
prefer 2
apply (unfold extractBytecode_def)
apply (unfold method'_def)
apply simp
apply (subgoal_tac "class ((safeP,objectC,[],[(sigSafeMain,PrimT Void,
10,10,initConsTable ct@initSizeTable st@instrs1,[])]) # Prog_RTS)
safeP = Some (objectC, [], [(sigSafeMain, PrimT Void, 10, 10,
initConsTable ct @ initSizeTable st @ instrs1, [])])")
apply simp
apply (unfold Prog_RTS_def)
apply (simp add:class_def)
(* we unfold the definition of trCodeStore *)
apply (unfold trCodeStore_def)
apply (case_tac "unzip3 ctmap",rename_tac fs1 rest,
case_tac rest,rename_tac ps1 contss1)
apply clarify apply (simp del: mapAccumL.simps trConsTable_def zip.simps upt_Suc)
apply (case_tac "mapAccumL (trSeq (map_of (zip (concat contss1)
[Suc 0..<Suc (length (concat contss1))])) (trConsTable ct)
(Suc (length (initConsTable ct) + length (initSizeTable st) + length fs1)))
(Suc (Suc (length (initConsTable ct) + length (initSizeTable st)
+ length fs1)), map_of (zip (zip ps1 (replicate (length fs1) 0))
[Suc (length (initConsTable ct) + length (initSizeTable st))..<
Suc (length (initConsTable ct) + length (initSizeTable st) +
length fs1)])) svms")
apply (rename_tac rest iss1,case_tac rest, rename_tac pc1 cdm1)
apply (clarify) apply (simp del: mapAccumL.simps trConsTable_def zip.simps upt_Suc)
apply (elim conjE,clarify)
(* we instantiate the existential vars *)
apply (rule_tac x="map_of (zip (concat contss1)
[Suc 0..<Suc (length (concat contss1))])" in exI)
apply (rule_tac x="Suc (length (initConsTable ct) + length (initSizeTable st)
+ length fs1)" in exI)
apply (rule_tac x="Suc (Suc (length (initConsTable ct)
+ length (initSizeTable st) + length fs1))" in exI)
apply (rule_tac x=" map_of (zip (zip ps1 (replicate (length fs1) 0))
[Suc (length (initConsTable ct) + length (initSizeTable st))..<
Suc (length (initConsTable ct) + length (initSizeTable st)
+ length fs1)])" in exI)
apply (rule_tac x="pc1" in exI)
apply (rule_tac x="iss1" in exI)
(* first conclusion *)
apply (rule conjI)
apply simp
(* second conclusion *)
apply (subgoal_tac "length fs1 =length ps1")
prefer 2 apply (rule unzip3_length,simp)
apply (subgoal_tac "length (map Goto
(zipWith (% p n. int (the (cdm (p, 0))) - int n) ps1
[Suc (length (initConsTable ct) + length (initSizeTable st))..<
Suc (length (initConsTable ct) + length (initSizeTable st) + length fs1)]))
= length fs1")
prefer 2
apply (subgoal_tac "length [Suc (length (initConsTable ct) +
length (initSizeTable st))..<
Suc (length (initConsTable ct) + length (initSizeTable st))
+ length fs1] =
(Suc (length (initConsTable ct) + length (initSizeTable st))
+ length fs1) -
(Suc (length (initConsTable ct) + length (initSizeTable st)))")
prefer 2 apply(rule upt_length,simp)
apply (subgoal_tac "length (zipWith ( % p n. int (the (cdm (p, 0)))
- int n) ps1
[Suc (length (initConsTable ct) + length (initSizeTable st))..<
Suc (length (initConsTable ct) + length (initSizeTable st)
+ length fs1)]) =
min (length ps1) (length [Suc (length (initConsTable ct) +
length (initSizeTable st))..<
Suc (length (initConsTable ct) + length (initSizeTable st)
+ length fs1)])")
prefer 2 apply (rule zipWith_length)
apply simp
apply (simp add: drop_append)
done
axioms fun_SVM2JVM_aux:
"[| l < length svms; svms ! l = (p, seq, fn);
((pc, cdm), bcs) = mapAccumL (trSeq ctm' com pcc) (pcini, cdini) svms;
((pc2, cdm2), bcSeq) = trSeq ctm' com pcc (pcSeq, cdmSeq) (svms ! l)
|] ==> (∀ j≥0. (p, j) ∉ dom cdmSeq)"
lemma fun_SVM2JVM [rule_format]:
"(P', cdm, ctm, com) = trSVM2JVM ((svms, ctmap), ini, ct, st) -->
l < length svms -->
svms ! l = (p,seq,fn) -->
i < length seq -->
svm = fst (the (map_of svms p)) ! i -->
pc = the (cdm (p,i)) -->
bytecode = extractBytecode P' -->
(∃ cdm' ctm' pcc inss bytecode' .
inss = trInstr pc cdm' ctm' com pcc svm ∧
drop pc bytecode = inss @ bytecode' ∧
cdm' ⊆m cdm)"
apply (rule impI)+
(* we apply lemma on the translation of the whole code store *)
apply (insert fun_trCodeStore [of P' cdm ctm com svms ctmap ini ct st bytecode])
apply (drule mp, assumption)+
apply (erule exE)+
apply(elim conjE)
(* we apply lemma on the translation of a single sequence *)
apply (subgoal_tac "(∃ pc' cdm' pc'' cdm'' bc' rest .
((pc'',cdm''),bc') = trSeq ctm' com pcc (pc',cdm') (svms ! l)
∧ drop pc' bytecode = bc' @ rest
∧ cdm'' ⊆m cdm)")
prefer 2 apply (rule fun_trSeq) apply(simp,assumption,simp,simp)
apply (elim exE, elim conjE)
apply clarify
apply (rename_tac pcSeq cdmSeq pc2 cdm2 bcSeq restSeq)
(* we apply the lemma on the translation of a single SVM instruction *)
apply (subgoal_tac "∃ is iss . seq = is#iss")
prefer 2 apply (rule list_non_empty,force)
apply (elim exE)
apply (subgoal_tac "seq=fst (the (map_of svms p))")
prefer 2 apply (subgoal_tac "map_of svms p= Some (seq,fn)")
prefer 2 apply (rule map_of_distinct)
apply (rule svms_good,simp,simp)
apply simp
apply (insert svms_good [of svms])
apply (subgoal_tac " (∃ pc'' cdm'' bc'' rest .
bc'' = trInstr pc'' cdm'' ctm' com pcc (seq ! i)
∧ drop pc'' (extractBytecode P') = bc'' @ rest
∧ cdm'' (p,i) = Some pc''
∧ cdm'' ⊆m cdm2)")
prefer 2 apply (rule fun_trInstr)
apply (simp)
apply (rule sym)
apply force
apply (erule fun_SVM2JVM_aux [of l svms p seq fn],assumption,simp,simp)
apply simp
apply simp
apply simp
apply (elim exE, elim conjE)
(* we instantiate the existential vars *)
apply (rule_tac x="cdm''" in exI)
apply (rule_tac x="ctm'" in exI)
apply (rule_tac x="pcc" in exI)
apply (rule_tac x="bc''" in exI)
apply (rule_tac x="rest" in exI)
apply (subgoal_tac "cdm'' ⊆m cdm")
prefer 2 apply (erule map_le_trans,assumption)
apply (subgoal_tac "the (cdm (p,i))=pc''")
prefer 2 apply (unfold map_le_def)
apply force
apply clarify
apply simp
done
consts
nonJumping :: "SafeInstr => bool"
primrec
"nonJumping DECREGION = True"
"nonJumping (SLIDE m n) = True"
"nonJumping (PRIMOP oper) = True"
"nonJumping REUSE = True"
"nonJumping COPY = True"
"nonJumping (PUSHCONT p) = True"
"nonJumping (BUILDENV its) = True"
"nonJumping (BUILDCLS c is i) = True"
"nonJumping (CALL p) = False"
"nonJumping POPCONT = False"
"nonJumping (MATCHN l v m ps) = False"
"nonJumping (MATCH l ps) = False"
"nonJumping (MATCHD l ps) = False"
axioms nonJumping_Suc_pc :
"[| (P', cdm, ctm, com) = trSVM2JVM ((svms, ctmap), ini, ct, st);
svm = fst (the (map_of svms l)) ! i;
nonJumping svm;
iss = trInstr (the (cdm (l, i))) cdm' ctm' com pcc svm
|] ==> the (cdm (l,i+1)) = the (cdm (l,i)) + length iss"
end
lemma fun_trInstr1_aux:
[| !!j. i ≤ j ==> (p, j) ∉ dom cdm;
((pc', i', cdm'), insts) =
mapAccumL (trInstrAux p ctm com pcc) (pc, i, cdm) svms |]
==> cdm ⊆m cdm' ∧ (∀j≥i'. (p, j) ∉ dom cdm')
lemma fun_trInstr1:
[| !!j. i ≤ j ==> (p, j) ∉ dom cdm;
((pc', i', cdm'), insts) =
mapAccumL (trInstrAux p ctm com pcc) (pc, i, cdm) svms |]
==> cdm ⊆m cdm'
lemma fun_trInstrAux:
((pc', cdm'), bc') = trSeq ctm com pcc (pc, cdm) (p, svms, fn) -->
svms = is # iss -->
(∀j≥0. (p, j) ∉ dom cdm) -->
drop pc bc = bc' @ rest -->
(∀i<length svms.
∃pc'' cdm'' bc'' rest' insts1.
((pc'' + length bc'', i + 1, cdm''((p, i) |-> pc'')), bc'') =
trInstrAux p ctm com pcc (pc'', i, cdm'') (svms ! i) ∧
drop (pc'' - pc) bc' = bc'' @ rest' ∧
((pc'', i, cdm''), insts1) =
mapAccumL (trInstrAux p ctm com pcc) (pc, 0, cdm) (take i svms) ∧
cdm''((p, i) |-> pc'') ⊆m cdm')
lemma fun_trInstr:
[| ((pc', cdm'), bc') = trSeq ctm com pcc (pc, cdm) (p, svms, fn);
svms = is1.0 # iss; ∀j≥0. (p, j) ∉ dom cdm; drop pc bc = bc' @ rest;
svm = svms ! i; i < length svms |]
==> ∃pc'' cdm'' bc'' rest.
bc'' = trInstr pc'' cdm'' ctm com pcc svm ∧
drop pc'' bc = bc'' @ rest ∧ cdm'' (p, i) = Some pc'' ∧ cdm'' ⊆m cdm'
lemma fun_trSeq3:
((pc2.0, cdm2.0), bcs) = mapAccumL (trSeq ctm com pcc) (pc1.0, cdm1.0) svms
==> cdm1.0 ⊆m cdm2.0
lemma fun_trSeq_aux:
((pc, cdm), bcs) = mapAccumL (trSeq ctm com pcc) (pcini, cdini) svms -->
drop pcini bc = concat bcs -->
(∀i<length svms.
∃pc1 cdm1 pc2 cdm2 bcs1 bcs2 bc2.
((pc1, cdm1), bcs1) =
mapAccumL (trSeq ctm com pcc) (pcini, cdini) (take i svms) ∧
((pc2, cdm2), bc2) = trSeq ctm com pcc (pc1, cdm1) (svms ! i) ∧
((pc, cdm), bcs2) =
mapAccumL (trSeq ctm com pcc) (pc1, cdm1) (drop i svms) ∧
bcs = bcs1 @ bcs2 ∧ pc1 - pcini = length (concat bcs1) ∧ cdm2 ⊆m cdm)
lemma fun_trSeq:
[| ((pc, cdm), bcs) = mapAccumL (trSeq ctm com pcc) (pcini, cdini) svms;
drop pcini bc = concat bcs; l < length svms; seq = svms ! l |]
==> ∃pc' cdm' pc'' cdm'' bc' rest.
((pc'', cdm''), bc') = trSeq ctm com pcc (pc', cdm') seq ∧
drop pc' bc = bc' @ rest ∧ cdm'' ⊆m cdm
lemma fun_trCodeStore:
(P', cdm, ctm, com) = trSVM2JVM ((svms, ctmap), ini, ct, st) -->
bc = extractBytecode P' -->
(∃cdm' ctm' pcc pcini cdini pc bcs.
((pc, cdm), bcs) = mapAccumL (trSeq ctm' com pcc) (pcini, cdini) svms ∧
drop pcini bc = concat bcs)
lemma fun_SVM2JVM:
[| (P', cdm, ctm, com) = trSVM2JVM ((svms, ctmap), ini, ct, st);
l < length svms; svms ! l = (p, seq, fn); i < length seq;
svm = fst (the (map_of svms p)) ! i; pc = the (cdm (p, i));
bytecode = extractBytecode P' |]
==> ∃cdm' ctm' pcc inss bytecode'.
inss = trInstr pc cdm' ctm' com pcc svm ∧
drop pc bytecode = inss @ bytecode' ∧ cdm' ⊆m cdm