Theory J1JVMBisim
section ‹The delay bisimulation between intermediate language and JVM›
theory J1JVMBisim imports
Execs
"../BV/BVNoTypeError"
J1
begin
declare Listn.lesub_list_impl_same_size[simp del]
lemma (in JVM_heap_conf_base') τexec_1_τexec_1_d:
"⟦ wf_jvm_prog⇘Φ⇙ P; τexec_1 P t σ σ'; Φ |- t:σ [ok] ⟧ ⟹ τexec_1_d P t σ σ'"
by(auto simp add: τexec_1_def τexec_1_d_def welltyped_commute[symmetric] elim: jvmd_NormalE)
context JVM_conf_read begin
lemma τExec_1r_preserves_correct_state:
assumes wf: "wf_jvm_prog⇘Φ⇙ P"
and exec: "τExec_1r P t σ σ'"
shows "Φ |- t:σ [ok] ⟹ Φ |- t:σ' [ok]"
using exec
by(induct)(blast intro: BV_correct_1[OF wf])+
lemma τExec_1t_preserves_correct_state:
assumes wf: "wf_jvm_prog⇘Φ⇙ P"
and exec: "τExec_1t P t σ σ'"
shows "Φ |- t:σ [ok] ⟹ Φ |- t:σ' [ok]"
using exec
by(induct)(blast intro: BV_correct_1[OF wf])+
lemma τExec_1r_τExec_1_dr:
assumes wf: "wf_jvm_prog⇘Φ⇙ P"
shows "⟦ τExec_1r P t σ σ'; Φ |- t:σ [ok] ⟧ ⟹ τExec_1_dr P t σ σ'"
apply(induct rule: rtranclp_induct)
apply(blast intro: rtranclp.rtrancl_into_rtrancl τexec_1_τexec_1_d[OF wf] τExec_1r_preserves_correct_state[OF wf])+
done
lemma τExec_1t_τExec_1_dt:
assumes wf: "wf_jvm_prog⇘Φ⇙ P"
shows "⟦ τExec_1t P t σ σ'; Φ |- t:σ [ok] ⟧ ⟹ τExec_1_dt P t σ σ'"
apply(induct rule: tranclp_induct)
apply(blast intro: tranclp.trancl_into_trancl τexec_1_τexec_1_d[OF wf] τExec_1t_preserves_correct_state[OF wf])+
done
lemma τExec_1_dr_preserves_correct_state:
assumes wf: "wf_jvm_prog⇘Φ⇙ P"
and exec: "τExec_1_dr P t σ σ'"
shows "Φ |- t: σ [ok] ⟹ Φ |- t: σ' [ok]"
using exec
by(induct)(blast intro: BV_correct_1[OF wf])+
lemma τExec_1_dt_preserves_correct_state:
assumes wf: "wf_jvm_prog⇘Φ⇙ P"
and exec: "τExec_1_dt P t σ σ'"
shows "Φ |- t:σ [ok] ⟹ Φ |- t:σ' [ok]"
using exec
by(induct)(blast intro: BV_correct_1[OF wf])+
end
locale J1_JVM_heap_base =
J1_heap_base +
JVM_heap_base +
constrains addr2thread_id :: "('addr :: addr) ⇒ 'thread_id"
and thread_id2addr :: "'thread_id ⇒ 'addr"
and spurious_wakeups :: bool
and empty_heap :: "'heap"
and allocate :: "'heap ⇒ htype ⇒ ('heap × 'addr) set"
and typeof_addr :: "'heap ⇒ 'addr ⇀ htype"
and heap_read :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ bool"
and heap_write :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ 'heap ⇒ bool"
begin
inductive bisim1 ::
"'m prog ⇒ 'heap ⇒ 'addr expr1 ⇒ ('addr expr1 × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
and bisims1 ::
"'m prog ⇒ 'heap ⇒ 'addr expr1 list ⇒ ('addr expr1 list × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
and bisim1_syntax ::
"'m prog ⇒ 'addr expr1 ⇒ 'heap ⇒ ('addr expr1 × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
("_,_,_ ⊢ _ ↔ _" [50, 0, 0, 0, 50] 100)
and bisims1_syntax ::
"'m prog ⇒ 'addr expr1 list ⇒ 'heap ⇒ ('addr expr1 list × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
("_,_,_ ⊢ _ [↔] _" [50, 0, 0, 0, 50] 100)
for P :: "'m prog" and h :: 'heap
where
"P, e, h ⊢ exs ↔ s ≡ bisim1 P h e exs s"
| "P, es, h ⊢ esxs [↔] s ≡ bisims1 P h es esxs s"
| bisim1Val2:
"pc = length (compE2 e) ⟹ P, e, h ⊢ (Val v, xs) ↔ (v # [], xs, pc, None)"
| bisim1New:
"P, new C, h ⊢ (new C, xs) ↔ ([], xs, 0, None)"
| bisim1NewThrow:
"P, new C, h ⊢ (THROW OutOfMemory, xs) ↔ ([], xs, 0, ⌊addr_of_sys_xcpt OutOfMemory⌋)"
| bisim1NewArray:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, newA T⌊e⌉, h ⊢ (newA T⌊e'⌉, xs) ↔ (stk, loc, pc, xcp)"
| bisim1NewArrayThrow:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ P, newA T⌊e⌉, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1NewArrayFail:
"P, newA T⌊e⌉, h ⊢ (Throw a, xs) ↔ ([v], xs, length (compE2 e), ⌊a⌋)"
| bisim1Cast:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, Cast T e, h ⊢ (Cast T e', xs) ↔ (stk, loc, pc, xcp)"
| bisim1CastThrow:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ P, Cast T e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1CastFail:
"P, Cast T e, h ⊢ (THROW ClassCast, xs) ↔ ([v], xs, length (compE2 e), ⌊addr_of_sys_xcpt ClassCast⌋)"
| bisim1InstanceOf:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, e instanceof T, h ⊢ (e' instanceof T, xs) ↔ (stk, loc, pc, xcp)"
| bisim1InstanceOfThrow:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ P, e instanceof T, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Val: "P, Val v, h ⊢ (Val v, xs) ↔ ([], xs, 0, None)"
| bisim1Var: "P, Var V, h ⊢ (Var V, xs) ↔ ([], xs, 0, None)"
| bisim1BinOp1:
"P, e1, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, e1«bop»e2, h ⊢ (e'«bop»e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1BinOp2:
"P, e2, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e1«bop»e2, h ⊢ (Val v1 «bop» e', xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
| bisim1BinOpThrow1:
"P, e1, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1BinOpThrow2:
"P, e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, ⌊a⌋)"
| bisim1BinOpThrow:
"P, e1«bop»e2, h ⊢ (Throw a, xs) ↔ ([v1, v2], xs, length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1LAss1:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, V:=e, h ⊢ (V:=e', xs) ↔ (stk, loc, pc, xcp)"
| bisim1LAss2:
"P, V:=e, h ⊢ (unit, xs) ↔ ([], xs, Suc (length (compE2 e)), None)"
| bisim1LAssThrow:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ P, V:=e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1AAcc1:
"P, a, h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a⌊i⌉, h ⊢ (a'⌊i⌉, xs) ↔ (stk, loc, pc, xcp)"
| bisim1AAcc2:
"P, i, h ⊢ (i', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a⌊i⌉, h ⊢ (Val v⌊i'⌉, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, xcp)"
| bisim1AAccThrow1:
"P, a, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a⌊i⌉, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1AAccThrow2:
"P, i, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a⌊i⌉, h ⊢ (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, ⌊ad⌋)"
| bisim1AAccFail:
"P, a⌊i⌉, h ⊢ (Throw ad, xs) ↔ ([v, v'], xs, length (compE2 a) + length (compE2 i), ⌊ad⌋)"
| bisim1AAss1:
"P, a, h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a⌊i⌉ := e, h ⊢ (a'⌊i⌉ := e, xs) ↔ (stk, loc, pc, xcp)"
| bisim1AAss2:
"P, i, h ⊢ (i', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a⌊i⌉ := e, h ⊢ (Val v⌊i'⌉ := e, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, xcp)"
| bisim1AAss3:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a⌊i⌉ := e, h ⊢ (Val v⌊Val v'⌉ := e', xs) ↔ (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, xcp)"
| bisim1AAssThrow1:
"P, a, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a⌊i⌉ := e, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1AAssThrow2:
"P, i, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a⌊i⌉ := e, h ⊢ (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, ⌊ad⌋)"
| bisim1AAssThrow3:
"P, e, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a⌊i⌉ := e, h ⊢ (Throw ad, xs) ↔ (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, ⌊ad⌋)"
| bisim1AAssFail:
"P, a⌊i⌉ := e, h ⊢ (Throw ad, xs) ↔ ([v', v, v''], xs, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊ad⌋)"
| bisim1AAss4:
"P, a⌊i⌉ := e, h ⊢ (unit, xs) ↔ ([], xs, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
| bisim1ALength:
"P, a, h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a∙length, h ⊢ (a'∙length, xs) ↔ (stk, loc, pc, xcp)"
| bisim1ALengthThrow:
"P, a, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a∙length, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1ALengthNull:
"P, a∙length, h ⊢ (THROW NullPointer, xs) ↔ ([Null], xs, length (compE2 a), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1FAcc:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e∙F{D}, h ⊢ (e'∙F{D}, xs) ↔ (stk, loc, pc, xcp)"
| bisim1FAccThrow:
"P, e, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e∙F{D}, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1FAccNull:
"P, e∙F{D}, h ⊢ (THROW NullPointer, xs) ↔ ([Null], xs, length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1FAss1:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e∙F{D} := e2, h ⊢ (e'∙F{D} := e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1FAss2:
"P, e2, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e∙F{D} := e2, h ⊢ (Val v∙F{D} := e', xs) ↔ (stk @ [v], loc, length (compE2 e) + pc, xcp)"
| bisim1FAssThrow1:
"P, e, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e∙F{D} := e2, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1FAssThrow2:
"P, e2, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e∙F{D} := e2, h ⊢ (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 e) + pc, ⌊ad⌋)"
| bisim1FAssNull:
"P, e∙F{D} := e2, h ⊢ (THROW NullPointer, xs) ↔ ([v, Null], xs, length (compE2 e) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1FAss3:
"P, e∙F{D} := e2, h ⊢ (unit, xs) ↔ ([], xs, Suc (length (compE2 e) + length (compE2 e2)), None)"
| bisim1CAS1:
"P, e1, h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (e1'∙compareAndSwap(D∙F, e2, e3), xs) ↔ (stk, loc, pc, xcp)"
| bisim1CAS2:
"P, e2, h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Val v∙compareAndSwap(D∙F, e2', e3), xs) ↔ (stk @ [v], loc, length (compE2 e1) + pc, xcp)"
| bisim1CAS3:
"P, e3, h ⊢ (e3', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Val v∙compareAndSwap(D∙F, Val v', e3'), xs) ↔ (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp)"
| bisim1CASThrow1:
"P, e1, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1CASThrow2:
"P, e2, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 e1) + pc, ⌊ad⌋)"
| bisim1CASThrow3:
"P, e3, h ⊢ (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw ad, xs) ↔ (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, ⌊ad⌋)"
| bisim1CASFail:
"P, e1∙compareAndSwap(D∙F, e2, e3), h ⊢ (Throw ad, xs) ↔ ([v', v, v''], xs, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊ad⌋)"
| bisim1Call1:
"P, obj, h ⊢ (obj', xs) ↔ (stk, loc, pc, xcp)
⟹ P, obj∙M(ps), h ⊢ (obj'∙M(ps), xs) ↔ (stk, loc, pc, xcp)"
| bisim1CallParams:
"P, ps, h ⊢ (ps', xs) [↔] (stk, loc, pc, xcp)
⟹ P, obj∙M(ps), h ⊢ (Val v∙M(ps'), xs) ↔ (stk @ [v], loc, length (compE2 obj) + pc, xcp)"
| bisim1CallThrowObj:
"P, obj, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, obj∙M(ps), h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1CallThrowParams:
"P, ps, h ⊢ (map Val vs @ Throw a # ps', xs) [↔] (stk, loc, pc, ⌊a⌋)
⟹ P, obj∙M(ps), h ⊢ (Throw a, xs) ↔ (stk @ [v], loc, length (compE2 obj) + pc, ⌊a⌋)"
| bisim1CallThrow:
"length ps = length vs
⟹ P, obj∙M(ps), h ⊢ (Throw a, xs) ↔ (vs @ [v], xs, length (compE2 obj) + length (compEs2 ps), ⌊a⌋)"
| bisim1BlockSome1:
"P, {V:T=⌊v⌋; e}, h ⊢ ({V:T=⌊v⌋; e}, xs) ↔ ([], xs, 0, None)"
| bisim1BlockSome2:
"P, {V:T=⌊v⌋; e}, h ⊢ ({V:T=⌊v⌋; e}, xs) ↔ ([v], xs, Suc 0, None)"
| bisim1BlockSome4:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, {V:T=⌊v⌋; e}, h ⊢ ({V:T=None; e'}, xs) ↔ (stk, loc, Suc (Suc pc), xcp)"
| bisim1BlockThrowSome:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, {V:T=⌊v⌋; e}, h ⊢ (Throw a, xs) ↔ (stk, loc, Suc (Suc pc), ⌊a⌋)"
| bisim1BlockNone:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, {V:T=None; e}, h ⊢ ({V:T=None; e'}, xs) ↔ (stk, loc, pc, xcp)"
| bisim1BlockThrowNone:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, {V:T=None; e}, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Sync1:
"P, e1, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, sync⇘V⇙ (e1) e2, h ⊢ (sync⇘V⇙ (e') e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1Sync2:
"P, sync⇘V⇙ (e1) e2, h ⊢ (sync⇘V⇙ (Val v) e2, xs) ↔ ([v, v], xs, Suc (length (compE2 e1)), None)"
| bisim1Sync3:
"P, sync⇘V⇙ (e1) e2, h ⊢ (sync⇘V⇙ (Val v) e2, xs) ↔ ([v], xs[V := v], Suc (Suc (length (compE2 e1))), None)"
| bisim1Sync4:
"P, e2, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, sync⇘V⇙ (e1) e2, h ⊢ (insync⇘V⇙ (a) e', xs) ↔ (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp)"
| bisim1Sync5:
"P, sync⇘V⇙ (e1) e2, h ⊢ (insync⇘V⇙ (a) Val v, xs) ↔ ([xs ! V, v], xs, 4 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync6:
"P, sync⇘V⇙ (e1) e2, h ⊢ (Val v, xs) ↔ ([v], xs, 5 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync7:
"P, sync⇘V⇙ (e1) e2, h ⊢ (insync⇘V⇙ (a) Throw a', xs) ↔ ([Addr a'], xs, 6 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync8:
"P, sync⇘V⇙ (e1) e2, h ⊢ (insync⇘V⇙ (a) Throw a', xs) ↔
([xs ! V, Addr a'], xs, 7 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync9:
"P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔ ([Addr a], xs, 8 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync10:
"P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔ ([Addr a], xs, 8 + length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1Sync11:
"P, sync⇘V⇙ (e1) e2, h ⊢ (THROW NullPointer, xs) ↔ ([Null], xs, Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1Sync12:
"P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔ ([v, v'], xs, 4 + length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1Sync14:
"P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔
([v, Addr a'], xs, 7 + length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1SyncThrow:
"P, e1, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, sync⇘V⇙ (e1) e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1InSync:
"P, insync⇘V⇙ (a) e, h ⊢ (insync⇘V⇙ (a) e, xs) ↔ ([], xs, 0, None)"
| bisim1Seq1:
"P, e1, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, e1;;e2, h ⊢ (e';;e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1SeqThrow1:
"P, e1, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ P, e1;;e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Seq2:
"P, e2, h ⊢ exs ↔ (stk, loc, pc, xcp)
⟹ P, e1;;e2, h ⊢ exs ↔ (stk, loc, Suc (length (compE2 e1) + pc), xcp)"
| bisim1Cond1:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, if (e) e1 else e2, h ⊢ (if (e') e1 else e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1CondThen:
"P, e1, h ⊢ exs ↔ (stk, loc, pc, xcp)
⟹ P, if (e) e1 else e2, h ⊢ exs ↔ (stk, loc, Suc (length (compE2 e) + pc), xcp)"
| bisim1CondElse:
"P, e2, h ⊢ exs ↔ (stk, loc, pc, xcp)
⟹ P, if (e) e1 else e2, h ⊢ exs ↔ (stk, loc, Suc (Suc (length (compE2 e) + length (compE2 e1) + pc)), xcp)"
| bisim1CondThrow:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, if (e) e1 else e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1While1:
"P, while (c) e, h ⊢ (while (c) e, xs) ↔ ([], xs, 0, None)"
| bisim1While3:
"P, c, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, while (c) e, h ⊢ (if (e') (e;; while (c) e) else unit, xs) ↔ (stk, loc, pc, xcp)"
| bisim1While4:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, while (c) e, h ⊢ (e';; while (c) e, xs) ↔ (stk, loc, Suc (length (compE2 c) + pc), xcp)"
| bisim1While6:
"P, while (c) e, h ⊢ (while (c) e, xs) ↔ ([], xs, Suc (Suc (length (compE2 c) + length (compE2 e))), None)"
| bisim1While7:
"P, while (c) e, h ⊢ (unit, xs) ↔ ([], xs, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)"
| bisim1WhileThrow1:
"P, c, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, while (c) e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1WhileThrow2:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, while (c) e, h ⊢ (Throw a, xs) ↔ (stk, loc, Suc (length (compE2 c) + pc), ⌊a⌋)"
| bisim1Throw1:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, throw e, h ⊢ (throw e', xs) ↔ (stk, loc, pc, xcp)"
| bisim1Throw2:
"P, throw e, h ⊢ (Throw a, xs) ↔ ([Addr a], xs, length (compE2 e), ⌊a⌋)"
| bisim1ThrowNull:
"P, throw e, h ⊢ (THROW NullPointer, xs) ↔ ([Null], xs, length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1ThrowThrow:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ P, throw e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Try:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, try e catch(C V) e2, h ⊢ (try e' catch(C V) e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1TryCatch1:
"⟦ P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋); typeof_addr h a = ⌊Class_type C'⌋; P ⊢ C' ≼⇧* C ⟧
⟹ P, try e catch(C V) e2, h ⊢ ({V:Class C=None; e2}, xs[V := Addr a]) ↔ ([Addr a], loc, Suc (length (compE2 e)), None)"
| bisim1TryCatch2:
"P, e2, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, try e catch(C V) e2, h ⊢ ({V:Class C=None; e'}, xs) ↔ (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp)"
| bisim1TryFail:
"⟦ P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋); typeof_addr h a = ⌊Class_type C'⌋; ¬ P ⊢ C' ≼⇧* C ⟧
⟹ P, try e catch(C V) e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1TryCatchThrow:
"P, e2, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, try e catch(C V) e2, h ⊢ (Throw a, xs) ↔ (stk, loc, Suc (Suc (length (compE2 e) + pc)), ⌊a⌋)"
| bisims1Nil: "P, [], h ⊢ ([], xs) [↔] ([], xs, 0, None)"
| bisims1List1:
"P, e, h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ P, e#es, h ⊢ (e'#es, xs) [↔] (stk, loc, pc, xcp)"
| bisims1List2:
"P, es, h ⊢ (es', xs) [↔] (stk, loc, pc, xcp)
⟹ P, e#es, h ⊢ (Val v # es', xs) [↔] (stk @ [v], loc, length (compE2 e) + pc, xcp)"
inductive_cases bisim1_cases:
"P,e,h ⊢ (Val v, xs) ↔ (stk, loc, pc, xcp)"
lemma bisim1_refl: "P,e,h ⊢ (e, xs) ↔ ([], xs, 0, None)"
and bisims1_refl: "P,es,h ⊢ (es, xs) [↔] ([], xs, 0, None)"
apply(induct e and es rule: call.induct calls.induct)
apply(auto intro: bisim1_bisims1.intros simp add: nat_fun_sum_eq_conv)
apply(rename_tac option a)
apply(case_tac option)
apply(auto intro: bisim1_bisims1.intros split: if_split_asm)
done
lemma bisims1_lengthD: "P, es, h ⊢ (es', xs) [↔] s ⟹ length es = length es'"
apply(induct es arbitrary: es' s)
apply(auto elim: bisims1.cases)
done
text ‹
Derive an alternative induction rule for @{term bisim1} such that
(i) induction hypothesis are generated for all subexpressions and
(ii) the number of surrounding blocks is passed through.
›
inductive bisim1' ::
"'m prog ⇒ 'heap ⇒ 'addr expr1 ⇒ nat ⇒ ('addr expr1 × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
and bisims1' ::
"'m prog ⇒ 'heap ⇒ 'addr expr1 list ⇒ nat ⇒ ('addr expr1 list × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
and bisim1'_syntax ::
"'m prog ⇒ 'addr expr1 ⇒ nat ⇒ 'heap ⇒ ('addr expr1 × 'addr locals1)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
("_,_,_,_ ⊢'' _ ↔ _" [50, 0, 0, 0, 0, 50] 100)
and bisims1'_syntax ::
"'m prog ⇒ 'addr expr1 list ⇒ nat ⇒ 'heap ⇒ ('addr expr1 list × 'addr val list)
⇒ ('addr val list × 'addr val list × pc × 'addr option) ⇒ bool"
("_,_,_,_ ⊢'' _ [↔] _" [50, 0, 0, 0, 0, 50] 100)
for P :: "'m prog" and h :: 'heap
where
"P, e, n, h ⊢' exs ↔ s ≡ bisim1' P h e n exs s"
| "P, es, n, h ⊢' esxs [↔] s ≡ bisims1' P h es n esxs s"
| bisim1Val2':
"P, e, n, h ⊢' (Val v, xs) ↔ (v # [], xs, length (compE2 e), None)"
| bisim1New':
"P, new C, n, h ⊢' (new C, xs) ↔ ([], xs, 0, None)"
| bisim1NewThrow':
"P, new C, n, h ⊢' (THROW OutOfMemory, xs) ↔ ([], xs, 0, ⌊addr_of_sys_xcpt OutOfMemory⌋)"
| bisim1NewArray':
"P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, newA T⌊e⌉, n, h ⊢' (newA T⌊e'⌉, xs) ↔ (stk, loc, pc, xcp)"
| bisim1NewArrayThrow':
"P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, newA T⌊e⌉, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1NewArrayFail':
"(⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, newA T⌊e⌉, n, h ⊢' (Throw a, xs) ↔ ([v], xs, length (compE2 e), ⌊a⌋)"
| bisim1Cast':
"P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, Cast T e, n, h ⊢' (Cast T e', xs) ↔ (stk, loc, pc, xcp)"
| bisim1CastThrow':
"P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, Cast T e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1CastFail':
"(⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, Cast T e, n, h ⊢' (THROW ClassCast, xs) ↔ ([v], xs, length (compE2 e), ⌊addr_of_sys_xcpt ClassCast⌋)"
| bisim1InstanceOf':
"P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e instanceof T, n, h ⊢' (e' instanceof T, xs) ↔ (stk, loc, pc, xcp)"
| bisim1InstanceOfThrow':
"P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, e instanceof T, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Val': "P, Val v, n, h ⊢' (Val v, xs) ↔ ([], xs, 0, None)"
| bisim1Var': "P, Var V, n, h ⊢' (Var V, xs) ↔ ([], xs, 0, None)"
| bisim1BinOp1':
"⟦ P, e1, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1«bop»e2, n, h ⊢' (e'«bop»e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1BinOp2':
"⟦ P, e2, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1«bop»e2, n, h ⊢' (Val v1 «bop» e', xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
| bisim1BinOpThrow1':
"⟦ P, e1, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1«bop»e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1BinOpThrow2':
"⟦ P, e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1«bop»e2, n, h ⊢' (Throw a, xs) ↔ (stk @ [v1], loc, length (compE2 e1) + pc, ⌊a⌋)"
| bisim1BinOpThrow':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1«bop»e2, n, h ⊢' (Throw a, xs) ↔ ([v1, v2], xs, length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1LAss1':
"P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, V:=e, n, h ⊢' (V:=e', xs) ↔ (stk, loc, pc, xcp)"
| bisim1LAss2':
"(⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, V:=e, n, h ⊢' (unit, xs) ↔ ([], xs, Suc (length (compE2 e)), None)"
| bisim1LAssThrow':
"P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, V:=e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1AAcc1':
"⟦ P, a, n, h ⊢' (a', xs) ↔ (stk, loc, pc, xcp); ⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉, n, h ⊢' (a'⌊i⌉, xs) ↔ (stk, loc, pc, xcp)"
| bisim1AAcc2':
"⟦ P, i, n, h ⊢' (i', xs) ↔ (stk, loc, pc, xcp); ⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉, n, h ⊢' (Val v⌊i'⌉, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, xcp)"
| bisim1AAccThrow1':
"⟦ P, a, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1AAccThrow2':
"⟦ P, i, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉, n, h ⊢' (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, ⌊ad⌋)"
| bisim1AAccFail':
"⟦ ⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None); ⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉, n, h ⊢' (Throw ad, xs) ↔ ([v, v'], xs, length (compE2 a) + length (compE2 i), ⌊ad⌋)"
| bisim1AAss1':
"⟦ P, a, n, h ⊢' (a', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (a'⌊i⌉ := e, xs) ↔ (stk, loc, pc, xcp)"
| bisim1AAss2':
"⟦ P, i, n, h ⊢' (i', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (Val v⌊i'⌉ := e, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, xcp)"
| bisim1AAss3':
"⟦ P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (Val v⌊Val v'⌉ := e', xs) ↔ (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, xcp)"
| bisim1AAssThrow1':
"⟦ P, a, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1AAssThrow2':
"⟦ P, i, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 a) + pc, ⌊ad⌋)"
| bisim1AAssThrow3':
"⟦ P, e, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (Throw ad, xs) ↔ (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, ⌊ad⌋)"
| bisim1AAssFail':
"⟦ ⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (Throw ad, xs) ↔ ([v', v, v''], xs, length (compE2 a) + length (compE2 i) + length (compE2 e), ⌊ad⌋)"
| bisim1AAss4':
"⟦ ⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None);
⋀xs. P, i, n, h ⊢' (i, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, a⌊i⌉ := e, n, h ⊢' (unit, xs) ↔ ([], xs, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
| bisim1ALength':
"P, a, n, h ⊢' (a', xs) ↔ (stk, loc, pc, xcp)
⟹ P, a∙length, n, h ⊢' (a'∙length, xs) ↔ (stk, loc, pc, xcp)"
| bisim1ALengthThrow':
"P, a, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, a∙length, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1ALengthNull':
"(⋀xs. P, a, n, h ⊢' (a, xs) ↔ ([], xs, 0, None))
⟹ P, a∙length, n, h ⊢' (THROW NullPointer, xs) ↔ ([Null], xs, length (compE2 a), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1FAcc':
"P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, e∙F{D}, n, h ⊢' (e'∙F{D}, xs) ↔ (stk, loc, pc, xcp)"
| bisim1FAccThrow':
"P, e, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)
⟹ P, e∙F{D}, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1FAccNull':
"(⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, e∙F{D}, n, h ⊢' (THROW NullPointer, xs) ↔ ([Null], xs, length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1FAss1':
"⟦ P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e∙F{D} := e2, n, h ⊢' (e'∙F{D} := e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1FAss2':
"⟦ P, e2, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e∙F{D} := e2, n, h ⊢' (Val v∙F{D} := e', xs) ↔ (stk @ [v], loc, length (compE2 e) + pc, xcp)"
| bisim1FAssThrow1':
"⟦ P, e, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e∙F{D} := e2, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1FAssThrow2':
"⟦ P, e2, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e∙F{D} := e2, n, h ⊢' (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 e) + pc, ⌊ad⌋)"
| bisim1FAssNull':
"⟦ ⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e∙F{D} := e2, n, h ⊢' (THROW NullPointer, xs) ↔ ([v, Null], xs, length (compE2 e) + length (compE2 e2), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1FAss3':
"⟦ ⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e∙F{D} := e2, n, h ⊢' (unit, xs) ↔ ([], xs, Suc (length (compE2 e) + length (compE2 e2)), None)"
| bisim1CAS1':
"⟦ P, e1, n, h ⊢' (e1', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None);
⋀xs. P, e3, n, h ⊢' (e3, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (e1'∙compareAndSwap(D∙F, e2, e3), xs) ↔ (stk, loc, pc, xcp)"
| bisim1CAS2':
"⟦ P, e2, n, h ⊢' (e2', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e3, n, h ⊢' (e3, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (Val v∙compareAndSwap(D∙F, e2', e3), xs) ↔ (stk @ [v], loc, length (compE2 e1) + pc, xcp)"
| bisim1CAS3':
"⟦ P, e3, n, h ⊢' (e3', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (Val v∙compareAndSwap(D∙F, Val v', e3'), xs) ↔ (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp)"
| bisim1CASThrow1':
"⟦ P, e1, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None);
⋀xs. P, e3, n, h ⊢' (e3, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋)"
| bisim1CASThrow2':
"⟦ P, e2, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e3, n, h ⊢' (e3, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (Throw ad, xs) ↔ (stk @ [v], loc, length (compE2 e1) + pc, ⌊ad⌋)"
| bisim1CASThrow3':
"⟦ P, e3, n, h ⊢' (Throw ad, xs) ↔ (stk, loc, pc, ⌊ad⌋);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (Throw ad, xs) ↔ (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, ⌊ad⌋)"
| bisim1CASFail':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None);
⋀xs. P, e3, n, h ⊢' (e3, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1∙compareAndSwap(D∙F, e2, e3), n, h ⊢' (Throw ad, xs) ↔ ([v', v, v''], xs, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), ⌊ad⌋)"
| bisim1Call1':
"⟦ P, obj, n, h ⊢' (obj', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, ps, n, h ⊢' (ps, xs) [↔] ([], xs, 0, None) ⟧
⟹ P, obj∙M(ps), n, h ⊢' (obj'∙M(ps), xs) ↔ (stk, loc, pc, xcp)"
| bisim1CallParams':
"⟦ P, ps, n, h ⊢' (ps', xs) [↔] (stk, loc, pc, xcp); ps ≠ [];
⋀xs. P, obj, n, h ⊢' (obj, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, obj∙M(ps), n, h ⊢' (Val v∙M(ps'), xs) ↔ (stk @ [v], loc, length (compE2 obj) + pc, xcp)"
| bisim1CallThrowObj':
"⟦ P, obj, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, ps, n, h ⊢' (ps, xs) [↔] ([], xs, 0, None)⟧
⟹ P, obj∙M(ps), n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1CallThrowParams':
"⟦ P, ps, n, h ⊢' (map Val vs @ Throw a # ps', xs) [↔] (stk, loc, pc, ⌊a⌋);
⋀xs. P, obj, n, h ⊢' (obj, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, obj∙M(ps), n, h ⊢' (Throw a, xs) ↔ (stk @ [v], loc, length (compE2 obj) + pc, ⌊a⌋)"
| bisim1CallThrow':
"⟦ length ps = length vs;
⋀xs. P, obj, n, h ⊢' (obj, xs) ↔ ([], xs, 0, None); ⋀xs. P, ps, n, h ⊢' (ps, xs) [↔] ([], xs, 0, None) ⟧
⟹ P, obj∙M(ps), n, h ⊢' (Throw a, xs) ↔ (vs @ [v], xs, length (compE2 obj) + length (compEs2 ps), ⌊a⌋)"
| bisim1BlockSome1':
"(⋀xs. P, e, Suc n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, {V:T=⌊v⌋; e}, n, h ⊢' ({V:T=⌊v⌋; e}, xs) ↔ ([], xs, 0, None)"
| bisim1BlockSome2':
"(⋀xs. P, e, Suc n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, {V:T=⌊v⌋; e}, n, h ⊢' ({V:T=⌊v⌋; e}, xs) ↔ ([v], xs, Suc 0, None)"
| bisim1BlockSome4':
"P, e, Suc n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, {V:T=⌊v⌋; e}, n, h ⊢' ({V:T=None; e'}, xs) ↔ (stk, loc, Suc (Suc pc), xcp)"
| bisim1BlockThrowSome':
"P, e, Suc n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, {V:T=⌊v⌋; e}, n, h ⊢' (Throw a, xs) ↔ (stk, loc, Suc (Suc pc), ⌊a⌋)"
| bisim1BlockNone':
"P, e, Suc n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, {V:T=None; e}, n, h ⊢' ({V:T=None; e'}, xs) ↔ (stk, loc, pc, xcp)"
| bisim1BlockThrowNone':
"P, e, Suc n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, {V:T=None; e}, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Sync1':
"⟦ P, e1, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (sync⇘V⇙ (e') e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1Sync2':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (sync⇘V⇙ (Val v) e2, xs) ↔ ([v, v], xs, Suc (length (compE2 e1)), None)"
| bisim1Sync3':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (sync⇘V⇙ (Val v) e2, xs) ↔ ([v], xs[V := v], Suc (Suc (length (compE2 e1))), None)"
| bisim1Sync4':
"⟦ P, e2, Suc n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (insync⇘V⇙ (a) e', xs) ↔ (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp)"
| bisim1Sync5':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (insync⇘V⇙ (a) Val v, xs) ↔ ([xs ! V, v], xs, 4 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync6':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (Val v, xs) ↔ ([v], xs, 5 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync7':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (insync⇘V⇙ (a) Throw a', xs) ↔ ([Addr a'], xs, 6 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync8':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (insync⇘V⇙ (a) Throw a', xs) ↔
([xs ! V, Addr a'], xs, 7 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync9':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (Throw a, xs) ↔ ([Addr a], xs, 8 + length (compE2 e1) + length (compE2 e2), None)"
| bisim1Sync10':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (Throw a, xs) ↔ ([Addr a], xs, 8 + length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1Sync11':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (THROW NullPointer, xs) ↔ ([Null], xs, Suc (Suc (length (compE2 e1))), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1Sync12':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (Throw a, xs) ↔ ([v, v'], xs, 4 + length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1Sync14':
"⟦ ⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (Throw a, xs) ↔
([v, Addr a'], xs, 7 + length (compE2 e1) + length (compE2 e2), ⌊a⌋)"
| bisim1SyncThrow':
"⟦ P, e1, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, sync⇘V⇙ (e1) e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1InSync':
"P, insync⇘V⇙ (a) e, n, h ⊢' (insync⇘V⇙ (a) e, xs) ↔ ([], xs, 0, None)"
| bisim1Seq1':
"⟦ P, e1, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1;;e2, n, h ⊢' (e';;e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1SeqThrow1':
"⟦ P, e1, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1;;e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Seq2':
"⟦ P, e2, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e1;;e2, n, h ⊢' (e', xs) ↔ (stk, loc, Suc (length (compE2 e1) + pc), xcp)"
| bisim1Cond1':
"⟦ P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, if (e) e1 else e2, n, h ⊢' (if (e') e1 else e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1CondThen':
"⟦ P, e1, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, if (e) e1 else e2, n, h ⊢' (e', xs) ↔ (stk, loc, Suc (length (compE2 e) + pc), xcp)"
| bisim1CondElse':
"⟦ P, e2, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, if (e) e1 else e2, n, h ⊢' (e', xs) ↔ (stk, loc, Suc (Suc (length (compE2 e) + length (compE2 e1) + pc)), xcp)"
| bisim1CondThrow':
"⟦ P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e1, n, h ⊢' (e1, xs) ↔ ([], xs, 0, None);
⋀xs. P, e2, n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, if (e) e1 else e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1While1':
"⟦ ⋀xs. P, c, n, h ⊢' (c, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, while (c) e, n, h ⊢' (while (c) e, xs) ↔ ([], xs, 0, None)"
| bisim1While3':
"⟦ P, c, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, while (c) e, n, h ⊢' (if (e') (e;; while (c) e) else unit, xs) ↔ (stk, loc, pc, xcp)"
| bisim1While4':
"⟦ P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, c, n, h ⊢' (c, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, while (c) e, n, h ⊢' (e';; while (c) e, xs) ↔ (stk, loc, Suc (length (compE2 c) + pc), xcp)"
| bisim1While6':
"⟦ ⋀xs. P, c, n, h ⊢' (c, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧ ⟹
P, while (c) e, n, h ⊢' (while (c) e, xs) ↔ ([], xs, Suc (Suc (length (compE2 c) + length (compE2 e))), None)"
| bisim1While7':
"⟦ ⋀xs. P, c, n, h ⊢' (c, xs) ↔ ([], xs, 0, None);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧ ⟹
P, while (c) e, n, h ⊢' (unit, xs) ↔ ([], xs, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)"
| bisim1WhileThrow1':
"⟦ P, c, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, while (c) e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1WhileThrow2':
"⟦ P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, c, n, h ⊢' (c, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, while (c) e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, Suc (length (compE2 c) + pc), ⌊a⌋)"
| bisim1Throw1':
"P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp)
⟹ P, throw e, n, h ⊢' (throw e', xs) ↔ (stk, loc, pc, xcp)"
| bisim1Throw2':
"(⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, throw e, n, h ⊢' (Throw a, xs) ↔ ([Addr a], xs, length (compE2 e), ⌊a⌋)"
| bisim1ThrowNull':
"(⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None))
⟹ P, throw e, n, h ⊢' (THROW NullPointer, xs) ↔ ([Null], xs, length (compE2 e), ⌊addr_of_sys_xcpt NullPointer⌋)"
| bisim1ThrowThrow':
"P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ P, throw e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1Try':
"⟦ P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, try e catch(C V) e2, n, h ⊢' (try e' catch(C V) e2, xs) ↔ (stk, loc, pc, xcp)"
| bisim1TryCatch1':
"⟦ P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋); typeof_addr h a = ⌊Class_type C'⌋; P ⊢ C' ≼⇧* C;
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, try e catch(C V) e2, n, h ⊢' ({V:Class C=None; e2}, xs[V := Addr a]) ↔ ([Addr a], loc, Suc (length (compE2 e)), None)"
| bisim1TryCatch2':
"⟦ P, e2, Suc n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, try e catch(C V) e2, n, h ⊢' ({V:Class C=None; e'}, xs) ↔ (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp)"
| bisim1TryFail':
"⟦ P, e, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋); typeof_addr h a = ⌊Class_type C'⌋; ¬ P ⊢ C' ≼⇧* C;
⋀xs. P, e2, Suc n, h ⊢' (e2, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, try e catch(C V) e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)"
| bisim1TryCatchThrow':
"⟦ P, e2, Suc n, h ⊢' (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, try e catch(C V) e2, n, h ⊢' (Throw a, xs) ↔ (stk, loc, Suc (Suc (length (compE2 e) + pc)), ⌊a⌋)"
| bisims1Nil': "P, [], n, h ⊢' ([], xs) [↔] ([], xs, 0, None)"
| bisims1List1':
"⟦ P, e, n, h ⊢' (e', xs) ↔ (stk, loc, pc, xcp);
⋀xs. P, es, n, h ⊢' (es, xs) [↔] ([], xs, 0, None) ⟧
⟹ P, e#es, n, h ⊢' (e'#es, xs) [↔] (stk, loc, pc, xcp)"
| bisims1List2':
"⟦ P, es, n, h ⊢' (es', xs) [↔] (stk, loc, pc, xcp);
⋀xs. P, e, n, h ⊢' (e, xs) ↔ ([], xs, 0, None) ⟧
⟹ P, e#es, n, h ⊢' (Val v # es', xs) [↔] (stk @ [v], loc, length (compE2 e) + pc, xcp)"
lemma bisim1'_refl: "P,e,n,h ⊢' (e,xs) ↔ ([],xs,0,None)"
and bisims1'_refl: "P,es,n,h ⊢' (es,xs) [↔] ([],xs,0,None)"
apply(induct e and es arbitrary: n xs and n xs rule: call.induct calls.induct)
apply(auto intro: bisim1'_bisims1'.intros simp add: nat_fun_sum_eq_conv)
apply(rename_tac option a b c)
apply(case_tac option)
apply(auto intro: bisim1'_bisims1'.intros simp add: fun_eq_iff split: if_split_asm)
done
lemma bisim1_imp_bisim1': "P, e, h ⊢ exs ↔ s ⟹ P, e, n, h ⊢' exs ↔ s"
and bisims1_imp_bisims1': "P, es, h ⊢ esxs [↔] s ⟹ P, es, n, h ⊢' esxs [↔] s"
proof(induct arbitrary: n and n rule: bisim1_bisims1.inducts)
case (bisim1CallParams ps ps' xs stk loc pc xcp obj M v)
show ?case
proof(cases "ps = []")
case True
with ‹P,ps,h ⊢ (ps', xs) [↔] (stk, loc, pc, xcp)› have "ps' = []" "pc = 0" "stk = []" "loc = xs" "xcp = None"
by(auto elim: bisims1.cases)
moreover have "P,obj,n,h ⊢' (Val v,xs) ↔ ([v],xs,length (compE2 obj),None)"
by(blast intro: bisim1Val2' bisim1'_refl)
hence "P,obj∙M([]),n,h ⊢' (Val v∙M([]),xs) ↔ ([v],xs,length (compE2 obj),None)"
by-(rule bisim1Call1', auto intro!: bisims1Nil' simp add: bsoks_def)
ultimately show ?thesis using True by simp
next
case False with bisim1CallParams show ?thesis
by(auto intro: bisim1CallParams' bisims1'_refl bisim1'_refl)
qed
qed(auto intro: bisim1'_bisims1'.intros bisim1'_refl bisims1'_refl)
lemma bisim1'_imp_bisim1: "P, e, n, h ⊢' exs ↔ s ⟹ P, e, h ⊢ exs ↔ s"
and bisims1'_imp_bisims1: "P, es, n, h ⊢' esxs [↔] s ⟹ P, es, h ⊢ esxs [↔] s"
apply(induct rule: bisim1'_bisims1'.inducts)
apply(blast intro: bisim1_bisims1.intros)+
done
lemma bisim1'_eq_bisim1: "bisim1' P h e n = bisim1 P h e"
and bisims1'_eq_bisims1: "bisims1' P h es n = bisims1 P h es"
by(blast intro!: ext bisim1_imp_bisim1' bisims1_imp_bisims1' bisim1'_imp_bisim1 bisims1'_imp_bisims1)+
end
lemmas bisim1_bisims1_inducts =
J1_JVM_heap_base.bisim1'_bisims1'.inducts
[simplified J1_JVM_heap_base.bisim1'_eq_bisim1 J1_JVM_heap_base.bisims1'_eq_bisims1,
consumes 1,
case_names bisim1Val2 bisim1New bisim1NewThrow
bisim1NewArray bisim1NewArrayThrow bisim1NewArrayFail bisim1Cast bisim1CastThrow bisim1CastFail
bisim1InstanceOf bisim1InstanceOfThrow
bisim1Val bisim1Var bisim1BinOp1 bisim1BinOp2 bisim1BinOpThrow1 bisim1BinOpThrow2 bisim1BinOpThrow
bisim1LAss1 bisim1LAss2 bisim1LAssThrow
bisim1AAcc1 bisim1AAcc2 bisim1AAccThrow1 bisim1AAccThrow2 bisim1AAccFail
bisim1AAss1 bisim1AAss2 bisim1AAss3 bisim1AAssThrow1 bisim1AAssThrow2
bisim1AAssThrow3 bisim1AAssFail bisim1AAss4
bisim1ALength bisim1ALengthThrow bisim1ALengthNull
bisim1FAcc bisim1FAccThrow bisim1FAccNull
bisim1FAss1 bisim1FAss2 bisim1FAssThrow1 bisim1FAssThrow2 bisim1FAssNull bisim1FAss3
bisim1CAS1 bisim1CAS2 bisim1CAS3 bisim1CASThrow1 bisim1CASThrow2
bisim1CASThrow3 bisim1CASFail
bisim1Call1 bisim1CallParams bisim1CallThrowObj bisim1CallThrowParams
bisim1CallThrow
bisim1BlockSome1 bisim1BlockSome2 bisim1BlockSome4 bisim1BlockThrowSome
bisim1BlockNone bisim1BlockThrowNone
bisim1Sync1 bisim1Sync2 bisim1Sync3 bisim1Sync4 bisim1Sync5 bisim1Sync6
bisim1Sync7 bisim1Sync8 bisim1Sync9 bisim1Sync10 bisim1Sync11 bisim1Sync12
bisim1Sync14 bisim1SyncThrow bisim1InSync
bisim1Seq1 bisim1SeqThrow1 bisim1Seq2
bisim1Cond1 bisim1CondThen bisim1CondElse bisim1CondThrow
bisim1While1 bisim1While3 bisim1While4
bisim1While6 bisim1While7 bisim1WhileThrow1 bisim1WhileThrow2
bisim1Throw1 bisim1Throw2 bisim1ThrowNull bisim1ThrowThrow
bisim1Try bisim1TryCatch1 bisim1TryCatch2 bisim1TryFail bisim1TryCatchThrow
bisims1Nil bisims1List1 bisims1List2]
lemmas bisim1_bisims1_inducts_split = bisim1_bisims1_inducts[split_format (complete)]
context J1_JVM_heap_base begin
lemma bisim1_pc_length_compE2: "P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp) ⟹ pc ≤ length (compE2 E)"
and bisims1_pc_length_compEs2: "P,Es,h ⊢ (es, xs) [↔] (stk, loc, pc, xcp) ⟹ pc ≤ length (compEs2 Es)"
apply(induct "(stk, loc, pc, xcp)" and "(stk, loc, pc, xcp)"
arbitrary: stk loc pc xcp and stk loc pc xcp rule: bisim1_bisims1.inducts)
apply(auto)
done
lemma bisim1_pc_length_compE2D:
"P,e,h ⊢ (e', xs) ↔ (stk,loc,length (compE2 e),xcp)
⟹ xcp = None ∧ call1 e' = None ∧ (∃v. stk = [v] ∧ (is_val e' ⟶ e' = Val v ∧ xs = loc))"
and bisims1_pc_length_compEs2D:
"P,es,h ⊢ (es', xs) [↔] (stk,loc,length (compEs2 es),xcp)
⟹ xcp = None ∧ calls1 es' = None ∧ (∃vs. stk = rev vs ∧ length vs = length es ∧ (is_vals es' ⟶ es' = map Val vs ∧ xs = loc))"
proof(induct "(e', xs)" "(stk, loc, length (compE2 e), xcp)"
and "(es', xs)" "(stk, loc, length (compEs2 es), xcp)"
arbitrary: e' xs stk loc xcp and es' xs stk loc xcp rule: bisim1_bisims1.inducts)
case (bisims1List2 es es' xs stk loc pc xcp e v)
then obtain vs where "xcp = None" "calls1 es' = None"
"stk = rev vs" "length vs = length es" "is_vals es' ⟶ es' = map Val vs ∧ xs = loc" by auto
thus ?case
by(clarsimp)(rule_tac x="v#vs" in exI, auto)
qed(simp_all (no_asm_use), (fastforce dest: bisim1_pc_length_compE2 bisims1_pc_length_compEs2 split: bop.split_asm if_split_asm)+)
corollary bisim1_call_pcD: "⟦ P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp); call1 e' = ⌊aMvs⌋ ⟧ ⟹ pc < length (compE2 e)"
and bisims1_calls_pcD: "⟦ P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, xcp); calls1 es' = ⌊aMvs⌋ ⟧ ⟹ pc < length (compEs2 es)"
proof -
assume bisim: "P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)"
and call: "call1 e' = ⌊aMvs⌋"
{ assume "pc = length (compE2 e)"
with bisim call have False
by(auto dest: bisim1_pc_length_compE2D) }
moreover from bisim have "pc ≤ length (compE2 e)"
by(rule bisim1_pc_length_compE2)
ultimately show "pc < length (compE2 e)"
by(cases "pc < length (compE2 e)")(auto)
next
assume bisim: "P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, xcp)"
and call: "calls1 es' = ⌊aMvs⌋"
{ assume "pc = length (compEs2 es)"
with bisim call have False
by(auto dest: bisims1_pc_length_compEs2D) }
moreover from bisim have "pc ≤ length (compEs2 es)"
by(rule bisims1_pc_length_compEs2)
ultimately show "pc < length (compEs2 es)"
by(cases "pc < length (compEs2 es)")(auto)
qed
lemma bisim1_length_xs: "P,e,h ⊢ (e',xs) ↔ (stk, loc, pc, xcp) ⟹ length xs = length loc"
and bisims1_length_xs: "P,es,h ⊢ (es',xs) [↔] (stk, loc, pc, xcp) ⟹ length xs = length loc"
by(induct "(e',xs)" "(stk, loc, pc, xcp)" and "(es',xs)" "(stk, loc, pc, xcp)"
arbitrary: e' xs stk loc pc xcp and es' xs stk loc pc xcp rule: bisim1_bisims1.inducts)
auto
lemma bisim1_Val_length_compE2D:
"P,e,h ⊢ (Val v,xs) ↔ (stk, loc, length (compE2 e), xcp) ⟹ stk = [v] ∧ xs = loc ∧ xcp = None"
and bisims1_Val_length_compEs2D:
"P,es,h ⊢ (map Val vs,xs) [↔] (stk, loc, length (compEs2 es), xcp) ⟹ stk = rev vs ∧ xs = loc ∧ xcp = None"
by(auto dest: bisim1_pc_length_compE2D bisims1_pc_length_compEs2D)
lemma bisim_Val_loc_eq_xcp_None:
"P, e, h ⊢ (Val v, xs) ↔ (stk, loc, pc, xcp) ⟹ xs = loc ∧ xcp = None"
and bisims_Val_loc_eq_xcp_None:
"P, es, h ⊢ (map Val vs, xs) [↔] (stk, loc, pc, xcp) ⟹ xs = loc ∧ xcp = None"
apply(induct "(Val v :: 'addr expr1, xs)" "(stk, loc, pc, xcp)"
and "(map Val vs :: 'addr expr1 list, xs)" "(stk, loc, pc, xcp)"
arbitrary: v xs stk loc pc xcp and vs xs stk loc pc xcp rule: bisim1_bisims1.inducts)
apply(auto)
done
lemma bisim_Val_pc_not_Invoke:
"⟦ P,e,h ⊢ (Val v,xs) ↔ (stk,loc,pc,xcp); pc < length (compE2 e) ⟧ ⟹ compE2 e ! pc ≠ Invoke M n'"
and bisims_Val_pc_not_Invoke:
"⟦ P,es,h ⊢ (map Val vs,xs) [↔] (stk,loc,pc,xcp); pc < length (compEs2 es) ⟧ ⟹ compEs2 es ! pc ≠ Invoke M n'"
apply(induct "(Val v :: 'addr expr1, xs)" "(stk, loc, pc, xcp)"
and "(map Val vs :: 'addr expr1 list, xs)" "(stk, loc, pc, xcp)"
arbitrary: v xs stk loc pc xcp and vs xs stk loc pc xcp rule: bisim1_bisims1.inducts)
apply(auto simp add: nth_append compEs2_map_Val dest: bisim1_pc_length_compE2)
done
lemma bisim1_VarD: "P, E, h ⊢ (Var V,xs) ↔ (stk,loc,pc,xcp) ⟹ xs = loc"
and "P, es, h ⊢ (es', xs) [↔] (stk, loc, pc, xcp) ⟹ True"
by(induct "(Var V :: 'addr expr1, xs)" "(stk, loc, pc, xcp)" and arbitrary: V xs stk loc pc xcp and rule: bisim1_bisims1.inducts) auto
lemma bisim1_ThrowD:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, xcp)
⟹ pc < length (compE2 e) ∧ (xcp = ⌊a⌋ ∨ xcp = None) ∧ xs = loc"
and bisims1_ThrowD:
"P, es, h ⊢ (map Val vs @ Throw a # es', xs) [↔] (stk, loc, pc, xcp)
⟹ pc < length (compEs2 es) ∧ (xcp = ⌊a⌋ ∨ xcp = None) ∧ xs = loc"
apply(induct "(Throw a :: 'addr expr1, xs)" "(stk, loc, pc, xcp)"
and "(map Val vs @ Throw a # es', xs)" "(stk, loc, pc, xcp)"
arbitrary: xs stk loc pc xcp and vs es' xs stk loc pc xcp rule: bisim1_bisims1.inducts)
apply(fastforce dest: bisim1_pc_length_compE2 bisim_Val_loc_eq_xcp_None simp add: Cons_eq_append_conv)+
done
lemma fixes P :: "'addr J1_prog"
shows bisim1_Invoke_stkD:
"⟦ P,e,h ⊢ exs ↔ (stk,loc,pc,None); pc < length (compE2 e); compE2 e ! pc = Invoke M n' ⟧
⟹ ∃vs v stk'. stk = vs @ v # stk' ∧ length vs = n'"
and bisims1_Invoke_stkD:
"⟦ P,es,h ⊢ esxs [↔] (stk,loc,pc,None); pc < length (compEs2 es); compEs2 es ! pc = Invoke M n' ⟧
⟹ ∃vs v stk'. stk = vs @ v # stk' ∧ length vs = n'"
proof(induct "(stk, loc, pc, None :: 'addr option)" and "(stk, loc, pc, None :: 'addr option)"
arbitrary: stk loc pc and stk loc pc rule: bisim1_bisims1.inducts)
case bisim1Call1
thus ?case
apply(clarsimp simp add: nth_append append_eq_append_conv2 neq_Nil_conv split: if_split_asm)
apply(drule bisim1_pc_length_compE2, clarsimp simp add: neq_Nil_conv nth_append)
apply(frule bisim1_pc_length_compE2, clarsimp)
apply(drule bisim1_pc_length_compE2D, fastforce)
done
next
case bisim1CallParams thus ?case
apply(clarsimp simp add: nth_append append_eq_Cons_conv split: if_split_asm)
apply(fastforce simp add: append_eq_append_conv2 Cons_eq_append_conv)
apply(frule bisims1_pc_length_compEs2, clarsimp)
apply(drule bisims1_pc_length_compEs2D, fastforce simp add: append_eq_append_conv2)
done
qed(fastforce simp add: nth_append append_eq_append_conv2 neq_Nil_conv split: if_split_asm bop.split_asm dest: bisim1_pc_length_compE2 bisims1_pc_length_compEs2)+
lemma fixes P :: "'addr J1_prog"
shows bisim1_call_xcpNone: "P,e,h ⊢ (e',xs) ↔ (stk,loc,pc,⌊a⌋) ⟹ call1 e' = None"
and bisims1_calls_xcpNone: "P,es,h ⊢ (es',xs) [↔] (stk,loc,pc,⌊a⌋) ⟹ calls1 es' = None"
apply(induct "(e', xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)" and "(es',xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)"
arbitrary: e' xs stk loc pc and es' xs stk loc pc rule: bisim1_bisims1.inducts)
apply(auto dest: bisim_Val_loc_eq_xcp_None bisims_Val_loc_eq_xcp_None simp add: is_vals_conv)
done
lemma bisims1_map_Val_append:
assumes bisim: "P, es', h ⊢ (es'', xs) [↔] (stk, loc, pc, xcp)"
shows "length es = length vs
⟹ P, es @ es', h ⊢ (map Val vs @ es'', xs) [↔] (stk @ rev vs, loc, length (compEs2 es) + pc, xcp)"
proof(induction vs arbitrary: es)
case Nil thus ?case using bisim by simp
next
case (Cons v vs)
from ‹length es = length (v # vs)› obtain e es''' where [simp]: "es = e # es'''" by(cases es, auto)
with ‹length es = length (v # vs)› have len: "length es''' = length vs" by simp
from Cons.IH[OF len]
show ?case by(simp add: add.assoc append_assoc[symmetric] del: append_assoc)(rule bisims1List2, auto)
qed
lemma bisim1_hext_mono: "⟦ P,e,h ⊢ exs ↔ s; hext h h' ⟧ ⟹ P,e,h' ⊢ exs ↔ s" (is "PROP ?thesis1")
and bisims1_hext_mono: "⟦ P,es,h ⊢ esxs [↔] s; hext h h' ⟧ ⟹ P,es,h' ⊢ esxs [↔] s" (is "PROP ?thesis2")
proof -
assume hext: "hext h h'"
have "P,e,h ⊢ exs ↔ s ⟹ P,e,h' ⊢ exs ↔ s"
and "P,es,h ⊢ esxs [↔] s ⟹ P,es,h' ⊢ esxs [↔] s"
apply(induct rule: bisim1_bisims1.inducts)
apply(insert hext)
apply(auto intro: bisim1_bisims1.intros dest: hext_objD)
done
thus "PROP ?thesis1" and "PROP ?thesis2" by auto
qed
declare match_ex_table_append_not_pcs [simp]
match_ex_table_eq_NoneI[simp]
outside_pcs_compxE2_not_matches_entry[simp]
outside_pcs_compxEs2_not_matches_entry[simp]
lemma bisim1_xcp_Some_not_caught:
"P, e, h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)
⟹ match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e pc' d) = None"
and bisims1_xcp_Some_not_caught:
"P, es, h ⊢ (map Val vs @ Throw a # es', xs) [↔] (stk, loc, pc, ⌊a⌋)
⟹ match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxEs2 es pc' d) = None"
proof(induct "(Throw a :: 'addr expr1, xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)"
and "(map Val vs @ Throw a # es' :: 'addr expr1 list, xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)"
arbitrary: xs stk loc pc pc' d and xs stk loc pc vs es' pc' d rule: bisim1_bisims1.inducts)
case bisim1Sync10
thus ?case by(simp add: matches_ex_entry_def)
next
case bisim1Sync11
thus ?case by(simp add: matches_ex_entry_def)
next
case (bisim1SyncThrow e1 xs stk loc pc e2)
note IH = ‹match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e1 pc' d) = None›
from ‹P,e1,h ⊢ (Throw a,xs) ↔ (stk,loc,pc,⌊a⌋)› have "pc < length (compE2 e1)" by(auto dest: bisim1_ThrowD)
with IH show ?case
by(auto simp add: match_ex_table_append matches_ex_entry_def dest: match_ex_table_pc_length_compE2 intro: match_ex_table_not_pcs_None)
next
case bisims1List1 thus ?case
by(auto simp add: Cons_eq_append_conv dest: bisim1_ThrowD bisim_Val_loc_eq_xcp_None)
next
case (bisims1List2 es es'' xs stk loc pc e v)
hence "⋀pc' d. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxEs2 es pc' d) = None"
by(auto simp add: Cons_eq_append_conv)
from this[of "pc' + length (compE2 e)" "Suc d"] show ?case by(auto simp add: add.assoc)
next
case (bisim1BlockThrowSome e xs stk loc pc T v)
hence "⋀pc'. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e pc' d) = None" by auto
from this[of "2+pc'"] show ?case by(auto)
next
case (bisim1Seq2 e2 stk loc pc e1 xs)
hence "⋀pc'. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e2 pc' d) = None" by auto
from this[of "Suc (pc' + length (compE2 e1))"] show ?case by(simp add: add.assoc)
next
case (bisim1CondThen e1 stk loc pc e e2 xs)
hence "⋀pc'. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e1 pc' d) = None" by auto
note this[of "Suc (pc' + length (compE2 e))"]
moreover from ‹P,e1,h ⊢ (Throw a,xs) ↔ (stk,loc,pc,⌊a⌋)›
have "pc < length (compE2 e1)" by(auto dest: bisim1_ThrowD)
ultimately show ?case by(simp add: add.assoc match_ex_table_eq_NoneI outside_pcs_compxE2_not_matches_entry)
next
case (bisim1CondElse e2 stk loc pc e e1 xs)
hence "⋀pc'. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e2 pc' d) = None" by auto
note this[of "Suc (Suc (pc' + (length (compE2 e) + length (compE2 e1))))"]
thus ?case by(simp add: add.assoc)
next
case (bisim1WhileThrow2 e xs stk loc pc c)
hence "⋀pc'. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e pc' d) = None" by auto
from this[of "Suc (pc' + (length (compE2 c)))"]
show ?case by(simp add: add.assoc)
next
case (bisim1Throw1 e xs stk loc pc)
thus ?case by(auto dest: bisim_Val_loc_eq_xcp_None)
next
case (bisim1TryFail e xs stk loc pc C' C e2)
hence "match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e pc' d) = None" by auto
moreover from ‹P,e,h ⊢ (Throw a,xs) ↔ (stk,loc,pc,⌊a⌋)› have "pc < length (compE2 e)"
by(auto dest: bisim1_ThrowD)
ultimately show ?case using ‹typeof_addr h a = ⌊Class_type C'⌋› ‹¬ P ⊢ C' ≼⇧* C›
by(simp add: matches_ex_entry_def cname_of_def)
next
case (bisim1TryCatchThrow e2 xs stk loc pc e C)
hence "⋀pc'. match_ex_table (compP f P) (cname_of h a) (pc' + pc) (compxE2 e2 pc' d) = None" by auto
from this[of "Suc (Suc (pc' + (length (compE2 e))))"]
show ?case by(simp add: add.assoc matches_ex_entry_def)
next
case bisim1Sync12 thus ?case
by(auto dest: bisim1_ThrowD simp add: match_ex_table_append eval_nat_numeral, simp add: matches_ex_entry_def)
next
case bisim1Sync14 thus ?case
by(auto dest: bisim1_ThrowD simp add: match_ex_table_append eval_nat_numeral, simp add: matches_ex_entry_def)
qed(fastforce dest: bisim1_ThrowD simp add: add.assoc[symmetric])+
declare match_ex_table_append_not_pcs [simp del]
match_ex_table_eq_NoneI[simp del]
outside_pcs_compxE2_not_matches_entry[simp del]
outside_pcs_compxEs2_not_matches_entry[simp del]
lemma bisim1_xcp_pcD: "P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ pc < length (compE2 e)"
and bisims1_xcp_pcD: "P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, ⌊a⌋) ⟹ pc < length (compEs2 es)"
by(induct "(e', xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)" and "(es', xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)"
arbitrary: e' xs stk loc pc and es' xs stk loc pc rule: bisim1_bisims1.inducts)
auto
declare nth_append [simp]
lemma bisim1_Val_τExec_move:
"⟦ P, E, h ⊢ (Val v, xs) ↔ (stk, loc, pc, xcp); pc < length (compE2 E) ⟧
⟹ xs = loc ∧ xcp = None ∧
τExec_mover_a P t E h (stk, xs, pc, None) ([v], xs, length (compE2 E), None)"
and bisims1_Val_τExec_moves:
"⟦ P, Es, h ⊢ (map Val vs, xs) [↔] (stk, loc, pc, xcp); pc < length (compEs2 Es) ⟧
⟹ xs = loc ∧ xcp = None ∧
τExec_movesr_a P t Es h (stk, xs, pc, None) (rev vs, xs, length (compEs2 Es), None)"
proof(induct "(Val v :: 'addr expr1, xs)" "(stk, loc, pc, xcp)"
and "(map Val vs :: 'addr expr1 list, xs)" "(stk, loc, pc, xcp)"
arbitrary: v xs stk loc pc xcp and vs xs stk loc pc xcp rule: bisim1_bisims1.inducts)
case bisim1Val thus ?case by(auto intro!: τExecr1step exec_instr τmove2Val simp add: exec_move_def)
next
case (bisim1LAss2 V e xs)
have "τExec_mover_a P t (V:=e) h ([], xs, Suc (length (compE2 e)), None) ([Unit], xs, Suc (Suc (length (compE2 e))), None)"
by(auto intro!: τExecr1step exec_instr τmove2LAssRed2 simp add: exec_move_def)
with bisim1LAss2 show ?case by simp
next
case (bisim1AAss4 a i e xs)
have "τExec_mover_a P t (a⌊i⌉ := e) h ([], xs, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None) ([Unit], xs, Suc (Suc (length (compE2 a) + length (compE2 i) + length (compE2 e))), None)"
by(auto intro!: τExecr1step exec_instr τmove2AAssRed simp add: exec_move_def)
with bisim1AAss4 show ?case by(simp add: ac_simps)
next
case (bisim1FAss3 e F D e2 xs)
have "τExec_mover_a P t (e∙F{D} := e2) h ([], xs, Suc (length (compE2 e) + length (compE2 e2)), None) ([Unit], xs, Suc (Suc (length (compE2 e) + length (compE2 e2))), None)"
by(auto intro!: τExecr1step exec_instr τmove2FAssRed simp add: exec_move_def)
with bisim1FAss3 show ?case by simp
next
case (bisim1Sync6 V e1 e2 v xs)
have "τExec_mover_a P t (sync⇘V⇙ (e1) e2) h ([v], xs, 5 + length (compE2 e1) + length (compE2 e2), None)
([v], xs, 9 + length (compE2 e1) + length (compE2 e2), None)"
by(rule τExecr1step)(auto intro: exec_instr τmove2Sync6 simp add: exec_move_def)
with bisim1Sync6 show ?case by(auto simp add: eval_nat_numeral)
next
case (bisim1Seq2 e2 stk loc pc xcp e1 v xs)
from ‹Suc (length (compE2 e1) + pc) < length (compE2 (e1;; e2))› have pc: "pc < length (compE2 e2)" by simp
with ‹pc < length (compE2 e2) ⟹ xs = loc ∧ xcp = None ∧ τExec_mover_a P t e2 h (stk, xs, pc, None) ([v], xs, length (compE2 e2), None)›
have "xs = loc" "xcp = None"
"τExec_mover_a P t e2 h (stk, xs, pc, None) ([v], xs, length (compE2 e2), None)" by auto
moreover
hence "τExec_mover_a P t (e1;;e2) h (stk, xs, Suc (length (compE2 e1) + pc), None) ([v], xs, Suc (length (compE2 e1) + length (compE2 e2)), None)"
by -(rule Seq_τExecrI2)
ultimately show ?case by(simp)
next
case (bisim1CondThen e1 stk loc pc xcp e e2 v xs)
from ‹P, e1, h ⊢ (Val v,xs) ↔ (stk,loc,pc,xcp)›
have "pc ≤ length (compE2 e1)" by(rule bisim1_pc_length_compE2)
have e: "τExec_mover_a P t (if (e) e1 else e2) h
([v], xs, Suc (length (compE2 e) + (length (compE2 e1))), None)
([v], xs, length (compE2 (if (e) e1 else e2)), None)"
by(rule τExecr1step)(auto simp add: exec_move_def intro!: exec_instr τmove2CondThenExit)
show ?case
proof(cases "pc < length (compE2 e1)")
case True
with ‹pc < length (compE2 e1)
⟹ xs = loc ∧ xcp = None ∧ τExec_mover_a P t e1 h (stk, xs, pc, None) ([v], xs, length (compE2 e1), None)›
have s: "xs = loc" "xcp = None"
and "τExec_mover_a P t e1 h (stk, xs, pc, None) ([v], xs, length (compE2 e1), None)" by auto
hence "τExec_mover_a P t (if (e) e1 else e2) h
(stk, xs, Suc (length (compE2 e) + pc), None)
([v], xs, Suc (length (compE2 e) + length (compE2 e1)), None)"
by -(rule Cond_τExecrI2)
with e True s show ?thesis by(simp)
next
case False
with ‹pc ≤ length (compE2 e1)› have pc: "pc = length (compE2 e1)" by auto
with ‹P, e1, h ⊢ (Val v,xs) ↔ (stk,loc,pc,xcp)›
have "stk = [v]" "xs = loc" "xcp = None" by(auto dest: bisim1_Val_length_compE2D)
with pc e show ?thesis by(simp)
qed
next
case (bisim1CondElse e2 stk loc pc xcp e e1 v xs)
from ‹P, e2, h ⊢ (Val v,xs) ↔ (stk,loc,pc,xcp)›
have "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e2)")
case True
with ‹pc < length (compE2 e2)
⟹ xs = loc ∧ xcp = None ∧ τExec_mover_a P t e2 h (stk, xs, pc, None) ([v], xs, length (compE2 e2), None)›
have s: "xs = loc" "xcp = None"
and e: "τExec_mover_a P t e2 h (stk, xs, pc, None) ([v], xs, length (compE2 e2), None)" by auto
from e have "τExec_mover_a P t (if (e) e1 else e2) h (stk, xs, Suc (Suc (length (compE2 e) + length (compE2 e1) + pc)), None) ([v], xs, Suc (Suc (length (compE2 e) + length (compE2 e1) + length (compE2 e2))), None)"
by(rule Cond_τExecrI3)
with True s show ?thesis by(simp add: add.assoc)
next
case False
with ‹pc ≤ length (compE2 e2)› have pc: "pc = length (compE2 e2)" by auto
with ‹P, e2, h ⊢ (Val v,xs) ↔ (stk,loc,pc,xcp)›
have "stk = [v]" "xs = loc" "xcp = None" by(auto dest: bisim1_Val_length_compE2D)
with pc show ?thesis by(simp add: add.assoc)
qed
next
case (bisim1While7 c e xs)
have "τExec_mover_a P t (while (c) e) h
([], xs, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)
([Unit], xs, length (compE2 (while (c) e)), None)"
by(auto intro!: τExecr1step exec_instr τmove2While4 simp add: exec_move_def)
thus ?case by(simp)
next
case (bisims1List1 e e' xs stk loc pc xcp es)
from ‹e' # es = map Val vs› obtain v vs' where [simp]: "vs = v # vs'" "e' = Val v" "es = map Val vs'" by auto
from ‹P,e,h ⊢ (e',xs) ↔ (stk,loc,pc,xcp)›
have length: "pc ≤ length (compE2 e)" by(auto dest: bisim1_pc_length_compE2)
hence "xs = loc ∧ xcp = None ∧ τExec_mover_a P t e h (stk, xs, pc, None) ([v], xs, length (compE2 e), None)"
proof(cases "pc < length (compE2 e)")
case True
with ‹⟦e' = Val v; pc < length (compE2 e)⟧ ⟹ xs = loc ∧ xcp = None ∧ τExec_mover_a P t e h (stk, xs, pc, None) ([v], xs, length (compE2 e), None)›
show ?thesis by auto
next
case False
with length have pc: "pc = length (compE2 e)" by auto
with ‹P,e,h ⊢ (e',xs) ↔ (stk,loc,pc,xcp)› have "stk = [v]" "xs = loc" "xcp = None"
by(auto dest: bisim1_Val_length_compE2D)
with pc show ?thesis by(auto)
qed
hence s: "xs = loc" "xcp = None"
and exec1: "τExec_mover_a P t e h (stk, xs, pc, None) ([v], xs, length (compE2 e), None)" by auto
from exec1 have "τExec_movesr_a P t (e # es) h (stk, xs, pc, None) ([v], xs, length (compE2 e), None)"
by(auto intro: τExec_mover_τExec_movesr)
moreover have "τExec_movesr_a P t (map Val vs') h ([], xs, 0, None) (rev vs', xs, length (compEs2 (map Val vs')), None)"
by(rule τExec_movesr_map_Val)
hence "τExec_movesr_a P t ([e] @ map Val vs') h ([] @ [v], xs, length (compEs2 [e]) + 0, None) (rev vs' @ [v], xs, length (compEs2 [e]) + length (compEs2 (map Val vs')), None)"
by -(rule append_τExec_movesr, auto)
ultimately show ?case using s by(auto)
next
case (bisims1List2 es es' xs stk loc pc xcp e v)
from ‹Val v # es' = map Val vs› obtain vs' where [simp]: "vs = v # vs'" "es' = map Val vs'" by auto
from ‹P,es,h ⊢ (es',xs) [↔] (stk,loc,pc,xcp)›
have length: "pc ≤ length (compEs2 es)" by(auto dest: bisims1_pc_length_compEs2)
hence "xs = loc ∧ xcp = None ∧ τExec_movesr_a P t es h (stk, xs, pc, None) (rev vs', xs, length (compEs2 es), None)"
proof(cases "pc < length (compEs2 es)")
case True
with ‹⟦es' = map Val vs'; pc < length (compEs2 es)⟧ ⟹ xs = loc ∧ xcp = None ∧ τExec_movesr_a P t es h (stk, xs, pc, None)
(rev vs', xs, length (compEs2 es), None)›
show ?thesis by auto
next
case False
with length have pc: "pc = length (compEs2 es)" by auto
with ‹P,es,h ⊢ (es',xs) [↔] (stk,loc,pc,xcp)› have "stk = rev vs'" "xs = loc" "xcp = None"
by(auto dest: bisims1_Val_length_compEs2D)
with pc show ?thesis by(auto)
qed
hence s: "xs = loc" "xcp = None"
and exec1: "τExec_movesr_a P t es h (stk, xs, pc, None) (rev vs', xs, length (compEs2 es), None)" by auto
from exec1 have "τExec_movesr_a P t ([e] @ es) h (stk @ [v], xs, length (compEs2 [e]) + pc, None) (rev vs' @ [v], xs, length (compEs2 [e]) + length (compEs2 es), None)"
by -(rule append_τExec_movesr, auto)
thus ?case using s by(auto)
qed(auto)
lemma bisim1Val2D1:
assumes bisim: "P, e, h ⊢ (Val v,xs) ↔ (stk,loc,pc,xcp)"
shows "xcp = None ∧ xs = loc ∧ τExec_mover_a P t e h (stk, loc, pc, xcp) ([v], loc, length (compE2 e), None)"
proof -
from bisim have "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
moreover
have "τExec_mover_a P t e h (stk, loc, pc, xcp) ([v], loc, length (compE2 e), None)"
proof(cases "pc < length (compE2 e)")
case True
from bisim1_Val_τExec_move[OF bisim True] show ?thesis by auto
next
case False
from bisim have "pc ≤ length (compE2 e)" by(auto dest: bisim1_pc_length_compE2)
with False have "pc = length (compE2 e)" by auto
with bisim have "stk = [v]" "loc = xs" "xcp=None" by(auto dest: bisim1_Val_length_compE2D)
with ‹pc = length (compE2 e)› show ?thesis by(auto)
qed
ultimately show ?thesis by simp
qed
lemma bisim1_Throw_τExec_movet:
"⟦ P, e, h ⊢ (Throw a,xs) ↔ (stk,loc,pc,None) ⟧
⟹ ∃pc'. τExec_movet_a P t e h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋) ∧
P, e, h ⊢ (Throw a,xs) ↔ ([Addr a], loc, pc', ⌊a⌋) ∧ xs = loc"
and bisims1_Throw_τExec_movest:
"⟦ P, es, h ⊢ (map Val vs @ Throw a # es',xs) [↔] (stk,loc,pc,None) ⟧
⟹ ∃pc'. τExec_movest_a P t es h (stk, loc, pc, None) (Addr a # rev vs, loc, pc', ⌊a⌋) ∧
P, es, h ⊢ (map Val vs @ Throw a # es',xs) [↔] (Addr a # rev vs, loc, pc', ⌊a⌋) ∧ xs = loc"
proof(induct e "n :: nat" "Throw a :: 'addr expr1" xs stk loc pc "None :: 'addr option"
and es "n :: nat" "map Val vs @ Throw a # es' :: 'addr expr1 list" xs stk loc pc "None :: 'addr option"
arbitrary: and vs rule: bisim1_bisims1_inducts_split)
case (bisim1Sync9 e1 n e2 V xs)
let ?pc = "8 + length (compE2 e1) + length (compE2 e2)"
have "τExec_movet_a P t (sync⇘V⇙ (e1) e2) h ([Addr a], xs, ?pc, None) ([Addr a], xs, ?pc, ⌊a⌋)"
by(rule τExect1step)(auto intro: exec_instr τmove2_τmoves2.intros simp add: is_Ref_def exec_move_def)
moreover
have "P,sync⇘V⇙ (e1) e2,h ⊢ (Throw a,xs) ↔ ([Addr a],xs,?pc,⌊a⌋)" by(rule bisim1Sync10)
ultimately show ?case by auto
next
case (bisim1Seq2 e2 n xs stk loc pc e1)
then obtain pc' where "τExec_movet_a P t e2 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
"P, e2, h ⊢ (Throw a,xs) ↔ ([Addr a],loc,pc',⌊a⌋)" "xs = loc" by auto
thus ?case by(auto intro: Seq_τExectI2 bisim1_bisims1.bisim1Seq2)
next
case (bisim1CondThen e1 n xs stk loc pc e e2)
then obtain pc' where exec: "τExec_movet_a P t e1 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim: "P, e1, h ⊢ (Throw a,xs) ↔ ([Addr a],loc,pc',⌊a⌋)" and s: "xs = loc" by auto
from exec have "τExec_movet_a P t (if (e) e1 else e2) h (stk, loc, Suc (length (compE2 e) + pc), None) ([Addr a], loc, Suc (length (compE2 e) + pc'), ⌊a⌋)"
by(rule Cond_τExectI2)
moreover from bisim
have "P, if (e) e1 else e2, h ⊢ (Throw a, xs) ↔ ([Addr a], loc, Suc (length (compE2 e) + pc'), ⌊a⌋)"
by(rule bisim1_bisims1.bisim1CondThen)
ultimately show ?case using s by(auto)
next
case (bisim1CondElse e2 n xs stk loc pc e e1)
then obtain pc' where exec: "τExec_movet_a P t e2 h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim: "P, e2, h ⊢ (Throw a, xs ) ↔ ([Addr a], loc, pc', ⌊a⌋)" and s: "xs = loc" by auto
let "?pc pc" = "Suc (Suc (length (compE2 e) + length (compE2 e1) + pc))"
from exec have "τExec_movet_a P t (if (e) e1 else e2) h (stk, loc, (?pc pc), None) ([Addr a], loc, ?pc pc', ⌊a⌋)"
by(rule Cond_τExectI3)
moreover from bisim
have "P, if (e) e1 else e2, h ⊢ (Throw a, xs ) ↔ ([Addr a], loc, ?pc pc', ⌊a⌋)"
by(rule bisim1_bisims1.bisim1CondElse)
ultimately show ?case using s by auto
next
case (bisim1Throw1 e n xs stk loc pc)
note bisim = ‹P, e, h ⊢ (addr a, xs) ↔ (stk, loc, pc, None)›
hence s: "xs = loc"
and exec: "τExec_mover_a P t e h (stk, loc, pc, None) ([Addr a], loc, length (compE2 e), None)"
by(auto dest: bisim1Val2D1)
from exec have "τExec_mover_a P t (throw e) h (stk, loc, pc, None) ([Addr a], loc, length (compE2 e), None)"
by(rule Throw_τExecrI)
also have "τExec_movet_a P t (throw e) h ([Addr a], loc, length (compE2 e), None) ([Addr a], loc, length (compE2 e), ⌊a⌋)"
by(rule τExect1step, auto intro: exec_instr τmove2Throw2 simp add: is_Ref_def exec_move_def)
also have "P, throw e, h ⊢ (Throw a, loc ) ↔ ([Addr a], loc, length (compE2 e), ⌊a⌋)"
by(rule bisim1Throw2)
ultimately show ?case using s by auto
next
case (bisims1List1 e n e' xs stk loc pc es vs)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
show ?case
proof(cases "is_val e'")
case True
with ‹e' # es = map Val vs @ Throw a # es'› obtain v vs' where "vs = v # vs'" "e' = Val v"
and es: "es = map Val vs' @ Throw a # es'" by(auto simp add: Cons_eq_append_conv)
with bisim have "P,e,h ⊢ (Val v, xs) ↔ (stk, loc, pc, None)" by simp
from bisim1Val2D1[OF this] have [simp]: "xs = loc"
and exec: "τExec_mover_a P t e h (stk, loc, pc, None) ([v], loc, length (compE2 e), None)"
by auto
from exec have "τExec_movesr_a P t (e # es) h (stk, loc, pc, None) ([v], loc, length (compE2 e), None)"
by(rule τExec_mover_τExec_movesr)
also from es ‹es = map Val vs' @ Throw a # es'
⟹ ∃pc'. τExec_movest_a P t es h ([], loc, 0, None) (Addr a # rev vs', loc, pc', ⌊a⌋) ∧
P,es,h ⊢ (map Val vs' @ Throw a # es', loc) [↔] (Addr a # rev vs', loc, pc', ⌊a⌋) ∧ loc = loc›
obtain pc' where execes: "τExec_movest_a P t es h ([], loc, 0, None) (Addr a # rev vs', loc, pc', ⌊a⌋)"
and bisim': "P,es,h ⊢ (map Val vs' @ Throw a # es', loc) [↔] (Addr a # rev vs', loc, pc', ⌊a⌋)" by auto
from append_τExec_movest[OF _ execes, of "[v]" "[e]"]
have "τExec_movest_a P t (e # es) h ([v], loc, length (compE2 e), None) (Addr a # rev vs' @ [v], loc, length (compE2 e) + pc', ⌊a⌋)" by simp
also from bisims1List2[OF bisim', of e v] es ‹e' = Val v› ‹vs = v # vs'›
have "P,e # es,h ⊢ (e' # es, xs) [↔] ((Addr a # rev vs), loc, length (compE2 e) + pc', ⌊a⌋)" by simp
ultimately show ?thesis using ‹vs = v # vs'› es ‹e' = Val v› by auto
next
case False
with ‹e' # es = map Val vs @ Throw a # es'› have [simp]: "e' = Throw a" "es = es'" "vs = []"
by(auto simp add: Cons_eq_append_conv)
from ‹e' = Throw a ⟹ ∃pc'. τExec_movet_a P t e h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋) ∧ P,e,h ⊢ (Throw a, xs ) ↔ ([Addr a], loc, pc', ⌊a⌋) ∧ xs = loc›
obtain pc' where "τExec_movet_a P t e h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
and bisim: "P,e,h ⊢ (Throw a, xs ) ↔ ([Addr a], loc, pc', ⌊a⌋)" and s: "xs = loc" by auto
hence "τExec_movest_a P t (e # es) h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋)"
by-(rule τExec_movet_τExec_movest)
moreover from bisim
have "P,e#es,h ⊢ (Throw a#es,xs) [↔] ([Addr a],loc,pc',⌊a⌋)" by(rule bisim1_bisims1.bisims1List1)
ultimately show ?thesis using s by auto
qed
next
case (bisims1List2 es n es'' xs stk loc pc e v)
note IH = ‹⋀vs. es'' = map Val vs @ Throw a # es'
⟹ ∃pc'. τExec_movest_a P t es h (stk, loc, pc, None) (Addr a # rev vs, loc, pc', ⌊a⌋) ∧
P,es,h ⊢ (map Val vs @ Throw a # es',xs) [↔] (Addr a # rev vs,loc,pc',⌊a⌋) ∧ xs = loc›
from ‹Val v # es'' = map Val vs @ Throw a # es'›
obtain vs' where [simp]: "vs = v # vs'" "es'' = map Val vs' @ Throw a # es'" by(auto simp add: Cons_eq_append_conv)
from IH[OF ‹es'' = map Val vs' @ Throw a # es'›]
obtain pc' where exec: "τExec_movest_a P t es h (stk, loc, pc, None) (Addr a # rev vs', loc, pc', ⌊a⌋)"
and bisim: "P,es,h ⊢ (map Val vs' @ Throw a # es',xs) [↔] (Addr a # rev vs',loc,pc',⌊a⌋)"
and [simp]: "xs = loc" by auto
from append_τExec_movest[OF _ exec, of "[v]" "[e]"]
have "τExec_movest_a P t (e # es) h (stk @ [v], loc, length (compE2 e) + pc, None) (Addr a # rev vs, loc, length (compE2 e) + pc', ⌊a⌋)" by simp
moreover from bisim
have "P,e#es,h ⊢ (Val v # map Val vs' @ Throw a # es',xs) [↔] ((Addr a # rev vs')@[v],loc,length (compE2 e) + pc',⌊a⌋)"
by(rule bisim1_bisims1.bisims1List2)
ultimately show ?case by(auto)
qed(auto)
lemma bisim1_Throw_τExec_mover:
"⟦ P, e, h ⊢ (Throw a,xs) ↔ (stk,loc,pc,None) ⟧
⟹ ∃pc'. τExec_mover_a P t e h (stk, loc, pc, None) ([Addr a], loc, pc', ⌊a⌋) ∧
P, e, h ⊢ (Throw a,xs) ↔ ([Addr a], loc, pc', ⌊a⌋) ∧ xs = loc"
by(drule bisim1_Throw_τExec_movet)(blast intro: tranclp_into_rtranclp)
lemma bisims1_Throw_τExec_movesr:
"⟦ P, es, h ⊢ (map Val vs @ Throw a # es',xs) [↔] (stk,loc,pc,None) ⟧
⟹ ∃pc'. τExec_movesr_a P t es h (stk, loc, pc, None) (Addr a # rev vs, loc, pc', ⌊a⌋) ∧
P, es, h ⊢ (map Val vs @ Throw a # es',xs) [↔] (Addr a # rev vs, loc, pc', ⌊a⌋) ∧ xs = loc"
by(drule bisims1_Throw_τExec_movest)(blast intro: tranclp_into_rtranclp)
declare split_beta [simp]
lemma bisim1_inline_call_Throw:
"⟦ P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None); call1 e' = ⌊(a, M, vs)⌋;
compE2 e ! pc = Invoke M n0; pc < length (compE2 e) ⟧
⟹ n0 = length vs ∧ P,e,h ⊢ (inline_call (Throw A) e', xs) ↔ (stk, loc, pc, ⌊A⌋)"
(is "⟦ _; _; _; _ ⟧ ⟹ ?concl e n e' xs pc stk loc")
and bisims1_inline_calls_Throw:
"⟦ P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, None); calls1 es' = ⌊(a, M, vs)⌋;
compEs2 es ! pc = Invoke M n0; pc < length (compEs2 es) ⟧
⟹ n0 = length vs ∧ P,es,h ⊢ (inline_calls (Throw A) es', xs) [↔] (stk, loc, pc, ⌊A⌋)"
(is "⟦ _; _; _; _ ⟧ ⟹ ?concls es n es' xs pc stk loc")
proof(induct e "n :: nat" e' xs stk loc pc "None :: 'addr option"
and es "n :: nat" es' xs stk loc pc "None :: 'addr option"
rule: bisim1_bisims1_inducts_split)
case (bisim1BinOp1 e1 n e' xs stk loc pc e2 bop)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e1 ! pc = Invoke M n0; pc < length (compE2 e1) ⟧
⟹ ?concl e1 n e' xs pc stk loc›
note bisim1 = ‹P,e1,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 (e1 «bop» e2) ! pc = Invoke M n0›
note call = ‹call1 (e' «bop» e2) = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e1)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1BinOp1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e1)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e1)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e1)" by(cases "pc < length (compE2 e1)") auto
from call ins show ?thesis by simp
qed
next
case bisim1BinOp2 thus ?case
by(auto split: if_split_asm bop.split_asm dest: bisim1_bisims1.bisim1BinOp2)
next
case (bisim1AAcc1 A n a' xs stk loc pc i)
note IH1 = ‹⟦call1 a' = ⌊(a, M, vs)⌋; compE2 A ! pc = Invoke M n0; pc < length (compE2 A) ⟧
⟹ ?concl A n a' xs pc stk loc›
note bisim1 = ‹P,A,h ⊢ (a', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 (A⌊i⌉) ! pc = Invoke M n0›
note call = ‹call1 (a'⌊i⌉) = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val a'")
case False
with bisim1 call have "pc < length (compE2 A)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1AAcc1)
next
case True
then obtain v where [simp]: "a' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 A)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 A)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 A)" by(cases "pc < length (compE2 A)") auto
from call ins show ?thesis by simp
qed
next
case bisim1AAcc2 thus ?case
by(auto split: if_split_asm dest: bisim1_bisims1.bisim1AAcc2)
next
case (bisim1AAss1 A n a' xs stk loc pc i e)
note IH1 = ‹⟦call1 a' = ⌊(a, M, vs)⌋; compE2 A ! pc = Invoke M n0; pc < length (compE2 A) ⟧
⟹ ?concl A n a' xs pc stk loc›
note bisim1 = ‹P,A,h ⊢ (a', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 (A⌊i⌉ := e) ! pc = Invoke M n0›
note call = ‹call1 (a'⌊i⌉ := e) = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val a'")
case False
with bisim1 call have "pc < length (compE2 A)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1AAss1)
next
case True
then obtain v where [simp]: "a' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 A)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 A)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 A)" by(cases "pc < length (compE2 A)") auto
from call ins show ?thesis by simp
qed
next
case (bisim1AAss2 i n i' xs stk loc pc A e v)
note IH1 = ‹⟦call1 i' = ⌊(a, M, vs)⌋; compE2 i ! pc = Invoke M n0; pc < length (compE2 i) ⟧
⟹ ?concl i n i' xs pc stk loc›
note bisim1 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 (A⌊i⌉ := e) ! (length (compE2 A) + pc) = Invoke M n0›
note call = ‹call1 (Val v⌊i'⌉ := e) = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val i'")
case False
with bisim1 call have "pc < length (compE2 i)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1AAss2)
next
case True
then obtain v where [simp]: "i' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 i)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 i)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 i)" by(cases "pc < length (compE2 i)") auto
from call ins show ?thesis by simp
qed
next
case bisim1AAss3 thus ?case
by(auto split: if_split_asm nat.split_asm simp add: nth_Cons dest: bisim1_bisims1.bisim1AAss3)
next
case (bisim1FAss1 e n e' xs stk loc pc e2 F D)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e ! pc = Invoke M n0; pc < length (compE2 e) ⟧
⟹ ?concl e n e' xs pc stk loc›
note bisim1 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 (e∙F{D} := e2) ! pc = Invoke M n0›
note call = ‹call1 (e'∙F{D} := e2) = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1FAss1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e)" by(cases "pc < length (compE2 e)") auto
from call ins show ?thesis by simp
qed
next
case bisim1FAss2 thus ?case
by(auto split: if_split_asm nat.split_asm simp add: nth_Cons dest: bisim1_bisims1.bisim1FAss2)
next
case (bisim1CAS1 E n e' xs stk loc pc e2 e3 D F)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 E ! pc = Invoke M n0; pc < length (compE2 E) ⟧
⟹ ?concl E n e' xs pc stk loc›
note bisim1 = ‹P,E,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 _ ! pc = Invoke M n0›
note call = ‹call1 _ = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 E)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1CAS1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 E)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 E)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 E)" by(cases "pc < length (compE2 E)") auto
from call ins show ?thesis by simp
qed
next
case (bisim1CAS2 e2 n e2' xs stk loc pc e1 e3 D F v)
note IH1 = ‹⟦call1 e2' = ⌊(a, M, vs)⌋; compE2 e2 ! pc = Invoke M n0; pc < length (compE2 e2) ⟧
⟹ ?concl e2 n e2' xs pc stk loc›
note bisim1 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, None)›
note ins = ‹compE2 _ ! (length (compE2 e1) + pc) = Invoke M n0›
note call = ‹call1 _ = ⌊(a, M, vs)⌋›
show ?case
proof(cases "is_val e2'")
case False
with bisim1 call have "pc < length (compE2 e2)"
by(auto intro: bisim1_call_pcD)
with call ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1CAS2)
next
case True
then obtain v where [simp]: "e2' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e2)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e2)"
with bisim1 ins have False
by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e2)" by(cases "pc < length (compE2 e2)") auto
from call ins show ?thesis by simp
qed
next
case (bisim1Call1 obj n obj' xs stk loc pc ps M')
note IH1 = ‹⟦call1 obj' = ⌊(a, M, vs)⌋; compE2 obj ! pc = Invoke M n0;
pc < length (compE2 obj) ⟧
⟹ ?concl obj n obj' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦calls1 ps = ⌊(a, M, vs)⌋; compEs2 ps ! 0 = Invoke M n0; 0 < length (compEs2 ps) ⟧
⟹ ?concls ps n ps xs 0 [] xs›
note ins = ‹compE2 (obj∙M'(ps)) ! pc = Invoke M n0›
note bisim1 = ‹P,obj,h ⊢ (obj', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (obj'∙M'(ps)) = ⌊(a, M, vs)⌋›
thus ?case
proof(cases rule: call1_callE)
case CallObj
with bisim1 call have "pc < length (compE2 obj)" by(auto intro: bisim1_call_pcD)
with call ins CallObj IH1 show ?thesis
by(auto intro: bisim1_bisims1.bisim1Call1)
next
case (CallParams v)
from bisim1 have "pc ≤ length (compE2 obj)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 obj)"
with bisim1 ins CallParams have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 obj)" by(cases "pc < length (compE2 obj)") auto
with bisim1 CallParams have [simp]: "stk = [v]" "loc = xs" by(auto dest: bisim1_Val_length_compE2D)
from IH2[of loc] CallParams ins
show ?thesis
apply(clarsimp simp add: compEs2_map_Val is_vals_conv split: if_split_asm)
apply(drule bisim1_bisims1.bisim1CallParams)
apply(auto simp add: neq_Nil_conv)
done
next
case [simp]: Call
from bisim1 have "pc ≤ length (compE2 obj)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 obj)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 obj)" by(cases "pc < length (compE2 obj)") auto
with ins have [simp]: "vs = []" by(auto simp add: compEs2_map_Val split: if_split_asm)
from bisim1 have [simp]: "stk = [Addr a]" "xs = loc" by(auto dest: bisim1_Val_length_compE2D)
from ins show ?thesis by(auto intro: bisim1CallThrow[of "[]" "[]", simplified])
qed
next
case (bisim1CallParams ps n ps' xs stk loc pc obj M' v)
note IH2 = ‹⟦calls1 ps' = ⌊(a, M, vs)⌋; compEs2 ps ! pc = Invoke M n0; pc < length (compEs2 ps) ⟧
⟹ ?concls ps n ps' xs pc stk loc›
note ins = ‹compE2 (obj∙M'(ps)) ! (length (compE2 obj) + pc) = Invoke M n0›
note bisim2 = ‹P,ps,h ⊢ (ps', xs) [↔] (stk, loc, pc, None)›
note call = ‹call1 (Val v∙M'(ps')) = ⌊(a, M, vs)⌋›
thus ?case
proof(cases rule: call1_callE)
case CallObj thus ?thesis by simp
next
case (CallParams v')
hence [simp]: "v' = v" and call': "calls1 ps' = ⌊(a, M, vs)⌋" by auto
from bisim2 call' have "pc < length (compEs2 ps)" by(auto intro: bisims1_calls_pcD)
with IH2 CallParams ins show ?thesis
by(auto simp add: is_vals_conv split: if_split_asm intro: bisim1_bisims1.bisim1CallParams)
next
case Call
hence [simp]: "v = Addr a" "M' = M" "ps' = map Val vs" by auto
from bisim2 have "pc ≤ length (compEs2 ps)" by(auto dest: bisims1_pc_length_compEs2)
moreover {
assume pc: "pc < length (compEs2 ps)"
with bisim2 ins have False by(auto dest: bisims_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compEs2 ps)" by(cases "pc < length (compEs2 ps)") auto
from bisim2 have [simp]: "stk = rev vs" "xs = loc" by(auto dest: bisims1_Val_length_compEs2D)
from bisim2 have "length ps = length vs" by(auto dest: bisims1_lengthD)
with ins show ?thesis by(auto intro: bisim1CallThrow)
qed
next
case (bisims1List1 e n e' xs stk loc pc es)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e ! pc = Invoke M n0; pc < length (compE2 e) ⟧
⟹ ?concl e n e' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦calls1 es = ⌊(a, M, vs)⌋; compEs2 es ! 0 = Invoke M n0; 0 < length (compEs2 es) ⟧
⟹ ?concls es n es xs 0 [] xs›
note bisim1 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹calls1 (e' # es) = ⌊(a, M, vs)⌋›
note ins = ‹compEs2 (e # es) ! pc = Invoke M n0›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis
by(auto intro: bisim1_bisims1.bisims1List1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e)" by(cases "pc < length (compE2 e)") auto
with bisim1 have [simp]: "stk = [v]" "loc = xs" by(auto dest: bisim1_Val_length_compE2D)
from call have "es ≠ []" by(cases es) simp_all
with IH2[of loc] call ins
show ?thesis by(auto split: if_split_asm dest: bisims1List2)
qed
qed(auto split: if_split_asm bop.split_asm intro: bisim1_bisims1.intros dest: bisim1_pc_length_compE2)
lemma bisim1_max_stack: "P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp) ⟹ length stk ≤ max_stack e"
and bisims1_max_stacks: "P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, xcp) ⟹ length stk ≤ max_stacks es"
apply(induct "(e', xs)" "(stk, loc, pc, xcp)" and "(es', xs)" "(stk, loc, pc, xcp)"
arbitrary: e' xs stk loc pc xcp and es' xs stk loc pc xcp rule: bisim1_bisims1.inducts)
apply(auto simp add: max_stack1[simplified] max_def max_stacks_ge_length)
apply(drule sym, simp add: max_stacks_ge_length, drule sym, simp, rule le_trans[OF max_stacks_ge_length], simp)
done
inductive bisim1_fr :: "'addr J1_prog ⇒ 'heap ⇒ 'addr expr1 × 'addr locals1 ⇒ 'addr frame ⇒ bool"
for P :: "'addr J1_prog" and h :: 'heap
where
"⟦ P ⊢ C sees M:Ts→T = ⌊body⌋ in D;
P,blocks1 0 (Class D#Ts) body, h ⊢ (e, xs) ↔ (stk, loc, pc, None);
call1 e = ⌊(a, M', vs)⌋;
max_vars e ≤ length xs ⟧
⟹ bisim1_fr P h (e, xs) (stk, loc, C, M, pc)"
declare bisim1_fr.intros [intro]
declare bisim1_fr.cases [elim]
lemma bisim1_fr_hext_mono:
"⟦ bisim1_fr P h exs fr; hext h h' ⟧ ⟹ bisim1_fr P h' exs fr"
by(auto intro: bisim1_hext_mono)
lemma bisim1_max_vars: "P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp) ⟹ max_vars E ≥ max_vars e"
and : "P,Es,h ⊢ (es,xs) [↔] (stk,loc,pc,xcp) ⟹ max_varss Es ≥ max_varss es"
apply(induct E "(e, xs)" "(stk, loc, pc, xcp)" and Es "(es, xs)" "(stk, loc, pc, xcp)"
arbitrary: e xs stk loc pc xcp and es xs stk loc pc xcp rule: bisim1_bisims1.inducts)
apply(auto)
done
lemma bisim1_call_τExec_move:
"⟦ P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None); call1 e' = ⌊(a, M', vs)⌋; n + max_vars e' ≤ length xs; ¬ contains_insync e ⟧
⟹ ∃pc' loc' stk'. τExec_mover_a P t e h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None) ∧
pc' < length (compE2 e) ∧ compE2 e ! pc' = Invoke M' (length vs) ∧
P,e,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)"
(is "⟦ _; _; _; _ ⟧ ⟹ ?concl e n e' xs pc stk loc")
and bisims1_calls_τExec_moves:
"⟦ P,es,h ⊢ (es',xs) [↔] (stk, loc, pc, None); calls1 es' = ⌊(a, M', vs)⌋;
n + max_varss es' ≤ length xs; ¬ contains_insyncs es ⟧
⟹ ∃pc' stk' loc'. τExec_movesr_a P t es h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None) ∧
pc' < length (compEs2 es) ∧ compEs2 es ! pc' = Invoke M' (length vs) ∧
P,es,h ⊢ (es', xs) [↔] (rev vs @ Addr a # stk', loc', pc', None)"
(is "⟦_; _; _; _ ⟧ ⟹ ?concls es n es' xs pc stk loc")
proof(induct e "n :: nat" e' xs stk loc pc xcp≡"None :: 'addr option"
and es "n :: nat" es' xs stk loc pc xcp≡"None :: 'addr option"
rule: bisim1_bisims1_inducts_split)
case bisim1Val2 thus ?case by auto
next
case bisim1New thus ?case by auto
next
case bisim1NewArray thus ?case
by auto (fastforce intro: bisim1_bisims1.bisim1NewArray elim!: NewArray_τExecrI intro!: exI)
next
case bisim1Cast thus ?case
by(auto)(fastforce intro: bisim1_bisims1.bisim1Cast elim!: Cast_τExecrI intro!: exI)+
next
case bisim1InstanceOf thus ?case
by(auto)(fastforce intro: bisim1_bisims1.bisim1InstanceOf elim!: InstanceOf_τExecrI intro!: exI)+
next
case bisim1Val thus ?case by auto
next
case bisim1Var thus ?case by auto
next
case (bisim1BinOp1 e1 n e' xs stk loc pc e2 bop)
note IH1 = ‹⟦call1 e' = ⌊(a, M', vs)⌋; n + max_vars e' ≤ length xs; ¬ contains_insync e1 ⟧ ⟹ ?concl e1 n e' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦call1 e2 = ⌊(a, M', vs)⌋; n + max_vars e2 ≤ length xs; ¬ contains_insync e2 ⟧ ⟹ ?concl e2 n e2 xs 0 [] xs›
note call = ‹call1 (e' «bop» e2) = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars (e' «bop» e2) ≤ length xs›
note bisim1 = ‹P,e1,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note cs = ‹¬ contains_insync (e1 «bop» e2)›
show ?case
proof(cases "is_val e'")
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], loc, length (compE2 e1), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence "τExec_mover_a P t (e1«bop»e2) h (stk, loc, pc, None) ([v], loc, length (compE2 e1), None)"
by-(rule BinOp_τExecrI1)
also from call IH2[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e2 h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e2 ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e2)"
and bisim': "P,e2,h ⊢ (e2, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from BinOp_τExecrI2[OF exec, of e1 bop v]
have "τExec_mover_a P t (e1«bop»e2) h ([v], loc, length (compE2 e1), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 e1) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,e1«bop»e2,h ⊢ (Val v «bop» e2, xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 e1) + pc', None)"
by(rule bisim1BinOp2)
ultimately show ?thesis using ins by fastforce
next
case False with IH1 len False call cs show ?thesis
by(clarsimp)(fastforce intro: bisim1_bisims1.bisim1BinOp1 elim!: BinOp_τExecrI1 intro!: exI)
qed
next
case (bisim1BinOp2 e2 n e' xs stk loc pc e1 bop v1)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e2)" "compE2 e2 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e2,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from exec have "τExec_mover_a P t (e1 «bop» e2) h (stk @ [v1], loc, length (compE2 e1) + pc, None)
((rev vs @ Addr a # stk') @ [v1], loc', length (compE2 e1) + pc', None)"
by(rule BinOp_τExecrI2)
moreover from bisim'
have "P,e1 «bop» e2,h ⊢ (Val v1 «bop» e', xs) ↔ ((rev vs @ Addr a # stk') @ [v1], loc', length (compE2 e1) + pc', None)"
by(rule bisim1_bisims1.bisim1BinOp2)
ultimately show ?case using pc' by(fastforce)
next
case bisim1LAss1 thus ?case
by(auto)(fastforce intro: bisim1_bisims1.bisim1LAss1 elim!: LAss_τExecrI intro!: exI)
next
case bisim1LAss2 thus ?case by simp
next
case (bisim1AAcc1 A n a' xs stk loc pc i)
note IH1 = ‹⟦call1 a' = ⌊(a, M', vs)⌋; n + max_vars a' ≤ length xs; ¬ contains_insync A⟧ ⟹ ?concl A n a' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦call1 i = ⌊(a, M', vs)⌋; n + max_vars i ≤ length xs; ¬ contains_insync i⟧ ⟹ ?concl i n i xs 0 [] xs›
note call = ‹call1 (a'⌊i⌉) = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars (a'⌊i⌉) ≤ length xs›
note bisim1 = ‹P,A,h ⊢ (a', xs) ↔ (stk, loc, pc, None)›
note cs = ‹¬ contains_insync (A⌊i⌉)›
show ?case
proof(cases "is_val a'")
case True
then obtain v where [simp]: "a' = Val v" by auto
from bisim1 have "τExec_mover_a P t A h (stk, loc, pc, None) ([v], loc, length (compE2 A), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence "τExec_mover_a P t (A⌊i⌉) h (stk, loc, pc, None) ([v], loc, length (compE2 A), None)"
by-(rule AAcc_τExecrI1)
also from call IH2[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t i h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 i ! pc' = Invoke M' (length vs)" "pc' < length (compE2 i)"
and bisim': "P,i,h ⊢ (i, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from AAcc_τExecrI2[OF exec, of A v]
have "τExec_mover_a P t (A⌊i⌉) h ([v], loc, length (compE2 A), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 A) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,A⌊i⌉,h ⊢ (Val v⌊i⌉, xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 A) + pc', None)"
by(rule bisim1AAcc2)
ultimately show ?thesis using ins by fastforce
next
case False with IH1 len False call cs show ?thesis
by(clarsimp)(fastforce intro: bisim1_bisims1.bisim1AAcc1 elim!: AAcc_τExecrI1 intro!: exI)
qed
next
case (bisim1AAcc2 i n i' xs stk loc pc A v)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 i)" "compE2 i ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t i h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,i,h ⊢ (i', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from exec have "τExec_mover_a P t (A⌊i⌉) h (stk @ [v], loc, length (compE2 A) + pc, None)
((rev vs @ Addr a # stk') @ [v], loc', length (compE2 A) + pc', None)"
by(rule AAcc_τExecrI2)
moreover from bisim'
have "P,A⌊i⌉,h ⊢ (Val v⌊i'⌉, xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 A) + pc', None)"
by(rule bisim1_bisims1.bisim1AAcc2)
ultimately show ?case using pc' by(fastforce)
next
case (bisim1AAss1 A n a' xs stk loc pc i e)
note IH1 = ‹⟦call1 a' = ⌊(a, M', vs)⌋; n + max_vars a' ≤ length xs; ¬ contains_insync A ⟧ ⟹ ?concl A n a' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦call1 i = ⌊(a, M', vs)⌋; n + max_vars i ≤ length xs; ¬ contains_insync i⟧ ⟹ ?concl i n i xs 0 [] xs›
note IH3 = ‹⋀xs. ⟦call1 e = ⌊(a, M', vs)⌋; n + max_vars e ≤ length xs; ¬ contains_insync e⟧ ⟹ ?concl e n e xs 0 [] xs›
note call = ‹call1 (a'⌊i⌉ := e) = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars (a'⌊i⌉ := e) ≤ length xs›
note bisim1 = ‹P,A,h ⊢ (a', xs) ↔ (stk, loc, pc, None)›
note bisim2 = ‹P,i,h ⊢ (i, loc) ↔ ([], loc, 0, None)›
note cs = ‹¬ contains_insync (A⌊i⌉ := e)›
show ?case
proof(cases "is_val a'")
case True
then obtain v where [simp]: "a' = Val v" by auto
from bisim1 have "τExec_mover_a P t A h (stk, loc, pc, None) ([v], loc, length (compE2 A), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence exec: "τExec_mover_a P t (A⌊i⌉ := e) h (stk, loc, pc, None) ([v], loc, length (compE2 A), None)"
by-(rule AAss_τExecrI1)
show ?thesis
proof(cases "is_val i")
case True
then obtain v' where [simp]: "i = Val v'" by auto
note exec also from bisim2
have "τExec_mover_a P t i h ([], loc, 0, None) ([v'], loc, length (compE2 i), None)"
by(auto dest!: bisim1Val2D1)
from AAss_τExecrI2[OF this, of A e v]
have "τExec_mover_a P t (A⌊i⌉ := e) h ([v], loc, length (compE2 A), None) ([v', v], loc, length (compE2 A) + length (compE2 i), None)" by simp
also (rtranclp_trans) from call IH3[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e h ([], loc, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e)"
and bisim': "P,e,h ⊢ (e, loc) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from AAss_τExecrI3[OF exec, of A i v' v]
have "τExec_mover_a P t (A⌊i⌉ := e) h ([v', v], loc, length (compE2 A) + length (compE2 i), None)
((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 A) + length (compE2 i) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,A⌊i⌉ := e,h ⊢ (Val v⌊Val v'⌉ := e, xs) ↔ ((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 A) + length (compE2 i) + pc', None)"
by - (rule bisim1AAss3, simp)
ultimately show ?thesis using ins by fastforce
next
case False
note exec also from False call IH2[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t i h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 i ! pc' = Invoke M' (length vs)" "pc' < length (compE2 i)"
and bisim': "P,i,h ⊢ (i, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from AAss_τExecrI2[OF exec, of A e v]
have "τExec_mover_a P t (A⌊i⌉ := e) h ([v], loc, length (compE2 A), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 A) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,A⌊i⌉ := e,h ⊢ (Val v⌊i⌉ := e, xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 A) + pc', None)"
by(rule bisim1AAss2)
ultimately show ?thesis using ins False by(fastforce intro!: exI)
qed
next
case False with IH1 len False call cs show ?thesis
by(clarsimp)(fastforce intro: bisim1_bisims1.bisim1AAss1 elim!: AAss_τExecrI1 intro!: exI)
qed
next
case (bisim1AAss2 i n i' xs stk loc pc A e v)
note IH2 = ‹⟦call1 i' = ⌊(a, M', vs)⌋; n + max_vars i' ≤ length xs; ¬ contains_insync i⟧ ⟹ ?concl i n i' xs pc stk loc›
note IH3 = ‹⋀xs. ⟦call1 e = ⌊(a, M', vs)⌋; n + max_vars e ≤ length xs; ¬ contains_insync e⟧ ⟹ ?concl e n e xs 0 [] xs›
note call = ‹call1 (Val v⌊i'⌉ := e) = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars (Val v⌊i'⌉ := e) ≤ length xs›
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, None)›
note cs = ‹¬ contains_insync (A⌊i⌉ := e)›
show ?case
proof(cases "is_val i'")
case True
then obtain v' where [simp]: "i' = Val v'" by auto
from bisim2 have exec: "τExec_mover_a P t i h (stk, loc, pc, None) ([v'], loc, length (compE2 i), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
from AAss_τExecrI2[OF exec, of A e v]
have "τExec_mover_a P t (A⌊i⌉ := e) h (stk @ [v], loc, length (compE2 A) + pc, None) ([v', v], loc, length (compE2 A) + length (compE2 i), None)" by simp
also from call IH3[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e)"
and bisim': "P,e,h ⊢ (e, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from AAss_τExecrI3[OF exec, of A i v' v]
have "τExec_mover_a P t (A⌊i⌉ := e) h ([v', v], loc, length (compE2 A) + length (compE2 i), None)
((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 A) + length (compE2 i) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,A⌊i⌉ := e,h ⊢ (Val v⌊Val v'⌉ := e, xs) ↔ ((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 A) + length (compE2 i) + pc', None)"
by(rule bisim1AAss3)
ultimately show ?thesis using ins by(fastforce intro!: exI)
next
case False
with IH2 len call cs obtain pc' loc' stk'
where ins: "pc' < length (compE2 i)" "compE2 i ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t i h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,i,h ⊢ (i', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from bisim' have "P,A⌊i⌉ := e,h ⊢ (Val v⌊i'⌉ := e, xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 A) + pc', None)"
by(rule bisim1_bisims1.bisim1AAss2)
with AAss_τExecrI2[OF exec, of A e v] ins False show ?thesis by(auto intro!: exI)
qed
next
case (bisim1AAss3 e n e' xs stk loc pc A i v v')
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e)" "compE2 e ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from exec have "τExec_mover_a P t (A⌊i⌉:=e) h (stk @ [v', v], loc, length (compE2 A) + length (compE2 i) + pc, None)
((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 A) + length (compE2 i) + pc', None)"
by(rule AAss_τExecrI3)
moreover from bisim'
have "P,A⌊i⌉ := e,h ⊢ (Val v⌊Val v'⌉ := e', xs) ↔ ((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 A) + length (compE2 i) + pc', None)"
by(rule bisim1_bisims1.bisim1AAss3)
ultimately show ?case using pc' by(fastforce intro!: exI)
next
case bisim1AAss4 thus ?case by simp
next
case bisim1ALength thus ?case
by(auto)(fastforce intro: bisim1_bisims1.bisim1ALength elim!: ALength_τExecrI intro!: exI)
next
case bisim1FAcc thus ?case
by(auto)(fastforce intro: bisim1_bisims1.bisim1FAcc elim!: FAcc_τExecrI intro!: exI)
next
case (bisim1FAss1 e n e' xs stk loc pc e2 F D)
note IH1 = ‹⟦call1 e' = ⌊(a, M', vs)⌋; n + max_vars e' ≤ length xs; ¬ contains_insync e⟧ ⟹ ?concl e n e' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦call1 e2 = ⌊(a, M', vs)⌋; n + max_vars e2 ≤ length xs; ¬ contains_insync e2⟧ ⟹ ?concl e2 n e2 xs 0 [] xs›
note call = ‹call1 (e'∙F{D} := e2) = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars (e'∙F{D} := e2) ≤ length xs›
note bisim1 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note cs = ‹¬ contains_insync (e∙F{D} := e2)›
show ?case
proof(cases "is_val e'")
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "τExec_mover_a P t e h (stk, loc, pc, None) ([v], loc, length (compE2 e), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence "τExec_mover_a P t (e∙F{D} := e2) h (stk, loc, pc, None) ([v], loc, length (compE2 e), None)"
by-(rule FAss_τExecrI1)
also from call IH2[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e2 h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e2 ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e2)"
and bisim': "P,e2,h ⊢ (e2, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from FAss_τExecrI2[OF exec, of e F D v]
have "τExec_mover_a P t (e∙F{D} := e2) h ([v], loc, length (compE2 e), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 e) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,e∙F{D} := e2,h ⊢ (Val v∙F{D} := e2, xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 e) + pc', None)"
by(rule bisim1FAss2)
ultimately show ?thesis using ins by fastforce
next
case False with IH1 len False call cs show ?thesis
by(clarsimp)(fastforce intro: bisim1_bisims1.bisim1FAss1 elim!: FAss_τExecrI1 intro!: exI)
qed
next
case (bisim1FAss2 e2 n e' xs stk loc pc e F D v)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e2)" "compE2 e2 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e2,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from exec have "τExec_mover_a P t (e∙F{D} := e2) h (stk @ [v], loc, length (compE2 e) + pc, None)
((rev vs @ Addr a # stk') @ [v], loc', length (compE2 e) + pc', None)"
by(rule FAss_τExecrI2)
moreover from bisim'
have "P,e∙F{D} := e2,h ⊢ (Val v∙F{D} := e', xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 e) + pc', None)"
by(rule bisim1_bisims1.bisim1FAss2)
ultimately show ?case using pc' by(fastforce)
next
case bisim1FAss3 thus ?case by simp
next
case (bisim1CAS1 e1 n e' xs stk loc pc e2 e3 D F)
note IH1 = ‹⟦call1 e' = ⌊(a, M', vs)⌋; n + max_vars e' ≤ length xs; ¬ contains_insync e1 ⟧ ⟹ ?concl e1 n e' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦call1 e2 = ⌊(a, M', vs)⌋; n + max_vars e2 ≤ length xs; ¬ contains_insync e2⟧ ⟹ ?concl e2 n e2 xs 0 [] xs›
note IH3 = ‹⋀xs. ⟦call1 e3 = ⌊(a, M', vs)⌋; n + max_vars e3 ≤ length xs; ¬ contains_insync e3⟧ ⟹ ?concl e3 n e3 xs 0 [] xs›
note call = ‹call1 _ = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars _ ≤ length xs›
note bisim1 = ‹P,e1,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note bisim2 = ‹P,e2,h ⊢ (e2, loc) ↔ ([], loc, 0, None)›
note cs = ‹¬ contains_insync _›
show ?case
proof(cases "is_val e'")
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], loc, length (compE2 e1), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence exec: "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk, loc, pc, None) ([v], loc, length (compE2 e1), None)"
by-(rule CAS_τExecrI1)
show ?thesis
proof(cases "is_val e2")
case True
then obtain v' where [simp]: "e2 = Val v'" by auto
note exec also from bisim2
have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v'], loc, length (compE2 e2), None)"
by(auto dest!: bisim1Val2D1)
from CAS_τExecrI2[OF this, of e1 D F e3]
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v], loc, length (compE2 e1), None) ([v', v], loc, length (compE2 e1) + length (compE2 e2), None)" by simp
also (rtranclp_trans) from call IH3[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e3 h ([], loc, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e3 ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e3)"
and bisim': "P,e3,h ⊢ (e3, loc) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from CAS_τExecrI3[OF exec, of e1 D F e2 v' v]
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v], loc, length (compE2 e1) + length (compE2 e2), None)
((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h ⊢ (Val v∙compareAndSwap(D∙F, Val v', e3), xs) ↔ ((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', None)"
by - (rule bisim1CAS3, simp)
ultimately show ?thesis using ins by fastforce
next
case False
note exec also from False call IH2[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e2 h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e2 ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e2)"
and bisim': "P,e2,h ⊢ (e2, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from CAS_τExecrI2[OF exec, of e1 D F e3 v]
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v], loc, length (compE2 e1), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 e1) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h ⊢ (Val v∙compareAndSwap(D∙F, e2, e3), xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 e1) + pc', None)"
by(rule bisim1CAS2)
ultimately show ?thesis using ins False by(fastforce intro!: exI)
qed
next
case False with IH1 len False call cs show ?thesis
by(clarsimp)(fastforce intro: bisim1_bisims1.bisim1CAS1 elim!: CAS_τExecrI1 intro!: exI)
qed
next
case (bisim1CAS2 e2 n e2' xs stk loc pc e1 e3 D F v)
note IH2 = ‹⟦call1 e2' = ⌊(a, M', vs)⌋; n + max_vars e2' ≤ length xs; ¬ contains_insync e2⟧ ⟹ ?concl e2 n e2' xs pc stk loc›
note IH3 = ‹⋀xs. ⟦call1 e3 = ⌊(a, M', vs)⌋; n + max_vars e3 ≤ length xs; ¬ contains_insync e3⟧ ⟹ ?concl e3 n e3 xs 0 [] xs›
note call = ‹call1 _ = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars _ ≤ length xs›
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, None)›
note cs = ‹¬ contains_insync _›
show ?case
proof(cases "is_val e2'")
case True
then obtain v' where [simp]: "e2' = Val v'" by auto
from bisim2 have exec: "τExec_mover_a P t e2 h (stk, loc, pc, None) ([v'], loc, length (compE2 e2), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
from CAS_τExecrI2[OF exec, of e1 D F e3 v]
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v], loc, length (compE2 e1) + pc, None) ([v', v], loc, length (compE2 e1) + length (compE2 e2), None)" by simp
also from call IH3[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_mover_a P t e3 h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compE2 e3 ! pc' = Invoke M' (length vs)" "pc' < length (compE2 e3)"
and bisim': "P,e3,h ⊢ (e3, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from CAS_τExecrI3[OF exec, of e1 D F e2 v' v]
have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h ([v', v], loc, length (compE2 e1) + length (compE2 e2), None)
((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', None)" by simp
also (rtranclp_trans) from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h ⊢ (Val v∙compareAndSwap(D∙F, Val v', e3), xs) ↔ ((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', None)"
by(rule bisim1CAS3)
ultimately show ?thesis using ins by(fastforce intro!: exI)
next
case False
with IH2 len call cs obtain pc' loc' stk'
where ins: "pc' < length (compE2 e2)" "compE2 e2 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e2,h ⊢ (e2', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from bisim' have "P,e1∙compareAndSwap(D∙F, e2, e3),h ⊢ (Val v∙compareAndSwap(D∙F, e2', e3), xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 e1) + pc', None)"
by(rule bisim1_bisims1.bisim1CAS2)
with CAS_τExecrI2[OF exec, of e1 D F e3 v] ins False show ?thesis by(auto intro!: exI)
qed
next
case (bisim1CAS3 e3 n e3' xs stk loc pc e1 e2 D F v v')
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e3)" "compE2 e3 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e3 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e3,h ⊢ (e3', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by fastforce
from exec have "τExec_mover_a P t (e1∙compareAndSwap(D∙F, e2, e3)) h (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, None)
((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', None)"
by(rule CAS_τExecrI3)
moreover from bisim'
have "P,e1∙compareAndSwap(D∙F, e2, e3),h ⊢ (Val v∙compareAndSwap(D∙F, Val v', e3'), xs) ↔ ((rev vs @ Addr a # stk') @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', None)"
by(rule bisim1_bisims1.bisim1CAS3)
ultimately show ?case using pc' by(fastforce intro!: exI)
next
case (bisim1Call1 obj n obj' xs stk loc pc ps M)
note IH1 = ‹⟦call1 obj' = ⌊(a, M', vs)⌋; n + max_vars obj' ≤ length xs; ¬ contains_insync obj⟧ ⟹ ?concl obj n obj' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦calls1 ps = ⌊(a, M', vs)⌋; n + max_varss ps ≤ length xs; ¬ contains_insyncs ps⟧ ⟹ ?concls ps n ps xs 0 [] xs›
note len = ‹n + max_vars (obj'∙M(ps)) ≤ length xs›
note bisim1 = ‹P,obj,h ⊢ (obj', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (obj'∙M(ps)) = ⌊(a, M', vs)⌋›
note cs = ‹¬ contains_insync (obj∙M(ps))›
from call show ?case
proof(cases rule: call1_callE)
case CallObj
hence "¬ is_val obj'" by auto
with CallObj IH1 len cs show ?thesis
by(clarsimp)(fastforce intro: bisim1_bisims1.bisim1Call1 elim!: Call_τExecrI1 intro!: exI)
next
case (CallParams v)
with bisim1 have "τExec_mover_a P t obj h (stk, loc, pc, None) ([v], loc, length (compE2 obj), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence "τExec_mover_a P t (obj∙M(ps)) h (stk, loc, pc, None) ([v], loc, length (compE2 obj), None)"
by-(rule Call_τExecrI1)
also from IH2[of loc] CallParams len cs obtain pc' stk' loc'
where exec: "τExec_movesr_a P t ps h ([], loc, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compEs2 ps ! pc' = Invoke M' (length vs)" "pc' < length (compEs2 ps)"
and bisim': "P,ps,h ⊢ (ps, xs) [↔] (rev vs @ Addr a # stk',loc',pc',None)" by auto
from Call_τExecrI2[OF exec, of obj M v]
have "τExec_mover_a P t (obj∙M(ps)) h ([v], loc, length (compE2 obj), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 obj) + pc', None)" by simp
also (rtranclp_trans)
have "P,obj∙M(ps),h ⊢ (Val v∙M(ps), xs) ↔ ((rev vs @ Addr a # stk') @ [v], loc', length (compE2 obj) + pc', None)"
using bisim' by(rule bisim1CallParams)
ultimately show ?thesis using ins CallParams by fastforce
next
case [simp]: Call
from bisim1 have "τExec_mover_a P t obj h (stk, loc, pc, None) ([Addr a], loc, length (compE2 obj), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence "τExec_mover_a P t (obj∙M(ps)) h (stk, loc, pc, None) ([Addr a], loc, length (compE2 obj), None)"
by-(rule Call_τExecrI1)
also have "τExec_movesr_a P t ps h ([], xs, 0, None) (rev vs, xs, length (compEs2 ps), None)"
proof(cases vs)
case Nil with Call show ?thesis by(auto)
next
case Cons with Call bisims1_Val_τExec_moves[OF bisims1_refl[of P h "map Val vs" loc]]
show ?thesis by(auto simp add: bsoks_def)
qed
from Call_τExecrI2[OF this, of obj M "Addr a"]
have "τExec_mover_a P t (obj∙M(ps)) h ([Addr a], loc, length (compE2 obj), None) (rev vs @ [Addr a], xs, length (compE2 obj) + length (compEs2 ps), None)" by simp
also (rtranclp_trans)
have "P,ps,h ⊢ (map Val vs,xs) [↔] (rev vs,xs,length (compEs2 ps),None)"
by(rule bisims1_map_Val_append[OF bisims1Nil, simplified])(simp_all add: bsoks_def)
hence "P,obj∙M(ps),h ⊢ (addr a∙M(map Val vs), xs) ↔ (rev vs @ [Addr a], xs, length (compE2 obj) + length (compEs2 ps), None)"
by(rule bisim1CallParams)
ultimately show ?thesis by fastforce
qed
next
case (bisim1CallParams ps n ps' xs stk loc pc obj M v)
note IH2 = ‹⟦calls1 ps' = ⌊(a, M', vs)⌋; n + max_varss ps' ≤ length xs; ¬ contains_insyncs ps⟧ ⟹ ?concls ps n ps' xs pc stk loc›
note bisim2 = ‹P,ps,h ⊢ (ps', xs) [↔] (stk, loc, pc, None)›
note call = ‹call1 (Val v∙M(ps')) = ⌊(a, M', vs)⌋›
note len = ‹n + max_vars (Val v∙M(ps')) ≤ length xs›
note cs = ‹¬ contains_insync (obj∙M(ps))›
from call show ?case
proof(cases rule: call1_callE)
case CallObj thus ?thesis by simp
next
case (CallParams v')
with IH2 len cs obtain pc' stk' loc'
where exec: "τExec_movesr_a P t ps h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "pc' < length (compEs2 ps)" "compEs2 ps ! pc' = Invoke M' (length vs)"
and bisim': "P,ps,h ⊢ (ps', xs) [↔] (rev vs @ Addr a # stk',loc',pc',None)" by auto
from exec have "τExec_mover_a P t (obj∙M(ps)) h (stk @ [v], loc, length (compE2 obj) + pc, None)
((rev vs @ Addr a # stk') @ [v], loc', length (compE2 obj) + pc', None)"
by(rule Call_τExecrI2)
moreover have "P,obj∙M(ps),h ⊢ (Val v∙M(ps'), xs) ↔
((rev vs @ Addr a # stk') @ [v], loc', length (compE2 obj) + pc', None)"
using bisim' by(rule bisim1_bisims1.bisim1CallParams)
ultimately show ?thesis using ins by fastforce
next
case Call
hence [simp]: "v = Addr a" "ps' = map Val vs" "M' = M" by simp_all
have "xs = loc ∧ τExec_movesr_a P t ps h (stk, loc, pc, None) (rev vs, loc, length (compEs2 ps), None)"
proof(cases "pc < length (compEs2 ps)")
case True with bisim2 show ?thesis by(auto dest: bisims1_Val_τExec_moves)
next
case False
from bisim2 have "pc ≤ length (compEs2 ps)" by(rule bisims1_pc_length_compEs2)
with False have "pc = length (compEs2 ps)" by simp
with bisim2 show ?thesis by(auto dest: bisims1_Val_length_compEs2D)
qed
then obtain [simp]: "xs = loc"
and exec: "τExec_movesr_a P t ps h (stk, loc, pc, None) (rev vs, loc, length (compEs2 ps), None)" ..
from exec have "τExec_mover_a P t (obj∙M(ps)) h (stk @ [v], loc, length (compE2 obj) + pc, None)
(rev vs @ [v], loc, length (compE2 obj) + length (compEs2 ps), None)"
by(rule Call_τExecrI2)
moreover from bisim2 have len: "length ps = length ps'" by(auto dest: bisims1_lengthD)
moreover have "P,ps,h ⊢ (map Val vs,xs) [↔] (rev vs,xs,length (compEs2 ps),None)" using len
by-(rule bisims1_map_Val_append[OF bisims1Nil, simplified], simp_all)
hence "P,obj∙M(ps),h ⊢ (addr a∙M(map Val vs), xs) ↔ (rev vs @ [Addr a], xs, length (compE2 obj) + length (compEs2 ps), None)" by(rule bisim1_bisims1.bisim1CallParams)
ultimately show ?thesis by fastforce
qed
next
case bisim1BlockSome1 thus ?case by simp
next
case bisim1BlockSome2 thus ?case by simp
next
case (bisim1BlockSome4 e n e' xs stk loc pc V T v)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e)" "compE2 e ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
note Block_τExecrI_Some[OF exec, of V T v]
moreover from bisim' have "P,{V:T=⌊v⌋; e},h ⊢ ({V:T=None; e'}, xs) ↔ (rev vs @ Addr a # stk', loc', Suc (Suc pc'), None)"
by(rule bisim1_bisims1.bisim1BlockSome4)
ultimately show ?case using pc' by fastforce
next
case (bisim1BlockNone e n e' xs stk loc pc V T)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e)" "compE2 e ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
note Block_τExecrI_None[OF exec, of V T]
moreover from bisim' have "P,{V:T=None; e},h ⊢ ({V:T=None; e'}, xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)"
by(rule bisim1_bisims1.bisim1BlockNone)
ultimately show ?case using pc' by fastforce
next
case bisim1Sync1 thus ?case
by (auto)(fastforce intro: bisim1_bisims1.bisim1Sync1 elim!: Sync_τExecrI intro!: exI)
next
case bisim1Sync2 thus ?case by simp
next
case bisim1Sync3 thus ?case by simp
next
case bisim1Sync4 thus ?case
by (auto)(fastforce intro: bisim1_bisims1.bisim1Sync4 elim!: Insync_τExecrI intro!: exI)
next
case bisim1Sync5 thus ?case by simp
next
case bisim1Sync6 thus ?case by simp
next
case bisim1Sync7 thus ?case by simp
next
case bisim1Sync8 thus ?case by simp
next
case bisim1Sync9 thus ?case by simp
next
case bisim1InSync thus ?case by simp
next
case bisim1Seq1 thus ?case
by (auto)(fastforce intro: bisim1_bisims1.bisim1Seq1 elim!: Seq_τExecrI1 intro!: exI)
next
case (bisim1Seq2 e2 n e' xs stk loc pc e1)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e2)" "compE2 e2 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e2,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from Seq_τExecrI2[OF exec, of e1] pc' bisim'
show ?case by(fastforce intro: bisim1_bisims1.bisim1Seq2 intro!: exI)
next
case bisim1Cond1 thus ?case
by (auto)(fastforce intro: bisim1_bisims1.bisim1Cond1 elim!: Cond_τExecrI1 intro!: exI)+
next
case (bisim1CondThen e1 n e' xs stk loc pc e e2)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e1)" "compE2 e1 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e1 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e1,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from Cond_τExecrI2[OF exec] pc' bisim' show ?case
by(fastforce intro: bisim1_bisims1.bisim1CondThen intro!: exI)
next
case (bisim1CondElse e2 n e' xs stk loc pc e e1)
then obtain pc' loc' stk' where pc': "pc' < length (compE2 e2)" "compE2 e2 ! pc' = Invoke M' (length vs)"
and exec: "τExec_mover_a P t e2 h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,e2,h ⊢ (e', xs) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from Cond_τExecrI3[OF exec] pc' bisim' show ?case
by (fastforce intro: bisim1_bisims1.bisim1CondElse intro!: exI)
next
case bisim1While1 thus ?case by simp
next
case bisim1While3 thus ?case
by (auto)(fastforce intro: bisim1_bisims1.bisim1While3 elim!: While_τExecrI1 intro!: exI)+
next
case bisim1While4 thus ?case
by (auto)(fastforce intro!: While_τExecrI2 bisim1_bisims1.bisim1While4 exI)+
next
case bisim1While6 thus ?case by simp
next
case bisim1While7 thus ?case by simp
next
case bisim1Throw1 thus ?case
by (auto)(fastforce intro!: exI bisim1_bisims1.bisim1Throw1 elim!: Throw_τExecrI)+
next
case bisim1Try thus ?case
by (auto)(fastforce intro: bisim1_bisims1.bisim1Try elim!: Try_τExecrI1 intro!: exI)+
next
case (bisim1TryCatch1 e n a' xs stk loc pc C' C e2 V)
note IH2 = ‹⋀xs. ⟦call1 e2 = ⌊(a, M', vs)⌋; Suc n + max_vars e2 ≤ length xs; ¬ contains_insync e2 ⟧ ⟹ ?concl e2 (Suc V) e2 xs 0 [] xs›
note bisim1 = ‹P,e,h ⊢ (Throw a', xs) ↔ (stk, loc, pc, ⌊a'⌋)›
note bisim2 = ‹⋀xs. P,e2,h ⊢ (e2, xs) ↔ ([], xs, 0, None)›
note len = ‹n + max_vars {V:Class C=None; e2} ≤ length (xs[V := Addr a'])›
note cs = ‹¬ contains_insync (try e catch(C V) e2)›
from bisim1 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
from len have "τExec_mover_a P t (try e catch(C V) e2) h ([Addr a'], loc, Suc (length (compE2 e)), None) ([], loc[V := Addr a'], Suc (Suc (length (compE2 e))), None)"
by -(rule τExecr1step,auto simp add: exec_move_def intro: τmove2_τmoves2.intros exec_instr)
also from IH2[of "loc[V := Addr a']"] len ‹call1 {V:Class C=None; e2} = ⌊(a, M', vs)⌋› cs
obtain pc' loc' stk'
where exec: "τExec_mover_a P t e2 h ([], loc[V := Addr a'], 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "pc' < length (compE2 e2)" "compE2 e2 ! pc' = Invoke M' (length vs)"
and bisim': "P,e2,h ⊢ (e2, loc[V := Addr a']) ↔ (rev vs @ Addr a # stk', loc', pc', None)" by auto
from Try_τExecrI2[OF exec, of e C V]
have "τExec_mover_a P t (try e catch(C V) e2) h ([], loc[V := Addr a'], Suc (Suc (length (compE2 e))), None) (rev vs @ Addr a # stk', loc', Suc (Suc (length (compE2 e) + pc')), None)" by simp
also from bisim'
have "P,try e catch(C V) e2,h ⊢ ({V:Class C=None; e2}, loc[V := Addr a']) ↔ (rev vs @ Addr a # stk', loc', (Suc (Suc (length (compE2 e) + pc'))), None)"
by(rule bisim1TryCatch2)
ultimately show ?case using ins by fastforce
next
case bisim1TryCatch2 thus ?case
by (auto)(fastforce intro!: Try_τExecrI2 bisim1_bisims1.bisim1TryCatch2 exI)+
next
case bisims1Nil thus ?case by simp
next
case (bisims1List1 e n e' xs stk loc pc es)
note IH1 = ‹⟦call1 e' = ⌊(a, M', vs)⌋; n + max_vars e' ≤ length xs; ¬ contains_insync e⟧ ⟹ ?concl e n e' xs pc stk loc›
note IH2 = ‹⋀xs. ⟦calls1 es = ⌊(a, M', vs)⌋; n + max_varss es ≤ length xs; ¬ contains_insyncs es⟧ ⟹ ?concls es n es xs 0 [] xs›
note bisim1 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹calls1 (e' # es) = ⌊(a, M', vs)⌋›
note len = ‹n + max_varss (e' # es) ≤ length xs›
note cs = ‹¬ contains_insyncs (e # es)›
show ?case
proof(cases "is_val e'")
case True
then obtain v where [simp]: "e' = Val v" by auto
with bisim1 have "τExec_mover_a P t e h (stk, loc, pc, None) ([v], loc, length (compE2 e), None)"
and [simp]: "xs = loc" by(auto dest!: bisim1Val2D1)
hence "τExec_movesr_a P t (e # es) h (stk, loc, pc, None) ([v], loc, length (compE2 e), None)"
by-(rule τExec_mover_τExec_movesr)
also from call IH2[of loc] len cs obtain pc' stk' loc'
where exec: "τExec_movesr_a P t es h ([], xs, 0, None) (rev vs @ Addr a # stk', loc', pc', None)"
and ins: "compEs2 es ! pc' = Invoke M' (length vs)" "pc' < length (compEs2 es)"
and bisim': "P,es,h ⊢ (es, xs) [↔] (rev vs @ Addr a # stk',loc',pc',None)" by auto
from append_τExec_movesr[OF _ exec, of "[v]" "[e]"]
have "τExec_movesr_a P t (e # es) h ([v], loc, length (compE2 e), None) (rev vs @ Addr a # (stk' @ [v]), loc', length (compE2 e) + pc', None)"
by simp
also (rtranclp_trans) from bisim'
have "P,e # es,h ⊢ (Val v # es, xs) [↔]
((rev vs @ Addr a # stk') @ [v],loc',length (compE2 e) + pc',None)"
by(rule bisim1_bisims1.bisims1List2)
ultimately show ?thesis using ins by fastforce
next
case False
with call IH1 len cs show ?thesis
by (auto)(fastforce intro!: τExec_mover_τExec_movesr bisim1_bisims1.bisims1List1 exI)+
qed
next
case (bisims1List2 es n es' xs stk loc pc e v)
then obtain pc' stk' loc' where pc': "pc' < length (compEs2 es)" "compEs2 es ! pc' = Invoke M' (length vs)"
and exec: "τExec_movesr_a P t es h (stk, loc, pc, None) (rev vs @ Addr a # stk', loc', pc', None)"
and bisim': "P,es,h ⊢ (es', xs) [↔] (rev vs @ Addr a # stk', loc', pc', None)" by auto
note append_τExec_movesr[OF _ exec, of "[v]" "[e]"]
moreover from bisim'
have "P,e#es,h ⊢ (Val v# es', xs) [↔] ((rev vs @ Addr a # stk') @ [v],loc',length (compE2 e) + pc',None)"
by(rule bisim1_bisims1.bisims1List2)
ultimately show ?case using pc' by fastforce
qed
lemma fixes P :: "'addr J1_prog"
shows bisim1_inline_call_Val:
"⟦ P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None); call1 e' = ⌊(a, M, vs)⌋;
compE2 e ! pc = Invoke M n0 ⟧
⟹ length stk ≥ Suc (length vs) ∧ n0 = length vs ∧
P,e,h ⊢ (inline_call (Val v) e', xs) ↔ (v # drop (Suc (length vs)) stk, loc, Suc pc, None)"
(is "⟦ _; _; _ ⟧ ⟹ ?concl e n e' xs pc stk loc")
and bisims1_inline_calls_Val:
"⟦ P,es,h ⊢ (es',xs) [↔] (stk,loc,pc,None); calls1 es' = ⌊(a, M, vs)⌋;
compEs2 es ! pc = Invoke M n0 ⟧
⟹ length stk ≥ Suc (length vs) ∧ n0 = length vs ∧
P,es,h ⊢ (inline_calls (Val v) es', xs) [↔] (v # drop (Suc (length vs)) stk,loc,Suc pc,None)"
(is "⟦ _; _; _ ⟧ ⟹ ?concls es n es' xs pc stk loc")
proof(induct "(e', xs)" "(stk, loc, pc, None :: 'addr option)"
and "(es', xs)" "(stk, loc, pc, None :: 'addr option)"
arbitrary: e' xs stk loc pc and es' xs stk loc pc rule: bisim1_bisims1.inducts)
case bisim1Val2 thus ?case by simp
next
case bisim1New thus ?case by simp
next
case bisim1NewArray thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1NewArray)
next
case bisim1Cast thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1Cast)
next
case bisim1InstanceOf thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1InstanceOf)
next
case bisim1Val thus ?case by simp
next
case bisim1Var thus ?case by simp
next
case (bisim1BinOp1 e1 e' xs stk loc pc bop e2)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e1 ! pc = Invoke M n0 ⟧ ⟹ ?concl e1 n e' xs pc stk loc›
note bisim1 = ‹P,e1,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (e' «bop» e2) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (e1 «bop» e2) ! pc = Invoke M n0›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e1)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis
by(auto intro: bisim1_bisims1.bisim1BinOp1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e1)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e1)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e1)" by(cases "pc < length (compE2 e1)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1BinOp2 e2 e' xs stk loc pc e1 bop v1)
note IH2 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e2 ! pc = Invoke M n0⟧ ⟹ ?concl e2 n e' xs pc stk loc›
note bisim2 = ‹P,e2,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (Val v1 «bop» e') = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (e1 «bop» e2) ! (length (compE2 e1) + pc) = Invoke M n0›
from call bisim2 have pc: "pc < length (compE2 e2)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 e2 ! pc = Invoke M n0" by(simp)
from IH2 ins' pc call show ?case by(auto dest: bisim1_bisims1.bisim1BinOp2)
next
case bisim1LAss1 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1LAss1)
next
case bisim1LAss2 thus ?case by simp
next
case (bisim1AAcc1 A a' xs stk loc pc i)
note IH1 = ‹⟦call1 a' = ⌊(a, M, vs)⌋; compE2 A ! pc = Invoke M n0⟧ ⟹ ?concl A n a' xs pc stk loc›
note bisim1 = ‹P,A,h ⊢ (a', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (a'⌊i⌉) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (A⌊i⌉) ! pc = Invoke M n0›
show ?case
proof(cases "is_val a'")
case False
with bisim1 call have "pc < length (compE2 A)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis
by(auto intro: bisim1_bisims1.bisim1AAcc1)
next
case True
then obtain v where [simp]: "a' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 A)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 A)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 A)" by(cases "pc < length (compE2 A)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1AAcc2 i i' xs stk loc pc A v)
note IH2 = ‹⟦call1 i' = ⌊(a, M, vs)⌋; compE2 i ! pc = Invoke M n0⟧ ⟹ ?concl i n i' xs pc stk loc›
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (Val v⌊i'⌉) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (A⌊i⌉) ! (length (compE2 A) + pc) = Invoke M n0›
from call bisim2 have pc: "pc < length (compE2 i)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 i ! pc = Invoke M n0" by(simp)
from IH2 ins' pc call show ?case
by(auto dest: bisim1_bisims1.bisim1AAcc2)
next
case (bisim1AAss1 A a' xs stk loc pc i e)
note IH1 = ‹⟦call1 a' = ⌊(a, M, vs)⌋; compE2 A ! pc = Invoke M n0⟧ ⟹ ?concl A n a' xs pc stk loc›
note bisim1 = ‹P,A,h ⊢ (a', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (a'⌊i⌉ := e) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (A⌊i⌉ := e) ! pc = Invoke M n0›
show ?case
proof(cases "is_val a'")
case False
with bisim1 call have "pc < length (compE2 A)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis by(auto intro: bisim1_bisims1.bisim1AAss1)
next
case True
then obtain v where [simp]: "a' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 A)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 A)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 A)" by(cases "pc < length (compE2 A)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1AAss2 i i' xs stk loc pc A e v)
note IH2 = ‹⟦call1 i' = ⌊(a, M, vs)⌋; compE2 i ! pc = Invoke M n0⟧ ⟹ ?concl i n i' xs pc stk loc›
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (Val v⌊i'⌉ := e) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (A⌊i⌉ := e) ! (length (compE2 A) + pc) = Invoke M n0›
show ?case
proof(cases "is_val i'")
case False
with bisim2 call have pc: "pc < length (compE2 i)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 i ! pc = Invoke M n0" by(simp)
from IH2 ins' pc False call show ?thesis by(auto dest: bisim1_bisims1.bisim1AAss2)
next
case True
then obtain v where [simp]: "i' = Val v" by auto
from bisim2 have "pc ≤ length (compE2 i)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 i)"
with bisim2 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 i)" by(cases "pc < length (compE2 i)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1AAss3 e e' xs stk loc pc i A v v')
note IH2 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e ! pc = Invoke M n0⟧ ⟹ ?concl e n e' xs pc stk loc›
note bisim3 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (Val v⌊Val v'⌉ := e') = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (i⌊A⌉ := e) ! (length (compE2 i) + length (compE2 A) + pc) = Invoke M n0›
from call bisim3 have pc: "pc < length (compE2 e)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 e ! pc = Invoke M n0" by(simp)
from IH2 ins' pc call show ?case by(auto dest: bisim1_bisims1.bisim1AAss3)
next
case bisim1AAss4 thus ?case by simp
next
case bisim1ALength thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1ALength)
next
case bisim1FAcc thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1FAcc)
next
case (bisim1FAss1 e1 e' xs stk loc pc F D e2)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e1 ! pc = Invoke M n0⟧ ⟹ ?concl e1 n e' xs pc stk loc›
note bisim1 = ‹P,e1,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (e'∙F{D} := e2) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (e1∙F{D} := e2) ! pc = Invoke M n0›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e1)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis
by(auto intro: bisim1_bisims1.bisim1FAss1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e1)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e1)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e1)" by(cases "pc < length (compE2 e1)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1FAss2 e2 e' xs stk loc pc e1 F D v1)
note IH2 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e2 ! pc = Invoke M n0⟧ ⟹ ?concl e2 n e' xs pc stk loc›
note bisim2 = ‹P,e2,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (Val v1∙F{D} := e') = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (e1∙F{D} := e2) ! (length (compE2 e1) + pc) = Invoke M n0›
from call bisim2 have pc: "pc < length (compE2 e2)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 e2 ! pc = Invoke M n0" by(simp)
from IH2 ins' pc call show ?case by(auto dest: bisim1_bisims1.bisim1FAss2)
next
case bisim1FAss3 thus ?case by simp
next
case (bisim1CAS1 e1 e' xs stk loc pc D F e2 E3)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e1 ! pc = Invoke M n0⟧ ⟹ ?concl e1 n e' xs pc stk loc›
note bisim1 = ‹P,e1,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 _ = ⌊(a, M, vs)⌋›
note ins = ‹compE2 _ ! pc = Invoke M n0›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e1)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis by(auto intro: bisim1_bisims1.bisim1CAS1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e1)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e1)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e1)" by(cases "pc < length (compE2 e1)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1CAS2 e2 e2' xs stk loc pc e1 D F e3 v)
note IH2 = ‹⟦call1 e2' = ⌊(a, M, vs)⌋; compE2 e2 ! pc = Invoke M n0⟧ ⟹ ?concl e2 n e2' xs pc stk loc›
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 _ = ⌊(a, M, vs)⌋›
note ins = ‹compE2 _ ! (length (compE2 e1) + pc) = Invoke M n0›
show ?case
proof(cases "is_val e2'")
case False
with bisim2 call have pc: "pc < length (compE2 e2)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 e2 ! pc = Invoke M n0" by(simp)
from IH2 ins' pc False call show ?thesis by(auto dest: bisim1_bisims1.bisim1CAS2)
next
case True
then obtain v where [simp]: "e2' = Val v" by auto
from bisim2 have "pc ≤ length (compE2 e2)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e2)"
with bisim2 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e2)" by(cases "pc < length (compE2 e2)") auto
with ins have False by(simp)
thus ?thesis ..
qed
next
case (bisim1CAS3 e3 e3' xs stk loc pc e1 D F e2 v v')
note IH2 = ‹⟦call1 e3' = ⌊(a, M, vs)⌋; compE2 e3 ! pc = Invoke M n0⟧ ⟹ ?concl e3 n e3' xs pc stk loc›
note bisim3 = ‹P,e3,h ⊢ (e3', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 _ = ⌊(a, M, vs)⌋›
note ins = ‹compE2 _ ! (length (compE2 e1) + length (compE2 e2) + pc) = Invoke M n0›
from call bisim3 have pc: "pc < length (compE2 e3)" by(auto intro: bisim1_call_pcD)
with ins have ins': "compE2 e3 ! pc = Invoke M n0" by(simp)
from IH2 ins' pc call show ?case by(auto dest: bisim1_bisims1.bisim1CAS3)
next
case (bisim1Call1 obj obj' xs stk loc pc M' ps)
note IH1 = ‹⟦call1 obj' = ⌊(a, M, vs)⌋; compE2 obj ! pc = Invoke M n0⟧ ⟹ ?concl obj n obj' xs pc stk loc›
note bisim1 = ‹P,obj,h ⊢ (obj', xs) ↔ (stk, loc, pc, None)›
note call = ‹call1 (obj'∙M'(ps)) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (obj∙M'(ps)) ! pc = Invoke M n0›
show ?case
proof(cases "is_val obj'")
case False
with call bisim1 have "pc < length (compE2 obj)" by(auto intro: bisim1_call_pcD)
with call False ins IH1 False show ?thesis
by(auto intro: bisim1_bisims1.bisim1Call1)
next
case True
then obtain v' where [simp]: "obj' = Val v'" by auto
from bisim1 have "pc ≤ length (compE2 obj)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 obj)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 obj)" by(cases "pc < length (compE2 obj)") auto
with ins have [simp]: "ps = []" "M' = M"
by(auto split: if_split_asm)(auto simp add: neq_Nil_conv)
from ins call have [simp]: "vs = []" by(auto split: if_split_asm)
with bisim1 have [simp]: "stk = [v']" "xs = loc" by(auto dest: bisim1_pc_length_compE2D)
from bisim1Val2[of "length (compE2 (obj∙M([])))" "obj∙M([])" P h v loc] call ins
show ?thesis by(auto simp add: is_val_iff)
qed
next
case (bisim1CallParams ps ps' xs stk loc pc obj M' v')
note IH2 = ‹⟦calls1 ps' = ⌊(a, M, vs)⌋; compEs2 ps ! pc = Invoke M n0⟧ ⟹ ?concls ps n ps' xs pc stk loc›
note bisim = ‹P,ps,h ⊢ (ps', xs) [↔] (stk, loc, pc, None)›
note call = ‹call1 (Val v'∙M'(ps')) = ⌊(a, M, vs)⌋›
note ins = ‹compE2 (obj∙M'(ps)) ! (length (compE2 obj) + pc) = Invoke M n0›
from call show ?case
proof(cases rule: call1_callE)
case CallObj thus ?thesis by simp
next
case (CallParams v'')
hence [simp]: "v'' = v'" and call': "calls1 ps' = ⌊(a, M, vs)⌋" by simp_all
from bisim call' have pc: "pc < length (compEs2 ps)" by(rule bisims1_calls_pcD)
with ins have ins': "compEs2 ps ! pc = Invoke M n0" by(simp)
with IH2 call' ins pc
have "P,ps,h ⊢ (inline_calls (Val v) ps', xs)
[↔] (v # drop (Suc (length vs)) stk, loc, Suc pc, None)"
and len: "Suc (length vs) ≤ length stk" and n0: "n0 = length vs" by auto
hence "P,obj∙M'(ps),h ⊢ (Val v'∙M'(inline_calls (Val v) ps'), xs)
↔ ((v # drop (Suc (length vs)) stk) @ [v'], loc, length (compE2 obj) + Suc pc, None)"
by-(rule bisim1_bisims1.bisim1CallParams)
thus ?thesis using call' len n0 by(auto simp add: is_vals_conv)
next
case Call
hence [simp]: "v' = Addr a" "M' = M" "ps' = map Val vs" by auto
from bisim have "pc ≤ length (compEs2 ps)" by(auto dest: bisims1_pc_length_compEs2)
moreover {
assume pc: "pc < length (compEs2 ps)"
with bisim ins have False by(auto dest: bisims_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compEs2 ps)" by(cases "pc < length (compEs2 ps)") auto
from bisim have [simp]: "stk = rev vs" "xs = loc" by(auto dest: bisims1_Val_length_compEs2D)
hence "P,obj∙M(ps),h ⊢ (Val v, loc) ↔ ([v], loc, length (compE2 (obj∙M(ps))), None)" by-(rule bisim1Val2, simp)
moreover from bisim have "length ps = length ps'" by(rule bisims1_lengthD)
ultimately show ?thesis using ins by(auto)
qed
next
case bisim1BlockSome1 thus ?case by simp
next
case bisim1BlockSome2 thus ?case by simp
next
case bisim1BlockSome4 thus ?case
by(auto intro: bisim1_bisims1.bisim1BlockSome4)
next
case bisim1BlockNone thus ?case
by(auto intro: bisim1_bisims1.bisim1BlockNone)
next
case bisim1Sync1 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1Sync1)
next
case bisim1Sync2 thus ?case by simp
next
case bisim1Sync3 thus ?case by simp
next
case bisim1Sync4 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 bisim1_bisims1.bisim1Sync4)
next
case bisim1Sync5 thus ?case by simp
next
case bisim1Sync6 thus ?case by simp
next
case bisim1Sync7 thus ?case by simp
next
case bisim1Sync8 thus ?case by simp
next
case bisim1Sync9 thus ?case by simp
next
case bisim1InSync thus ?case by(simp)
next
case bisim1Seq1 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1Seq1)
next
case bisim1Seq2 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2)(fastforce dest: bisim1_bisims1.bisim1Seq2)
next
case bisim1Cond1 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1Cond1)
next
case (bisim1CondThen e1 stk loc pc e e2 e' xs) thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2)
(fastforce dest: bisim1_bisims1.bisim1CondThen[where e=e and ?e2.0=e2])
next
case (bisim1CondElse e2 stk loc pc e e1 e' xs) thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2)
(fastforce dest: bisim1_bisims1.bisim1CondElse[where e=e and ?e1.0=e1])
next
case bisim1While1 thus ?case by simp
next
case bisim1While3 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1While3)
next
case bisim1While4 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2)(fastforce dest: bisim1_bisims1.bisim1While4)
next
case bisim1While6 thus ?case by simp
next
case bisim1While7 thus ?case by simp
next
case bisim1Throw1 thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1Throw1)
next
case bisim1Try thus ?case
by(auto split: if_split_asm dest: bisim1_pc_length_compE2 intro: bisim1_bisims1.bisim1Try)
next
case bisim1TryCatch1 thus ?case by simp
next
case bisim1TryCatch2 thus ?case
by(fastforce dest: bisim1_bisims1.bisim1TryCatch2)
next
case bisims1Nil thus ?case by simp
next
case (bisims1List1 e e' xs stk loc pc es)
note IH1 = ‹⟦call1 e' = ⌊(a, M, vs)⌋; compE2 e ! pc = Invoke M n0⟧ ⟹ ?concl e n e' xs pc stk loc›
note bisim1 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, None)›
note call = ‹calls1 (e' # es) = ⌊(a, M, vs)⌋›
note ins = ‹compEs2 (e # es) ! pc = Invoke M n0›
show ?case
proof(cases "is_val e'")
case False
with bisim1 call have "pc < length (compE2 e)" by(auto intro: bisim1_call_pcD)
with call ins False IH1 show ?thesis
by(auto intro: bisim1_bisims1.bisims1List1)
next
case True
then obtain v where [simp]: "e' = Val v" by auto
from bisim1 have "pc ≤ length (compE2 e)" by(auto dest: bisim1_pc_length_compE2)
moreover {
assume pc: "pc < length (compE2 e)"
with bisim1 ins have False by(auto dest: bisim_Val_pc_not_Invoke) }
ultimately have [simp]: "pc = length (compE2 e)" by(cases "pc < length (compE2 e)") auto
with ins call have False by(cases es)(auto)
thus ?thesis ..
qed
next
case (bisims1List2 es es' xs stk loc pc e v')
note IH = ‹⟦calls1 es' = ⌊(a, M, vs)⌋; compEs2 es ! pc = Invoke M n0⟧ ⟹ ?concls es n es' xs pc stk loc›
note call = ‹calls1 (Val v' # es') = ⌊(a, M, vs)⌋›
note bisim = ‹P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, None)›
note ins = ‹compEs2 (e # es) ! (length (compE2 e) + pc) = Invoke M n0›
from call have call': "calls1 es' = ⌊(a, M, vs)⌋" by simp
with bisim have pc: "pc < length (compEs2 es)" by(rule bisims1_calls_pcD)
with ins have ins': "compEs2 es ! pc = Invoke M n0" by(simp)
from IH call ins pc show ?case
by(auto split: if_split_asm dest: bisim1_bisims1.bisims1List2)
qed
lemma bisim1_fv: "P,e,h ⊢ (e', xs) ↔ s ⟹ fv e' ⊆ fv e"
and bisims1_fvs: "P,es,h ⊢ (es', xs) [↔] s ⟹ fvs es' ⊆ fvs es"
apply(induct "(e', xs)" s and "(es', xs)" s arbitrary: e' xs and es' xs rule: bisim1_bisims1.inducts)
apply(auto)
done
lemma bisim1_syncvars: "⟦ P,e,h ⊢ (e', xs) ↔ s; syncvars e ⟧ ⟹ syncvars e'"
and : "⟦ P,es,h ⊢ (es', xs) [↔] s; syncvarss es ⟧ ⟹ syncvarss es'"
apply(induct "(e', xs)" s and "(es', xs)" s arbitrary: e' xs and es' xs rule: bisim1_bisims1.inducts)
apply(auto dest: bisim1_fv)
done
declare pcs_stack_xlift [simp]
lemma bisim1_Val_τred1r:
"⟦ P, E, h ⊢ (e, xs) ↔ ([v], loc, length (compE2 E), None); n + max_vars e ≤ length xs; ℬ E n ⟧
⟹ τred1r P t h (e, xs) (Val v, loc)"
and bisims1_Val_τReds1r:
"⟦ P, Es, h ⊢ (es, xs) [↔] (rev vs, loc, length (compEs2 Es), None); n + max_varss es ≤ length xs; ℬs Es n ⟧
⟹ τreds1r P t h (es, xs) (map Val vs, loc)"
proof(induct E n e xs stk≡"[v]" loc pc≡"length (compE2 E)" xcp≡"None::'addr option"
and Es n es xs stk≡"rev vs" loc pc≡"length (compEs2 Es)" xcp≡"None::'addr option"
arbitrary: v and vs rule: bisim1_bisims1_inducts_split)
case bisim1BlockSome2 thus ?case by(simp (no_asm_use))
next
case (bisim1BlockSome4 e n e' xs loc pc V T val)
from ‹ℬ {V:T=⌊val⌋; e} n› have [simp]: "n = V" and "ℬ e (Suc n)" by auto
note len = ‹n + max_vars {V:T=None; e'} ≤ length xs›
hence V: "V < length xs" by simp
from ‹P,e,h ⊢ (e', xs) ↔ ([v], loc, pc, None)›
have lenxs: "length xs = length loc" by(auto dest: bisim1_length_xs)
note IH = ‹⟦pc = length (compE2 e); Suc n + max_vars e' ≤ length xs; ℬ e (Suc n)⟧
⟹ τred1r P t h (e', xs) (Val v, loc)›
with len ‹Suc (Suc pc) = length (compE2 {V:T=⌊val⌋; e})› ‹ℬ e (Suc n)›
have "τred1r P t h (e', xs) (Val v, loc)" by(simp)
hence "τred1r P t h ({V:T=None; e'}, xs) ({V:T=None; Val v}, loc)"
by(rule Block_None_τred1r_xt)
thus ?case using V lenxs by(auto elim!: rtranclp.rtrancl_into_rtrancl intro: Red1Block τmove1BlockRed)
next
case (bisim1BlockNone e n e' xs loc V T)
from ‹ℬ {V:T=None; e} n› have [simp]: "n = V" and "ℬ e (Suc n)" by auto
note len = ‹n + max_vars {V:T=None; e'} ≤ length xs›
hence V: "V < length xs" by simp
from ‹P,e,h ⊢ (e', xs) ↔ ([v], loc, length (compE2 {V:T=None; e}), None)›
have lenxs: "length xs = length loc" by(auto dest: bisim1_length_xs)
note IH = ‹⟦length (compE2 {V:T=None; e}) = length (compE2 e); Suc n + max_vars e' ≤ length xs; ℬ e (Suc n) ⟧
⟹ τred1r P t h (e', xs) (Val v, loc)›
with len ‹ℬ e (Suc n)› have "τred1r P t h (e', xs) (Val v, loc)" by(simp)
hence "τred1r P t h ({V:T=None; e'}, xs) ({V:T=None; Val v}, loc)"
by(rule Block_None_τred1r_xt)
thus ?case using V lenxs by(auto elim!: rtranclp.rtrancl_into_rtrancl intro: Red1Block τmove1BlockRed)
next
case (bisim1TryCatch2 e2 n e' xs loc pc e C V)
from ‹ℬ (try e catch(C V) e2) n› have [simp]: "n = V" and "ℬ e2 (Suc n)" by auto
note len = ‹n + max_vars {V:Class C=None; e'} ≤ length xs›
hence V: "V < length xs" by simp
from ‹P,e2,h ⊢ (e', xs) ↔ ([v], loc, pc, None)›
have lenxs: "length xs = length loc" by(auto dest: bisim1_length_xs)
note IH = ‹⟦pc = length (compE2 e2); Suc n + max_vars e' ≤ length xs; ℬ e2 (Suc n)⟧
⟹ τred1r P t h (e', xs) (Val v, loc)›
with len ‹Suc (Suc (length (compE2 e) + pc)) = length (compE2 (try e catch(C V) e2))› ‹ℬ e2 (Suc n)›
have "τred1r P t h (e', xs) (Val v, loc)" by(simp)
hence "τred1r P t h ({V:Class C=None; e'}, xs) ({V:Class C=None; Val v}, loc)"
by(rule Block_None_τred1r_xt)
thus ?case using V lenxs by(auto elim!: rtranclp.rtrancl_into_rtrancl intro: Red1Block τmove1BlockRed)
next
case (bisims1List1 e n e' xs loc es)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (rev vs, loc, length (compEs2 (e # es)), None)›
then have es: "es = []" and pc: "length (compEs2 (e # es)) = length (compE2 e)"
by(auto dest: bisim1_pc_length_compE2)
with bisim obtain val where stk: "rev vs = [val]" and e': "is_val e' ⟹ e' = Val val"
by(auto dest: bisim1_pc_length_compE2D)
with es pc bisims1List1 have "τred1r P t h (e', xs) (Val val, loc)" by simp
with stk es show ?case by(auto intro: τred1r_inj_τreds1r)
next
case (bisims1List2 es n es' xs stk loc pc e v)
from ‹stk @ [v] = rev vs› obtain vs' where vs: "vs = v # vs'" by(cases vs) auto
with bisims1List2 show ?case by(auto intro: τreds1r_cons_τreds1r)
qed(fastforce dest: bisim1_pc_length_compE2 bisims1_pc_length_compEs2)+
lemma exec_meth_stk_split:
"⟦ P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, xcp);
exec_meth_d (compP2 P) (compE2 E) (stack_xlift (length STK) (compxE2 E 0 0)) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp') ⟧
⟹ ∃stk''. stk' = stk'' @ STK ∧ exec_meth_d (compP2 P) (compE2 E) (compxE2 E 0 0) t
h (stk, loc, pc, xcp) ta h' (stk'', loc', pc', xcp')"
(is "⟦ _; ?exec E stk STK loc pc xcp stk' loc' pc' xcp' ⟧ ⟹ ?concl E stk STK loc pc xcp stk' loc' pc' xcp'")
and exec_meth_stk_splits:
"⟦ P,Es,h ⊢ (es,xs) [↔] (stk,loc,pc,xcp);
exec_meth_d (compP2 P) (compEs2 Es) (stack_xlift (length STK) (compxEs2 Es 0 0)) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp') ⟧
⟹ ∃stk''. stk' = stk'' @ STK ∧ exec_meth_d (compP2 P) (compEs2 Es) (compxEs2 Es 0 0) t
h (stk, loc, pc, xcp) ta h' (stk'', loc', pc', xcp')"
(is "⟦ _; ?execs Es stk STK loc pc xcp stk' loc' pc' xcp' ⟧ ⟹ ?concls Es stk STK loc pc xcp stk' loc' pc' xcp'")
proof(induct E "n :: nat" e xs stk loc pc xcp and Es "n :: nat" es xs stk loc pc xcp
arbitrary: stk' loc' pc' xcp' STK and stk' loc' pc' xcp' STK rule: bisim1_bisims1_inducts_split)
case bisim1InSync thus ?case by(auto elim!: exec_meth.cases intro!: exec_meth.intros)
next
case bisim1Val2 thus ?case by(auto dest: exec_meth_length_compE2_stack_xliftD)
next
case bisim1New thus ?case
by (fastforce elim: exec_meth.cases intro: exec_meth.intros split: if_split_asm cong del: image_cong_simp)
next
case bisim1NewThrow thus ?case by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1NewArray e n e' xs stk loc pc xcp T)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (newA T⌊e⌉) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
with bisim obtain v where [simp]: "stk = [v]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec show ?thesis
apply simp
apply (erule exec_meth.cases)
apply (auto 4 4 intro: exec_meth.intros split: if_split_asm cong del: image_cong_simp)
done
qed
next
case (bisim1NewArrayThrow e n a xs stk loc pc T)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (newA T⌊e⌉) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp)(erule exec_meth_take[OF _ pc])
from IH[OF this] show ?case by(auto)
next
case bisim1NewArrayFail thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1Cast e n e' xs stk loc pc xcp T)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (Cast T e) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
with bisim obtain v where [simp]: "stk = [v]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec show ?thesis apply(simp)
by(erule exec_meth.cases)(auto intro!: exec_meth.intros split: if_split_asm)
qed
next
case (bisim1CastThrow e n a xs stk loc pc T)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (Cast T e) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp)(erule exec_meth_take[OF _ pc])
from IH[OF this] show ?case by(auto)
next
case bisim1CastFail thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1InstanceOf e n e' xs stk loc pc xcp T)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (e instanceof T) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
with bisim obtain v where [simp]: "stk = [v]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec show ?thesis apply(simp)
by(erule exec_meth.cases)(auto intro!: exec_meth.intros split: if_split_asm)
qed
next
case (bisim1InstanceOfThrow e n a xs stk loc pc T)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e instanceof T) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp)(erule exec_meth_take[OF _ pc])
from IH[OF this] show ?case by(auto)
next
case bisim1Val thus ?case by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case bisim1Var thus ?case by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1BinOp1 e1 n e1' xs stk loc pc xcp e2 bop)
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc xcp stk' loc' pc' xcp'›
note IH2 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec e2 [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl e2 [] STK xs 0 None stk' loc' pc' xcp'›
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹P,e2,h ⊢ (e2, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec (e1 «bop» e2) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 e1)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e1)")
case True
with exec have "?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take_xt)
from IH1[OF this] show ?thesis by auto
next
case False
with pc have pc: "pc = length (compE2 e1)" by simp
with exec have "pc' ≥ length (compE2 e1)"
by(simp add: compxE2_size_convs stack_xlift_compxE2)(auto split: bop.splits elim!: exec_meth_drop_xt_pc)
then obtain PC where PC: "pc' = PC + length (compE2 e1)"
by -(rule_tac PC34="pc' - length (compE2 e1)" in that, simp)
from pc bisim1 obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec pc have "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2)
(stack_xlift (length STK) (compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0))) t h (stk @ STK, loc, length (compE2 e1) + 0, xcp) ta h' (stk', loc', pc', xcp')"
by-(rule exec_meth_take, auto)
hence "?exec e2 [] (v # STK) loc 0 None stk' loc' (pc' - length (compE2 e1)) xcp'"
using ‹stk = [v]› ‹xcp = None›
by -(rule exec_meth_drop_xt, auto simp add: stack_xlift_compxE2 shift_compxE2)
from IH2[OF this] PC obtain stk'' where stk': "stk' = stk'' @ v # STK"
and "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ [BinOpInstr bop])
(compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v]) (compxE2 e2 0 0))) t h
([] @ [v], loc, length (compE2 e1) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 e1) + PC, xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by(auto)
thus ?thesis using ‹stk = [v]› ‹xcp = None› stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1BinOp2 e2 n e2' xs stk loc pc xcp e1 bop v1)
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim1 = ‹P,e1,h ⊢ (e1, xs) ↔ ([], xs, 0, None)›
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec (e1 «bop» e2) (stk @ [v1]) STK loc (length (compE2 e1) + pc) xcp stk' loc' pc' xcp'›
from bisim2 have pc: "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e2)")
case True
from exec have "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ [BinOpInstr bop])
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e1) + pc, xcp) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2) (stack_xlift (length STK) (compxE2 e1 0 0) @
shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e1) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: True)
hence "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, xcp) ta h' (stk', loc', pc' - length (compE2 e1), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec e2 stk (v1 # STK) loc pc xcp stk' loc' (pc' - length (compE2 e1)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 e1), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length [v1]) (compxE2 e2 0 0)) t h (stk @ [v1], loc, pc, xcp)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 e1), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e1) + pc, xcp)
ta h' (stk'' @ [v1], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ [BinOpInstr bop]) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e1) + pc, xcp)
ta h' (stk'' @ [v1], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length (compE2 e1)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk' by(simp add: stack_xlift_compxE2 shift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 e2)" by simp
with bisim2 obtain v2 where [simp]: "stk = [v2]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec pc show ?thesis
by(fastforce elim: exec_meth.cases split: sum.split_asm intro!: exec_meth.intros)
qed
next
case (bisim1BinOpThrow1 e1 n a xs stk loc pc e2 bop)
note bisim1 = ‹P,e1,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e1 «bop» e2) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim1 have pc: "pc < length (compE2 e1)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 e1 @ (compE2 e2 @ [BinOpInstr bop]))
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence "?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule pc)
from IH1[OF this] show ?case by(auto)
next
case (bisim1BinOpThrow2 e2 n a xs stk loc pc e1 bop v1)
note bisim2 = ‹P,e2,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e1 «bop» e2) (stk @ [v1]) STK loc (length (compE2 e1) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim2 have pc: "pc < length (compE2 e2)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ [BinOpInstr bop])
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0))))
t h (stk @ v1 # STK, loc, length (compE2 e1) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2)
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e1) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: pc)
hence "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc' - length (compE2 e1), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec e2 stk (v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 e1)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 e1), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length [v1]) (compxE2 e2 0 0)) t h (stk @ [v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 e1), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e1) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ [BinOpInstr bop]) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e1) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
by(rule exec_meth_append)
moreover from exec' have pc': "pc' ≥ length (compE2 e1)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case bisim1BinOpThrow thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1LAss1 e n e' xs stk loc pc xcp V)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (V := e) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
with bisim obtain v where [simp]: "stk = [v]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec show ?thesis apply(simp)
by(erule exec_meth.cases)(auto intro!: exec_meth.intros)
qed
next
case (bisim1LAss2 e n xs V)
thus ?case by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1LAssThrow e n a xs stk loc pc V)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (V := e) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp)(erule exec_meth_take[OF _ pc])
from IH[OF this] show ?case by(auto)
next
case (bisim1AAcc1 a n a' xs stk loc pc xcp i)
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec a stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl a stk STK loc pc xcp stk' loc' pc' xcp'›
note IH2 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec i [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl i [] STK xs 0 None stk' loc' pc' xcp'›
note bisim1 = ‹P,a,h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹P,i,h ⊢ (i, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec (a⌊i⌉) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 a)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 a)")
case True
with exec have "?exec a stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take_xt)
from IH1[OF this] show ?thesis by auto
next
case False
with pc have pc: "pc = length (compE2 a)" by simp
with exec have "pc' ≥ length (compE2 a)"
by(simp add: compxE2_size_convs stack_xlift_compxE2)(auto elim!: exec_meth_drop_xt_pc)
then obtain PC where PC: "pc' = PC + length (compE2 a)"
by -(rule_tac PC34="pc' - length (compE2 a)" in that, simp)
from pc bisim1 obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec pc have "exec_meth_d (compP2 P) (compE2 a @ compE2 i)
(stack_xlift (length STK) (compxE2 a 0 0 @ compxE2 i (length (compE2 a)) (Suc 0))) t h (stk @ STK, loc, length (compE2 a) + 0, xcp) ta h' (stk', loc', pc', xcp')"
by-(rule exec_meth_take, auto)
hence "?exec i [] (v # STK) loc 0 None stk' loc' (pc' - length (compE2 a)) xcp'"
using ‹stk = [v]› ‹xcp = None›
by -(rule exec_meth_drop_xt, auto simp add: stack_xlift_compxE2 shift_compxE2)
from IH2[OF this] PC obtain stk'' where stk': "stk' = stk'' @ v # STK"
and "exec_meth_d (compP2 P) (compE2 i) (compxE2 i 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ [ALoad])
(compxE2 a 0 0 @ shift (length (compE2 a)) (stack_xlift (length [v]) (compxE2 i 0 0))) t h
([] @ [v], loc, length (compE2 a) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 a) + PC, xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by(auto)
thus ?thesis using ‹stk = [v]› ‹xcp = None› stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1AAcc2 i n i' xs stk loc pc xcp a v1)
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec i stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl i stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec (a⌊i⌉) (stk @ [v1]) STK loc (length (compE2 a) + pc) xcp stk' loc' pc' xcp'›
from bisim2 have pc: "pc ≤ length (compE2 i)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 i)")
case True
from exec have "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ [ALoad])
(stack_xlift (length STK) (compxE2 a 0 0) @ shift (length (compE2 a)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 a) + pc, xcp) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 a @ compE2 i) (stack_xlift (length STK) (compxE2 a 0 0) @
shift (length (compE2 a)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 a) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: True)
hence "exec_meth_d (compP2 P) (compE2 i) (stack_xlift (length STK) (compxE2 i 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, xcp) ta h' (stk', loc', pc' - length (compE2 a), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec i stk (v1 # STK) loc pc xcp stk' loc' (pc' - length (compE2 a)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK"
and exec'': "exec_meth_d (compP2 P) (compE2 i) (compxE2 i 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 a), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 i) (stack_xlift (length [v1]) (compxE2 i 0 0)) t h (stk @ [v1], loc, pc, xcp)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 a), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 a @ compE2 i) (compxE2 a 0 0 @ shift (length (compE2 a)) (stack_xlift (length [v1]) (compxE2 i 0 0))) t h (stk @ [v1], loc, length (compE2 a) + pc, xcp)
ta h' (stk'' @ [v1], loc', length (compE2 a) + (pc' - length (compE2 a)), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ [ALoad]) (compxE2 a 0 0 @ shift (length (compE2 a)) (stack_xlift (length [v1]) (compxE2 i 0 0))) t h (stk @ [v1], loc, length (compE2 a) + pc, xcp)
ta h' (stk'' @ [v1], loc', length (compE2 a) + (pc' - length (compE2 a)), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length (compE2 a)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk' by(simp add: stack_xlift_compxE2 shift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 i)" by simp
with bisim2 obtain v2 where [simp]: "stk = [v2]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec pc show ?thesis
by(clarsimp)(erule exec_meth.cases, auto intro!: exec_meth.intros split: if_split_asm)
qed
next
case (bisim1AAccThrow1 A n a xs stk loc pc i)
note bisim1 = ‹P,A,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec A stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl A stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (A⌊i⌉) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim1 have pc: "pc < length (compE2 A)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 A @ (compE2 i @ [ALoad]))
(stack_xlift (length STK) (compxE2 A 0 0) @ shift (length (compE2 A)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence "?exec A stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'" by(rule exec_meth_take_xt)(rule pc)
from IH1[OF this] show ?case by(auto)
next
case (bisim1AAccThrow2 i n a xs stk loc pc A v1)
note bisim2 = ‹P,i,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec i stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl i stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (A⌊i⌉) (stk @ [v1]) STK loc (length (compE2 A) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim2 have pc: "pc < length (compE2 i)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) ((compE2 A @ compE2 i) @ [ALoad])
(stack_xlift (length STK) (compxE2 A 0 0) @ shift (length (compE2 A)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 A) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 A @ compE2 i)
(stack_xlift (length STK) (compxE2 A 0 0) @ shift (length (compE2 A)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 A) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: pc)
hence "exec_meth_d (compP2 P) (compE2 i) (stack_xlift (length STK) (compxE2 i 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc' - length (compE2 A), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec i stk (v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 A)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 i) (compxE2 i 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 A), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 i) (stack_xlift (length [v1]) (compxE2 i 0 0)) t h (stk @ [v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 A), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 A @ compE2 i) (compxE2 A 0 0 @ shift (length (compE2 A)) (stack_xlift (length [v1]) (compxE2 i 0 0))) t h (stk @ [v1], loc, length (compE2 A) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 A) + (pc' - length (compE2 A)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) ((compE2 A @ compE2 i) @ [ALoad]) (compxE2 A 0 0 @ shift (length (compE2 A)) (stack_xlift (length [v1]) (compxE2 i 0 0))) t h (stk @ [v1], loc, length (compE2 A) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 A) + (pc' - length (compE2 A)), xcp')"
by(rule exec_meth_append)
moreover from exec' have pc': "pc' ≥ length (compE2 A)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case bisim1AAccFail thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1AAss1 a n a' xs stk loc pc xcp i e)
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec a stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl a stk STK loc pc xcp stk' loc' pc' xcp'›
note IH2 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec i [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl i [] STK xs 0 None stk' loc' pc' xcp'›
note bisim1 = ‹P,a,h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹P,i,h ⊢ (i, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec (a⌊i⌉ := e) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 a)" by(rule bisim1_pc_length_compE2)
from exec have exec': "exec_meth_d (compP2 P) (compE2 a @ compE2 i @ compE2 e @ [AStore, Push Unit]) (stack_xlift (length STK) (compxE2 a 0 0) @ shift (length (compE2 a)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0) @ compxE2 e (length (compE2 i)) (Suc (Suc 0))))) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
show ?case
proof(cases "pc < length (compE2 a)")
case True
with exec' have "?exec a stk STK loc pc xcp stk' loc' pc' xcp'" by(rule exec_meth_take_xt)
from IH1[OF this] show ?thesis by auto
next
case False
with pc have pc: "pc = length (compE2 a)" by simp
with exec' have "pc' ≥ length (compE2 a)" by -(erule exec_meth_drop_xt_pc, auto)
then obtain PC where PC: "pc' = PC + length (compE2 a)"
by -(rule_tac PC34="pc' - length (compE2 a)" in that, simp)
from pc bisim1 obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec PC pc
have "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ compE2 e @ [AStore, Push Unit]) (stack_xlift (length STK) (compxE2 a 0 0 @ shift (length (compE2 a)) (compxE2 i 0 (Suc 0))) @ shift (length (compE2 a @ compE2 i)) (compxE2 e 0 (length STK + Suc (Suc 0)))) t
h (v # STK, loc, length (compE2 a) + 0, None) ta h' (stk', loc', length (compE2 a) + PC, xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence "exec_meth_d (compP2 P) (compE2 a @ compE2 i)
(stack_xlift (length STK) (compxE2 a 0 0 @ shift (length (compE2 a)) (compxE2 i 0 (Suc 0)))) t h (v # STK, loc, length (compE2 a) + 0, None) ta h' (stk', loc', length (compE2 a) + PC, xcp')"
by(rule exec_meth_take_xt) simp
hence "?exec i [] (v # STK) loc 0 None stk' loc' ((length (compE2 a) + PC) - length (compE2 a)) xcp'"
by -(rule exec_meth_drop_xt, auto simp add: stack_xlift_compxE2 shift_compxE2)
from IH2[OF this] PC obtain stk'' where stk': "stk' = stk'' @ v # STK"
and "exec_meth_d (compP2 P) (compE2 i) (compxE2 i 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ (compE2 e @ [AStore, Push Unit]))
((compxE2 a 0 0 @ shift (length (compE2 a)) (stack_xlift (length [v]) (compxE2 i 0 0))) @
shift (length (compE2 a @ compE2 i)) (compxE2 e 0 (Suc (Suc 0)))) t h
([] @ [v], loc, length (compE2 a) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 a) + PC, xcp')"
apply -
apply(rule exec_meth_append_xt)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by(auto)
thus ?thesis using ‹stk = [v]› ‹xcp = None› stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1AAss2 i n i' xs stk loc pc xcp a e v)
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec i stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl i stk STK loc pc xcp stk' loc' pc' xcp'›
note IH3 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec e [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl e [] STK xs 0 None stk' loc' pc' xcp'›
note bisim2 = ‹P,i,h ⊢ (i', xs) ↔ (stk, loc, pc, xcp)›
note bisim3 = ‹P,e,h ⊢ (e, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec (a⌊i⌉ := e) (stk @ [v]) STK loc (length (compE2 a) + pc) xcp stk' loc' pc' xcp'›
from bisim2 have pc: "pc ≤ length (compE2 i)" by(rule bisim1_pc_length_compE2)
from exec have exec': "⋀v'. exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ compE2 e @ [AStore, Push Unit]) ((compxE2 a 0 (length STK) @ shift (length (compE2 a)) (stack_xlift (length (v # STK)) (compxE2 i 0 0))) @ shift (length (compE2 a @ compE2 i)) (stack_xlift (length (v' # v # STK)) (compxE2 e 0 0))) t
h (stk @ v # STK, loc, length (compE2 a) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2)
show ?case
proof(cases "pc < length (compE2 i)")
case True with exec'[of arbitrary]
have exec'': "exec_meth_d (compP2 P) (compE2 a @ compE2 i) (compxE2 a 0 (length STK) @ shift (length (compE2 a)) (stack_xlift (length (v # STK)) (compxE2 i 0 0))) t h (stk @ v # STK, loc, length (compE2 a) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by-(erule exec_meth_take_xt, simp)
hence "?exec i stk (v # STK) loc pc xcp stk' loc' (pc' - length (compE2 a)) xcp'"
by(rule exec_meth_drop_xt) auto
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec''': "exec_meth_d (compP2 P) (compE2 i) (compxE2 i 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 a), xcp')" by blast
from exec''' have "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ compE2 e @ [AStore, Push Unit]) ((compxE2 a 0 0 @ shift (length (compE2 a)) (stack_xlift (length [v]) (compxE2 i 0 0))) @ shift (length (compE2 a @ compE2 i)) (compxE2 e 0 (Suc (Suc 0)))) t h (stk @ [v], loc, length (compE2 a) + pc, xcp) ta h' (stk'' @ [v], loc', length (compE2 a) + (pc' - length (compE2 a)), xcp')"
apply -
apply(rule exec_meth_append_xt)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by auto
moreover from exec'' have "pc' ≥ length (compE2 a)"
by(rule exec_meth_drop_xt_pc) auto
ultimately show ?thesis using stk' by(auto simp add: shift_compxE2 stack_xlift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 i)" by simp
with exec'[of arbitrary] have "pc' ≥ length (compE2 a @ compE2 i)"
by-(erule exec_meth_drop_xt_pc, auto simp add: shift_compxE2 stack_xlift_compxE2)
then obtain PC where PC: "pc' = PC + length (compE2 a) + length (compE2 i)"
by -(rule_tac PC34="pc' - length (compE2 a @ compE2 i)" in that, simp)
from pc bisim2 obtain v' where stk: "stk = [v']" and xcp: "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
from exec'[of v']
have "exec_meth_d (compP2 P) (compE2 e @ [AStore, Push Unit]) (stack_xlift (length (v' # v # STK)) (compxE2 e 0 0)) t
h (v' # v # STK, loc, 0, xcp) ta h' (stk', loc', pc' - length (compE2 a @ compE2 i), xcp')"
unfolding stk pc append_Cons append_Nil
by -(rule exec_meth_drop_xt, simp only: add_0_right length_append, auto simp add: shift_compxE2 stack_xlift_compxE2)
with PC xcp have "?exec e [] (v' # v # STK) loc 0 None stk' loc' PC xcp'"
by -(rule exec_meth_take,auto)
from IH3[OF this] obtain stk'' where stk': "stk' = stk'' @ v' # v # STK"
and "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) (((compE2 a @ compE2 i) @ compE2 e) @ [AStore, Push Unit]) ((compxE2 a 0 0 @ compxE2 i (length (compE2 a)) (Suc 0)) @ shift (length (compE2 a @ compE2 i)) (stack_xlift (length [v', v]) (compxE2 e 0 0))) t h ([] @ [v', v], loc, length (compE2 a @ compE2 i) + 0, None) ta h' (stk'' @ [v', v], loc', length (compE2 a @ compE2 i) + PC, xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by auto
thus ?thesis using stk xcp stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1AAss3 e n e' xs stk loc pc xcp a i v1 v2)
note IH3 = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim3 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec (a⌊i⌉ := e) (stk @ [v2, v1]) STK loc (length (compE2 a) + length (compE2 i) + pc) xcp stk' loc' pc' xcp'›
from bisim3 have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
from exec have "exec_meth_d (compP2 P) (((compE2 a @ compE2 i) @ compE2 e) @ [AStore, Push Unit])
((compxE2 a 0 (length STK) @ compxE2 i (length (compE2 a)) (Suc (length STK))) @ shift (length (compE2 a @ compE2 i)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 a @ compE2 i) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2)
hence exec': "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ compE2 e)
((compxE2 a 0 (length STK) @ compxE2 i (length (compE2 a)) (Suc (length STK))) @ shift (length (compE2 a @ compE2 i)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 a @ compE2 i) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: True)
hence "?exec e stk (v2 # v1 # STK) loc pc xcp stk' loc' (pc' - length (compE2 a @ compE2 i)) xcp'"
by(rule exec_meth_drop_xt) auto
from IH3[OF this] obtain stk'' where stk': "stk' = stk'' @ v2 # v1 # STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 a @ compE2 i), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e) (stack_xlift (length [v2, v1]) (compxE2 e 0 0)) t h (stk @ [v2, v1], loc, pc, xcp)
ta h' (stk'' @ [v2, v1], loc', pc' - length (compE2 a @ compE2 i), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) ((compE2 a @ compE2 i) @ compE2 e) ((compxE2 a 0 0 @ compxE2 i (length (compE2 a)) (Suc 0)) @ shift (length (compE2 a @ compE2 i)) (stack_xlift (length [v2, v1]) (compxE2 e 0 0))) t
h (stk @ [v2, v1], loc, length (compE2 a @ compE2 i) + pc, xcp)
ta h' (stk'' @ [v2, v1], loc', length (compE2 a @ compE2 i) + (pc' - length (compE2 a @ compE2 i)), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) (((compE2 a @ compE2 i) @ compE2 e) @ [AStore, Push Unit]) ((compxE2 a 0 0 @ compxE2 i (length (compE2 a)) (Suc 0)) @ shift (length (compE2 a @ compE2 i)) (stack_xlift (length [v2, v1]) (compxE2 e 0 0))) t
h (stk @ [v2, v1], loc, length (compE2 a @ compE2 i) + pc, xcp)
ta h' (stk'' @ [v2, v1], loc', length (compE2 a @ compE2 i) + (pc' - length (compE2 a @ compE2 i)), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length (compE2 a @ compE2 i)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk' by(simp add: stack_xlift_compxE2 shift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 e)" by simp
with bisim3 obtain v3 where [simp]: "stk = [v3]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec pc show ?thesis apply(simp)
by(erule exec_meth.cases)(auto intro!: exec_meth.intros split: if_split_asm)
qed
next
case (bisim1AAssThrow1 A n a xs stk loc pc i e)
note bisim1 = ‹P,A,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec A stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl A stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (A⌊i⌉ := e) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim1 have pc: "pc < length (compE2 A)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 A @ (compE2 i @ compE2 e @ [AStore, Push Unit]))
(stack_xlift (length STK) (compxE2 A 0 0) @ shift (length (compE2 A)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0) @ compxE2 e (length (compE2 i)) (Suc (Suc 0))))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence "?exec A stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'" by(rule exec_meth_take_xt)(rule pc)
from IH1[OF this] show ?case by(auto)
next
case (bisim1AAssThrow2 i n a xs stk loc pc A e v1)
note bisim2 = ‹P,i,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec i stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl i stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (A⌊i⌉ := e) (stk @ [v1]) STK loc (length (compE2 A) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim2 have pc: "pc < length (compE2 i)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) ((compE2 A @ compE2 i) @ compE2 e @ [AStore, Push Unit])
((stack_xlift (length STK) (compxE2 A 0 0) @ shift (length (compE2 A)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) @ (shift (length (compE2 A @ compE2 i)) (compxE2 e 0 (Suc (Suc (length STK)))))) t
h (stk @ v1 # STK, loc, length (compE2 A) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence exec': "exec_meth_d (compP2 P) (compE2 A @ compE2 i)
(stack_xlift (length STK) (compxE2 A 0 0) @ shift (length (compE2 A)) (stack_xlift (length STK) (compxE2 i 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 A) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take_xt)(simp add: pc)
hence "exec_meth_d (compP2 P) (compE2 i) (stack_xlift (length STK) (compxE2 i 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc' - length (compE2 A), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec i stk (v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 A)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 i) (compxE2 i 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 A), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 i) (stack_xlift (length [v1]) (compxE2 i 0 0)) t
h (stk @ [v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 A), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 A @ compE2 i) (compxE2 A 0 0 @ shift (length (compE2 A)) (stack_xlift (length [v1]) (compxE2 i 0 0))) t
h (stk @ [v1], loc, length (compE2 A) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 A) + (pc' - length (compE2 A)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) ((compE2 A @ compE2 i) @ compE2 e @ [AStore, Push Unit]) ((compxE2 A 0 0 @ shift (length (compE2 A)) (stack_xlift (length [v1]) (compxE2 i 0 0))) @ (shift (length (compE2 A @ compE2 i)) (compxE2 e 0 (Suc (Suc 0))))) t
h (stk @ [v1], loc, length (compE2 A) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 A) + (pc' - length (compE2 A)), xcp')"
by(rule exec_meth_append_xt)
moreover from exec' have pc': "pc' ≥ length (compE2 A)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case (bisim1AAssThrow3 e n a xs stk loc pc A i v2 v1)
note bisim3 = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH3 = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (A⌊i⌉ := e) (stk @ [v2, v1]) STK loc (length (compE2 A) + length (compE2 i) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim3 have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (((compE2 A @ compE2 i) @ compE2 e) @ [AStore, Push Unit])
((stack_xlift (length STK) (compxE2 A 0 0 @ compxE2 i (length (compE2 A)) (Suc 0))) @ shift (length (compE2 A @ compE2 i)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 A @ compE2 i) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence exec': "exec_meth_d (compP2 P) ((compE2 A @ compE2 i) @ compE2 e)
((stack_xlift (length STK) (compxE2 A 0 0 @ compxE2 i (length (compE2 A)) (Suc 0))) @ shift (length (compE2 A @ compE2 i)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 A @ compE2 i) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: pc)
hence "?exec e stk (v2 # v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 A @ compE2 i)) xcp'"
by(rule exec_meth_drop_xt) auto
from IH3[OF this] obtain stk'' where stk': "stk' = stk'' @ v2 # v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 A @ compE2 i), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e) (stack_xlift (length [v2, v1]) (compxE2 e 0 0)) t h (stk @ [v2, v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v2, v1], loc', pc' - length (compE2 A @ compE2 i), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) ((compE2 A @ compE2 i) @ compE2 e) ((compxE2 A 0 0 @ compxE2 i (length (compE2 A)) (Suc 0)) @ shift (length (compE2 A @ compE2 i)) (stack_xlift (length [v2, v1]) (compxE2 e 0 0))) t h (stk @ [v2, v1], loc, length (compE2 A @ compE2 i) + pc, ⌊a⌋)
ta h' (stk'' @ [v2, v1], loc', length (compE2 A @ compE2 i) + (pc' - length (compE2 A @ compE2 i)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) (((compE2 A @ compE2 i) @ compE2 e) @ [AStore, Push Unit]) ((compxE2 A 0 0 @ compxE2 i (length (compE2 A)) (Suc 0)) @ shift (length (compE2 A @ compE2 i)) (stack_xlift (length [v2, v1]) (compxE2 e 0 0))) t h (stk @ [v2, v1], loc, length (compE2 A @ compE2 i) + pc, ⌊a⌋)
ta h' (stk'' @ [v2, v1], loc', length (compE2 A @ compE2 i) + (pc' - length (compE2 A @ compE2 i)), xcp')"
by(rule exec_meth_append)
moreover from exec' have pc': "pc' ≥ length (compE2 A @ compE2 i)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case bisim1AAssFail thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case bisim1AAss4 thus ?case
by -(erule exec_meth.cases, auto intro!: exec_meth.exec_instr)
next
case (bisim1ALength a n a' xs stk loc pc xcp)
note bisim = ‹P,a,h ⊢ (a', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec a stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl a stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (a∙length) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 a)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 a)")
case True
with exec have "?exec a stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 a)" by simp
with bisim obtain v where [simp]: "stk = [v]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec show ?thesis apply(simp)
by(erule exec_meth.cases)(auto intro!: exec_meth.intros split: if_split_asm)
qed
next
case (bisim1ALengthThrow e n a xs stk loc pc)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e∙length) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp)(erule exec_meth_take[OF _ pc])
from IH[OF this] show ?case by(auto)
next
case bisim1ALengthNull thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1FAcc e n e' xs stk loc pc xcp F D)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (e∙F{D}) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
with bisim obtain v where [simp]: "stk = [v]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec show ?thesis apply(simp)
by(erule exec_meth.cases)(fastforce intro!: exec_meth.intros simp add: is_Ref_def split: if_split_asm)+
qed
next
case (bisim1FAccThrow e n a xs stk loc pc F D)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e∙F{D}) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp)(erule exec_meth_take[OF _ pc])
from IH[OF this] show ?case by(auto)
next
case bisim1FAccNull thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1FAss1 e n e' xs stk loc pc xcp e2 F D)
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note IH2 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec e2 [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl e2 [] STK xs 0 None stk' loc' pc' xcp'›
note bisim1 = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹P,e2,h ⊢ (e2, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec (e∙F{D} := e2) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxE2_size_convs)(erule exec_meth_take_xt)
from IH1[OF this] show ?thesis by auto
next
case False
with pc have pc: "pc = length (compE2 e)" by simp
with exec have "pc' ≥ length (compE2 e)"
by(simp add: compxE2_size_convs stack_xlift_compxE2)(auto elim!: exec_meth_drop_xt_pc)
then obtain PC where PC: "pc' = PC + length (compE2 e)"
by -(rule_tac PC34="pc' - length (compE2 e)" in that, simp)
from pc bisim1 obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec pc have "exec_meth_d (compP2 P) (compE2 e @ compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0 @ compxE2 e2 (length (compE2 e)) (Suc 0))) t
h (stk @ STK, loc, length (compE2 e) + 0, xcp) ta h' (stk', loc', pc', xcp')"
by-(rule exec_meth_take, auto)
hence "?exec e2 [] (v # STK) loc 0 None stk' loc' (pc' - length (compE2 e)) xcp'"
using ‹stk = [v]› ‹xcp = None›
by -(rule exec_meth_drop_xt, auto simp add: stack_xlift_compxE2 shift_compxE2)
from IH2[OF this] PC obtain stk'' where stk': "stk' = stk'' @ v # STK"
and "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) ((compE2 e @ compE2 e2) @ [Putfield F D, Push Unit])
(compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v]) (compxE2 e2 0 0))) t h
([] @ [v], loc, length (compE2 e) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 e) + PC, xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by(auto)
thus ?thesis using ‹stk = [v]› ‹xcp = None› stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1FAss2 e2 n e' xs stk loc pc xcp e F D v1)
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim2 = ‹P,e2,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec (e∙F{D} := e2) (stk @ [v1]) STK loc (length (compE2 e) + pc) xcp stk' loc' pc' xcp'›
from bisim2 have pc: "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e2)")
case True
from exec have "exec_meth_d (compP2 P) ((compE2 e @ compE2 e2) @ [Putfield F D, Push Unit])
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e) + pc, xcp) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 e @ compE2 e2) (stack_xlift (length STK) (compxE2 e 0 0) @
shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: True)
hence "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, xcp) ta h' (stk', loc', pc' - length (compE2 e), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec e2 stk (v1 # STK) loc pc xcp stk' loc' (pc' - length (compE2 e)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 e), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length [v1]) (compxE2 e2 0 0)) t h (stk @ [v1], loc, pc, xcp)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 e), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e @ compE2 e2) (compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e) + pc, xcp)
ta h' (stk'' @ [v1], loc', length (compE2 e) + (pc' - length (compE2 e)), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) ((compE2 e @ compE2 e2) @ [Putfield F D, Push Unit]) (compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e) + pc, xcp)
ta h' (stk'' @ [v1], loc', length (compE2 e) + (pc' - length (compE2 e)), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length (compE2 e)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk' by(simp add: stack_xlift_compxE2 shift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 e2)" by simp
with bisim2 obtain v2 where [simp]: "stk = [v2]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec pc show ?thesis apply(simp)
by(erule exec_meth.cases)(fastforce intro!: exec_meth.intros split: if_split_asm)+
qed
next
case (bisim1FAssThrow1 e n a xs stk loc pc e2 F D)
note bisim1 = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e∙F{D} := e2) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim1 have pc: "pc < length (compE2 e)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 e @ (compE2 e2 @ [Putfield F D, Push Unit]))
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'" by(rule exec_meth_take_xt)(rule pc)
from IH1[OF this] show ?case by(auto)
next
case (bisim1FAssThrow2 e2 n a xs stk loc pc e F D v1)
note bisim2 = ‹P,e2,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e∙F{D} := e2) (stk @ [v1]) STK loc (length (compE2 e) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim2 have pc: "pc < length (compE2 e2)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) ((compE2 e @ compE2 e2) @ [Putfield F D, Push Unit])
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 e @ compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: pc)
hence "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc' - length (compE2 e), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec e2 stk (v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 e)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 e), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length [v1]) (compxE2 e2 0 0)) t h (stk @ [v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 e), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e @ compE2 e2) (compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 e) + (pc' - length (compE2 e)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) ((compE2 e @ compE2 e2) @ [Putfield F D, Push Unit]) (compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t h (stk @ [v1], loc, length (compE2 e) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 e) + (pc' - length (compE2 e)), xcp')"
by(rule exec_meth_append)
moreover from exec' have pc': "pc' ≥ length (compE2 e)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case bisim1FAssNull thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case bisim1FAss3 thus ?case
by -(erule exec_meth.cases, auto intro!: exec_meth.exec_instr)
next
case (bisim1CAS1 e1 n e1' xs stk loc pc xcp e2 e3 D F)
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc xcp stk' loc' pc' xcp'›
note IH2 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec e2 [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl e2 [] STK xs 0 None stk' loc' pc' xcp'›
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note bisim2 = ‹P,e2,h ⊢ (e2, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec _ stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 e1)" by(rule bisim1_pc_length_compE2)
from exec have exec': "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2 @ compE2 e3 @ [CAS F D]) (stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0) @ compxE2 e3 (length (compE2 e2)) (Suc (Suc 0))))) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
show ?case
proof(cases "pc < length (compE2 e1)")
case True
with exec' have "?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'" by(rule exec_meth_take_xt)
from IH1[OF this] show ?thesis by auto
next
case False
with pc have pc: "pc = length (compE2 e1)" by simp
with exec' have "pc' ≥ length (compE2 e1)" by -(erule exec_meth_drop_xt_pc, auto)
then obtain PC where PC: "pc' = PC + length (compE2 e1)"
by -(rule_tac PC34="pc' - length (compE2 e1)" in that, simp)
from pc bisim1 obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec PC pc
have "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3 @ [CAS F D]) (stack_xlift (length STK) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (compxE2 e2 0 (Suc 0))) @ shift (length (compE2 e1 @ compE2 e2)) (compxE2 e3 0 (length STK + Suc (Suc 0)))) t
h (v # STK, loc, length (compE2 e1) + 0, None) ta h' (stk', loc', length (compE2 e1) + PC, xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2)
(stack_xlift (length STK) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (compxE2 e2 0 (Suc 0)))) t h (v # STK, loc, length (compE2 e1) + 0, None) ta h' (stk', loc', length (compE2 e1) + PC, xcp')"
by(rule exec_meth_take_xt) simp
hence "?exec e2 [] (v # STK) loc 0 None stk' loc' ((length (compE2 e1) + PC) - length (compE2 e1)) xcp'"
by -(rule exec_meth_drop_xt, auto simp add: stack_xlift_compxE2 shift_compxE2)
from IH2[OF this] PC obtain stk'' where stk': "stk' = stk'' @ v # STK"
and "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ (compE2 e3 @ [CAS F D]))
((compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v]) (compxE2 e2 0 0))) @
shift (length (compE2 e1 @ compE2 e2)) (compxE2 e3 0 (Suc (Suc 0)))) t h
([] @ [v], loc, length (compE2 e1) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 e1) + PC, xcp')"
apply -
apply(rule exec_meth_append_xt)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by(auto)
thus ?thesis using ‹stk = [v]› ‹xcp = None› stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1CAS2 e2 n e2' xs stk loc pc xcp e1 e3 D F v)
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note IH3 = ‹⋀xs stk' loc' pc' xcp' STK. ?exec e3 [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl e3 [] STK xs 0 None stk' loc' pc' xcp'›
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note bisim3 = ‹P,e3,h ⊢ (e3, loc) ↔ ([], loc, 0, None)›
note exec = ‹?exec _ (stk @ [v]) STK loc (length (compE2 e1) + pc) xcp stk' loc' pc' xcp'›
from bisim2 have pc: "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
from exec have exec': "⋀v'. exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3 @ [CAS F D]) ((compxE2 e1 0 (length STK) @ shift (length (compE2 e1)) (stack_xlift (length (v # STK)) (compxE2 e2 0 0))) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length (v' # v # STK)) (compxE2 e3 0 0))) t
h (stk @ v # STK, loc, length (compE2 e1) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2)
show ?case
proof(cases "pc < length (compE2 e2)")
case True with exec'[of undefined]
have exec'': "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2) (compxE2 e1 0 (length STK) @ shift (length (compE2 e1)) (stack_xlift (length (v # STK)) (compxE2 e2 0 0))) t h (stk @ v # STK, loc, length (compE2 e1) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by-(erule exec_meth_take_xt, simp)
hence "?exec e2 stk (v # STK) loc pc xcp stk' loc' (pc' - length (compE2 e1)) xcp'"
by(rule exec_meth_drop_xt) auto
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec''': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 e1), xcp')" by blast
from exec''' have "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3 @ [CAS F D]) ((compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v]) (compxE2 e2 0 0))) @ shift (length (compE2 e1 @ compE2 e2)) (compxE2 e3 0 (Suc (Suc 0)))) t h (stk @ [v], loc, length (compE2 e1) + pc, xcp) ta h' (stk'' @ [v], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
apply -
apply(rule exec_meth_append_xt)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by auto
moreover from exec'' have "pc' ≥ length (compE2 e1)"
by(rule exec_meth_drop_xt_pc) auto
ultimately show ?thesis using stk' by(auto simp add: shift_compxE2 stack_xlift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 e2)" by simp
with exec'[of undefined] have "pc' ≥ length (compE2 e1 @ compE2 e2)"
by-(erule exec_meth_drop_xt_pc, auto simp add: shift_compxE2 stack_xlift_compxE2)
then obtain PC where PC: "pc' = PC + length (compE2 e1) + length (compE2 e2)"
by -(rule_tac PC34="pc' - length (compE2 e1 @ compE2 e2)" in that, simp)
from pc bisim2 obtain v' where stk: "stk = [v']" and xcp: "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
from exec'[of v']
have "exec_meth_d (compP2 P) (compE2 e3 @ [CAS F D]) (stack_xlift (length (v' # v # STK)) (compxE2 e3 0 0)) t
h (v' # v # STK, loc, 0, xcp) ta h' (stk', loc', pc' - length (compE2 e1 @ compE2 e2), xcp')"
unfolding stk pc append_Cons append_Nil
by -(rule exec_meth_drop_xt, simp only: add_0_right length_append, auto simp add: shift_compxE2 stack_xlift_compxE2)
with PC xcp have "?exec e3 [] (v' # v # STK) loc 0 None stk' loc' PC xcp'"
by -(rule exec_meth_take,auto)
from IH3[OF this] obtain stk'' where stk': "stk' = stk'' @ v' # v # STK"
and "exec_meth_d (compP2 P) (compE2 e3) (compxE2 e3 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')" by auto
hence "exec_meth_d (compP2 P) (((compE2 e1 @ compE2 e2) @ compE2 e3) @ [CAS F D]) ((compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0)) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length [v', v]) (compxE2 e3 0 0))) t h ([] @ [v', v], loc, length (compE2 e1 @ compE2 e2) + 0, None) ta h' (stk'' @ [v', v], loc', length (compE2 e1 @ compE2 e2) + PC, xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by auto
thus ?thesis using stk xcp stk' pc PC
by(clarsimp simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
qed
next
case (bisim1CAS3 e3 n e3' xs stk loc pc xcp e1 e2 D F v1 v2)
note IH3 = ‹⋀stk' loc' pc' xcp' STK. ?exec e3 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e3 stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim3 = ‹P,e3,h ⊢ (e3', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec _ (stk @ [v2, v1]) STK loc (length (compE2 e1) + length (compE2 e2) + pc) xcp stk' loc' pc' xcp'›
from bisim3 have pc: "pc ≤ length (compE2 e3)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e3)")
case True
from exec have "exec_meth_d (compP2 P) (((compE2 e1 @ compE2 e2) @ compE2 e3) @ [CAS F D])
((compxE2 e1 0 (length STK) @ compxE2 e2 (length (compE2 e1)) (Suc (length STK))) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e3 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 e1 @ compE2 e2) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2)
hence exec': "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3)
((compxE2 e1 0 (length STK) @ compxE2 e2 (length (compE2 e1)) (Suc (length STK))) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e3 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 e1 @ compE2 e2) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: True)
hence "?exec e3 stk (v2 # v1 # STK) loc pc xcp stk' loc' (pc' - length (compE2 e1 @ compE2 e2)) xcp'"
by(rule exec_meth_drop_xt) auto
from IH3[OF this] obtain stk'' where stk': "stk' = stk'' @ v2 # v1 # STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e3) (compxE2 e3 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 e1 @ compE2 e2), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e3) (stack_xlift (length [v2, v1]) (compxE2 e3 0 0)) t h (stk @ [v2, v1], loc, pc, xcp)
ta h' (stk'' @ [v2, v1], loc', pc' - length (compE2 e1 @ compE2 e2), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3) ((compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0)) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length [v2, v1]) (compxE2 e3 0 0))) t
h (stk @ [v2, v1], loc, length (compE2 e1 @ compE2 e2) + pc, xcp)
ta h' (stk'' @ [v2, v1], loc', length (compE2 e1 @ compE2 e2) + (pc' - length (compE2 e1 @ compE2 e2)), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) (((compE2 e1 @ compE2 e2) @ compE2 e3) @ [CAS F D]) ((compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0)) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length [v2, v1]) (compxE2 e3 0 0))) t
h (stk @ [v2, v1], loc, length (compE2 e1 @ compE2 e2) + pc, xcp)
ta h' (stk'' @ [v2, v1], loc', length (compE2 e1 @ compE2 e2) + (pc' - length (compE2 e1 @ compE2 e2)), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length (compE2 e1 @ compE2 e2)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk' by(simp add: stack_xlift_compxE2 shift_compxE2)
next
case False
with pc have pc: "pc = length (compE2 e3)" by simp
with bisim3 obtain v3 where [simp]: "stk = [v3]" "xcp = None"
by(auto dest: dest: bisim1_pc_length_compE2D)
with exec pc show ?thesis apply(simp)
by(erule exec_meth.cases)(fastforce intro!: exec_meth.intros split: if_split_asm)+
qed
next
case (bisim1CASThrow1 e1 n a xs stk loc pc e2 e3 D F)
note bisim1 = ‹P,e1,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec _ stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim1 have pc: "pc < length (compE2 e1)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 e1 @ (compE2 e2 @ compE2 e3 @ [CAS F D]))
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0) @ compxE2 e3 (length (compE2 e2)) (Suc (Suc 0))))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')" by(simp add: compxE2_size_convs)
hence "?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'" by(rule exec_meth_take_xt)(rule pc)
from IH1[OF this] show ?case by(auto)
next
case (bisim1CASThrow2 e2 n a xs stk loc pc e1 e3 D F v1)
note bisim2 = ‹P,e2,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH2 = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec _ (stk @ [v1]) STK loc (length (compE2 e1) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim2 have pc: "pc < length (compE2 e2)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3 @ [CAS F D])
((stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) @ (shift (length (compE2 e1 @ compE2 e2)) (compxE2 e3 0 (Suc (Suc (length STK)))))) t
h (stk @ v1 # STK, loc, length (compE2 e1) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence exec': "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2)
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0)))) t
h (stk @ v1 # STK, loc, length (compE2 e1) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take_xt)(simp add: pc)
hence "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length STK) (compxE2 e2 0 (Suc 0))) t
h (stk @ v1 # STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc' - length (compE2 e1), xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec e2 stk (v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 e1)) xcp'"
by(simp add: compxE2_stack_xlift_convs)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 e1), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e2) (stack_xlift (length [v1]) (compxE2 e2 0 0)) t
h (stk @ [v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', pc' - length (compE2 e1), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e1 @ compE2 e2) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) t
h (stk @ [v1], loc, length (compE2 e1) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3 @ [CAS F D]) ((compxE2 e1 0 0 @ shift (length (compE2 e1)) (stack_xlift (length [v1]) (compxE2 e2 0 0))) @ (shift (length (compE2 e1 @ compE2 e2)) (compxE2 e3 0 (Suc (Suc 0))))) t
h (stk @ [v1], loc, length (compE2 e1) + pc, ⌊a⌋)
ta h' (stk'' @ [v1], loc', length (compE2 e1) + (pc' - length (compE2 e1)), xcp')"
by(rule exec_meth_append_xt)
moreover from exec' have pc': "pc' ≥ length (compE2 e1)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case (bisim1CASThrow3 e3 n a xs stk loc pc e1 e2 D F v2 v1)
note bisim3 = ‹P,e3,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH3 = ‹⋀stk' loc' pc' xcp' STK. ?exec e3 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e3 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec _ (stk @ [v2, v1]) STK loc (length (compE2 e1) + length (compE2 e2) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim3 have pc: "pc < length (compE2 e3)" and [simp]: "xs = loc"
by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (((compE2 e1 @ compE2 e2) @ compE2 e3) @ [CAS F D])
((stack_xlift (length STK) (compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0))) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e3 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 e1 @ compE2 e2) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence exec': "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3)
((stack_xlift (length STK) (compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0))) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length (v2 # v1 # STK)) (compxE2 e3 0 0))) t
h (stk @ v2 # v1 # STK, loc, length (compE2 e1 @ compE2 e2) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: pc)
hence "?exec e3 stk (v2 # v1 # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 e1 @ compE2 e2)) xcp'"
by(rule exec_meth_drop_xt) auto
from IH3[OF this] obtain stk'' where stk': "stk' = stk'' @ v2 # v1 # STK" and
exec'': "exec_meth_d (compP2 P) (compE2 e3) (compxE2 e3 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 e1 @ compE2 e2), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e3) (stack_xlift (length [v2, v1]) (compxE2 e3 0 0)) t h (stk @ [v2, v1], loc, pc, ⌊a⌋)
ta h' (stk'' @ [v2, v1], loc', pc' - length (compE2 e1 @ compE2 e2), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) ((compE2 e1 @ compE2 e2) @ compE2 e3) ((compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0)) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length [v2, v1]) (compxE2 e3 0 0))) t h (stk @ [v2, v1], loc, length (compE2 e1 @ compE2 e2) + pc, ⌊a⌋)
ta h' (stk'' @ [v2, v1], loc', length (compE2 e1 @ compE2 e2) + (pc' - length (compE2 e1 @ compE2 e2)), xcp')"
by(rule append_exec_meth_xt)(auto)
hence "exec_meth_d (compP2 P) (((compE2 e1 @ compE2 e2) @ compE2 e3) @ [CAS F D]) ((compxE2 e1 0 0 @ compxE2 e2 (length (compE2 e1)) (Suc 0)) @ shift (length (compE2 e1 @ compE2 e2)) (stack_xlift (length [v2, v1]) (compxE2 e3 0 0))) t h (stk @ [v2, v1], loc, length (compE2 e1 @ compE2 e2) + pc, ⌊a⌋)
ta h' (stk'' @ [v2, v1], loc', length (compE2 e1 @ compE2 e2) + (pc' - length (compE2 e1 @ compE2 e2)), xcp')"
by(rule exec_meth_append)
moreover from exec' have pc': "pc' ≥ length (compE2 e1 @ compE2 e2)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: stack_xlift_compxE2 shift_compxE2)
next
case bisim1CASFail thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case (bisim1Call1 obj n obj' xs stk loc pc xcp ps M')
note bisimObj = ‹P,obj,h ⊢ (obj', xs) ↔ (stk, loc, pc, xcp)›
note IHobj = ‹⋀stk' loc' pc' xcp' STK. ?exec obj stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl obj stk STK loc pc xcp stk' loc' pc' xcp'›
note IHparams = ‹⋀xs stk' loc' pc' xcp' STK. ?execs ps [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concls ps [] STK xs 0 None stk' loc' pc' xcp'›
note exec = ‹?exec (obj∙M'(ps)) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisimObj have pc: "pc ≤ length (compE2 obj)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 obj)")
case True
from exec have "?exec obj stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxEs2_size_convs)(erule exec_meth_take_xt[OF _ True])
from IHobj[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 obj)" by simp
with exec have "pc' ≥ length (compE2 obj)"
by(simp add: compxEs2_size_convs stack_xlift_compxE2)(auto elim!: exec_meth_drop_xt_pc)
then obtain PC where PC: "pc' = PC + length (compE2 obj)"
by -(rule_tac PC34="pc' - length (compE2 obj)" in that, simp)
from pc bisimObj obtain v where [simp]: "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
show ?thesis
proof(cases ps)
case Cons
with exec pc have "exec_meth_d (compP2 P) (compE2 obj @ compEs2 ps)
(stack_xlift (length STK) (compxE2 obj 0 0 @ compxEs2 ps (length (compE2 obj)) (Suc 0))) t
h (stk @ STK, loc, length (compE2 obj) + 0, xcp) ta h' (stk', loc', pc', xcp')"
by -(rule exec_meth_take, auto)
hence "?execs ps [] (v # STK) loc 0 None stk' loc' (pc' - length (compE2 obj)) xcp'"
apply -
apply(rule exec_meth_drop_xt)
apply(simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)
apply(auto simp add: stack_xlift_compxE2)
done
from IHparams[OF this] PC obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec': "exec_meth_d (compP2 P) (compEs2 ps) (compxEs2 ps 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', PC, xcp')"
by auto
from exec' have "exec_meth_d (compP2 P) ((compE2 obj @ compEs2 ps) @ [Invoke M' (length ps)]) (compxE2 obj 0 0 @ shift (length (compE2 obj)) (stack_xlift (length [v]) (compxEs2 ps 0 0))) t h ([] @ [v], loc, length (compE2 obj) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 obj) + PC, xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
by(auto)
thus ?thesis using stk' PC by(clarsimp simp add: shift_compxEs2 stack_xlift_compxEs2 ac_simps)
next
case Nil
with exec pc show ?thesis
apply(auto elim!: exec_meth.cases intro!: exec_meth.intros simp add: split_beta split: if_split_asm)
apply(auto split: extCallRet.split_asm intro!: exec_meth.intros)
apply(force intro!: exI)
apply(force intro!: exI)
apply(force intro!: exI)
done
qed
qed
next
case (bisim1CallParams ps n ps' xs stk loc pc xcp obj M' v)
note bisimParam = ‹P,ps,h ⊢ (ps',xs) [↔] (stk,loc,pc,xcp)›
note IHparam = ‹⋀stk' loc' pc' xcp' STK. ?execs ps stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concls ps stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (obj∙M'(ps)) (stk @ [v]) STK loc (length (compE2 obj) + pc) xcp stk' loc' pc' xcp'›
show ?case
proof(cases ps)
case Nil
with bisimParam have "pc = 0" "xcp = None" by(auto elim: bisims1.cases)
with exec Nil show ?thesis
apply(auto elim!: exec_meth.cases intro!: exec_meth.intros simp add: split_beta extRet2JVM_def split: if_split_asm)
apply(auto split: extCallRet.split_asm simp add: neq_Nil_conv)
apply(force intro!: exec_meth.intros)+
done
next
case Cons
from bisimParam have pc: "pc ≤ length (compEs2 ps)" by(rule bisims1_pc_length_compEs2)
show ?thesis
proof(cases "pc < length (compEs2 ps)")
case True
from exec have "exec_meth_d (compP2 P) ((compE2 obj @ compEs2 ps) @ [Invoke M' (length ps)])
(stack_xlift (length STK) (compxE2 obj 0 0) @ shift (length (compE2 obj)) (stack_xlift (length (v # STK)) (compxEs2 ps 0 0))) t
h (stk @ v # STK, loc, length (compE2 obj) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 obj @ compEs2 ps) (stack_xlift (length STK) (compxE2 obj 0 0) @
shift (length (compE2 obj)) (stack_xlift (length (v # STK)) (compxEs2 ps 0 0))) t
h (stk @ v # STK, loc, length (compE2 obj) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: True)
hence "?execs ps stk (v # STK) loc pc xcp stk' loc' (pc' - length (compE2 obj)) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IHparam[OF this] obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec'': "exec_meth_d (compP2 P) (compEs2 ps) (compxEs2 ps 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 obj), xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compEs2 ps) (stack_xlift (length [v]) (compxEs2 ps 0 0)) t h (stk @ [v], loc, pc, xcp) ta h' (stk'' @ [v], loc', pc' - length (compE2 obj), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 obj @ compEs2 ps) (compxE2 obj 0 0 @ shift (length (compE2 obj)) (stack_xlift (length [v]) (compxEs2 ps 0 0))) t
h (stk @ [v], loc, length (compE2 obj) + pc, xcp) ta h' (stk'' @ [v], loc', length (compE2 obj) + (pc' - length (compE2 obj)), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) ((compE2 obj @ compEs2 ps) @ [Invoke M' (length ps)])
(compxE2 obj 0 0 @ shift (length (compE2 obj)) (stack_xlift (length [v]) (compxEs2 ps 0 0))) t
h (stk @ [v], loc, length (compE2 obj) + pc, xcp) ta h' (stk'' @ [v], loc', length (compE2 obj) + (pc' - length (compE2 obj)), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length (compE2 obj)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk'
by(auto simp add: shift_compxEs2 stack_xlift_compxEs2)
next
case False
with pc have pc: "pc = length (compEs2 ps)" by simp
with bisimParam obtain vs where "stk = vs" "length vs = length ps" "xcp = None"
by(auto dest: bisims1_pc_length_compEs2D)
with exec pc Cons show ?thesis
apply(auto elim!: exec_meth.cases intro!: exec_meth.intros simp add: split_beta extRet2JVM_def split: if_split_asm)
apply(auto simp add: neq_Nil_conv split: extCallRet.split_asm)
apply(force intro!: exec_meth.intros)+
done
qed
qed
next
case (bisim1CallThrowObj obj n a xs stk loc pc ps M')
note bisim = ‹P,obj,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec obj stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl obj stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (obj∙M'(ps)) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have "pc < length (compE2 obj)" and [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
with exec have "?exec obj stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)(erule exec_meth_take_xt)
from IH[OF this] show ?case by auto
next
case (bisim1CallThrowParams ps n vs a ps' xs stk loc pc obj M' v)
note bisim = ‹P,ps,h ⊢ (map Val vs @ Throw a # ps',xs) [↔] (stk,loc,pc,⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?execs ps stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concls ps stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (obj∙M'(ps)) (stk @ [v]) STK loc (length (compE2 obj) + pc) ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compEs2 ps)" "loc = xs" by(auto dest: bisims1_ThrowD)
from exec have "exec_meth_d (compP2 P) ((compE2 obj @ compEs2 ps) @ [Invoke M' (length ps)])
(stack_xlift (length STK) (compxE2 obj 0 0) @ shift (length (compE2 obj)) (stack_xlift (length (v # STK)) (compxEs2 ps 0 0))) t
h (stk @ v # STK, loc, length (compE2 obj) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)
hence exec': "exec_meth_d (compP2 P) (compE2 obj @ compEs2 ps) (stack_xlift (length STK) (compxE2 obj 0 0) @
shift (length (compE2 obj)) (stack_xlift (length (v # STK)) (compxEs2 ps 0 0))) t
h (stk @ v # STK, loc, length (compE2 obj) + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(simp add: pc)
hence "?execs ps stk (v # STK) loc pc ⌊a⌋ stk' loc' (pc' - length (compE2 obj)) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec'': "exec_meth_d (compP2 P) (compEs2 ps) (compxEs2 ps 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length (compE2 obj), xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) ((compE2 obj @ compEs2 ps) @ [Invoke M' (length ps)])
(compxE2 obj 0 0 @ shift (length (compE2 obj)) (stack_xlift (length [v]) (compxEs2 ps 0 0))) t
h (stk @ [v], loc, length (compE2 obj) + pc, ⌊a⌋) ta h' (stk'' @ [v], loc', length (compE2 obj) + (pc' - length (compE2 obj)), xcp')"
apply -
apply(rule exec_meth_append)
apply(rule append_exec_meth_xt)
apply(erule exec_meth_stk_offer)
apply auto
done
moreover from exec' have "pc' ≥ length (compE2 obj)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)
next
case bisim1CallThrow thus ?case
by(auto elim!: exec_meth.cases dest: match_ex_table_pcsD simp add: stack_xlift_compxEs2 stack_xlift_compxE2)
next
case bisim1BlockSome1 thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case bisim1BlockSome2 thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1BlockSome4 e n e' xs stk loc pc xcp V T v)
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec {V:T=⌊v⌋; e} stk STK loc (Suc (Suc pc)) xcp stk' loc' pc' xcp'›
hence exec': "exec_meth_d (compP2 P) ([Push v, Store V] @ compE2 e)
(shift (length [Push v, Store V]) (stack_xlift (length STK) (compxE2 e 0 0))) t h (stk @ STK, loc, length [Push v, Store V] + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence "?exec e stk STK loc pc xcp stk' loc' (pc' - length [Push v, Store V]) xcp'"
by(rule exec_meth_drop) auto
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, xcp) ta
h' (stk'', loc', pc' - length [Push v, Store V], xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) ([Push v, Store V] @ compE2 e)
(shift (length [Push v, Store V]) (compxE2 e 0 0)) t h (stk, loc, length [Push v, Store V] + pc, xcp) ta h' (stk'', loc', length [Push v, Store V] + (pc' - length [Push v, Store V]), xcp')"
by(rule append_exec_meth) auto
moreover from exec' have "pc' ≥ length [Push v, Store V]"
by(rule exec_meth_drop_pc)(auto simp add: stack_xlift_compxE2)
hence "Suc (Suc (pc' - Suc (Suc 0))) = pc'" by(simp)
ultimately show ?case using stk' by(auto simp add: compxE2_size_convs)
next
case (bisim1BlockThrowSome e n a xs stk loc pc V T v)
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec {V:T=⌊v⌋; e} stk STK loc (Suc (Suc pc)) ⌊a⌋ stk' loc' pc' xcp'›
hence exec': "exec_meth_d (compP2 P) ([Push v, Store V] @ compE2 e)
(shift (length [Push v, Store V]) (stack_xlift (length STK) (compxE2 e 0 0))) t h (stk @ STK, loc, length [Push v, Store V] + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence "?exec e stk STK loc pc ⌊a⌋ stk' loc' (pc' - length [Push v, Store V]) xcp'"
by(rule exec_meth_drop) auto
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, ⌊a⌋) ta
h' (stk'', loc', pc' - length [Push v, Store V], xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) ([Push v, Store V] @ compE2 e)
(shift (length [Push v, Store V]) (compxE2 e 0 0)) t h (stk, loc, length [Push v, Store V] + pc, ⌊a⌋) ta h' (stk'', loc', length [Push v, Store V] + (pc' - length [Push v, Store V]), xcp')"
by(rule append_exec_meth) auto
moreover from exec' have "pc' ≥ length [Push v, Store V]"
by(rule exec_meth_drop_pc)(auto simp add: stack_xlift_compxE2)
hence "Suc (Suc (pc' - Suc (Suc 0))) = pc'" by(simp)
ultimately show ?case using stk' by(auto simp add: compxE2_size_convs)
next
case bisim1BlockNone thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case bisim1BlockThrowNone thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1Sync1 e1 n e1' xs stk loc pc xcp e2 V)
note bisim = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (sync⇘V⇙ (e1) e2) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e1)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e1)")
case True
from exec have "exec_meth_d (compP2 P)
(compE2 e1 @ (Dup # Store V # MEnter # compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc]))
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 3 0) @
stack_xlift (length STK) [(3, 3 + length (compE2 e2), None, 6 + length (compE2 e2), 0)])) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence "?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule True)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec': "exec_meth_d (compP2 P) (compE2 e1) (compxE2 e1 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc', xcp')"
by blast
from exec' have "exec_meth_d (compP2 P) (compE2 e1 @ (Dup # Store V # MEnter # compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc]))
(compxE2 e1 0 0 @ shift (length (compE2 e1)) (compxE2 e2 3 0 @ [(3, 3 + length (compE2 e2), None, 6 + length (compE2 e2), 0)])) t
h (stk, loc, pc, xcp) ta h' (stk'', loc', pc', xcp')"
by(rule exec_meth_append_xt)
thus ?thesis using stk' by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
next
case False
with pc have [simp]: "pc = length (compE2 e1)" by simp
with bisim obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
thus ?thesis using exec by(auto elim!: exec_meth.cases intro!: exec_meth.intros)
qed
next
case bisim1Sync2 thus ?case
by(fastforce elim!: exec_meth.cases intro!: exec_meth.intros)
next
case bisim1Sync3 thus ?case
by(fastforce elim!: exec_meth.cases intro!: exec_meth.intros split: if_split_asm)
next
case (bisim1Sync4 e2 n e2' xs stk loc pc xcp e1 V a)
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note bisim = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note exec = ‹?exec (sync⇘V⇙ (e1) e2) stk STK loc (Suc (Suc (Suc (length (compE2 e1) + pc)))) xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e2)")
case True
let ?pre = "compE2 e1 @ [Dup, Store V, MEnter]"
from exec have exec': "exec_meth_d (compP2 P) (?pre @ compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e2 0 0) @
[(0, length (compE2 e2), None, 3 + length (compE2 e2), length STK)])) t
h (stk @ STK, loc, length ?pre + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: stack_xlift_compxE2 shift_compxE2 eval_nat_numeral ac_simps)
hence exec'': "exec_meth_d (compP2 P) (compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(stack_xlift (length STK) (compxE2 e2 0 0) @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), length STK)]) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc' - length ?pre, xcp')"
by(rule exec_meth_drop_xt[where n=1])(auto simp add: stack_xlift_compxE2)
from exec' have pc': "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc[where n'=1])(auto simp add: stack_xlift_compxE2)
hence pc'': "(Suc (Suc (Suc (pc' - Suc (Suc (Suc 0)))))) = pc'" by simp
show ?thesis
proof(cases xcp)
case None
from exec'' None True
have "?exec e2 stk STK loc pc xcp stk' loc' (pc' - length ?pre) xcp'"
apply -
apply (erule exec_meth.cases)
apply (cases "compE2 e2 ! pc")
apply (fastforce simp add: is_Ref_def intro: exec_meth.intros split: if_split_asm cong del: image_cong_simp)+
done
from IH[OF this] obtain stk'' where stk: "stk' = stk'' @ STK"
and exec''': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp)
ta h' (stk'', loc', pc' - length ?pre, xcp')" by blast
from exec''' have "exec_meth_d (compP2 P) (compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(compxE2 e2 0 0 @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), 0)]) t
h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length ?pre, xcp')"
by(rule exec_meth_append_xt)
hence "exec_meth_d (compP2 P) (?pre @ compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(compxE2 e1 0 0 @ shift (length ?pre) (compxE2 e2 0 0 @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), 0)])) t
h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt[where n=1]) auto
thus ?thesis using stk pc' pc'' by(simp add: eval_nat_numeral shift_compxE2 ac_simps)
next
case (Some a)
with exec'' have [simp]: "h' = h" "xcp' = None" "loc' = loc" "ta = ε"
by(auto elim!: exec_meth.cases simp add: match_ex_table_append
split: if_split_asm dest!: match_ex_table_stack_xliftD)
show ?thesis
proof(cases "match_ex_table (compP2 P) (cname_of h a) pc (compxE2 e2 0 0)")
case None
with Some exec'' True have [simp]: "stk' = Addr a # STK"
and pc': "pc' = length (compE2 e1) + length (compE2 e2) + 6"
by(auto elim!: exec_meth.cases simp add: match_ex_table_append
split: if_split_asm dest!: match_ex_table_stack_xliftD)
with exec'' Some None
have "exec_meth_d (compP2 P) (compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(compxE2 e2 0 0 @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), 0)]) t
h (stk, loc, pc, ⌊a⌋) ε h (Addr a # drop (length stk - 0) stk, loc, pc' - length ?pre, None)"
by -(rule exec_catch, auto elim!: exec_meth.cases simp add: match_ex_table_append matches_ex_entry_def
split: if_split_asm dest!: match_ex_table_stack_xliftD)
hence "exec_meth_d (compP2 P) (?pre @ compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(compxE2 e1 0 0 @ shift (length ?pre) (compxE2 e2 0 0 @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), 0)])) t
h (stk, loc, length ?pre + pc, ⌊a⌋) ε h (Addr a # drop (length stk - 0) stk, loc,
length ?pre + (pc' - length ?pre), None)"
by(rule append_exec_meth_xt[where n=1]) auto
with pc' Some show ?thesis by(simp add: eval_nat_numeral shift_compxE2 ac_simps)
next
case (Some pcd)
with ‹xcp = ⌊a⌋› exec'' True
have "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t
h (stk, loc, pc, ⌊a⌋) ε h (Addr a # drop (length stk - snd pcd) stk, loc, pc' - length ?pre, None)"
apply -
apply(rule exec_catch)
apply(auto elim!: exec_meth.cases simp add: match_ex_table_append split: if_split_asm
dest!: match_ex_table_stack_xliftD)
done
hence "exec_meth_d (compP2 P) (compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc]) (compxE2 e2 0 0 @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), 0)]) t
h (stk, loc, pc, ⌊a⌋) ε h (Addr a # drop (length stk - snd pcd) stk, loc, pc' - length ?pre, None)"
by(rule exec_meth_append_xt)
hence "exec_meth_d (compP2 P) (?pre @ compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(compxE2 e1 0 0 @ shift (length ?pre) (compxE2 e2 0 0 @ [(0, length (compE2 e2), None, 3 + length (compE2 e2), 0)])) t
h (stk, loc, length ?pre + pc, ⌊a⌋) ε h (Addr a # drop (length stk - snd pcd) stk, loc, length ?pre + (pc' - length ?pre), None)"
by(rule append_exec_meth_xt[where n=1])(auto)
moreover from Some ‹xcp = ⌊a⌋› exec'' True pc'
have "pc' = length (compE2 e1) + 3 + fst pcd" "stk' = Addr a # drop (length stk - snd pcd) stk @ STK"
by(auto elim!: exec_meth.cases dest!: match_ex_table_stack_xliftD simp: match_ex_table_append split: if_split_asm)
ultimately show ?thesis using ‹xcp = ⌊a⌋› by(auto simp add: eval_nat_numeral shift_compxE2 ac_simps)
qed
qed
next
case False
with pc have [simp]: "pc = length (compE2 e2)" by simp
with exec show ?thesis
by(auto elim!: exec_meth.cases intro!: exec_meth.intros split: if_split_asm simp add: match_ex_table_append_not_pcs eval_nat_numeral)(simp_all add: matches_ex_entry_def)
qed
next
case bisim1Sync5 thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros split: if_split_asm)
next
case bisim1Sync6 thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros split: if_split_asm)
next
case bisim1Sync7 thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros split: if_split_asm)
next
case bisim1Sync8 thus ?case
by(fastforce elim: exec_meth.cases intro: exec_meth.intros split: if_split_asm)
next
case (bisim1Sync9 e1 n e2 V a xs)
note exec = ‹?exec (sync⇘V⇙ (e1) e2) [Addr a] STK xs (8 + length (compE2 e1) + length (compE2 e2)) None stk' loc' pc' xcp'›
let ?pre = "compE2 e1 @ Dup # Store V # MEnter # compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit]"
from exec have exec': "exec_meth_d (compP2 P) (?pre @ [ThrowExc]) (stack_xlift (length STK) (compxE2 (sync⇘V⇙ (e1) e2) 0 0) @ shift (length ?pre) []) t h (Addr a # STK, xs, length ?pre + 0, None) ta h' (stk', loc', pc', xcp')"
by(simp add: eval_nat_numeral)
hence "exec_meth_d (compP2 P) [ThrowExc] [] t h (Addr a # STK, xs, 0, None) ta h' (stk', loc', pc' - length ?pre, xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
moreover from exec' have "pc' = 8 + length (compE2 e1) + length (compE2 e2)" "stk' = Addr a # STK"
by(auto elim!: exec_meth.cases)
ultimately show ?case by(fastforce elim!: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1Sync10 e1 n e2 V a xs)
note exec = ‹?exec (sync⇘V⇙ (e1) e2) [Addr a] STK xs (8 + length (compE2 e1) + length (compE2 e2)) ⌊a⌋ stk' loc' pc' xcp'›
hence "match_ex_table (compP2 P) (cname_of h a) (8 + length (compE2 e1) + length (compE2 e2)) (stack_xlift (length STK) (compxE2 (sync⇘V⇙ (e1) e2) 0 0)) ≠ None"
by(rule exec_meth.cases) auto
hence False by(auto split: if_split_asm simp add: match_ex_table_append_not_pcs)(simp add: matches_ex_entry_def)
thus ?case ..
next
case (bisim1Sync11 e1 n e2 V xs)
note exec = ‹?exec (sync⇘V⇙ (e1) e2) [Null] STK xs (Suc (Suc (length (compE2 e1)))) ⌊addr_of_sys_xcpt NullPointer⌋ stk' loc' pc' xcp'›
hence "match_ex_table (compP2 P) (cname_of h (addr_of_sys_xcpt NullPointer)) (2 + length (compE2 e1)) (stack_xlift (length STK) (compxE2 (sync⇘V⇙ (e1) e2) 0 0)) ≠ None"
by(rule exec_meth.cases)(auto split: if_split_asm)
hence False by(auto split: if_split_asm simp add: match_ex_table_append_not_pcs)(simp add: matches_ex_entry_def)
thus ?case ..
next
case (bisim1SyncThrow e1 n a xs stk loc pc e2 V)
note exec = ‹?exec (sync⇘V⇙ (e1) e2) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note bisim = ‹P,e1,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
from bisim have pc: "pc < length (compE2 e1)"
and [simp]: "loc = xs" by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 e1 @ Dup # Store V # MEnter # compE2 e2 @ [Load V, MExit, Goto 4, Load V, MExit, ThrowExc])
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 3 0) @
[(3, 3 + length (compE2 e2), None, 6 + length (compE2 e2), length STK)])) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
hence "?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule pc)
from IH[OF this] show ?case by auto
next
case (bisim1Seq1 e1 n e1' xs stk loc pc xcp e2)
note bisim1 = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (e1;;e2) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 e1)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e1)")
case True
from exec have "exec_meth_d (compP2 P) (compE2 e1 @ Pop # compE2 e2) (stack_xlift (length STK) (compxE2 e1 0 0) @
shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 (Suc 0) 0))) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2)
hence "?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule True)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e1)" by simp
with bisim1 obtain v where "xcp = None" "stk = [v]" by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
qed
next
case (bisim1SeqThrow1 e1 n a xs stk loc pc e2)
note bisim1 = ‹P,e1,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (e1;;e2) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim1 have pc: "pc < length (compE2 e1)" by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 e1 @ Pop # compE2 e2) (stack_xlift (length STK) (compxE2 e1 0 0) @
shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 (Suc 0) 0))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: shift_compxE2 stack_xlift_compxE2)
hence "?exec e1 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule pc)
from IH[OF this] show ?case by(fastforce elim: exec_meth.cases intro: exec_meth.intros)
next
case (bisim1Seq2 e2 n e2' xs stk loc pc xcp e1)
note bisim2 = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (e1;;e2) stk STK loc (Suc (length (compE2 e1) + pc)) xcp stk' loc' pc' xcp'›
from bisim2 have pc: "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e2)")
case False
with pc have [simp]: "pc = length (compE2 e2)" by simp
from bisim2 have "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec have False by(auto elim: exec_meth.cases)
thus ?thesis ..
next
case True
from exec have exec':
"exec_meth_d (compP2 P) ((compE2 e1 @ [Pop]) @ compE2 e2) (stack_xlift (length STK) (compxE2 e1 0 0) @
shift (length (compE2 e1 @ [Pop])) (stack_xlift (length STK) (compxE2 e2 0 0))) t
h (stk @ STK, loc, length ((compE2 e1) @ [Pop]) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence "?exec e2 stk STK loc pc xcp stk' loc' (pc' - length ((compE2 e1) @ [Pop])) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp)
ta h' (stk'', loc', pc' - length (compE2 e1 @ [Pop]), xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) ((compE2 e1 @ [Pop]) @ compE2 e2) (compxE2 e1 0 0 @ shift (length (compE2 e1 @ [Pop])) (compxE2 e2 0 0)) t
h (stk, loc, length ((compE2 e1) @ [Pop]) + pc, xcp) ta h' (stk'', loc', length ((compE2 e1) @ [Pop]) + (pc' - length ((compE2 e1) @ [Pop])), xcp')"
by(rule append_exec_meth_xt) auto
moreover from exec' have "pc' ≥ length ((compE2 e1) @ [Pop])"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk' by(auto simp add: shift_compxE2 stack_xlift_compxE2)
qed
next
case (bisim1Cond1 e n e' xs stk loc pc xcp e1 e2)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (if (e) e1 else e2) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
from exec have "exec_meth_d (compP2 P) (compE2 e @ IfFalse (2 + int (length (compE2 e1))) # compE2 e1 @ Goto (1 + int (length (compE2 e2))) # compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e1 (Suc 0) 0) @
stack_xlift (length STK) (compxE2 e2 (Suc (Suc (length (compE2 e1)))) 0))) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: stack_xlift_compxE2 shift_compxE2 ac_simps)
hence "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule True)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
from bisim obtain v where "stk = [v]" "xcp = None"
by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(auto elim!: exec_meth.cases intro!: exec_meth.intros)
qed
next
case (bisim1CondThen e1 n e1' xs stk loc pc xcp e e2)
note bisim = ‹P,e1,h ⊢ (e1', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e1 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e1 stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (if (e) e1 else e2) stk STK loc (Suc (length (compE2 e) + pc)) xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e1)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e1)")
case True
let ?pre = "compE2 e @ [IfFalse (2 + int (length (compE2 e1)))]"
from exec have exec': "exec_meth_d (compP2 P) (?pre @ compE2 e1 @ Goto (1 + int (length (compE2 e2))) # compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e1 0 0) @
shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 (Suc 0) 0)))) t
h (stk @ STK, loc, length ?pre + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: stack_xlift_compxE2 shift_compxE2 ac_simps)
hence "exec_meth_d (compP2 P) (compE2 e1 @ Goto (1 + int (length (compE2 e2))) # compE2 e2)
(stack_xlift (length STK) (compxE2 e1 0 0) @ shift (length (compE2 e1)) (stack_xlift (length STK) (compxE2 e2 (Suc 0) 0))) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc' - length ?pre, xcp')"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
hence "?exec e1 stk STK loc pc xcp stk' loc' (pc' - length ?pre) xcp'"
by(rule exec_meth_take_xt)(rule True)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e1) (compxE2 e1 0 0) t h (stk, loc, pc, xcp)
ta h' (stk'', loc', pc' - length ?pre, xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (compE2 e1 @ Goto (1 + int (length (compE2 e2))) # compE2 e2)
(compxE2 e1 0 0 @ shift (length (compE2 e1)) (compxE2 e2 (Suc 0) 0)) t
h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length ?pre, xcp')"
by(rule exec_meth_append_xt)
hence "exec_meth_d (compP2 P) (?pre @ compE2 e1 @ Goto (1 + int (length (compE2 e2))) # compE2 e2)
(compxE2 e 0 0 @ shift (length ?pre) (compxE2 e1 0 0 @ shift (length (compE2 e1)) (compxE2 e2 (Suc 0) 0))) t
h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt)(auto)
moreover from exec' have "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using stk'
by(auto simp add: shift_compxE2 stack_xlift_compxE2 ac_simps)
next
case False
with pc have [simp]: "pc = length (compE2 e1)" by simp
from bisim obtain v where "stk = [v]" "xcp = None"
by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(auto elim!: exec_meth.cases intro!: exec_meth.intros)
qed
next
case (bisim1CondElse e2 n e2' xs stk loc pc xcp e e1)
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (if (e) e1 else e2) stk STK loc (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc))) xcp stk' loc' pc' xcp'›
note bisim = ‹P,e2,h ⊢ (e2', xs) ↔ (stk, loc, pc, xcp)›
from bisim have pc: "pc ≤ length (compE2 e2)" by(rule bisim1_pc_length_compE2)
let ?pre = "compE2 e @ IfFalse (2 + int (length (compE2 e1))) # compE2 e1 @ [Goto (1 + int (length (compE2 e2)))]"
from exec have exec': "exec_meth_d (compP2 P) (?pre @ compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0 @ compxE2 e1 (Suc (length (compE2 e))) 0) @
shift (length ?pre) (stack_xlift (length STK) (compxE2 e2 0 0))) t
h (stk @ STK, loc, length ?pre + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: stack_xlift_compxE2 shift_compxE2 ac_simps)
hence "?exec e2 stk STK loc pc xcp stk' loc' (pc' - length ?pre) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2 shift_compxEs2 ac_simps)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp)
ta h' (stk'', loc', pc' - length ?pre, xcp')" by blast
from exec'' have "exec_meth_d (compP2 P) (?pre @ compE2 e2)
((compxE2 e 0 0 @ compxE2 e1 (Suc (length (compE2 e))) 0) @ shift (length ?pre) (compxE2 e2 0 0)) t
h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt)(auto)
moreover from exec' have "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
moreover hence "(Suc (Suc (pc' - Suc (Suc 0)))) = pc'" by simp
ultimately show ?case using stk'
by(auto simp add: shift_compxE2 stack_xlift_compxE2 ac_simps eval_nat_numeral)
next
case (bisim1CondThrow e n a xs stk loc pc e1 e2)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (if (e) e1 else e2) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 e @ IfFalse (2 + int (length (compE2 e1))) # compE2 e1 @ Goto (1 + int (length (compE2 e2))) # compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e1 (Suc 0) 0) @
stack_xlift (length STK) (compxE2 e2 (Suc (Suc (length (compE2 e1)))) 0))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: stack_xlift_compxE2 shift_compxE2 ac_simps)
hence "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule pc)
from IH[OF this] show ?case by auto
next
case (bisim1While1 c n e xs)
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec c [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concl c [] STK xs 0 None stk' loc' pc' xcp'›
note exec = ‹?exec (while (c) e) [] STK xs 0 None stk' loc' pc' xcp'›
hence "exec_meth_d (compP2 P) (compE2 c @ IfFalse (int (length (compE2 e)) + 3) # compE2 e @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(stack_xlift (length STK) (compxE2 c 0 0) @ shift (length (compE2 c)) (stack_xlift (length STK) (compxE2 e (Suc 0) 0))) t
h ([] @ STK, xs, 0, None) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence "?exec c [] STK xs 0 None stk' loc' pc' xcp'"
by(rule exec_meth_take_xt) simp
from IH[OF this] show ?case by auto
next
case (bisim1While3 c n c' xs stk loc pc xcp e)
note bisim = ‹P,c,h ⊢ (c', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec c stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl c stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (while (c) e) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 c)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 c)")
case True
from exec have "exec_meth_d (compP2 P) (compE2 c @ IfFalse (int (length (compE2 e)) + 3) # compE2 e @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(stack_xlift (length STK) (compxE2 c 0 0) @ shift (length (compE2 c)) (stack_xlift (length STK) (compxE2 e (Suc 0) 0))) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence "?exec c stk STK loc pc xcp stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule True)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 c)" by simp
from bisim obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(auto elim!: exec_meth.cases intro!: exec_meth.intros)
qed
next
case (bisim1While4 e n e' xs stk loc pc xcp c)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (while (c) e) stk STK loc (Suc (length (compE2 c) + pc)) xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
let ?pre = "compE2 c @ [IfFalse (int (length (compE2 e)) + 3)]"
from exec have "exec_meth_d (compP2 P) ((?pre @ compE2 e) @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(stack_xlift (length STK) (compxE2 c 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e 0 0))) t
h (stk @ STK, loc, length ?pre + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (?pre @ compE2 e) (stack_xlift (length STK) (compxE2 c 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e 0 0))) t
h (stk @ STK, loc, length ?pre + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(auto intro: True)
hence "?exec e stk STK loc pc xcp stk' loc' (pc' - length ?pre) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length ?pre, xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) (?pre @ compE2 e) (compxE2 c 0 0 @ shift (length ?pre) (compxE2 e 0 0)) t
h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) ((?pre @ compE2 e) @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(compxE2 c 0 0 @ shift (length ?pre) (compxE2 e 0 0)) t
h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
moreover have "-2 + (- int (length (compE2 e)) - int (length (compE2 c))) = - int (length (compE2 c)) + (-2 - int (length (compE2 e)))" by simp
ultimately show ?thesis using stk'
by(auto simp add: shift_compxE2 stack_xlift_compxE2 algebra_simps uminus_minus_left_commute)
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
from bisim obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(auto elim!: exec_meth.cases intro!: exec_meth.intros)
qed
next
case (bisim1While6 c n e xs)
note exec = ‹?exec (while (c) e) [] STK xs (Suc (Suc (length (compE2 c) + length (compE2 e)))) None stk' loc' pc' xcp'›
thus ?case by(rule exec_meth.cases)(simp_all, auto intro!: exec_meth.intros)
next
case (bisim1While7 c n e xs)
note exec = ‹?exec (while (c) e) [] STK xs (Suc (Suc (Suc (length (compE2 c) + length (compE2 e))))) None stk' loc' pc' xcp'›
thus ?case by(rule exec_meth.cases)(simp_all, auto intro!: exec_meth.intros)
next
case (bisim1WhileThrow1 c n a xs stk loc pc e)
note bisim = ‹P,c,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec c stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl c stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (while (c) e) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 c)" by(auto dest: bisim1_ThrowD)
from exec have "exec_meth_d (compP2 P) (compE2 c @ IfFalse (int (length (compE2 e)) + 3) # compE2 e @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(stack_xlift (length STK) (compxE2 c 0 0) @ shift (length (compE2 c)) (stack_xlift (length STK) (compxE2 e (Suc 0) 0))) t
h (stk @ STK, loc, pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence "?exec c stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(rule exec_meth_take_xt)(rule pc)
from IH[OF this] show ?case by auto
next
case (bisim1WhileThrow2 e n a xs stk loc pc c)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (while (c) e) stk STK loc (Suc (length (compE2 c) + pc)) ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" by(auto dest: bisim1_ThrowD)
let ?pre = "compE2 c @ [IfFalse (int (length (compE2 e)) + 3)]"
from exec have "exec_meth_d (compP2 P) ((?pre @ compE2 e) @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(stack_xlift (length STK) (compxE2 c 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e 0 0))) t
h (stk @ STK, loc, length ?pre + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
hence exec': "exec_meth_d (compP2 P) (?pre @ compE2 e)
(stack_xlift (length STK) (compxE2 c 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e 0 0))) t
h (stk @ STK, loc, (length ?pre + pc), ⌊a⌋) ta h' (stk', loc', pc', xcp')"
by(rule exec_meth_take)(auto intro: pc)
hence "?exec e stk STK loc pc ⌊a⌋ stk' loc' (pc' - length ?pre) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length ?pre, xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) (?pre @ compE2 e) (compxE2 c 0 0 @ shift (length ?pre) (compxE2 e 0 0)) t
h (stk, loc, length ?pre + pc, ⌊a⌋) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) ((?pre @ compE2 e) @ [Pop, Goto (-2 + (- int (length (compE2 e)) - int (length (compE2 c)))), Push Unit])
(compxE2 c 0 0 @ shift (length ?pre) (compxE2 e 0 0)) t
h (stk, loc, length ?pre + pc, ⌊a⌋) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule exec_meth_append)
moreover from exec' have "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
moreover have "-2 + (- int (length (compE2 e)) - int (length (compE2 c))) = - int (length (compE2 c)) + (-2 - int (length (compE2 e)))" by simp
ultimately show ?case using stk'
by(auto simp add: shift_compxE2 stack_xlift_compxE2 algebra_simps uminus_minus_left_commute)
next
case (bisim1Throw1 e n e' xs stk loc pc xcp)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (throw e) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'" by(auto elim: exec_meth_take)
from IH[OF this] show ?thesis by auto
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
from bisim obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(auto elim!: exec_meth.cases intro!: exec_meth.intros split: if_split_asm)
qed
next
case bisim1Throw2 thus ?case
apply(auto elim!:exec_meth.cases intro: exec_meth.intros dest!: match_ex_table_stack_xliftD)
apply(auto intro: exec_meth.intros dest!: match_ex_table_stack_xliftD intro!: exI)
apply(auto simp add: le_Suc_eq)
done
next
case bisim1ThrowNull thus ?case
apply(auto elim!:exec_meth.cases intro: exec_meth.intros dest!: match_ex_table_stack_xliftD)
apply(auto intro: exec_meth.intros dest!: match_ex_table_stack_xliftD intro!: exI)
apply(auto simp add: le_Suc_eq)
done
next
case (bisim1ThrowThrow e n a xs stk loc pc)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (throw e) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e)" by(auto dest: bisim1_ThrowD)
with exec have "?exec e stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'"
by(auto elim: exec_meth_take simp add: compxE2_size_convs)
from IH[OF this] show ?case by auto
next
case (bisim1Try e n e' xs stk loc pc xcp e2 C' V)
note bisim = ‹P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (try e catch(C' V) e2) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
from exec have exec': "exec_meth_d (compP2 P) (compE2 e @ Goto (int (length (compE2 e2)) + 2) # Store V # compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length STK) (compxE2 e2 (Suc (Suc 0)) 0)) @ [(0, length (compE2 e), ⌊C'⌋, Suc (length (compE2 e)), length STK)]) t
h (stk @ STK, loc, pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxE2_size_convs)
show ?thesis
proof(cases xcp)
case None
with exec' True have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
apply -
apply (erule exec_meth.cases)
apply (cases "compE2 e ! pc")
apply (fastforce simp add: is_Ref_def intro: exec_meth.intros split: if_split_asm cong del: image_cong_simp)+
done
from IH[OF this] show ?thesis by auto
next
case (Some a)
with exec' have [simp]: "h' = h" "loc' = loc" "xcp' = None" "ta = ε"
by(auto elim: exec_meth.cases)
show ?thesis
proof(cases "match_ex_table (compP2 P) (cname_of h a) pc (compxE2 e 0 0)")
case (Some pcd)
from exec ‹xcp = ⌊a⌋› Some pc
have stk': "stk' = Addr a # (drop (length stk - snd pcd) stk) @ STK"
by(auto elim!: exec_meth.cases simp add: match_ex_table_append split: if_split_asm dest!: match_ex_table_stack_xliftD)
from exec' ‹xcp = ⌊a⌋› Some pc have "exec_meth_d (compP2 P)
(compE2 e) (stack_xlift (length STK) (compxE2 e 0 0)) t h (stk @ STK, loc, pc, ⌊a⌋) ε h (Addr a # (drop (length (stk @ STK) - (snd pcd + length STK)) (stk @ STK)), loc, pc', None)"
apply -
apply(rule exec_meth.intros)
apply(auto elim!: exec_meth.cases simp add: match_ex_table_append split: if_split_asm dest!: match_ex_table_shift_pcD match_ex_table_stack_xliftD)
done
from IH[unfolded ‹ta = ε› ‹xcp = ⌊a⌋› ‹h' = h›, OF this]
have stk: "Addr a # drop (length stk - snd pcd) (stk @ STK) = Addr a # drop (length stk - snd pcd) stk @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e) (compxE2 e 0 0) t h (stk, loc, pc, ⌊a⌋) ε h (Addr a # drop (length stk - snd pcd) stk, loc, pc', None)" by auto
thus ?thesis using Some stk' ‹xcp = ⌊a⌋› by(auto)
next
case None
with Some exec pc have stk': "stk' = Addr a # STK"
and pc': "pc' = Suc (length (compE2 e))"
and subcls: "compP2 P ⊢ cname_of h a ≼⇧* C'"
by(auto elim!: exec_meth.cases split: if_split_asm simp add: match_ex_table_append_not_pcs)(simp add: matches_ex_entry_def)
moreover from Some True None pc' subcls
have "exec_meth_d (compP2 P) (compE2 (try e catch(C' V) e2)) (compxE2 (try e catch(C' V) e2) 0 0) t h
(stk, loc, pc, ⌊a⌋) ε h (Addr a # drop (length stk - 0) stk, loc, pc', None)"
by -(rule exec_catch,auto simp add: match_ex_table_append_not_pcs matches_ex_entry_def)
ultimately show ?thesis using Some by auto
qed
qed
next
case False
with pc have [simp]: "pc = length (compE2 e)" by simp
from bisim obtain v where "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec show ?thesis by(auto elim!: exec_meth.cases intro!: exec_meth.intros split: if_split_asm)
qed
next
case bisim1TryCatch1 thus ?case
by(auto elim!: exec_meth.cases intro!: exec_meth.intros split: if_split_asm)
next
case (bisim1TryCatch2 e2 n e' xs stk loc pc xcp e C' V)
note bisim = ‹P,e2,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?exec (try e catch(C' V) e2) stk STK loc (Suc (Suc (length (compE2 e) + pc))) xcp stk' loc' pc' xcp'›
let ?pre = "compE2 e @ [Goto (int (length (compE2 e2)) + 2), Store V]"
from exec have exec': "exec_meth_d (compP2 P) (?pre @ compE2 e2)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length ?pre) (stack_xlift (length STK) (compxE2 e2 0 0))) t
h (stk @ STK, loc, length ?pre + pc, xcp) ta h' (stk', loc', pc', xcp')"
proof(cases)
case (exec_catch xcp'' d)
let ?stk = "stk @ STK" and ?PC = "Suc (Suc (length (compE2 e) + pc))"
note s = ‹stk' = Addr xcp'' # drop (length ?stk - d) ?stk›
‹ta = ε› ‹h' = h› ‹xcp' = None› ‹xcp = ⌊xcp''⌋› ‹loc' = loc›
from ‹match_ex_table (compP2 P) (cname_of h xcp'') ?PC (stack_xlift (length STK) (compxE2 (try e catch(C' V) e2) 0 0)) = ⌊(pc', d)⌋› ‹d ≤ length ?stk›
show ?thesis unfolding s
by -(rule exec_meth.exec_catch, simp_all add: shift_compxE2 stack_xlift_compxE2, simp add: match_ex_table_append add: matches_ex_entry_def)
qed(auto intro: exec_meth.intros simp add: shift_compxE2 stack_xlift_compxE2)
hence "?exec e2 stk STK loc pc xcp stk' loc' (pc' - length ?pre) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length ?pre, xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) (?pre @ compE2 e2) (compxE2 e 0 0 @ shift (length ?pre) (compxE2 e2 0 0)) t h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) (?pre @ compE2 e2) (compxE2 e 0 0 @ shift (length ?pre) (compxE2 e2 0 0) @ [(0, length (compE2 e), ⌊C'⌋, Suc (length (compE2 e)), 0)]) t h (stk, loc, length ?pre + pc, xcp) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule exec_meth.cases)(auto intro: exec_meth.intros simp add: match_ex_table_append_not_pcs)
moreover from exec' have "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
moreover hence "(Suc (Suc (pc' - Suc (Suc 0)))) = pc'" by simp
ultimately show ?case using stk' by(auto simp add: shift_compxE2 eval_nat_numeral)
next
case (bisim1TryFail e n a xs stk loc pc C' C'' e2 V)
note bisim = ‹P,e,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note exec = ‹?exec (try e catch(C'' V) e2) stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note a = ‹typeof_addr h a = ⌊Class_type C'⌋› ‹¬ P ⊢ C' ≼⇧* C''›
from bisim have "match_ex_table (compP2 P) (cname_of h a) (0 + pc) (compxE2 e 0 0) = None"
unfolding compP2_def by(rule bisim1_xcp_Some_not_caught)
moreover from bisim have "pc < length (compE2 e)" by(auto dest: bisim1_ThrowD)
ultimately have False using exec a
apply(auto elim!: exec_meth.cases simp add: outside_pcs_compxE2_not_matches_entry outside_pcs_not_matches_entry split: if_split_asm)
apply(auto simp add: compP2_def match_ex_entry match_ex_table_append_not_pcs cname_of_def split: if_split_asm)
done
thus ?case ..
next
case (bisim1TryCatchThrow e2 n a xs stk loc pc e C' V)
note bisim = ‹P,e2,h ⊢ (Throw a, xs) ↔ (stk, loc, pc, ⌊a⌋)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?exec e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'
⟹ ?concl e2 stk STK loc pc ⌊a⌋ stk' loc' pc' xcp'›
note exec = ‹?exec (try e catch(C' V) e2) stk STK loc (Suc (Suc (length (compE2 e) + pc))) ⌊a⌋ stk' loc' pc' xcp'›
from bisim have pc: "pc < length (compE2 e2)" by(auto dest: bisim1_ThrowD)
let ?pre = "compE2 e @ [Goto (int (length (compE2 e2)) + 2), Store V]"
from exec have exec': "exec_meth_d (compP2 P) (?pre @ compE2 e2) (stack_xlift (length STK) (compxE2 e 0 0) @
shift (length ?pre) (stack_xlift (length STK) (compxE2 e2 0 0))) t
h (stk @ STK, loc, length ?pre + pc, ⌊a⌋) ta h' (stk', loc', pc', xcp')"
proof(cases)
case (exec_catch d)
let ?stk = "stk @ STK" and ?PC = "Suc (Suc (length (compE2 e) + pc))"
note s = ‹stk' = Addr a # drop (length ?stk - d) ?stk› ‹loc' = loc›
‹ta = ε› ‹h' = h› ‹xcp' = None›
from ‹match_ex_table (compP2 P) (cname_of h a) ?PC (stack_xlift (length STK) (compxE2 (try e catch(C' V) e2) 0 0)) = ⌊(pc', d)⌋› ‹d ≤ length ?stk›
show ?thesis unfolding s
by -(rule exec_meth.exec_catch, simp_all add: shift_compxE2 stack_xlift_compxE2, simp add: match_ex_table_append add: matches_ex_entry_def)
qed
hence "?exec e2 stk STK loc pc ⌊a⌋ stk' loc' (pc' - length ?pre) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ STK"
and exec'': "exec_meth_d (compP2 P) (compE2 e2) (compxE2 e2 0 0) t h (stk, loc, pc, ⌊a⌋) ta h' (stk'', loc', pc' - length ?pre, xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) (?pre @ compE2 e2) (compxE2 e 0 0 @ shift (length ?pre) (compxE2 e2 0 0)) t h (stk, loc, length ?pre + pc, ⌊a⌋) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule append_exec_meth_xt) auto
hence "exec_meth_d (compP2 P) (?pre @ compE2 e2) (compxE2 e 0 0 @ shift (length ?pre) (compxE2 e2 0 0) @ [(0, length (compE2 e), ⌊C'⌋, Suc (length (compE2 e)), 0)]) t h (stk, loc, length ?pre + pc, ⌊a⌋) ta h' (stk'', loc', length ?pre + (pc' - length ?pre), xcp')"
by(rule exec_meth.cases)(auto intro!: exec_meth.intros simp add: match_ex_table_append_not_pcs)
moreover from exec' have "pc' ≥ length ?pre"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
moreover hence "(Suc (Suc (pc' - Suc (Suc 0)))) = pc'" by simp
ultimately show ?case using stk' by(auto simp add: shift_compxE2 eval_nat_numeral)
next
case bisims1Nil thus ?case by(auto elim: exec_meth.cases)
next
case (bisims1List1 e n e' xs stk loc pc xcp es)
note bisim1 = ‹P,e,h ⊢ (e', xs ) ↔ (stk, loc, pc, xcp)›
note IH1 = ‹⋀stk' loc' pc' xcp' STK. ?exec e stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concl e stk STK loc pc xcp stk' loc' pc' xcp'›
note IH2 = ‹⋀xs stk' loc' pc' xcp' STK. ?execs es [] STK xs 0 None stk' loc' pc' xcp'
⟹ ?concls es [] STK xs 0 None stk' loc' pc' xcp'›
note exec = ‹?execs (e # es) stk STK loc pc xcp stk' loc' pc' xcp'›
from bisim1 have pc: "pc ≤ length (compE2 e)" by(rule bisim1_pc_length_compE2)
show ?case
proof(cases "pc < length (compE2 e)")
case True
with exec have "?exec e stk STK loc pc xcp stk' loc' pc' xcp'"
by(simp add: compxEs2_size_convs)(erule exec_meth_take_xt)
from IH1[OF this] show ?thesis by auto
next
case False
with pc have pc: "pc = length (compE2 e)" by simp
with bisim1 obtain v where s: "stk = [v]" "xcp = None" by(auto dest: bisim1_pc_length_compE2D)
with exec pc have exec': "exec_meth_d (compP2 P) (compE2 e @ compEs2 es)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length (v # STK)) (compxEs2 es 0 0))) t
h ([] @ v # STK, loc, length (compE2 e) + 0, None) ta h' (stk', loc', pc', xcp')"
by(simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)
hence "?execs es [] (v # STK) loc 0 None stk' loc' (pc' - length (compE2 e)) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH2[OF this] obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec'': "exec_meth_d (compP2 P) (compEs2 es) (compxEs2 es 0 0) t h ([], loc, 0, None) ta h' (stk'', loc', pc' - length (compE2 e), xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) (compEs2 es) (stack_xlift (length [v]) (compxEs2 es 0 0)) t h ([] @ [v], loc, 0, None) ta h' (stk'' @ [v], loc', pc' - length (compE2 e), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e @ compEs2 es) (compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v]) (compxEs2 es 0 0))) t h ([] @ [v], loc, length (compE2 e) + 0, None) ta h' (stk'' @ [v], loc', length (compE2 e) + (pc' - length (compE2 e)), xcp')"
by(rule append_exec_meth_xt) auto
moreover from exec' have "pc' ≥ length (compE2 e)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?thesis using s pc stk' by(auto simp add: shift_compxEs2 stack_xlift_compxEs2)
qed
next
case (bisims1List2 es n es' xs stk loc pc xcp e v)
note bisim = ‹P,es,h ⊢ (es',xs) [↔] (stk,loc,pc,xcp)›
note IH = ‹⋀stk' loc' pc' xcp' STK. ?execs es stk STK loc pc xcp stk' loc' pc' xcp'
⟹ ?concls es stk STK loc pc xcp stk' loc' pc' xcp'›
note exec = ‹?execs (e # es) (stk @ [v]) STK loc (length (compE2 e) + pc) xcp stk' loc' pc' xcp'›
from exec have exec': "exec_meth_d (compP2 P) (compE2 e @ compEs2 es)
(stack_xlift (length STK) (compxE2 e 0 0) @ shift (length (compE2 e)) (stack_xlift (length (v # STK)) (compxEs2 es 0 0))) t
h (stk @ v # STK, loc, length (compE2 e) + pc, xcp) ta h' (stk', loc', pc', xcp')"
by(simp add: compxEs2_size_convs compxEs2_stack_xlift_convs)
hence "?execs es stk (v # STK) loc pc xcp stk' loc' (pc' - length (compE2 e)) xcp'"
by(rule exec_meth_drop_xt)(auto simp add: stack_xlift_compxE2)
from IH[OF this] obtain stk'' where stk': "stk' = stk'' @ v # STK"
and exec'': "exec_meth_d (compP2 P) (compEs2 es) (compxEs2 es 0 0) t h (stk, loc, pc, xcp) ta h' (stk'', loc', pc' - length (compE2 e), xcp')" by auto
from exec'' have "exec_meth_d (compP2 P) (compEs2 es) (stack_xlift (length [v]) (compxEs2 es 0 0)) t h (stk @ [v], loc, pc, xcp) ta h' (stk'' @ [v], loc', pc' - length (compE2 e), xcp')"
by(rule exec_meth_stk_offer)
hence "exec_meth_d (compP2 P) (compE2 e @ compEs2 es) (compxE2 e 0 0 @ shift (length (compE2 e)) (stack_xlift (length [v]) (compxEs2 es 0 0))) t h (stk @ [v], loc, length (compE2 e) + pc, xcp) ta h' (stk'' @ [v], loc', length (compE2 e) + (pc' - length (compE2 e)), xcp')"
by(rule append_exec_meth_xt) auto
moreover from exec' have "pc' ≥ length (compE2 e)"
by(rule exec_meth_drop_xt_pc)(auto simp add: stack_xlift_compxE2)
ultimately show ?case using stk' by(auto simp add: shift_compxEs2 stack_xlift_compxEs2)
next
case (bisim1Sync12 e1 n e2 V a xs v v')
note exec = ‹?exec (sync⇘V⇙ (e1) e2) [v, v'] STK xs (4 + length (compE2 e1) + length (compE2 e2)) ⌊a⌋ stk' loc' pc' xcp'›
thus ?case by(auto elim!: exec_meth.cases split: if_split_asm simp add: match_ex_table_append_not_pcs)(simp add: matches_ex_entry_def)
next
case (bisim1Sync14 e1 n e2 V a xs v a')
note exec = ‹?exec (sync⇘V⇙ (e1) e2) [v, Addr a'] STK xs (7 + length (compE2 e1) + length (compE2 e2)) ⌊a⌋ stk' loc' pc' xcp'›
thus ?case by(auto elim!: exec_meth.cases split: if_split_asm simp add: match_ex_table_append_not_pcs)(simp add: matches_ex_entry_def)
qed
lemma shows bisim1_callD:
"⟦ P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, xcp); call1 e' = ⌊(a, M, vs)⌋;
compE2 e ! pc = Invoke M' n0 ⟧
⟹ M = M'"
and bisims1_callD:
"⟦ P,es,h ⊢ (es',xs) [↔] (stk,loc,pc, xcp); calls1 es' = ⌊(a, M, vs)⌋;
compEs2 es ! pc = Invoke M' n0 ⟧
⟹ M = M'"
proof(induct e "n :: nat" e' xs stk loc pc xcp and es "n :: nat" es' xs stk loc pc xcp
rule: bisim1_bisims1_inducts_split)
case bisim1AAss1 thus ?case
apply(simp (no_asm_use) split: if_split_asm add: is_val_iff)
apply(fastforce dest: bisim_Val_pc_not_Invoke)
apply(fastforce dest: bisim_Val_pc_not_Invoke)
apply(fastforce dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)+
done
next
case bisim1Call1 thus ?case
apply(clarsimp split: if_split_asm simp add: is_vals_conv)
apply(drule bisim_Val_pc_not_Invoke, simp, fastforce)
apply(drule bisim_Val_pc_not_Invoke, simp, fastforce)
apply(drule bisim1_pc_length_compE2, clarsimp simp add: neq_Nil_conv)
apply(drule bisim1_pc_length_compE2, simp)
apply(drule bisim1_pc_length_compE2, simp)
apply(drule bisim1_pc_length_compE2, simp)
apply(drule bisim1_call_pcD, simp, simp)
apply(drule bisim1_call_pcD, simp, simp)
done
next
case bisim1CallParams thus ?case
apply(clarsimp split: if_split_asm simp add: is_vals_conv)
apply(drule bisims_Val_pc_not_Invoke, simp, fastforce)
apply(drule bisims1_pc_length_compEs2, simp)
apply(drule bisims1_calls_pcD, simp, simp)
done
qed(fastforce split: if_split_asm dest: bisim1_pc_length_compE2 bisims1_pc_length_compEs2 bisim1_call_pcD bisims1_calls_pcD bisim1_call_xcpNone bisims1_calls_xcpNone bisim_Val_pc_not_Invoke bisims_Val_pc_not_Invoke)+
lemma bisim1_xcpD: "P,e,h ⊢ (e', xs) ↔ (stk, loc, pc, ⌊a⌋) ⟹ pc < length (compE2 e)"
and bisims1_xcpD: "P,es,h ⊢ (es', xs) [↔] (stk, loc, pc, ⌊a⌋) ⟹ pc < length (compEs2 es)"
by(induct "(e', xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)" and "(es', xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)"
arbitrary: e' xs stk loc pc and es' xs stk loc pc rule: bisim1_bisims1.inducts)
simp_all
lemma bisim1_match_Some_stk_length:
"⟦ P,E,h ⊢ (e, xs) ↔ (stk, loc, pc, ⌊a⌋);
match_ex_table (compP2 P) (cname_of h a) pc (compxE2 E 0 0) = ⌊(pc', d)⌋ ⟧
⟹ d ≤ length stk"
and bisims1_match_Some_stk_length:
"⟦ P,Es,h ⊢ (es, xs) [↔] (stk, loc, pc, ⌊a⌋);
match_ex_table (compP2 P) (cname_of h a) pc (compxEs2 Es 0 0) = ⌊(pc', d)⌋ ⟧
⟹ d ≤ length stk"
proof(induct "(e, xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)" and "(es, xs)" "(stk, loc, pc, ⌊a :: 'addr⌋)"
arbitrary: pc' d e xs stk loc pc and pc' d es xs stk loc pc rule: bisim1_bisims1.inducts)
case bisim1Call1 thus ?case
by(fastforce dest: bisim1_xcpD simp add: match_ex_table_append match_ex_table_not_pcs_None)
next
case bisim1CallThrowObj thus ?case
by(fastforce dest: bisim1_xcpD simp add: match_ex_table_append match_ex_table_not_pcs_None)
next
case bisim1Sync4 thus ?case
apply(clarsimp simp add: match_ex_table_not_pcs_None match_ex_table_append matches_ex_entry_def split: if_split_asm)
apply(fastforce simp add: match_ex_table_compxE2_shift_conv dest: bisim1_xcpD)
done
next
case bisim1Try thus ?case
by(fastforce simp add: match_ex_table_append matches_ex_entry_def match_ex_table_not_pcs_None dest: bisim1_xcpD split: if_split_asm)
next
case bisim1TryCatch2 thus ?case
apply(clarsimp simp add: match_ex_table_not_pcs_None match_ex_table_append matches_ex_entry_def split: if_split_asm)
apply(fastforce simp add: match_ex_table_compxE2_shift_conv dest: bisim1_xcpD)
done
next
case bisim1TryFail thus ?case
by(fastforce simp add: match_ex_table_append matches_ex_entry_def match_ex_table_not_pcs_None dest: bisim1_xcpD split: if_split_asm)
next
case bisim1TryCatchThrow thus ?case
apply(clarsimp simp add: match_ex_table_not_pcs_None match_ex_table_append matches_ex_entry_def split: if_split_asm)
apply(fastforce simp add: match_ex_table_compxE2_shift_conv dest: bisim1_xcpD)
done
next
case bisims1List1 thus ?case
by(fastforce simp add: match_ex_table_append split: if_split_asm dest: bisim1_xcpD match_ex_table_pcsD)
qed(fastforce simp add: match_ex_table_not_pcs_None match_ex_table_append match_ex_table_compxE2_shift_conv match_ex_table_compxEs2_shift_conv match_ex_table_compxE2_stack_conv match_ex_table_compxEs2_stack_conv matches_ex_entry_def dest: bisim1_xcpD)+
end
locale J1_JVM_heap_conf_base =
J1_JVM_heap_base
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
+
J1_heap_conf_base
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
hconf P
+
JVM_heap_conf_base
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
hconf "compP2 P"
for addr2thread_id :: "('addr :: addr) ⇒ 'thread_id"
and thread_id2addr :: "'thread_id ⇒ 'addr"
and spurious_wakeups :: bool
and empty_heap :: "'heap"
and allocate :: "'heap ⇒ htype ⇒ ('heap × 'addr) set"
and typeof_addr :: "'heap ⇒ 'addr ⇀ htype"
and heap_read :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ bool"
and heap_write :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ 'heap ⇒ bool"
and hconf :: "'heap ⇒ bool"
and P :: "'addr J1_prog"
begin
inductive bisim1_list1 ::
"'thread_id ⇒ 'heap ⇒ 'addr expr1 × 'addr locals1 ⇒ ('addr expr1 × 'addr locals1) list
⇒ 'addr option ⇒ 'addr frame list ⇒ bool"
for t :: 'thread_id and h :: 'heap
where
bl1_Normal:
"⟦ compTP P ⊢ t:(xcp, h, (stk, loc, C, M, pc) # frs) √;
P ⊢ C sees M : Ts→T = ⌊body⌋ in D;
P,blocks1 0 (Class D#Ts) body, h ⊢ (e, xs) ↔ (stk, loc, pc, xcp); max_vars e ≤ length xs;
list_all2 (bisim1_fr P h) exs frs ⟧
⟹ bisim1_list1 t h (e, xs) exs xcp ((stk, loc, C, M, pc) # frs)"
| bl1_finalVal:
"⟦ hconf h; preallocated h ⟧ ⟹ bisim1_list1 t h (Val v, xs) [] None []"
| bl1_finalThrow:
"⟦ hconf h; preallocated h ⟧ ⟹ bisim1_list1 t h (Throw a, xs) [] ⌊a⌋ []"
fun wbisim1 ::
"'thread_id
⇒ ((('addr expr1 × 'addr locals1) × ('addr expr1 × 'addr locals1) list) × 'heap,
('addr option × 'addr frame list) × 'heap) bisim"
where "wbisim1 t ((ex, exs), h) ((xcp, frs), h') ⟷ h = h' ∧ bisim1_list1 t h ex exs xcp frs"
lemma new_thread_conf_compTP:
assumes hconf: "hconf h" "preallocated h"
and ha: "typeof_addr h a = ⌊Class_type C⌋"
and sub: "typeof_addr h (thread_id2addr t) = ⌊Class_type C'⌋" "P ⊢ C' ≼⇧* Thread"
and sees: "P ⊢ C sees M: []→T = ⌊meth⌋ in D"
shows "compTP P ⊢ t:(None, h, [([], Addr a # replicate (max_vars meth) undefined_value, D, M, 0)]) √"
proof -
from ha sees_method_decl_above[OF sees]
have "P,h ⊢ Addr a :≤ Class D" by(simp add: conf_def)
moreover
hence "compP2 P,h ⊢ Addr a :≤ Class D" by(simp add: compP2_def)
hence "compP2 P,h ⊢ Addr a # replicate (max_vars meth) undefined_value [:≤⇩⊤] map (λi. if i = 0 then OK ([Class D] ! i) else Err) [0..<max_vars meth] @ [Err]"
by -(rule list_all2_all_nthI, simp_all)
hence "conf_f (compP2 P) h ([], map (λi. if i = 0 then OK ([Class D] ! i) else Err) [0..<max_vars meth] @ [Err])
(compE2 meth @ [Return]) ([], Addr a # replicate (max_vars meth) undefined_value, D, M, 0)"
unfolding conf_f_def2 by(simp add: compP2_def)
ultimately have "conf_f (compP2 P) h ([], TC0.ty⇩l (Suc (max_vars meth)) [Class D] {0}) (compE2 meth @ [Return])
([], Addr a # replicate (max_vars meth) undefined_value, D, M, 0)"
by(simp add: TC0.ty⇩l_def conf_f_def2 compP2_def)
with hconf ha sub sees_method_compP[OF sees, where f="λC M Ts T. compMb2"] sees_method_idemp[OF sees]
show ?thesis
by(auto simp add: TC0.ty⇩i'_def correct_state_def compTP_def tconf_def)(fastforce simp add: compP2_def compMb2_def tconf_def intro: sees_method_idemp)+
qed
lemma ta_bisim12_extTA2J1_extTA2JVM:
assumes nt: "⋀n T C M a h. ⟦ n < length ⦃ta⦄⇘t⇙; ⦃ta⦄⇘t⇙ ! n = NewThread T (C, M, a) h ⟧
⟹ typeof_addr h a = ⌊Class_type C⌋ ∧ (∃C'. typeof_addr h (thread_id2addr T) = ⌊Class_type C'⌋ ∧ P ⊢ C' ≼⇧* Thread) ∧
(∃T meth D. P ⊢ C sees M:[]→T =⌊meth⌋ in D) ∧ hconf h ∧ preallocated h"
shows "ta_bisim wbisim1 (extTA2J1 P ta) (extTA2JVM (compP2 P) ta)"
proof -
{ fix n t C M a m
assume "n < length ⦃ta⦄⇘t⇙" and "⦃ta⦄⇘t⇙ ! n = NewThread t (C, M, a) m"
from nt[OF this] obtain T meth D C'
where ma: "typeof_addr m a = ⌊Class_type C⌋"
and sees: "P ⊢ C sees M: []→T = ⌊meth⌋ in D"
and sub: "typeof_addr m (thread_id2addr t) = ⌊Class_type C'⌋" "P ⊢ C' ≼⇧* Thread"
and mconf: "hconf m" "preallocated m" by fastforce
from sees_method_compP[OF sees, where f="λC M Ts T. compMb2"]
have sees': "compP2 P ⊢ C sees M: []→T = ⌊(max_stack meth, max_vars meth, compE2 meth @ [Return], compxE2 meth 0 0)⌋ in D"
by(simp add: compMb2_def compP2_def)
have "bisim1_list1 t m ({0:Class D=None; meth}, Addr a # replicate (max_vars meth) undefined_value) ([]) None [([], Addr a # replicate (max_vars meth) undefined_value, D, M, 0)]"
proof
from mconf ma sub sees
show "compTP P ⊢ t:(None, m, [([], Addr a # replicate (max_vars meth) undefined_value, D, M, 0)]) √"
by(rule new_thread_conf_compTP)
from sees show "P ⊢ D sees M: []→T = ⌊meth⌋ in D" by(rule sees_method_idemp)
show "list_all2 (bisim1_fr P m) [] []" by simp
show "P,blocks1 0 [Class D] meth,m ⊢ ({0:Class D=None; meth}, Addr a # replicate (max_vars meth) undefined_value) ↔
([], Addr a # replicate (max_vars meth) undefined_value, 0, None)"
by simp(rule bisim1_refl)
qed simp
with sees sees' have "bisim1_list1 t m ({0:Class (fst (method P C M))=None; the (snd (snd (snd (method P C M))))}, Addr a # replicate (max_vars (the (snd (snd (snd (method P C M)))))) undefined_value) [] None [([], Addr a # replicate (fst (snd (the (snd (snd (snd (method (compP2 P) C M))))))) undefined_value, fst (method (compP2 P) C M), M, 0)]" by simp }
thus ?thesis
apply(auto simp add: ta_bisim_def intro!: list_all2_all_nthI)
apply(case_tac "⦃ta⦄⇘t⇙ ! n", auto simp add: extNTA2JVM_def)
done
qed
end
definition no_call2 :: "'addr expr1 ⇒ pc ⇒ bool"
where "no_call2 e pc ⟷ (pc ≤ length (compE2 e)) ∧ (pc < length (compE2 e) ⟶ (∀M n. compE2 e ! pc ≠ Invoke M n))"
definition no_calls2 :: "'addr expr1 list ⇒ pc ⇒ bool"
where "no_calls2 es pc ⟷ (pc ≤ length (compEs2 es)) ∧ (pc < length (compEs2 es) ⟶ (∀M n. compEs2 es ! pc ≠ Invoke M n))"
locale J1_JVM_conf_read =
J1_JVM_heap_conf_base
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
hconf P
+
JVM_conf_read
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
hconf "compP2 P"
for addr2thread_id :: "('addr :: addr) ⇒ 'thread_id"
and thread_id2addr :: "'thread_id ⇒ 'addr"
and spurious_wakeups :: bool
and empty_heap :: "'heap"
and allocate :: "'heap ⇒ htype ⇒ ('heap × 'addr) set"
and typeof_addr :: "'heap ⇒ 'addr ⇀ htype"
and heap_read :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ bool"
and heap_write :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ 'heap ⇒ bool"
and hconf :: "'heap ⇒ bool"
and P :: "'addr J1_prog"
locale J1_JVM_heap_conf =
J1_JVM_heap_conf_base
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
hconf P
+
JVM_heap_conf
addr2thread_id thread_id2addr
spurious_wakeups
empty_heap allocate typeof_addr heap_read heap_write
hconf "compP2 P"
for addr2thread_id :: "('addr :: addr) ⇒ 'thread_id"
and thread_id2addr :: "'thread_id ⇒ 'addr"
and spurious_wakeups :: bool
and empty_heap :: "'heap"
and allocate :: "'heap ⇒ htype ⇒ ('heap × 'addr) set"
and typeof_addr :: "'heap ⇒ 'addr ⇀ htype"
and heap_read :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ bool"
and heap_write :: "'heap ⇒ 'addr ⇒ addr_loc ⇒ 'addr val ⇒ 'heap ⇒ bool"
and hconf :: "'heap ⇒ bool"
and P :: "'addr J1_prog"
begin
lemma red_external_ta_bisim21:
"⟦ wf_prog wf_md P; P,t ⊢ ⟨a∙M(vs), h⟩ -ta→ext ⟨va, h'⟩; hconf h'; preallocated h' ⟧
⟹ ta_bisim wbisim1 (extTA2J1 P ta) (extTA2JVM (compP2 P) ta)"
apply(rule ta_bisim12_extTA2J1_extTA2JVM)
apply(frule (1) red_external_new_thread_sees)
apply(fastforce simp add: in_set_conv_nth)
apply(frule red_ext_new_thread_heap)
apply(fastforce simp add: in_set_conv_nth)
apply(frule red_external_new_thread_exists_thread_object[unfolded compP2_def, simplified])
apply(fastforce simp add: in_set_conv_nth)
apply simp
done
lemma ta_bisim_red_extTA2J1_extTA2JVM:
assumes wf: "wf_prog wf_md P"
and red: "uf,P,t' ⊢1 ⟨e, s⟩ -ta→ ⟨e', s'⟩"
and hconf: "hconf (hp s')" "preallocated (hp s')"
shows "ta_bisim wbisim1 (extTA2J1 P ta) (extTA2JVM (compP2 P) ta)"
proof -
{ fix n t C M a H
assume len: "n < length ⦃ta⦄⇘t⇙" and tan: "⦃ta⦄⇘t⇙ ! n = NewThread t (C, M, a) H"
hence nt: "NewThread t (C, M, a) H ∈ set ⦃ta⦄⇘t⇙" unfolding set_conv_nth by(auto intro!: exI)
from red1_new_threadD[OF red nt] obtain ad M' vs va T C' Ts' Tr' D'
where rede: "P,t' ⊢ ⟨ad∙M'(vs),hp s⟩ -ta→ext ⟨va,hp s'⟩"
and ad: "typeof_addr (hp s) ad = ⌊T⌋" by blast
from red_ext_new_thread_heap[OF rede nt] have [simp]: "hp s' = H" by simp
from red_external_new_thread_sees[OF wf rede nt]
obtain T body D where Ha: "typeof_addr H a = ⌊Class_type C⌋"
and sees: "P ⊢ C sees M:[]→T=⌊body⌋ in D" by auto
have sees': "compP2 P ⊢ C sees M:[]→T=⌊(max_stack body, max_vars body, compE2 body @ [Return], compxE2 body 0 0)⌋ in D"
using sees unfolding compP2_def compMb2_def Let_def by(auto dest: sees_method_compP)
from red_external_new_thread_exists_thread_object[unfolded compP2_def, simplified, OF rede nt] hconf Ha sees
have "compTP P ⊢ t:(None, H, [([], Addr a # replicate (max_vars body) undefined_value, D, M, 0)]) √"
by(auto intro: new_thread_conf_compTP)
hence "bisim1_list1 t H ({0:Class D=None; body}, Addr a # replicate (max_vars body) undefined_value) [] None [([], Addr a # replicate (max_vars body) undefined_value, D, M, 0)]"
proof
from sees show "P ⊢ D sees M:[]→T=⌊body⌋ in D" by(rule sees_method_idemp)
show "P,blocks1 0 [Class D] body,H ⊢ ({0:Class D=None; body}, Addr a # replicate (max_vars body) undefined_value) ↔
([], Addr a # replicate (max_vars body) undefined_value, 0, None)"
by(auto intro: bisim1_refl)
qed simp_all
hence "bisim1_list1 t H ({0:Class (fst (method P C M))=None; the (snd (snd (snd (method P C M))))},
Addr a # replicate (max_vars (the (snd (snd (snd (method P C M)))))) undefined_value)
[]
None [([], Addr a # replicate (fst (snd (the (snd (snd (snd (method (compP2 P) C M))))))) undefined_value,
fst (method (compP2 P) C M), M, 0)]"
using sees sees' by simp }
thus ?thesis
apply(auto simp add: ta_bisim_def intro!: list_all2_all_nthI)
apply(case_tac "⦃ta⦄⇘t⇙ ! n")
apply(auto simp add: extNTA2JVM_def extNTA2J1_def)
done
qed
end
sublocale J1_JVM_conf_read < heap_conf?: J1_JVM_heap_conf
by(unfold_locales)
sublocale J1_JVM_conf_read < heap?: J1_heap
apply(rule J1_heap.intro)
apply(subst compP_heap[symmetric, where f="λ_ _ _ _. compMb2", folded compP2_def])
apply(unfold_locales)
done
end