Theory Std_to_Inca_simulation
theory Std_to_Inca_simulation
imports Global List_util Std Inca
"VeriComp.Simulation"
begin
section βΉGeneric definitionsβΊ
locale std_inca_simulation =
Sstd: std
Fstd_empty Fstd_get Fstd_add Fstd_to_list
heap_empty heap_get heap_add heap_to_list
uninitialized is_true is_false
ππ ππ―π¦π±πΆ +
Sinca: inca
Finca_empty Finca_get Finca_add Finca_to_list
heap_empty heap_get heap_add heap_to_list
uninitialized is_true is_false
ππ ππ―π¦π±πΆ βπ«π©ππ βπ«π© βπ°βπ«π© ππ’βπ«π©
for
Fstd_empty and
Fstd_get :: "'fenv_std β 'fun β ('label, ('dyn, 'var, 'fun, 'label, 'op) Std.instr) fundef option" and
Fstd_add and Fstd_to_list and
Finca_empty and
Finca_get :: "'fenv_inca β 'fun β ('label, ('dyn, 'var, 'fun, 'label, 'op, 'opinl) Inca.instr) fundef option" and
Finca_add and Finca_to_list and
heap_empty and
heap_get :: "'henv β 'var Γ 'dyn β 'dyn option" and
heap_add and heap_to_list and
uninitialized :: 'dyn and is_true and is_false and
ππ :: "'op β 'dyn list β 'dyn" and ππ―π¦π±πΆ and
βπ«π©ππ and βπ«π© and βπ°βπ«π© and ππ’βπ«π© :: "'opinl β 'op"
begin
fun norm_instr where
"norm_instr (Inca.IPush d) = Std.IPush d" |
"norm_instr Inca.IPop = Std.IPop" |
"norm_instr (Inca.IGet n) = Std.IGet n" |
"norm_instr (Inca.ISet n) = Std.ISet n" |
"norm_instr (Inca.ILoad x) = Std.ILoad x" |
"norm_instr (Inca.IStore x) = Std.IStore x" |
"norm_instr (Inca.IOp op) = Std.IOp op" |
"norm_instr (Inca.IOpInl opinl) = Std.IOp (ππ’βπ«π© opinl)" |
"norm_instr (Inca.ICJump lβ©t lβ©f) = Std.ICJump lβ©t lβ©f" |
"norm_instr (Inca.ICall x) = Std.ICall x" |
"norm_instr Inca.IReturn = Std.IReturn"
abbreviation norm_eq where
"norm_eq x y β‘ norm_instr y = x"
definition rel_fundefs where
"rel_fundefs f g = (βx. rel_option (rel_fundef (=) norm_eq) (f x) (g x))"
lemma rel_fundefsI:
assumes "βx. rel_option (rel_fundef (=) norm_eq) (F1 x) (F2 x)"
shows "rel_fundefs F1 F2"
using assms
by (simp add: rel_fundefs_def)
lemma rel_fundefsD:
assumes "rel_fundefs F1 F2"
shows "rel_option (rel_fundef (=) norm_eq) (F1 x) (F2 x)"
using assms
by (simp add: rel_fundefs_def)
lemma rel_fundefs_next_instr:
assumes rel_F1_F2: "rel_fundefs F1 F2"
shows "rel_option norm_eq (next_instr F1 f l pc) (next_instr F2 f l pc)"
proof -
have "rel_option (rel_fundef (=) norm_eq) (F1 f) (F2 f)"
using rel_F1_F2[unfolded rel_fundefs_def] by simp
thus ?thesis
proof (cases rule: option.rel_cases)
case None
then show ?thesis by (simp add: next_instr_def)
next
case (Some fd1 fd2)
hence "rel_option (list_all2 norm_eq) (map_of (body fd1) l) (map_of (body fd2) l)"
by (auto elim!: fundef.rel_cases intro: rel_option_map_of)
then show ?thesis
by (cases rule: option.rel_cases;
simp add: next_instr_def instr_at_def Some list_all2_conv_all_nth)
qed
qed
lemma rel_fundefs_next_instr1:
assumes rel_F1_F2: "rel_fundefs F1 F2" and next_instr1: "next_instr F1 f l pc = Some instr1"
shows "βinstr2. next_instr F2 f l pc = Some instr2 β§ norm_eq instr1 instr2"
using rel_fundefs_next_instr[OF rel_F1_F2, of f l pc]
unfolding next_instr1
unfolding option_rel_Some1
by assumption
lemma rel_fundefs_next_instr2:
assumes rel_F1_F2: "rel_fundefs F1 F2" and next_instr2: "next_instr F2 f l pc = Some instr2"
shows "βinstr1. next_instr F1 f l pc = Some instr1 β§ norm_eq instr1 instr2"
using rel_fundefs_next_instr[OF rel_F1_F2, of f l pc]
unfolding next_instr2
unfolding option_rel_Some2
by assumption
lemma rel_fundefs_empty: "rel_fundefs (Ξ»_. None) (Ξ»_. None)"
by (simp add: rel_fundefs_def)
lemma rel_fundefs_None1:
assumes "rel_fundefs f g" and "f x = None"
shows "g x = None"
by (metis assms rel_fundefs_def rel_option_None1)
lemma rel_fundefs_None2:
assumes "rel_fundefs f g" and "g x = None"
shows "f x = None"
by (metis assms rel_fundefs_def rel_option_None2)
lemma rel_fundefs_Some1:
assumes "rel_fundefs f g" and "f x = Some y"
shows "βz. g x = Some z β§ rel_fundef (=) norm_eq y z"
proof -
from assms(1) have "rel_option (rel_fundef (=) norm_eq) (f x) (g x)"
unfolding rel_fundefs_def by simp
with assms(2) show ?thesis
by (simp add: option_rel_Some1)
qed
lemma rel_fundefs_Some2:
assumes "rel_fundefs f g" and "g x = Some y"
shows "βz. f x = Some z β§ rel_fundef (=) norm_eq z y"
proof -
from assms(1) have "rel_option (rel_fundef (=) norm_eq) (f x) (g x)"
unfolding rel_fundefs_def by simp
with assms(2) show ?thesis
by (simp add: option_rel_Some2)
qed
lemma rel_fundefs_rel_option:
assumes "rel_fundefs f g" and "βx y. rel_fundef (=) norm_eq x y βΉ h x y"
shows "rel_option h (f z) (g z)"
proof -
have "rel_option (rel_fundef (=) norm_eq) (f z) (g z)"
using assms(1)[unfolded rel_fundefs_def] by simp
then show ?thesis
unfolding rel_option_unfold
by (auto simp add: assms(2))
qed
lemma rel_fundefs_rewriteI2:
assumes
rel_F1_F2: "rel_fundefs (Fstd_get F1) (Finca_get F2)" and
next_instr1: "next_instr (Fstd_get F1) f l pc = Some instr1"
"norm_eq instr1 instr2'"
shows "rel_fundefs (Fstd_get F1)
(Finca_get (Sinca.Fenv.map_entry F2 f (Ξ»fd. rewrite_fundef_body fd l pc instr2')))"
(is "rel_fundefs (Fstd_get ?F1') (Finca_get ?F2')")
proof (rule rel_fundefsI)
fix x
show "rel_option (rel_fundef (=) norm_eq) (Fstd_get ?F1' x) (Finca_get ?F2' x)"
proof (cases "f = x")
case True
show ?thesis
using rel_F1_F2[THEN rel_fundefsD, of x] True next_instr1 assms(3)
by (cases rule: option.rel_cases)
(auto intro!: rel_fundef_rewrite_body2' dest!: next_instrD)
next
case False
then show ?thesis
using rel_F1_F2[THEN rel_fundefsD, of x] by simp
qed
qed
section βΉSimulation relationβΊ
inductive match (infix "βΌ" 55) where
"wf_fundefs (Fstd_get F1) βΉ
rel_fundefs (Fstd_get F1) (Finca_get F2) βΉ
(State F1 H st) βΌ (State F2 H st)"
section βΉBackward simulationβΊ
lemma backward_lockstep_simulation:
assumes "Sinca.step s2 s2'" and "match s1 s2"
shows "βs1'. Sstd.step s1 s1' β§ match s1' s2'"
proof -
from assms(2) obtain F1 F2 H st where
s1_def: "s1 = State F1 H st" and
s2_def: "s2 = State F2 H st" and
ok_F1: "wf_fundefs (Fstd_get F1)" and
rel_F1_F2: "rel_fundefs (Fstd_get F1) (Finca_get F2)"
by (auto elim: match.cases)
note rel_F1_F2_next_instr = rel_fundefs_next_instr[OF rel_F1_F2]
from assms(1) show "?thesis"
unfolding s1_def s2_def
proof (induction "State F2 H st" s2' rule: Sinca.step.induct)
case (step_push f l pc d R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R (d # Ξ£) # st')"
have "?STEP ?s1'"
using step_push rel_F1_F2_next_instr[of f l pc]
by (auto intro!: Sstd.step_push simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_pop f l pc R d Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R Ξ£ # st')"
have "?STEP ?s1'"
using step_pop rel_F1_F2_next_instr[of f l pc]
by (auto intro!: Sstd.step_pop simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_get f l pc n R d Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R (d # Ξ£) # st')"
have "?STEP ?s1'"
using step_get rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sstd.step_get simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_set f l pc n R R' d Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R' Ξ£ # st')"
have "?STEP ?s1'"
using step_set rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sstd.step_set simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_load f l pc x y d R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R (d # Ξ£) # st')"
have "?STEP ?s1'"
using step_load rel_F1_F2_next_instr[of f l pc]
by (auto intro!: Sstd.step_load simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_store f l pc x y d H' R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H' (Frame f l (Suc pc) R Ξ£ # st')"
have "?STEP ?s1'"
using step_store rel_F1_F2_next_instr[of f l pc]
by (auto intro!: Sstd.step_store simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_op f l pc op ar Ξ£ x R st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s1'"
using step_op rel_F1_F2_next_instr[of f l pc]
by (auto intro!: Sstd.step_op simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_op_inl f l pc op ar Ξ£ opinl x F2' R st')
then obtain instr1 where
next_instr1: "next_instr (Fstd_get F1) f l pc = Some instr1" and
norm_eq_instr1_instr2: "norm_eq instr1 (Inca.IOp op)"
using rel_F1_F2_next_instr[of f l pc] by (simp add: option_rel_Some2)
then show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof (cases instr1)
case (IOp op')
hence "op' = op" using norm_eq_instr1_instr2 by simp
let ?s1' = "State F1 H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s1'"
using step_op_inl next_instr1 IOp βΉop' = opβΊ
using Sinca.βπ«π©ππ_correct Sinca.βπ«π©_invertible
by (auto intro: Sstd.step_op)
moreover have "?MATCH ?s1'"
using ok_F1 step_op_inl next_instr1 IOp βΉop' = opβΊ
using Sinca.βπ«π©_invertible
by (auto intro!: match.intros intro: rel_fundefs_rewriteI2[OF rel_F1_F2])
ultimately show "?thesis" by blast
qed simp_all
next
case (step_op_inl_hit f l pc opinl ar Ξ£ x R st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s1'"
using step_op_inl_hit rel_F1_F2_next_instr[of f l pc]
using Sinca.βπ«π©ππ_correct
by (auto intro: Sstd.step_op simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_op_inl_miss f l pc opinl ar Ξ£ x F' R st')
then obtain instr1 where
next_instr1: "next_instr (Fstd_get F1) f l pc = Some instr1" and
norm_eq_instr1_instr2: "norm_eq instr1 (Inca.IOpInl opinl)"
using rel_F1_F2_next_instr[of f l pc] by (simp add: option_rel_Some2)
then show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof (cases instr1)
case (IOp op)
hence "op = ππ’βπ«π© opinl" using norm_eq_instr1_instr2 by simp
let ?s1' = "State F1 H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s1'"
using step_op_inl_miss next_instr1 IOp βΉop = ππ’βπ«π© opinlβΊ
using Sinca.βπ«π©ππ_correct
by (auto intro: Sstd.step_op)
moreover have "?MATCH ?s1'"
using ok_F1 step_op_inl_miss next_instr1 IOp βΉop = ππ’βπ«π© opinlβΊ
using Sinca.βπ«π©_invertible
by (auto intro!: match.intros intro: rel_fundefs_rewriteI2[OF rel_F1_F2])
ultimately show "?thesis" by blast
qed simp_all
next
case (step_cjump f l pc lβ©t lβ©f d l' R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F1 H (Frame f l' 0 R Ξ£ # st')"
have "?STEP ?s1'"
using step_cjump rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sstd.step_cjump simp: option_rel_Some2)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_call f lβ©f pcβ©f g gd2 Ξ£β©f frameβ©g Rβ©f st')
then obtain gd1 where
F1_g: "Fstd_get F1 g = Some gd1" and
rel_gd1_gd2: "rel_fundef (=) norm_eq gd1 gd2"
using rel_fundefs_Some2[OF rel_F1_F2] by blast
have same_fst_label_gd1_gd2: "fst (hd (body gd1)) = fst (hd (body gd2))"
using wf_fundefs_imp_wf_fundef[OF ok_F1 F1_g, unfolded wf_fundef_def] rel_gd1_gd2
by (auto elim!: fundef.rel_cases dest: list_all2_rel_prod_fst_hd)
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?Ξ£g = "take (arity gd1) Ξ£β©f"
let ?lg = "(fst (hd (body gd1)))"
let ?s1' = "State F1 H (frameβ©g # Frame f lβ©f pcβ©f Rβ©f Ξ£β©f # st')"
have "?STEP ?s1'"
using step_call rel_F1_F2_next_instr[of f lβ©f pcβ©f]
using F1_g same_fst_label_gd1_gd2 rel_gd1_gd2
by (auto intro!: Sstd.step_call
simp: option_rel_Some2 allocate_frame_def rel_fundef_arities rel_fundef_locals)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2
by (auto intro: match.intros)
ultimately show ?thesis by auto
qed
next
case (step_return g lβ©g pcβ©g gd2 Ξ£β©f Ξ£β©g frameβ©f' f lβ©f pcβ©f Rβ©f Rβ©g st')
then obtain gd1 where
F1_g: "Fstd_get F1 g = Some gd1" and
rel_gd1_gd2: "rel_fundef (=) norm_eq gd1 gd2"
using rel_fundefs_Some2[OF rel_F1_F2] by blast
obtain instr1 where
next_instr1: "next_instr (Fstd_get F1) g lβ©g pcβ©g = Some instr1" and
norm_eq_instr1_instr2: "norm_eq instr1 Inca.IReturn"
using step_return rel_F1_F2_next_instr[of g lβ©g pcβ©g] by (simp add: option_rel_Some2)
then show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof (cases instr1)
case IReturn
let ?s1' = "State F1 H (frameβ©f' # st')"
have "?STEP ?s1'"
using step_return next_instr1 IReturn
using F1_g rel_gd1_gd2
by (auto intro!: Sstd.step_return simp: rel_fundef_arities rel_fundef_return)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show ?thesis by auto
qed simp_all
qed
qed
lemma match_final_backward:
assumes "match s1 s2" and final_s2: "final Finca_get Inca.IReturn s2"
shows "final Fstd_get Std.IReturn s1"
using βΉmatch s1 s2βΊ
proof (cases s1 s2 rule: match.cases)
case (1 F1 F2 H st)
show ?thesis
using final_s2[unfolded 1]
proof (cases _ _ "State F2 H st" rule: final.cases)
case (finalI f l pc R Ξ£)
then show ?thesis
using 1
by (auto intro!: final.intros dest: rel_fundefs_next_instr2)
qed
qed
sublocale std_inca_simulation:
backward_simulation where
step1 = Sstd.step and final1 = "final Fstd_get Std.IReturn" and
step2 = Sinca.step and final2 = "final Finca_get Inca.IReturn" and
order = "Ξ»_ _. False" and match = "Ξ»_. match"
using match_final_backward backward_lockstep_simulation
lockstep_to_plus_backward_simulation[of match Sinca.step Sstd.step]
by unfold_locales auto
section βΉForward simulationβΊ
lemma forward_lockstep_simulation:
assumes "Sstd.step s1 s1'" and "match s1 s2"
shows "βs2'. Sinca.step s2 s2' β§ s1' βΌ s2'"
proof -
from assms(2) obtain F1 F2 H st where
s1_def: "s1 = State F1 H st" and
s2_def: "s2 = State F2 H st" and
ok_F1: "wf_fundefs (Fstd_get F1)" and
rel_F1_F2: "rel_fundefs (Fstd_get F1) (Finca_get F2)"
by (auto elim: match.cases)
note rel_F1_F2_next_instr = rel_fundefs_next_instr[OF rel_F1_F2]
from assms(1) show "?thesis"
unfolding s1_def s2_def
proof(induction "State F1 H st" s1' rule: Sstd.step.induct)
case (step_push f l pc d R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H (Frame f l (Suc pc) R (d # Ξ£) # st')"
have "?STEP ?s1'"
using step_push rel_F1_F2_next_instr[of f l pc]
by (auto intro!: Sinca.step_push elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_pop f l pc R d Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H (Frame f l (Suc pc) R Ξ£ # st')"
have "?STEP ?s1'"
using step_pop rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sinca.step_pop elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_get f l pc n R d Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H (Frame f l (Suc pc) R (d # Ξ£) # st')"
have "?STEP ?s1'"
using step_get rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sinca.step_get elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_set f l pc n R R' d Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H (Frame f l (Suc pc) R' Ξ£ # st')"
have "?STEP ?s1'"
using step_set rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sinca.step_set elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_load f l pc x y d R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H (Frame f l (Suc pc) R (d # Ξ£) # st')"
have "?STEP ?s1'"
using step_load rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sinca.step_load elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_store f l pc x y d H' R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H' (Frame f l (Suc pc) R Ξ£ # st')"
have "?STEP ?s1'"
using step_store rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sinca.step_store elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_op f l pc op ar Ξ£ x R st')
then obtain instr2 where
next_instr2: "next_instr (Finca_get F2) f l pc = Some instr2" and
norm_eq_instr2: "norm_eq (Std.IOp op) instr2"
using rel_F1_F2_next_instr[of f l pc] by (auto simp: option_rel_Some1)
thus ?case (is "βx. ?STEP x β§ ?MATCH x")
proof (cases instr2)
case (IOp op')
then have "op' = op" using norm_eq_instr2 by simp
show ?thesis
proof (cases "βπ«π© op' (take ar Ξ£)")
case None
let ?s2' = "State F2 H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s2'"
using None IOp step_op βΉop' = opβΊ next_instr2
by (auto intro: Sinca.step_op)
moreover have "?MATCH ?s2'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show ?thesis by auto
next
case (Some opinl)
let ?F2' = "Sinca.Fenv.map_entry F2 f (Ξ»fd. rewrite_fundef_body fd l pc (IOpInl opinl))"
let ?s2' = "State ?F2' H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s2'"
using Some IOp step_op βΉop' = opβΊ
using Sinca.βπ«π©ππ_correct Sinca.βπ«π©_invertible next_instr2
by (auto intro: Sinca.step_op_inl)
moreover have "?MATCH ?s2'"
using ok_F1 step_op IOp βΉop' = opβΊ Some
by (auto intro!: match.intros intro: rel_fundefs_rewriteI2[OF rel_F1_F2]
simp: Sinca.βπ«π©_invertible)
ultimately show ?thesis by auto
qed
next
case (IOpInl opinl)
hence "op = ππ’βπ«π© opinl" using norm_eq_instr2 by simp
show ?thesis
proof (cases "βπ°βπ«π© opinl (take ar Ξ£)")
case True
let ?s2' = "State F2 H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s2'"
using step_op IOpInl βΉop = ππ’βπ«π© opinlβΊ True
using next_instr2 Sinca.βπ«π©ππ_correct
by (auto intro: Sinca.step_op_inl_hit)
moreover have "?MATCH ?s2'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show ?thesis by auto
next
case False
let ?F2' = "Sinca.Fenv.map_entry F2 f (Ξ»fd. rewrite_fundef_body fd l pc (IOp (ππ’βπ«π© opinl)))"
let ?s2' = "State ?F2' H (Frame f l (Suc pc) R (x # drop ar Ξ£) # st')"
have "?STEP ?s2'"
using step_op IOpInl βΉop = ππ’βπ«π© opinlβΊ False
using next_instr2 Sinca.βπ«π©ππ_correct
by (auto intro: Sinca.step_op_inl_miss)
moreover have "?MATCH ?s2'"
using ok_F1 step_op βΉop = ππ’βπ«π© opinlβΊ
by (auto intro!: match.intros intro: rel_fundefs_rewriteI2[OF rel_F1_F2])
ultimately show ?thesis by auto
qed
qed simp_all
next
case (step_cjump f l pc lβ©t lβ©f d l' R Ξ£ st')
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?s1' = "State F2 H (Frame f l' 0 R Ξ£ # st')"
have "?STEP ?s1'"
using step_cjump rel_F1_F2_next_instr[of f l pc]
by (auto intro: Sinca.step_cjump elim: norm_instr.elims simp: option_rel_Some1)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show "?thesis" by blast
qed
next
case (step_call f lβ©f pcβ©f g gd1 Ξ£β©f frameβ©g Rβ©f st')
then obtain gd2 where
F2_g: "Finca_get F2 g = Some gd2" and
rel_gd1_gd2: "rel_fundef (=) norm_eq gd1 gd2"
using rel_fundefs_Some1[OF rel_F1_F2] by blast
have same_fst_label_gd1_gd2: "fst (hd (body gd1)) = fst (hd (body gd2))"
using rel_gd1_gd2
using wf_fundefs_imp_wf_fundef[OF ok_F1 βΉFstd_get F1 g = Some gd1βΊ, unfolded wf_fundef_def]
by (auto elim: fundef.rel_cases dest!: list_all2_rel_prod_fst_hd)
show ?case (is "βx. ?STEP x β§ ?MATCH x")
proof -
let ?Ξ£g = "take (arity gd2) Ξ£β©f"
let ?s2' = "State F2 H (frameβ©g # Frame f lβ©f pcβ©f Rβ©f Ξ£β©f # st')"
have "?STEP ?s2'"
using step_call F2_g rel_gd1_gd2 rel_F1_F2_next_instr[of f lβ©f pcβ©f]
using same_fst_label_gd1_gd2
by (auto intro!: Sinca.step_call elim: norm_instr.elims
simp: option_rel_Some1 rel_fundef_arities rel_fundef_locals allocate_frame_def)
moreover have "?MATCH ?s2'"
using ok_F1 rel_F1_F2
by (auto intro: match.intros)
ultimately show ?thesis by auto
qed
next
case (step_return g lβ©g pcβ©g gd1 Ξ£β©f Ξ£β©g frameβ©f' f lβ©f pcβ©f Rβ©f Rβ©g st')
then obtain gd2 where
F2_g: "Finca_get F2 g = Some gd2" and
rel_gd1_gd2: "rel_fundef (=) norm_eq gd1 gd2"
using rel_fundefs_Some1[OF rel_F1_F2] by blast
obtain instr2 where
next_instr2: "next_instr (Finca_get F2) g lβ©g pcβ©g = Some instr2" and
norm_eq_instr1_instr2: "norm_eq Std.IReturn instr2"
using step_return rel_F1_F2_next_instr[of g lβ©g pcβ©g] by (auto simp: option_rel_Some1)
thus ?case (is "βx. ?STEP x β§ ?MATCH x")
proof (cases instr2)
case IReturn
let ?s1' = "State F2 H (frameβ©f' # st')"
have "?STEP ?s1'"
using step_return next_instr2 IReturn
using F2_g rel_gd1_gd2
by (auto intro!: Sinca.step_return simp: rel_fundef_arities rel_fundef_return)
moreover have "?MATCH ?s1'"
using ok_F1 rel_F1_F2 by (auto intro: match.intros)
ultimately show ?thesis by auto
qed simp_all
qed
qed
lemma match_final_forward:
assumes "match s1 s2" and final_s1: "final Fstd_get Std.IReturn s1"
shows "final Finca_get Inca.IReturn s2"
using βΉmatch s1 s2βΊ
proof (cases s1 s2 rule: match.cases)
case (1 F1 F2 H st)
show ?thesis
using final_s1[unfolded 1]
proof (cases _ _ "State F1 H st" rule: final.cases)
case (finalI f l pc R Ξ£)
then show ?thesis
using 1
by (auto intro: final.intros elim: norm_instr.elims dest: rel_fundefs_next_instr1)
qed
qed
sublocale std_inca_forward_simulation:
forward_simulation where
step1 = Sstd.step and final1 = "final Fstd_get Std.IReturn" and
step2 = Sinca.step and final2 = "final Finca_get Inca.IReturn" and
order = "Ξ»_ _. False" and match = "Ξ»_. match"
using match_final_forward forward_lockstep_simulation
lockstep_to_plus_forward_simulation[of match Sstd.step _ Sinca.step]
by unfold_locales auto
section βΉBisimulationβΊ
sublocale std_inca_bisimulation:
bisimulation where
step1 = Sstd.step and final1 = "final Fstd_get Std.IReturn" and
step2 = Sinca.step and final2 = "final Finca_get Inca.IReturn" and
order = "Ξ»_ _. False" and match = "Ξ»_. match"
by unfold_locales
end
end