Theory J1JVM

(*  Title:      JinjaThreads/Compiler/J1JVM.thy
    Author:     Andreas Lochbihler
*)

section ‹Correctness of Stage: From intermediate language to JVM›

theory J1JVM imports J1JVMBisim begin

context J1_JVM_heap_base begin

declare τmove1.simps [simp del] τmoves1.simps [simp del]

lemma bisim1_insync_Throw_exec:
  assumes bisim2: "P,e2,h  (Throw ad, xs)  (stk, loc, pc, xcp)"
  shows "τExec_movet_a P t (sync⇘V(e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, 6 + length (compE2 e1) + length (compE2 e2), None)"
proof -
  from bisim2 have pc: "pc < length (compE2 e2)" and [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
  let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
  let ?stk = "Addr ad # drop (size stk - 0) stk"
  from bisim2 have "xcp = ad  xcp = None" by(auto dest: bisim1_ThrowD)
  thus ?thesis
  proof
    assume [simp]: "xcp = ad"
    have "τExec_movet_a P t (sync⇘V(e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), ad) (?stk, loc, ?pc, None)"
    proof(rule τExect1step[unfolded exec_move_def, OF exec_catch])
      from bisim1_xcp_Some_not_caught[OF bisim2[simplified], of "λC M Ts T. compMb2" "Suc (Suc (Suc (length (compE2 e1))))" 0]
      have "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc)))) (compxE2 e2 (Suc (Suc (Suc (length (compE2 e1))))) 0) = None"
        by(simp add: compP2_def)
      thus "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc)))) (compxE2 (sync⇘V(e1) e2) 0 0) = (6 + length (compE2 e1) + length (compE2 e2), 0)"
        using pc
        by(auto simp add: compP2_def match_ex_table_append matches_ex_entry_def eval_nat_numeral
                dest: match_ex_table_pc_length_compE2)
    qed(insert pc, auto intro: τmove2xcp)
    thus ?thesis by simp
  next
    assume [simp]: "xcp = None"
    with bisim2 obtain pc'
      where "τExec_movet_a P t e2 h (stk, loc, pc, None) ([Addr ad], loc, pc', ad)"
      and bisim': "P, e2, h  (Throw ad, xs)  ([Addr ad], loc, pc', ad)" and [simp]: "xs = loc"
      by(auto dest: bisim1_Throw_τExec_movet)
    hence "τExec_movet_a P t (sync⇘V(e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), None) ([Addr ad], loc, Suc (Suc (Suc (length (compE2 e1) + pc'))), ad)"
      by-(rule Insync_τExectI)
    also let ?stk = "Addr ad # drop (size [Addr ad] - 0) [Addr ad]"
    from bisim' have pc': "pc' < length (compE2 e2)" by(auto dest: bisim1_ThrowD)
    have "τExec_movet_a P t (sync⇘V(e1) e2) h ([Addr ad], loc, Suc (Suc (Suc (length (compE2 e1) + pc'))), ad) (?stk, loc, ?pc, None)"
    proof(rule τExect1step[unfolded exec_move_def, OF exec_catch])
      from bisim1_xcp_Some_not_caught[OF bisim', of "λC M Ts T. compMb2" "Suc (Suc (Suc (length (compE2 e1))))" 0]
      have "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc')))) (compxE2 e2 (Suc (Suc (Suc (length (compE2 e1))))) 0) = None"
        by(simp add: compP2_def)
      thus "match_ex_table (compP2 P) (cname_of h ad) (Suc (Suc (Suc (length (compE2 e1) + pc')))) (compxE2 (sync⇘V(e1) e2) 0 0) = (6 + length (compE2 e1) + length (compE2 e2), 0)"
        using pc'
        by(auto simp add: compP2_def match_ex_table_append matches_ex_entry_def eval_nat_numeral
                dest: match_ex_table_pc_length_compE2)
    qed(insert pc', auto intro: τmove2xcp)
    finally (tranclp_trans) show ?thesis by simp
  qed
qed

end

primrec sim12_size :: "('a, 'b, 'addr) exp  nat"
  and sim12_sizes :: "('a, 'b, 'addr) exp list  nat"
where
  "sim12_size (new C) = 0"
| "sim12_size (newA Te) = Suc (sim12_size e)"
| "sim12_size (Cast T e) = Suc (sim12_size e)"
| "sim12_size (e instanceof T) = Suc (sim12_size e)"
| "sim12_size (e «bop» e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (Val v) = 0"
| "sim12_size (Var V) = 0"
| "sim12_size (V := e) = Suc (sim12_size e)"
| "sim12_size (ai) = Suc (sim12_size a + sim12_size i)"
| "sim12_size (ai := e) = Suc (sim12_size a + sim12_size i + sim12_size e)"
| "sim12_size (a∙length) = Suc (sim12_size a)"
| "sim12_size (eF{D}) = Suc (sim12_size e)"
| "sim12_size (eF{D} := e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (e∙compareAndSwap(DF, e', e'')) = Suc (sim12_size e + sim12_size e' + sim12_size e'')"
| "sim12_size (eM(es)) = Suc (sim12_size e + sim12_sizes es)"
| "sim12_size ({V:T=vo; e}) = Suc (sim12_size e)"
| "sim12_size (sync⇘V(e) e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (insync⇘V(a) e) = Suc (sim12_size e)"
| "sim12_size (e;; e') = Suc (sim12_size e + sim12_size e')"
| "sim12_size (if (e) e1 else e2) = Suc (sim12_size e)"
| "sim12_size (while(b) c) = Suc (Suc (sim12_size b))"
| "sim12_size (throw e) = Suc (sim12_size e)"
| "sim12_size (try e catch(C V) e') = Suc (sim12_size e)"

| "sim12_sizes [] = 0"
| "sim12_sizes (e # es) = sim12_size e + sim12_sizes es"

lemma sim12_sizes_map_Val [simp]:
  "sim12_sizes (map Val vs) = 0"
by(induct vs) simp_all

lemma sim12_sizes_append [simp]:
  "sim12_sizes (es @ es') = sim12_sizes es + sim12_sizes es'"
by(induct es) simp_all

context JVM_heap_base begin

lemma τExec_mover_length_compE2_conv [simp]:
  assumes pc: "pc  length (compE2 e)"
  shows "τExec_mover ci P t e h (stk, loc, pc, xcp) s  s = (stk, loc, pc, xcp)"
proof
  assume "τExec_mover ci P t e h (stk, loc, pc, xcp) s"
  thus "s = (stk, loc, pc, xcp)" using pc
    by induct(auto simp add: τexec_move_def)
qed auto

lemma τExec_movesr_length_compE2_conv [simp]:
  assumes pc: "pc  length (compEs2 es)"
  shows "τExec_movesr ci P t es h (stk, loc, pc, xcp) s  s = (stk, loc, pc, xcp)"
proof
  assume "τExec_movesr ci P t es h (stk, loc, pc, xcp) s"
  thus "s = (stk, loc, pc, xcp)" using pc
    by induct(auto simp add: τexec_moves_def)
qed auto

end

context J1_JVM_heap_base begin

lemma assumes wf: "wf_J1_prog P"
  defines [simp]: "sim_move  λe e'. if sim12_size e' < sim12_size e then τExec_mover_a else τExec_movet_a"
  and [simp]: "sim_moves  λes es'. if sim12_sizes es' < sim12_sizes es then τExec_movesr_a else τExec_movest_a"
  shows exec_instr_simulates_red1:
  " P, E, h  (e, xs)  (stk, loc, pc, xcp); True,P,t ⊢1 e, (h, xs) -ta e', (h', xs'); bsok E n 
   pc'' stk'' loc'' xcp''. P, E, h'  (e', xs')  (stk'', loc'', pc'', xcp'') 
      (if τmove1 P h e
       then h = h'  sim_move e e' P t E h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')
       else pc' stk' loc' xcp'. τExec_mover_a P t E h (stk, loc, pc, xcp) (stk', loc', pc', xcp') 
                                 exec_move_a P t E h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'') 
                                 ¬ τmove2 (compP2 P) h stk' E pc' xcp' 
                                 (call1 e = None  no_call2 E pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp))"
  (is " _; _; _ 
        pc'' stk'' loc'' xcp''. _  ?exec ta E e e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''")

  and exec_instr_simulates_reds1:  
  " P, Es, h  (es, xs) [↔] (stk, loc, pc, xcp); True,P,t ⊢1 es, (h, xs) [-ta→] es', (h', xs'); bsoks Es n 
   pc'' stk'' loc'' xcp''. P, Es, h'  (es', xs') [↔] (stk'', loc'', pc'', xcp'') 
      (if τmoves1 P h es
       then h = h'  sim_moves es es' P t Es h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')
       else pc' stk' loc' xcp'. τExec_movesr_a P t Es h (stk, loc, pc, xcp) (stk', loc', pc', xcp') 
                                 exec_moves_a P t Es h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')  
                                 ¬ τmoves2 (compP2 P) h stk' Es pc' xcp' 
                                 (calls1 es = None  no_calls2 Es pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp))"
  (is " _; _; _ 
        pc'' stk'' loc'' xcp''. _  ?execs ta Es es es' h stk loc pc xcp h' pc'' stk'' loc'' xcp''")
proof(induction E n e xs stk loc pc xcp and Es n es xs stk loc pc xcp
    arbitrary: e' h' xs' Env T Env' T' and es' h' xs' Env Ts Env' Ts' rule: bisim1_bisims1_inducts_split)
  case (bisim1Call1 obj n obj' xs stk loc pc xcp ps M')
  note IHobj = bisim1Call1.IH(2)
  note IHparam = bisim1Call1.IH(4)
  note bisim1 = P,obj,h  (obj', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,ps,h  (ps, xs) [↔] ([], xs, 0, None)
  note bsok = bsok (objM'(ps)) n
  note red = True,P,t ⊢1 obj'M'(ps),(h, xs) -ta e',(h', xs')
  from red show ?case
  proof(cases)
    case (Call1Obj E')
    note [simp] = e' = E'M'(ps)
      and red = True,P,t ⊢1 obj',(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h obj' = τmove1 P h (obj'M'(ps))" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (obj'M'(ps)) = call1 obj'" by auto
    moreover from IHobj[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,obj,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta obj obj' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,objM'(ps),h'  (E'M'(ps), xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Call1)
    moreover { 
      assume "no_call2 obj pc"
      hence "no_call2 (objM'(ps)) pc  pc = length (compE2 obj)" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Call_τExecrI1 Call_τExectI1 exec_move_CallI1)+
  next
    case (Call1Params es v)
    note [simp] = obj' = Val v e' = Val vM'(es)
      and red = True,P,t ⊢1 ps, (h, xs) [-ta→] es, (h', xs')
    from red have τ: "τmove1 P h (obj'M'(ps)) = τmoves1 P h ps" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and execo: "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (objM'(ps)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
      by-(rule Call_τExecrI1)
    moreover from IHparam[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,ps,h'  (es, xs') [↔] (stk'', loc'', pc'', xcp'')"
      and exec': "?execs ta ps ps es h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (objM'(ps)) (obj'M'(ps)) (obj'M(es)) h [v] loc (length (compE2 obj)) None h' (length (compE2 obj) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (obj'M'(ps))")
      case True
      with exec' τ have [simp]: "h = h'"
        and e: "sim_moves ps es P t ps h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (obj'M'(ps)) (obj'M'(es)) P t (objM'(ps)) h ([] @ [v], xs, length (compE2 obj) + 0, None) (stk'' @ [v], loc'', length (compE2 obj) + pc'', xcp'')"
        by(fastforce dest: Call_τExecrI2 Call_τExectI2)
      with s True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_movesr_a P t ps h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_moves_a P t ps h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmoves2 (compP2 P) h stk' ps pc' xcp'" 
        and call: "calls1 ps = None  no_calls2 ps 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (objM'(ps)) h ([] @ [v], xs, length (compE2 obj) + 0, None) (stk' @ [v], loc', length (compE2 obj) + pc', xcp')" by(rule Call_τExecrI2)
      moreover from e' have "exec_move_a P t (objM'(ps)) h (stk' @ [v], loc', length (compE2 obj) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 obj) + pc'', xcp'')"
        by(rule exec_move_CallI2)
      moreover from τ' e' have "τmove2 (compP2 P) h (stk' @ [v]) (objM'(ps)) (length (compE2 obj) + pc') xcp'  False"
        by(fastforce simp add: τmove2_iff τmoves2_iff τinstr_stk_drop_exec_moves split: if_split_asm)
      moreover from red have "call1 (obj'M'(ps)) = calls1 ps" by(auto simp add: is_vals_conv)
      moreover have "no_calls2 ps 0  no_call2 (objM'(ps)) (length (compE2 obj))  ps = []" "calls1 [] = None"
        by(auto simp add: no_calls2_def no_call2_def)
      ultimately show ?thesis using False s call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,objM'(ps),h'  (Val vM'(es), xs')  ((stk'' @ [v]), loc'', length (compE2 obj) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CallParams)
    moreover from bisim1 have "pc  length (compE2 obj)  no_call2 (objM'(ps)) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ execo
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (Call1ThrowObj a)
    note [simp] = obj' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (Throw aM'(ps))" by(rule τmove1CallThrowObj)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1 have "P, objM'(ps), h  (Throw a, xs)  (stk, loc, pc, a)"
        by(auto intro: bisim1_bisims1.bisim1CallThrowObj)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc'
        where "τExec_mover_a P t obj h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        and bisim': "P, obj, h  (Throw a, xs)  ([Addr a], loc, pc', a)" and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (objM'(ps)) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Call_τExecrI1)
      moreover from bisim' have "P, objM'(ps), h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(rule bisim1CallThrowObj)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (Call1ThrowParams vs a es' v)
    note [simp] = obj' = Val v ta = ε e' = Throw a h' = h xs' = xs
      and ps = ps = map Val vs @ Throw a # es'
    from bisim1 have [simp]: "xcp = None" "xs = loc"
      and "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (objM'(ps)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 obj), None)"
      by-(rule Call_τExecrI1)
    also from bisims1_Throw_τExec_movest[OF bisim2[of xs, unfolded ps]]
    obtain pc' where exec': "τExec_movest_a P t (map Val vs @ Throw a # es') h ([], xs, 0, None) (Addr a # rev vs, xs, pc', a)"
      and bisim': "P,map Val vs @ Throw a # es',h  (map Val vs @ Throw a # es', xs) [↔] (Addr a # rev vs, xs, pc', a)"
      by auto
    from Call_τExectI2[OF exec', of "obj" M' v] ps
    have "τExec_movet_a P t (objM'(ps)) h ([v], loc, length (compE2 obj), None) (Addr a # rev vs @ [v], xs, length (compE2 obj) + pc', a)" by simp
    also from bisim1_bisims1.bisim1CallThrowParams[OF bisim', of obj M' v] ps
    have bisim'': "P,objM'(ps),h  (Throw a, xs)  (Addr a # rev vs @ [v], xs, length (compE2 obj) + pc', a)" by simp
    moreover have "τmove1 P h (obj'M'(ps))" using ps by(auto intro: τmove1CallThrowParams)
    ultimately show ?thesis by fastforce
  next
    case (Red1CallExternal a Ta Ts Tr D vs va H')
    hence [simp]: "obj' = addr a" "ps = map Val vs"
      "e' = extRet2J (addr aM'(map Val vs)) va" "H' = h'" "xs' = xs"
      and Ta: "typeof_addr h a = Ta"
      and iec: "P  class_type_of Ta sees M': TsTr = Native in D"
      and redex: "P,t  aM'(vs),h -ta→ext va,h'" by auto
    from bisim1 have [simp]: "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    have τ: "τmove1 P h (addr aM'(map Val vs))   τmove2 (compP2 P) h (rev vs @ [Addr a]) (objM'(ps)) (length (compE2 obj) + length (compEs2 ps)) None" using Ta iec
      by(auto simp add: map_eq_append_conv τmove1.simps τmoves1.simps τmove2_iff compP2_def)
    from bisim1 have s: "xcp = None" "lcl (h, xs) = loc"
      and "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 obj), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (objM'(ps)) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 obj), None)"
      by-(rule Call_τExecrI1)
    also have "τExec_movesr_a P t ps h ([], loc, 0, None) (rev vs, loc, length (compEs2 ps), None)"
      unfolding ps = map Val vs by(rule τExec_movesr_map_Val)
    from Call_τExecrI2[OF this, of obj M' "Addr a"]
    have "τExec_mover_a P t (objM'(ps)) h ([Addr a], loc, length (compE2 obj), None) (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None)" by simp
    also (rtranclp_trans) from bisim1 have "pc  length (compE2 obj)" by(rule bisim1_pc_length_compE2)
    hence "no_call2 (objM'(ps)) pc  pc = length (compE2 obj) + length (compEs2 ps)"
      using bisim1 by(fastforce simp add: no_call2_def neq_Nil_conv dest: bisim_Val_pc_not_Invoke)
    moreover { 
      assume "pc = length (compE2 obj) + length (compEs2 ps)"
      with τExec_mover_a P t obj h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 obj), None)
      have "stk = rev vs @ [Addr a]" "xcp = None" by auto }
    moreover
    let ?ret = "extRet2JVM (length ps) h' (rev vs @ [Addr a]) loc undefined undefined (length (compE2 obj) + length (compEs2 ps)) [] va"
    let ?stk' = "fst (hd (snd (snd ?ret)))"
    let ?xcp' = "fst ?ret"
    let ?pc' = "snd (snd (snd (snd (hd (snd (snd ?ret))))))"
    from redex have redex': "(ta, va, h')  red_external_aggr (compP2 P) t a M' vs h"
      by -(rule red_external_imp_red_external_aggr, simp add: compP2_def)
    with Ta iec redex'
    have "exec_move_a P t (objM'(ps)) h (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None) (extTA2JVM (compP2 P) ta) h' (?stk', loc, ?pc', ?xcp')"
      unfolding exec_move_def
      by-(rule exec_instr,cases va,(force simp add: compP2_def simp del: split_paired_Ex)+)
    moreover have "P,objM'(ps),h'  (extRet2J1 (addr aM'(map Val vs)) va, loc)  (?stk', loc, ?pc', ?xcp')"
    proof(cases va)
      case (RetVal v)
      have "P,objM'(ps),h'  (Val v, loc)  ([v], loc, length (compE2 (objM'(ps))), None)"
        by(rule bisim1Val2) simp
      thus ?thesis unfolding RetVal by simp
    next
      case (RetExc ad) thus ?thesis by(auto intro: bisim1CallThrow)
    next
      case RetStaySame 
      from bisims1_map_Val_append[OF bisims1Nil, of "map Val vs" vs P h' loc]
      have "P,map Val vs,h'  (map Val vs, loc) [↔] (rev vs, loc, length (compEs2 (map Val vs)), None)" by simp
      hence "P,objM'(map Val vs),h'  (addr aM'(map Val vs), loc)  (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None)"
        by(rule bisim1CallParams)
      thus ?thesis using RetStaySame by simp
    qed
    moreover from redex Ta iec
    have "τmove1 P h (addr aM'(map Val vs))  ta = ε  h' = h"
      by(fastforce simp add: τmove1.simps τmoves1.simps map_eq_append_conv τexternal'_def τexternal_def dest: τexternal'_red_external_heap_unchanged τexternal'_red_external_TA_empty sees_method_fun)
    ultimately show ?thesis using τ
      apply(cases "τmove1 P h (addr aM'(map Val vs) :: 'addr expr1)")
      apply(auto simp del: split_paired_Ex simp add: compP2_def)
      apply(blast intro: rtranclp.rtrancl_into_rtrancl rtranclp_into_tranclp1 τexec_moveI)+
      done
  next
    case (Red1CallNull vs)
    note [simp] = h' = h xs' = xs ta = ε obj' = null ps = map Val vs e' = THROW NullPointer
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t obj h (stk, loc, pc, xcp) ([Null], loc, length (compE2 obj), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (objM'(map Val vs)) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 obj), None)"
      by-(rule Call_τExecrI1)
    also have "τExec_movesr_a P t (map Val vs) h ([], loc, 0, None) (rev vs, loc, length (compEs2 (map Val vs)), None)"
    proof(cases "vs")
      case Nil thus ?thesis by(auto)
    next
      case Cons 
      with bisims1_refl[of P "h" "map Val vs" loc, simplified] show ?thesis
        by -(drule bisims1_Val_τExec_moves, auto)
    qed
    from Call_τExecrI2[OF this, of obj M' Null]
    have "τExec_mover_a P t (objM'(map Val vs)) h ([Null], loc, length (compE2 obj), None) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None)" by simp
    also (rtranclp_trans) {
      have "τmove2 (compP2 P) h (rev vs @ [Null]) (objM'(map Val vs)) (length (compE2 obj) + length (compEs2 (map Val vs))) None"
        by(simp add: τmove2_iff)
      moreover have "exec_move_a P t (objM'(map Val vs)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None) ε h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), addr_of_sys_xcpt NullPointer)"
        unfolding exec_move_def by(cases vs)(auto intro: exec_instr)
      ultimately have "τExec_movet_a P t (objM'(map Val vs)) h  (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), None) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 (map Val vs)), addr_of_sys_xcpt NullPointer)"
        by(auto intro: τexec_moveI simp add: compP2_def) }
    also have "τmove1 P h (nullM'(map Val vs))" by(auto simp add: τmove1.simps τmoves1.simps map_eq_append_conv)
    moreover have "P,objM'(map Val vs),h  (THROW NullPointer, loc)  ((rev vs @ [Null]), loc, length (compE2 obj) + length (compEs2 (map Val vs)), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1CallThrow) simp
    ultimately show ?thesis using s by(auto simp del: split_paired_Ex)
  qed
next
  case bisim1Val2 thus ?case by fastforce
next
  case (bisim1New C' n xs)
  have τ: "¬ τmove1 P h (new C')" by(auto simp add: τmove1.simps τmoves1.simps)
  from True,P,t ⊢1 new C',(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Red1New a)
    hence "exec_meth_a (compP2 P) [New C'] [] t h ([], xs, 0, None) NewHeapElem a (Class_type C') h' ([Addr a], xs, Suc 0, None)"
      and [simp]: "e' = addr a" "xs' = xs" "ta = NewHeapElem a (Class_type C')"
      by (auto intro!: exec_instr simp add: compP2_def simp del: fun_upd_apply cong cong del: image_cong_simp)
    moreover have "P, new C', h'  (addr a, xs)  ([Addr a], xs, length (compE2 (new C')), None)"
      by(rule bisim1Val2)(simp)
    moreover have "¬ τmove2 (compP2 P) h [] (new C') 0 None" by(simp add: τmove2_iff)
    ultimately show ?thesis using τ 
      by(fastforce simp add: exec_move_def ta_upd_simps)
  next
    case Red1NewFail
    hence "exec_meth_a (compP2 P) [New C'] [] t h ([], xs, 0, None) ε h' ([], xs, 0, addr_of_sys_xcpt OutOfMemory)"
      and [simp]: "ta = ε" "xs' = xs" "e' = THROW OutOfMemory"
      by(auto intro!:exec_instr simp add: compP2_def simp del: fun_upd_apply)
    moreover have "P, new C', h'  (THROW OutOfMemory, xs)  ([], xs, 0, addr_of_sys_xcpt OutOfMemory)"
      by(rule bisim1NewThrow)
    moreover have "¬ τmove2 (compP2 P) h [] (new C') 0 None" by(simp add: τmove2_iff)
    ultimately show ?thesis using τ by(fastforce simp add: exec_move_def)
  qed
next
  case bisim1NewThrow thus ?case by fastforce
next
  case (bisim1NewArray E n e xs stk loc pc xcp U)
  note IH = bisim1NewArray.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 newA Ue,(h, xs) -ta e',(h', xs')
  note bsok = bsok (newA UE) n
  from red show ?case
  proof cases 
    case (New1ArrayRed ee')
    note [simp] = e' = newA Uee'
      and red = True,P,t ⊢1 e,(h, xs) -ta ee', (h', xs')
    from red have "τmove1 P h (newA Ue) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (newA Ue) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (ee', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,newA UE,h'  (newA Uee', xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1NewArray)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (newA UE) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: NewArray_τExecrI NewArray_τExectI exec_move_newArrayI)+
  next
    case (Red1NewArray i a)
    note [simp] = e = Val (Intg i) ta = NewHeapElem a (Array_type U (nat (sint i))) e' = addr a xs' = xs
      and new = (h', a)  allocate h (Array_type U (nat (sint i)))
    from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (newA UE) h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
      by(rule NewArray_τExecrI)
    moreover from new 0 <=s i
    have "exec_move_a P t (newA UE) h ([Intg i], loc, length (compE2 E), None) NewHeapElem a (Array_type U (nat (sint i))) h' ([Addr a], loc, Suc (length (compE2 E)), None)"
      by (auto intro!: exec_instr simp add: compP2_def exec_move_def cong del: image_cong_simp)
    moreover have "τmove2 (compP2 P) h [Intg i] (newA UE) (length (compE2 E)) None  False" by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (newA UVal (Intg i))" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "P, newA UE, h'  (addr a, loc)  ([Addr a], loc, length (compE2 (newA UE)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s by(auto simp del: fun_upd_apply simp add: ta_upd_simps) blast
  next
    case (Red1NewArrayNegative i)
    note [simp] = e = Val (Intg i) e' = THROW NegativeArraySize h' = h xs' = xs ta = ε
    have "¬ τmove1 P h (newA UVal (Intg i))" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    moreover from i <s 0
    have "exec_meth_a (compP2 P) (compE2 (newA UE)) (compxE2 (newA UE) 0 0) t h ([Intg i], loc, length (compE2 E), None) ε h ([Intg i], loc, length (compE2 E), addr_of_sys_xcpt NegativeArraySize)"
      by -(rule exec_instr, auto simp add: compP2_def)
    moreover have "τmove2 (compP2 P) h [Intg i] (newA UE) (length (compE2 E)) None  False" by(simp add: τmove2_iff)
    moreover
    have "P,newA UE,h  (THROW NegativeArraySize, loc)  ([Intg i], loc, length (compE2 E), addr_of_sys_xcpt NegativeArraySize)"
      by(auto intro!: bisim1_bisims1.bisim1NewArrayFail)
    ultimately show ?thesis using s 
      by(auto simp add: exec_move_def)(blast intro: NewArray_τExecrI)
  next
    case (Red1NewArrayFail i)
    note [simp] = e = Val (Intg i) e' = THROW OutOfMemory xs' = xs ta = ε h' = h
      and new = allocate h (Array_type U (nat (sint i))) = {}
    have "¬ τmove1 P h (newA UVal (Intg i))" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Intg i], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    moreover from 0 <=s i new
    have "exec_meth_a (compP2 P) (compE2 (newA UE)) (compxE2 (newA UE) 0 0) t h ([Intg i], loc, length (compE2 E), None) ε h' ([Intg i], loc, length (compE2 E), addr_of_sys_xcpt OutOfMemory)"
      by -(rule exec_instr, auto simp add: compP2_def)
    moreover have "τmove2 (compP2 P) h [Intg i] (newA UE) (length (compE2 E)) None  False" by(simp add: τmove2_iff)
    moreover
    have "P,newA UE,h'  (THROW OutOfMemory, loc)  ([Intg i], loc, length (compE2 E), addr_of_sys_xcpt OutOfMemory)"
      by(auto intro!: bisim1_bisims1.bisim1NewArrayFail)
    ultimately show ?thesis using s by (auto simp add: exec_move_def)(blast intro: NewArray_τExecrI)
  next
    case (New1ArrayThrow a)
    note [simp] = e = Throw a h' = h xs' = xs ta = ε e' = Throw a
    have τ: "τmove1 P h (newA Ue)" by(auto intro: τmove1NewArrayThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P,newA UE, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.bisim1NewArrayThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (newA UE) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule NewArray_τExecrI)
      moreover from bisim' have "P, newA UE, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(rule bisim1_bisims1.bisim1NewArrayThrow)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1NewArrayThrow thus ?case by auto
next
  case bisim1NewArrayFail thus ?case by auto
next
  case (bisim1Cast E n e xs stk loc pc xcp U)
  note IH = bisim1Cast.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 Cast U e,(h, xs) -ta e',(h', xs')
  note bsok = bsok (Cast U E) n
  from red show ?case
  proof cases
    case (Cast1Red ee')
    note [simp] = e' = Cast U ee'
      and red = True,P,t ⊢1 e,(h, xs) -ta ee', (h', xs')
    from red have "τmove1 P h (Cast U e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (Cast U e) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (ee', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,Cast U E,h'  (Cast U ee', xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Cast)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (Cast U E) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Cast_τExecrI Cast_τExectI exec_move_CastI)+
  next
    case (Red1Cast c U')
    hence [simp]: "e = Val c" "ta = ε" "e' = Val c" "h' = h" "xs' = xs"
      and type: "typeof⇘hc = U'" "P  U'  U" by auto
    from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (Cast U E) h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
      by(rule Cast_τExecrI)
    moreover from type
    have "exec_meth_a (compP2 P) (compE2 (Cast U E)) (compxE2 (Cast U E) 0 0) t h ([c], loc, length (compE2 E), None) ε h' ([c], loc, Suc (length (compE2 E)), None)"
      by(auto intro!: exec_instr simp add: compP2_def)
    moreover have "τmove2 (compP2 P) h [c] (Cast U E) (length (compE2 E)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_mover_a P t (Cast U E) h (stk, loc, pc, xcp) ([c], loc, Suc (length (compE2 E)), None)"
      by(fastforce elim: rtranclp.rtrancl_into_rtrancl intro: τexec_moveI simp add: exec_move_def compP2_def)
    moreover have "τmove1 P h (Cast U (Val c))" by(rule τmove1CastRed)
    moreover 
    have "P, Cast U E, h'  (Val c, loc)  ([c], loc, length (compE2 (Cast U E)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s by(auto simp add: exec_move_def)
  next
    case (Red1CastFail v U')
    note [simp] = e = Val v e' = THROW ClassCast h' = h xs' = xs ta = ε
    moreover from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (Cast U E) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(auto elim: Cast_τExecrI)
    moreover from ‹typeof⇘hp (h, xs)v = U' ¬ P  U'  U
    have "exec_meth_a (compP2 P) (compE2 (Cast U E)) (compxE2 (Cast U E) 0 0) t h ([v], loc, length (compE2 E), None) ε h ([v], loc, length (compE2 E), addr_of_sys_xcpt ClassCast)"
      by -(rule exec_instr, auto simp add: compP2_def)
    moreover have "τmove2 (compP2 P) h [v] (Cast U E) (length (compE2 E)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_movet_a P t (Cast U E) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), addr_of_sys_xcpt ClassCast)"
      by(fastforce simp add: exec_move_def compP2_def intro: rtranclp_into_tranclp1 τexec_moveI)
    moreover have "τmove1 P h (Cast U (Val v))" by(rule τmove1CastRed)
    moreover
    have "P,Cast U E,h  (THROW ClassCast, loc)  ([v], loc, length (compE2 E), addr_of_sys_xcpt ClassCast)"
      by(auto intro!: bisim1_bisims1.bisim1CastFail)
    ultimately show ?thesis using s by(auto simp add: exec_move_def)
  next
    case [simp]: (Cast1Throw a)
    have τ: "τmove1 P h (Cast U e)" by(auto intro: τmove1CastThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P,Cast U E, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.bisim1CastThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (Cast U E) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Cast_τExecrI)
      moreover from bisim' have "P, Cast U E, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by-(rule bisim1_bisims1.bisim1CastThrow, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1CastThrow thus ?case by auto
next
  case bisim1CastFail thus ?case by auto
next
  case (bisim1InstanceOf E n e xs stk loc pc xcp U)
  note IH = bisim1InstanceOf(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 e instanceof U,(h, xs) -ta e',(h', xs')
  note bsok = bsok (E instanceof U) n
  from red show ?case
  proof cases
    case (InstanceOf1Red ee')
    note [simp] = e' = ee' instanceof U
      and red = True,P,t ⊢1 e,(h, xs) -ta ee', (h', xs')
    from red have "τmove1 P h (e instanceof U) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (e instanceof U) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (ee', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,E instanceof U,h'  (ee' instanceof U, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1InstanceOf)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (E instanceof U) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: InstanceOf_τExecrI InstanceOf_τExectI exec_move_InstanceOfI)+
  next
    case (Red1InstanceOf c U' b)
    hence [simp]: "e = Val c" "ta = ε" "e' = Val (Bool (c  Null  P  U'  U))" "h' = h" "xs' = xs"
      "b = (c  Null  P  U'  U)"
      and type: "typeof⇘hc = U'" by auto
    from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (E instanceof U) h (stk, loc, pc, xcp) ([c], loc, length (compE2 E), None)"
      by(rule InstanceOf_τExecrI)
    moreover from type
    have "exec_meth_a (compP2 P) (compE2 (E instanceof U)) (compxE2 (E instanceof U) 0 0) t h ([c], loc, length (compE2 E), None) ε h' ([Bool b], loc, Suc (length (compE2 E)), None)"
      by(auto intro!: exec_instr simp add: compP2_def)
    moreover have "τmove2 (compP2 P) h [c] (E instanceof U) (length (compE2 E)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_mover_a P t (E instanceof U) h (stk, loc, pc, xcp) ([Bool b], loc, Suc (length (compE2 E)), None)"
      by(fastforce elim: rtranclp.rtrancl_into_rtrancl intro: τexec_moveI simp add: exec_move_def compP2_def)
    moreover have "τmove1 P h ((Val c) instanceof U)" by(rule τmove1InstanceOfRed)
    moreover
    have "P, E instanceof U, h'  (Val (Bool b), loc)  ([Bool b], loc, length (compE2 (E instanceof U)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s by(auto simp add: exec_move_def)
  next
    case (InstanceOf1Throw a)
    note [simp] = e = Throw a h' = h xs' = xs ta = ε e' = Throw a
    have τ: "τmove1 P h (e instanceof U)" by(auto intro: τmove1InstanceOfThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P,E instanceof U, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.bisim1InstanceOfThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (E instanceof U) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule InstanceOf_τExecrI)
      moreover from bisim' have "P, E instanceof U, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by-(rule bisim1_bisims1.bisim1InstanceOfThrow, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1InstanceOfThrow thus ?case by auto
next
  case bisim1Val thus ?case by fastforce
next
  case (bisim1Var V n xs)
  from True,P,t ⊢1 Var V,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Red1Var v)
    hence "exec_meth_a (compP2 P) [Load V] [] t h ([], xs, 0, None) ε h ([v], xs, 1, None)"
      and [simp]: "ta = ε" "h' = h" "xs' = xs" "e' = Val v"
      by(auto intro: exec_instr)
    moreover have "τmove2 (compP2 P) h [] (Var V) 0 None" by(simp add: τmove2_iff)
    ultimately have "τExec_movet_a P t (Var V) h ([], xs, 0, None) ([v], xs, 1, None)"
      by(auto intro: τExect1step simp add: exec_move_def compP2_def)
    moreover have "P, Var V, h  (Val v, xs)  ([v], xs, length (compE2 (Var V)), None)"
      by(rule bisim1Val2) simp
    moreover have "τmove1 P h (Var V)" by(rule τmove1Var)
    ultimately show ?thesis by(fastforce)
  qed
next
  case (bisim1BinOp1 e1 n e1' xs stk loc pc xcp e2 bop)
  note IH1 = bisim1BinOp1.IH(2)
  note IH2 = bisim1BinOp1.IH(4)
  note bisim1 = P,e1,h  (e1', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bsok = bsok (e1 «bop» e2) n
  from True,P,t ⊢1 e1' «bop» e2,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Bin1OpRed1 E')
    note [simp] = e' = E' «bop» e2
      and red = True,P,t ⊢1 e1',(h, xs) -ta E',(h', xs')
    from red have "τmove1 P h (e1' «bop» e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (e1' «bop» e2) = call1 e1'" by auto
    moreover from IH1[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim 
    have "P,e1«bop»e2,h'  (E'«bop»e2, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1BinOp1)
    moreover { 
      assume "no_call2 e1 pc"
      hence "no_call2 (e1«bop»e2) pc  pc = length (compE2 e1)" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: BinOp_τExecrI1 BinOp_τExectI1 exec_move_BinOpI1)+
  next
    case (Bin1OpRed2 E' v)
    note [simp] = e1' = Val v e' = Val v «bop» E'
      and red = True,P,t ⊢1 e2,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v «bop» e2) = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (e1«bop»e2) h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
      by(rule BinOp_τExecrI1)
    moreover
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (e1«bop»e2) (Val v«bop»e2) (Val v«bop»E') h ([] @ [v]) xs (length (compE2 e1) + 0) None h' (length (compE2 e1) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v «bop» e2)")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move e2 E' P t e2 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val v«bop»e2) (Val v«bop»E') P t (e1 «bop» e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
        by(fastforce dest: BinOp_τExecrI2 BinOp_τExectI2)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e2 h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'" 
        and call: "call1 e2 = None  no_call2 e2 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (e1 «bop» e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk' @ [v], loc', length (compE2 e1) + pc', xcp')" by(rule BinOp_τExecrI2)
      moreover from e' have "exec_move_a P t (e1 «bop» e2) h (stk' @ [v], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
        by(rule exec_move_BinOpI2)
      moreover from e' have "pc' < length (compE2 e2)" by auto
      with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (e1 «bop» e2) (length (compE2 e1) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (e1'«bop»e2) = call1 e2" by(auto)
      moreover have "no_call2 e2 0  no_call2 (e1«bop»e2) (length (compE2 e1))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,e1«bop»e2,h'  (Val v«bop»E', xs')  ((stk'' @ [v]), loc'', length (compE2 e1) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1BinOp2)
    moreover from bisim1 have "pc  length (compE2 e1)  no_call2 (e1«bop»e2) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (Red1BinOp v1 v2 v)
    note [simp] = e1' = Val v1 e2 = Val v2 ta = ε e' = Val v h' = h xs' = xs
      and binop = binop bop v1 v2 = Inl v
    have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1«bop»Val v2) h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
      by-(rule BinOp_τExecrI1)
    also have "τmove2 (compP2 P) h [v1] (e1 «bop» Val v2) (length (compE2 e1) + 0) None"
      by(rule τmove2BinOp2)(rule τmove2Val)
    with binop have "τExec_mover_a P t (e1«bop»Val v2) h ([v1], loc, length (compE2 e1), None) ([v2, v1], loc, Suc (length (compE2 e1)), None)"
      by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
    also (rtranclp_trans) from binop
    have "exec_meth_a (compP2 P) (compE2 (e1«bop»Val v2)) (compxE2 (e1«bop»Val v2) 0 0) t
                               h ([v2, v1], loc, Suc (length (compE2 e1)), None) ε
                               h ([v], loc, Suc (Suc (length (compE2 e1))), None)"
      by-(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»Val v2) (Suc (length (compE2 e1))) None" by(simp add: τmove2_iff) 
    ultimately have "τExec_mover_a P t (e1 «bop» Val v2) h (stk, loc, pc, xcp) ([v], loc, Suc (Suc (length (compE2 e1))), None)"
      by(fastforce intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: exec_move_def compP2_def)
    moreover
    have "P, e1 «bop» Val v2, h  (Val v, loc)  ([v], loc, length (compE2 (e1 «bop» Val v2)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by auto
  next
    case (Red1BinOpFail v1 v2 a)
    note [simp] = e1' = Val v1 e2 = Val v2 ta = ε e' = Throw a h' = h xs' = xs
      and binop = binop bop v1 v2 = Inr a
    have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1«bop»Val v2) h (stk, loc, pc, xcp) ([v1], loc, length (compE2 e1), None)"
      by-(rule BinOp_τExecrI1)
    also have "τmove2 (compP2 P) h [v1] (e1 «bop» Val v2) (length (compE2 e1) + 0) None"
      by(rule τmove2BinOp2)(rule τmove2Val)
    with binop have "τExec_mover_a P t (e1«bop»Val v2) h ([v1], loc, length (compE2 e1), None) ([v2, v1], loc, Suc (length (compE2 e1)), None)"
      by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
    also (rtranclp_trans) from binop
    have "exec_meth_a (compP2 P) (compE2 (e1«bop»Val v2)) (compxE2 (e1«bop»Val v2) 0 0) t
                               h ([v2, v1], loc, Suc (length (compE2 e1)), None) ε
                               h ([v2, v1], loc, Suc (length (compE2 e1)), a)"
      by-(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»Val v2) (Suc (length (compE2 e1))) None" by(simp add: τmove2_iff) 
    ultimately have "τExec_movet_a P t (e1 «bop» Val v2) h (stk, loc, pc, xcp) ([v2, v1], loc, Suc (length (compE2 e1)), a)"
      by(fastforce intro: rtranclp_into_tranclp1 τexec_moveI simp add: exec_move_def compP2_def)
    moreover 
    have "P, e1 «bop» Val v2, h  (Throw a, loc)  ([v2, v1], loc, length (compE2 e1) + length (compE2 (Val v2)), a)"
      by(rule bisim1BinOpThrow)
    ultimately show ?thesis using s τ by auto
  next
    case (Bin1OpThrow1 a)
    note [simp] = e1' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (Throw a «bop» e2)" by(rule τmove1BinOpThrow1)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1 have "P, e1«bop»e2, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1«bop»e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule BinOp_τExecrI1)
      moreover from bisim'
      have "P, e1«bop»e2, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(auto intro: bisim1_bisims1.bisim1BinOpThrow1)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (Bin1OpThrow2 v a)
    note [simp] = e1' = Val v e2 = Throw a ta = ε e' = Throw a h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1«bop»Throw a) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by-(rule BinOp_τExecrI1)
    also have "τExec_mover_a P t (e1«bop»Throw a) h ([v], loc, length (compE2 e1), None) ([Addr a, v], loc, Suc (length (compE2 e1)), a)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,e1«bop»Throw a,h  (Throw a, loc)  ([Addr a] @ [v], loc, (length (compE2 e1) + length (compE2 (addr a))), a)"
      by(rule bisim1BinOpThrow2[OF bisim1Throw2])
    moreover have "τmove1 P h (e1' «bop» e2)" by(auto intro: τmove1BinOpThrow2)
    ultimately show ?thesis using s by auto
  qed
next
  case (bisim1BinOp2 e2 n e2' xs stk loc pc xcp e1 bop v1)
  note IH2 = bisim1BinOp2.IH(2)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 Val v1 «bop» e2',(h, xs) -ta e',(h', xs')
  note bsok = bsok (e1 «bop» e2) n
  from red show ?case
  proof cases
    case (Bin1OpRed2 E')
    note [simp] = e' = Val v1 «bop» E'
      and red = True,P,t ⊢1 e2',(h, xs) -ta E',(h', xs')
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from red have τ: "τmove1 P h (Val v1 «bop» e2') = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
    have "no_call2 e2 pc  no_call2 (e1 «bop» e2) (length (compE2 e1) + pc)" by(auto simp add: no_call2_def)
    hence "?exec ta (e1«bop»e2) (Val v1«bop»e2') (Val v1«bop»E') h (stk @ [v1]) loc (length (compE2 e1) + pc) xcp h' (length (compE2 e1) + pc'') (stk'' @ [v1]) loc'' xcp''"
      using exec' τ
      apply(cases "τmove1 P h (Val v1 «bop» e2')")
      apply(auto)
      apply(blast intro: BinOp_τExecrI2 BinOp_τExectI2 exec_move_BinOpI2)
      apply(blast intro: BinOp_τExecrI2 BinOp_τExectI2 exec_move_BinOpI2)
      apply(rule exI conjI BinOp_τExecrI2 exec_move_BinOpI2|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI BinOp_τExecrI2 exec_move_BinOpI2|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI BinOp_τExecrI2 exec_move_BinOpI2 rtranclp.rtrancl_refl|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
      done
    moreover from bisim'
    have "P,e1«bop»e2,h'  (Val v1«bop»E', xs')  (stk''@[v1], loc'', length (compE2 e1) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1BinOp2)
    ultimately show ?thesis using τ by auto blast+
  next
    case (Red1BinOp v2 v)
    note [simp] = e2' = Val v2 ta = ε e' = Val v h' = h xs' = xs
      and binop = binop bop v1 v2 = Inl v
    have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
    from bisim2 have s: "xcp = None" "xs = loc" 
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v2], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1«bop»e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v2] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule BinOp_τExecrI2)
    moreover from binop
    have "exec_move_a P t (e1«bop»e2) h ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), None) ε
                                  h ([v], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»e2) (length (compE2 e1) + length (compE2 e2)) None"
      by(simp add: τmove2_iff)
    ultimately have "τExec_mover_a P t (e1 «bop» e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
      by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
    moreover 
    have "P, e1 «bop» e2, h  (Val v, loc)  ([v], loc, length (compE2 (e1 «bop» e2)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto)
  next
    case (Red1BinOpFail v2 a)
    note [simp] = e2' = Val v2 ta = ε e' = Throw a h' = h xs' = xs
      and binop = binop bop v1 v2 = Inr a
    have τ: "τmove1 P h (Val v1 «bop» Val v2)" by(rule τmove1BinOp)
    from bisim2 have s: "xcp = None" "xs = loc" 
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v2], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1«bop»e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v2] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule BinOp_τExecrI2)
    moreover from binop
    have "exec_move_a P t (e1«bop»e2) h ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), None) ε
                                  h ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), a)"
      unfolding exec_move_def by-(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [v2, v1] (e1«bop»e2) (length (compE2 e1) + length (compE2 e2)) None"
      by(simp add: τmove2_iff)
    ultimately have "τExec_movet_a P t (e1 «bop» e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), a)"
      by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
    moreover
    have "P, e1 «bop» e2, h  (Throw a, loc)  ([v2, v1], loc, length (compE2 e1) + length (compE2 e2), a)"
      by(rule bisim1BinOpThrow)
    ultimately show ?thesis using s τ by(auto)
  next
    case (Bin1OpThrow2 a)
    note [simp] = e2' = Throw a ta = ε h' = h xs' = xs e' = Throw a
    have τ: "τmove1 P h (Val v1 «bop» Throw a)" by(rule τmove1BinOpThrow2)
    from bisim2 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim2
      have "P, e1«bop»e2, h  (Throw a, xs)  (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
        by(auto intro: bisim1BinOpThrow2)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1«bop»e2) h (stk @ [v1], loc, length (compE2 e1) + pc, None) ([Addr a] @ [v1], loc, length (compE2 e1) + pc', a)"
        by-(rule BinOp_τExecrI2)
      moreover from bisim'
      have "P, e1«bop»e2, h  (Throw a, xs)  ([Addr a]@[v1], loc, length (compE2 e1) + pc', a)"
        by-(rule bisim1BinOpThrow2, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed auto
next
  case bisim1BinOpThrow1 thus ?case by fastforce
next
  case bisim1BinOpThrow2 thus ?case by fastforce
next
  case bisim1BinOpThrow thus ?case by fastforce
next
  case (bisim1LAss1 E n e xs stk loc pc xcp V)
  note IH = bisim1LAss1.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 V:=e,(h, xs) -ta e',(h', xs')
  note bsok = bsok (V:=E) n
  from red show ?case
  proof cases
    case (LAss1Red ee')
    note [simp] = e' = V := ee'
      and red = True,P,t ⊢1 e,(h, xs) -ta ee', (h', xs')
    from red have "τmove1 P h (V:=e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (V:=e) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (ee', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,V:=E,h'  (V:=ee', xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1LAss1)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (V:=E) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: LAss_τExecrI LAss_τExectI exec_move_LAssI)+
  next
    case (Red1LAss v)
    note [simp] = e = Val v ta = ε e' = unit h' = h xs' = xs[V := v]
      and V = V < length xs
    from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (V:=E) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(rule LAss_τExecrI)
    moreover have "exec_move_a P t (V:=E) h ([v], loc, length (compE2 E), None) ε h ([], loc[V := v], Suc (length (compE2 E)), None)"
      using V s by(auto intro: exec_instr simp add: exec_move_def)
    moreover have "τmove2 (compP2 P) h [v] (V := E) (length (compE2 E)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_mover_a P t (V:=E) h (stk, loc, pc, xcp) ([], loc[V := v], Suc (length (compE2 E)), None)"
      by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
    moreover have "τmove1 P h (V := Val v)" by(rule τmove1LAssRed)
    moreover have "P, V:=E, h  (unit, loc[V := v])  ([], loc[V := v], Suc (length (compE2 E)), None)"
      by(rule bisim1LAss2)
    ultimately show ?thesis using s by auto
  next
    case (LAss1Throw a)
    note [simp] = e = Throw a h' = h xs' = xs ta = ε e' = Throw a
    have τ: "τmove1 P h (V:=e)" by(auto intro: τmove1LAssThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P, V:=E, h  (Throw a, xs)  (stk, loc, pc, xcp)" by(auto intro: bisim1LAssThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (V:=E) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule LAss_τExecrI)
      moreover from bisim' have "P, V:=E, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by-(rule bisim1LAssThrow, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1LAss2 thus ?case by fastforce
next
  case bisim1LAssThrow thus ?case by fastforce
next
  case (bisim1AAcc1 a n a' xs stk loc pc xcp i)
  note IH1 = bisim1AAcc1.IH(2)
  note IH2 = bisim1AAcc1.IH(4)
  note bisim1 = P,a,h  (a', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,i,h  (i, xs)  ([], xs, 0, None)
  note bsok = bsok (ai) n
  from True,P,t ⊢1 a'i,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (AAcc1Red1 E')
    note [simp] = e' = E'i
      and red = True,P,t ⊢1 a',(h, xs) -ta E',(h', xs')
    from red have "τmove1 P h (a'i) = τmove1 P h a'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (a'i) = call1 a'" by auto
    moreover from IH1[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,a,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta a a' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim have "P,ai,h'  (E'i, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAcc1)
    moreover { 
      assume "no_call2 a pc"
      hence "no_call2 (ai) pc  pc = length (compE2 a)" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: AAcc_τExecrI1 AAcc_τExectI1 exec_move_AAccI1)+
  next
    case (AAcc1Red2 E' v)
    note [simp] = a' = Val v e' = Val vE'
      and red = True,P,t ⊢1 i,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val vi) = τmove1 P h i" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t a h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (ai) h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
      by(rule AAcc_τExecrI1)
    moreover
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,i,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta i i E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (ai) (Val vi) (Val vE') h ([] @ [v]) xs (length (compE2 a) + 0) None h' (length (compE2 a) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val vi)")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move i E' P t i h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (ai) (aE') P t (ai) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
        by(fastforce dest: AAcc_τExecrI2 AAcc_τExectI2)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t i h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t i h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' i pc' xcp'" 
        and call: "call1 i = None  no_call2 i 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (ai) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk' @ [v], loc', length (compE2 a) + pc', xcp')"
        by(rule AAcc_τExecrI2)
      moreover from e' have "exec_move_a P t (ai) h (stk' @ [v], loc', length (compE2 a) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
        by(rule exec_move_AAccI2)
      moreover from e' τ' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (ai) (length (compE2 a) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover have "call1 (a'i) = call1 i" by simp
      moreover have "no_call2 i 0  no_call2 (ai) (length (compE2 a))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,ai,h'  (Val vE', xs')  ((stk'' @ [v]), loc'', length (compE2 a) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAcc2)
    moreover from bisim1 have "pc  length (compE2 a)  no_call2 (ai) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (Red1AAcc A U len I v)
    hence [simp]: "a' = addr A" "e' = Val v" "i = Val (Intg I)" "h' = h" "xs' = xs"
                  "ta = ReadMem A (ACell (nat (sint I))) v"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len"
      and read: "heap_read h A (ACell (nat (sint I))) v" by auto
    have τ: "¬ τmove1 P h (addr AVal (Intg I))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (aVal (Intg I)) h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
      by-(rule AAcc_τExecrI1)
    also have "τmove2 (compP2 P) h [Addr A] (aVal (Intg I)) (length (compE2 a) + 0) None"
      by(rule τmove2AAcc2)(rule τmove2Val)
    hence "τExec_mover_a P t (aVal (Intg I)) h ([Addr A], loc, length (compE2 a), None) ([Intg I, Addr A], loc, Suc (length (compE2 a)), None)"
      by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
    also (rtranclp_trans) from hA I read
    have "exec_move_a P t (aVal (Intg I)) h ([Intg I, Addr A], loc, Suc (length (compE2 a)), None) 
                                           ReadMem A (ACell (nat (sint I))) v
                                           h ([v], loc, Suc (Suc (length (compE2 a))), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [Intg I, Addr A] (aVal (Intg I)) (Suc (length (compE2 a))) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, aVal (Intg I), h  (Val v, loc)  ([v], loc, length (compE2 (aVal (Intg I))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ
      by(auto simp add: ta_upd_simps) blast
  next
    case (Red1AAccNull v)
    note [simp] = a' = null i = Val v ta = ε e' = THROW NullPointer h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1 intro: AAcc_τExecrI1)
    hence "τExec_mover_a P t (ai) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
      by-(rule AAcc_τExecrI1)
    also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([v], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai) h ([] @ [Null], loc, length (compE2 a) + 0, None) ([v] @ [Null], loc, length (compE2 a) + length (compE2 i), None)"
      by(rule AAcc_τExecrI2)
    hence "τExec_mover_a P t (ai) h ([Null], loc, length (compE2 a), None) ([v, Null], loc, length (compE2 a) + length (compE2 i), None)" by simp
    also (rtranclp_trans) have "exec_move_a P t (ai) h ([v, Null], loc, length (compE2 a) + length (compE2 i), None) ε h ([v, Null], loc, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto)
    moreover have "¬ τmove2 (compP2 P) h [v, Null] (ai) (length (compE2 a) + length (compE2 i)) None"
      by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (a'i)" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover
    have "P,ai,h  (THROW NullPointer, xs)  ([v, Null], xs, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1AAccFail)
    ultimately show ?thesis using s by auto blast
  next
    case (Red1AAccBounds A U len I)
    hence [simp]: "a' = addr A" "e' = THROW ArrayIndexOutOfBounds" "i = Val (Intg I)"
      "ta = ε" "h' = h" "xs' = xs"
      and hA: "typeof_addr h A = Array_type U len" and I: "I <s 0  int len  sint I" by auto
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai) h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
      by-(rule AAcc_τExecrI1)
    also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
      by(rule AAcc_τExecrI2)
    hence "τExec_mover_a P t (ai) h ([Addr A], loc, length (compE2 a), None) ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None)" by simp
    also (rtranclp_trans) from I hA
    have "exec_move_a P t (ai) h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None) ε h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Intg I, Addr A] (ai) (length (compE2 a) + length (compE2 i)) None"
      by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (a'i)" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover
    have "P,ai,h  (THROW ArrayIndexOutOfBounds, xs)  ([Intg I, Addr A], xs, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      by(rule bisim1_bisims1.bisim1AAccFail)
    ultimately show ?thesis using s by auto blast
  next
    case (AAcc1Throw1 A)
    note [simp] = a' = Throw A ta = ε e' = Throw A h' = h xs' = xs
    have τ: "τmove1 P h (Throw Ai)" by(rule τmove1AAccThrow1)
    from bisim1 have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim1 have "P, ai, h  (Throw A, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' where "τExec_mover_a P t a h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        and bisim': "P, a, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (ai) h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        by-(rule AAcc_τExecrI1)
      moreover from bisim'
      have "P, ai, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        by(auto intro: bisim1_bisims1.bisim1AAccThrow1)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (AAcc1Throw2 v ad)
    note [simp] = a' = Val v i = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (aThrow ad) h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
      by-(rule AAcc_τExecrI1)
    also have "τExec_mover_a P t (aThrow ad) h ([v], loc, length (compE2 a), None) ([Addr ad, v], loc, Suc (length (compE2 a)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,aThrow ad,h  (Throw ad, loc)  ([Addr ad] @ [v], loc, (length (compE2 a) + length (compE2 (addr ad))), ad)"
      by(rule bisim1AAccThrow2[OF bisim1Throw2])
    moreover have "τmove1 P h (a'Throw ad)" by(auto intro: τmove1AAccThrow2)
    ultimately show ?thesis using s by auto
  qed
next
  case (bisim1AAcc2 i n i' xs stk loc pc xcp a v1)
  note IH2 = bisim1AAcc2.IH(2)
  note bisim1 = xs. P,a,h  (a, xs)  ([], xs, 0, None)
  note bisim2 = P,i,h  (i', xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 Val v1i',(h, xs) -ta e',(h', xs')
  note bsok = bsok (ai) n
  from red show ?case
  proof cases
    case (AAcc1Red2 E')
    note [simp] = e' = Val v1E'
      and red = True,P,t ⊢1 i',(h, xs) -ta E',(h', xs')
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,i,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta i i' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from red have τ: "τmove1 P h (Val v1i') = τmove1 P h i'" by(auto simp add: τmove1.simps τmoves1.simps)
    have "no_call2 i pc  no_call2 (ai) (length (compE2 a) + pc)" by(auto simp add: no_call2_def)
    hence "?exec ta (ai) (Val v1i') (Val v1E') h (stk @ [v1]) loc (length (compE2 a) + pc) xcp h' (length (compE2 a) + pc'') (stk'' @ [v1]) loc'' xcp''"
      using exec' τ
      apply(cases "τmove1 P h (Val v1i')")
      apply(auto)
      apply(blast intro: AAcc_τExecrI2 AAcc_τExectI2 exec_move_AAccI2)
      apply(blast intro: AAcc_τExecrI2 AAcc_τExectI2 exec_move_AAccI2)
      apply(rule exI conjI AAcc_τExecrI2 exec_move_AAccI2|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI AAcc_τExecrI2 exec_move_AAccI2|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI AAcc_τExecrI2 exec_move_AAccI2 rtranclp.rtrancl_refl|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
      done
    moreover from bisim'
    have "P,ai,h'  (Val v1E', xs')  (stk''@[v1], loc'', length (compE2 a) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAcc2)
    ultimately show ?thesis using τ by auto blast+
  next
    case (Red1AAcc A U len I v)
    hence [simp]: "v1 = Addr A" "e' = Val v" "i' = Val (Intg I)"
      "ta = ReadMem A (ACell (nat (sint I))) v" "h' = h" "xs' = xs"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len"
      and read: "heap_read h A (ACell (nat (sint I))) v" by auto
    have τ: "¬ τmove1 P h (addr AVal (Intg I))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAcc_τExecrI2)
    moreover from hA I read
    have "exec_move_a P t (ai) h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None)
                              ReadMem A (ACell (nat (sint I))) v
                              h ([v], loc, Suc (length (compE2 a) + length (compE2 i)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [Intg I, Addr A] (ai) (length (compE2 a) + length (compE2 i)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai, h  (Val v, loc)  ([v], loc, length (compE2 (ai)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (Red1AAccNull v)
    note [simp] = v1 = Null i' = Val v ta = ε e' = THROW NullPointer h' = h xs' = xs
    from bisim2 have [simp]: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([v], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai) h (stk @ [Null], loc, length (compE2 a) + pc, xcp) ([v] @ [Null], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAcc_τExecrI2)
    moreover have "exec_move_a P t (ai) h ([v, Null], loc, length (compE2 a) + length (compE2 i), None) ε h ([v, Null], loc, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto)
    moreover have "¬ τmove2 (compP2 P) h [v, Null] (ai) (length (compE2 a) + length (compE2 i)) None"
      by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (nulli')" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover
    have "P,ai,h  (THROW NullPointer, xs)  ([v, Null], xs, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1AAccFail)
    ultimately show ?thesis by auto blast
  next
    case (Red1AAccBounds A U len I)
    hence [simp]: "v1 = Addr A" "e' = THROW ArrayIndexOutOfBounds" "i' = Val (Intg I)"
      "ta = ε" "h' = h" "xs' = xs"
      and hA: "typeof_addr h A = Array_type U len" and I: "I <s 0  int len  sint I" by auto
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAcc_τExecrI2)
    moreover from I hA
    have "exec_move_a P t (ai) h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), None) ε h ([Intg I, Addr A], loc, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Intg I, Addr A] (ai) (length (compE2 a) + length (compE2 i)) None"
      by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (addr Ai')" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover 
    have "P,ai,h  (THROW ArrayIndexOutOfBounds, xs)  ([Intg I, Addr A], xs, length (compE2 a) + length (compE2 i), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      by(rule bisim1_bisims1.bisim1AAccFail)
    ultimately show ?thesis using s by auto blast
  next
    case (AAcc1Throw2 A)
    note [simp] = i' = Throw A ta = ε e' = Throw A h' = h xs' = xs
    have τ: "τmove1 P h (Val v1Throw A)" by(rule τmove1AAccThrow2)
    from bisim2 have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim2
      have "P, ai, h  (Throw A, xs)  (stk @ [v1], loc, length (compE2 a) + pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(auto)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc' where "τExec_mover_a P t i h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        and bisim': "P, i, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (ai) h (stk @ [v1], loc, length (compE2 a) + pc, None) ([Addr A] @ [v1], loc, length (compE2 a) + pc', A)"
        by-(rule AAcc_τExecrI2)
      moreover from bisim'
      have "P, ai, h  (Throw A, xs)  ([Addr A] @ [v1], loc, length (compE2 a) + pc', A)"
        by(rule bisim1_bisims1.bisim1AAccThrow2)
      ultimately show ?thesis using τ by auto
    qed
  qed auto
next
  case bisim1AAccThrow1 thus ?case by auto
next
  case bisim1AAccThrow2 thus ?case by auto
next
  case bisim1AAccFail thus ?case by auto
next
  case (bisim1AAss1 a n a' xs stk loc pc xcp i e)
  note IH1 = bisim1AAss1.IH(2)
  note IH2 = bisim1AAss1.IH(4)
  note IH3 = bisim1AAss1.IH(6)
  note bisim1 = P,a,h  (a', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,i,h  (i, xs)  ([], xs, 0, None)
  note bisim3 = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  note bsok = bsok (ai := e) n
  from True,P,t ⊢1 a'i := e,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (AAss1Red1 E')
    note [simp] = e' = E'i := e
      and red = True,P,t ⊢1 a',(h, xs) -ta E',(h', xs')
    from red have "τmove1 P h (a'i := e) = τmove1 P h a'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (a'i := e) = call1 a'" by auto
    moreover from IH1[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,a,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta a a' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim 
    have "P,ai := e,h'  (E'i := e, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAss1)
    moreover { 
      assume "no_call2 a pc"
      hence "no_call2 (ai := e) pc  pc = length (compE2 a)" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: AAss_τExecrI1 AAss_τExectI1 exec_move_AAssI1)+
  next
    case (AAss1Red2 E' v)
    note [simp] = a' = Val v e' = Val vE' := e
      and red = True,P,t ⊢1 i,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val vi := e) = τmove1 P h i" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t a h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (ai := e) h (stk, loc, pc, None) ([v], xs, length (compE2 a), None)"
      by(rule AAss_τExecrI1)
    moreover
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,i,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta i i E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (ai := e) (Val vi := e) (Val vE' := e) h ([] @ [v]) xs (length (compE2 a) + 0) None h' (length (compE2 a) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val vi := e)")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move i E' P t i h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (ai := e) (aE' := e) P t (ai := e) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
        by(fastforce dest: AAss_τExecrI2 AAss_τExectI2)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t i h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t i h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' i pc' xcp'" 
        and call: "call1 i = None  no_call2 i 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (ai := e) h ([] @ [v], xs, length (compE2 a) + 0, None) (stk' @ [v], loc', length (compE2 a) + pc', xcp')" by(rule AAss_τExecrI2)
      moreover from e' have "exec_move_a P t (ai := e) h (stk' @ [v], loc', length (compE2 a) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 a) + pc'', xcp'')"
        by(rule exec_move_AAssI2)
      moreover from e' have "pc' < length (compE2 i)" by(auto elim: exec_meth.cases)
      with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (ai := e) (length (compE2 a) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (a'i := e) = call1 i" by auto
      moreover have "no_call2 i 0  no_call2 (ai := e) (length (compE2 a))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,ai := e,h'  (Val vE' := e, xs')  ((stk'' @ [v]), loc'', length (compE2 a) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAss2)
    moreover from bisim1 have "pc  length (compE2 a)  no_call2 (ai := e) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (AAss1Red3 E' v v')
    note [simp] = i = Val v' a' = Val v e' = Val vVal v' := E'
      and red = True,P,t ⊢1 e,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val vVal v' := e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t a h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 a) + 0, None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (ai := e) h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 a) + 0, None)"
      by(rule AAss_τExecrI1)
    also from bisim2[of xs] 
    have "τExec_mover_a P t i h ([], xs, 0, None) ([v'], xs, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [v], xs, length (compE2 a) + 0, None) ([v'] @ [v], xs, length (compE2 a) + length (compE2 i), None)"
      by(rule AAss_τExecrI2)
    also (rtranclp_trans) from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e e E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (ai := e) (Val vVal v' := e) (Val vVal v' := E') h ([] @ [v', v]) xs (length (compE2 a) + length (compE2 i) + 0) None h' (length (compE2 a) + length (compE2 i) + pc'') (stk'' @ [v', v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val vVal v' := e)")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move e E' P t e h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val vVal v' := e) (Val vVal v' := E') P t (ai := e) h ([] @ [v', v], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk'' @ [v', v], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
        by(fastforce dest: AAss_τExectI3 AAss_τExecrI3 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e pc' xcp'" 
        and call: "call1 e = None  no_call2 e 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (ai := e) h ([] @ [v', v], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk' @ [v', v], loc', length (compE2 a) + length (compE2 i) + pc', xcp')" by(rule AAss_τExecrI3)
      moreover from e' have "exec_move_a P t (ai := e) h (stk' @ [v', v], loc', length (compE2 a) + length (compE2 i) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
        by(rule exec_move_AAssI3)
      moreover from e' τ'
      have "¬ τmove2 (compP2 P) h (stk' @ [v', v]) (ai := e) (length (compE2 a) + length (compE2 i) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover have "call1 (a'i := e) = call1 e" by simp
      moreover have "no_call2 e 0  no_call2 (ai := e) (length (compE2 a) + length (compE2 i))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,ai := e,h'  (Val vVal v' := E', xs')  ((stk'' @ [v', v]),  loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAss3) 
    moreover from bisim1 have "pc  length (compE2 a) + length (compE2 i)  no_call2 (ai := e) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (Red1AAss A U len I v U')
    hence [simp]: "a' = addr A" "e' = unit" "i = Val (Intg I)"
      "ta = WriteMem A (ACell (nat (sint I))) v" "xs' = xs" "e = Val v"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len" 
      and v: "typeof⇘hv = U'" "P  U'  U"
      and h': "heap_write h A (ACell (nat (sint I))) v h'" by auto
    have τ: "¬ τmove1 P h (AAss (addr A) (Val (Intg I)) (Val v))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
      by-(rule AAss_τExecrI1)
    also from bisim2[of loc]
    have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
      by(rule AAss_τExecrI2)
    also (rtranclp_trans) have "[Intg I] @ [Addr A] = [] @ [Intg I, Addr A]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans) from hA I v h'
    have "exec_move_a P t (ai := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)
                                 WriteMem A (ACell (nat (sint I))) v
                                 h' ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (unit, loc)  ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
      by(rule bisim1_bisims1.bisim1AAss4)
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (Red1AAssNull v v')
    note [simp] = a' = null e' = THROW NullPointer i = Val v xs' = xs ta = ε h' = h e = Val v'
    have τ: "¬ τmove1 P h (AAss null (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 a) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 a) + 0, None)"
      by-(rule AAss_τExecrI1)
    also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([v], loc, length (compE2 i) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Null], loc, length (compE2 a) + 0, None) ([v] @ [Null], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
      by(rule AAss_τExecrI2)
    also (rtranclp_trans) have "[v] @ [Null] = [] @ [v, Null]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v'], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v'] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans)
    have "exec_move_a P t (ai := e) h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Null] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW NullPointer, loc)  ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1AAssBounds A U len I v)
    hence [simp]: "a' = addr A" "e' = THROW ArrayIndexOutOfBounds" "i = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
      and hA: "typeof_addr h A = Array_type U len" and I: "I <s 0  int len  sint I" by auto
    have τ: "¬ τmove1 P h (AAss (addr A) i e)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
      by-(rule AAss_τExecrI1)
    also from bisim2[of loc] 
    have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
      by(rule AAss_τExecrI2)
    also (rtranclp_trans) have "[Intg I] @ [Addr A] = [] @ [Intg I, Addr A]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc]
    have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans) from hA I
    have "exec_move_a P t (ai := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW ArrayIndexOutOfBounds, loc)  ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1AAssStore A U len I v U')
    hence [simp]: "a' = addr A" "e' = THROW ArrayStore" "i = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len" 
      and U: "¬ P  U'  U" "typeof⇘hv = U'" by auto
    have τ: "¬ τmove1 P h (AAss (addr A) i e)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk, loc, pc, xcp) ([] @ [Addr A], loc, length (compE2 a) + 0, None)"
      by-(rule AAss_τExecrI1)
    also from bisim2[of loc] 
    have "τExec_mover_a P t i h ([], loc, 0, None) ([Intg I], loc, length (compE2 i) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Addr A], loc, length (compE2 a) + 0, None) ([Intg I] @ [Addr A], loc, length (compE2 a) + (length (compE2 i) + 0), None)"
      by(rule AAss_τExecrI2)
    also (rtranclp_trans) have "[Intg I] @ [Addr A] = [] @ [Intg I, Addr A]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc] 
    have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans) from hA I U
    have "exec_move_a P t (ai := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                  h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayStore)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def compP2_def)
    moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW ArrayStore, loc)  ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayStore)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (AAss1Throw1 A)
    hence [simp]: "a' = Throw A" "ta = ε" "e' = Throw A" "h' = h" "xs' = xs" by auto
    have τ: "τmove1 P h (Throw Ai := e)" by(rule τmove1AAssThrow1)
    from bisim1 have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim1 have "P, ai := e, h  (Throw A, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' where "τExec_mover_a P t a h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        and bisim': "P, a, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (ai := e) h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        by-(rule AAss_τExecrI1)
      moreover from bisim' 
      have "P, ai := e, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        by(auto intro: bisim1_bisims1.bisim1AAssThrow1)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (AAss1Throw2 v ad)
    note [simp] = a' = Val v i = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (aThrow ad := e) h (stk, loc, pc, xcp) ([v], loc, length (compE2 a), None)"
      by-(rule AAss_τExecrI1)
    also have "τExec_mover_a P t (aThrow ad:=e) h ([v], loc, length (compE2 a), None) ([Addr ad, v], loc, Suc (length (compE2 a)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,aThrow ad:=e,h  (Throw ad, loc)  ([Addr ad] @ [v], loc, (length (compE2 a) + length (compE2 (addr ad))), ad)"
      by(rule bisim1AAssThrow2[OF bisim1Throw2])
    moreover have "τmove1 P h (a'Throw ad:=e)" by(auto intro: τmove1AAssThrow2)
    ultimately show ?thesis using s by auto
  next
    case (AAss1Throw3 va vi ad)
    note [simp] = a' = Val va i = Val vi e = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([va], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := Throw ad) h (stk, loc, pc, xcp) ([va], loc, length (compE2 a), None)"
      by-(rule AAss_τExecrI1)
    also from bisim2[of loc] have "τExec_mover_a P t i h ([], loc, 0, None) ([vi], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    from AAss_τExecrI2[OF this, of a e va]
    have "τExec_mover_a P t (ai := Throw ad) h ([va], loc, length (compE2 a), None) ([vi, va], loc, length (compE2 a) + length (compE2 i), None)" by simp
    also (rtranclp_trans)
    have "τExec_mover_a P t (ai:=Throw ad) h ([vi, va], loc, length (compE2 a) + length (compE2 i), None) ([Addr ad, vi, va], loc, Suc (length (compE2 a) + length (compE2 i)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,ai:=Throw ad,h  (Throw ad, loc)  ([Addr ad] @ [vi, va], loc, (length (compE2 a) + length (compE2 i) + length (compE2 (addr ad))), ad)"
      by(rule bisim1AAssThrow3[OF bisim1Throw2])
    moreover have "τmove1 P h (AAss a' (Val vi) (Throw ad))" by(auto intro: τmove1AAssThrow3)
    ultimately show ?thesis using s by auto
  qed
next
  case (bisim1AAss2 i n i' xs stk loc pc xcp a e v1)
  note IH2 = bisim1AAss2.IH(2)
  note IH3 = bisim1AAss2.IH(6)
  note bisim2 = P,i,h  (i', xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,a,h  (a, xs)  ([], xs, 0, None)
  note bisim3 = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  note bsok = bsok (ai := e) n
  from True,P,t ⊢1 Val v1i' := e,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (AAss1Red2 E')
    note [simp] = e' = Val v1E' := e
      and red = True,P,t ⊢1 i',(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v1i' := e) = τmove1 P h i'" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,i,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta i i' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (ai := e) (Val v1i' := e) (Val v1E' := e) h (stk @ [v1]) loc (length (compE2 a) + pc) xcp h' (length (compE2 a) + pc'') (stk'' @ [v1]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v1i' := e)")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move i' E' P t i h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val v1i' := e) (Val v1E' := e) P t (ai := e) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) (stk'' @ [v1], loc'', length (compE2 a) + pc'', xcp'')"
        by(fastforce dest: AAss_τExecrI2 AAss_τExectI2 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t i h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t i h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' i pc' xcp'" 
        and call: "call1 i' = None  no_call2 i pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp" by auto
      from e have "τExec_mover_a P t (ai := e) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) (stk' @ [v1], loc', length (compE2 a) + pc', xcp')" by(rule AAss_τExecrI2)
      moreover from e' have "exec_move_a P t (ai := e) h (stk' @ [v1], loc', length (compE2 a) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v1], loc'', length (compE2 a) + pc'', xcp'')"
        by(rule exec_move_AAssI2)
      moreover from e' have "pc' < length (compE2 i)" by(auto elim: exec_meth.cases)
      with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v1]) (ai := e) (length (compE2 a) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (Val v1i' := e) = call1 i'" by auto
      moreover have "no_call2 i pc  no_call2 (ai := e) (length (compE2 a) + pc)"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) 
    qed
    moreover from bisim'
    have "P,ai := e,h'  (Val v1E' := e, xs')  ((stk'' @ [v1]),  loc'', length (compE2 a) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAss2)
    ultimately show ?thesis
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans)+
      done
  next
    case (AAss1Red3 E' v')
    note [simp] = i' = Val v' e' = Val v1Val v' := E'
      and red = True,P,t ⊢1 e,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v1Val v' := e) = τmove1 P h e"
      by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t i h (stk, loc, pc, xcp) ([v'], xs, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) ([v'] @ [v1], xs, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAss_τExecrI2)
    moreover from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e e E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (ai := e) (Val v1Val v' := e) (Val v1Val v' := E') h ([] @ [v', v1]) xs (length (compE2 a) + length (compE2 i) + 0) None h' (length (compE2 a) + length (compE2 i) + pc'') (stk'' @ [v', v1]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v1Val v' := e)")
      case True
      with exec' τ have [simp]: "h = h'"
        and e: "sim_move e E' P t e h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val v1Val v' := e) (Val v1Val v' := E') P t (ai := e) h ([] @ [v', v1], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk'' @ [v', v1], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
        by(fastforce dest: AAss_τExectI3 AAss_τExecrI3 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e pc' xcp'" 
        and call: "call1 e = None  no_call2 e 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (ai := e) h ([] @ [v', v1], xs, length (compE2 a) + length (compE2 i) + 0, None) (stk' @ [v', v1], loc', length (compE2 a) + length (compE2 i) + pc', xcp')" by(rule AAss_τExecrI3)
      moreover from e' have "exec_move_a P t (ai := e) h (stk' @ [v', v1], loc', length (compE2 a) + length (compE2 i) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v1], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
        by(rule exec_move_AAssI3)
      moreover from e' τ' have "¬ τmove2 (compP2 P) h (stk' @ [v', v1]) (ai := e) (length (compE2 a) + length (compE2 i) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (Val v1Val v' := e) = call1 e" by auto
      moreover have "no_call2 e 0  no_call2 (ai := e) (length (compE2 a) + length (compE2 i))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast 
    qed
    moreover from bisim'
    have "P,ai := e,h'  (Val v1Val v' := E', xs')  ((stk'' @ [v', v1]),  loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAss3)
    moreover from bisim2 have "pc  length (compE2 i)  no_call2 (ai := e) (length (compE2 a) + pc)"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (Red1AAss A U len I v U')
    hence [simp]: "v1 = Addr A" "e' = unit" "i' = Val (Intg I)"
      "ta = WriteMem A (ACell (nat (sint I))) v" "xs' = xs" "e = Val v"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len"
      and v: "typeof⇘hv = U'" "P  U'  U"
      and h': "heap_write h A (ACell (nat (sint I))) v h'" by auto
    have τ: "¬ τmove1 P h (AAss (addr A) (Val (Intg I)) (Val v))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAss_τExecrI2)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
    also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans) from hA I v h'
    have "exec_move_a P t (ai := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)
                                 WriteMem A (ACell (nat (sint I))) v
                                 h' ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (unit, loc)  ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
      by(rule bisim1_bisims1.bisim1AAss4)
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (Red1AAssNull v v')
    note [simp] = v1 = Null e' = THROW NullPointer i' = Val v xs' = xs ta = ε h' = h e = Val v'
    have τ: "¬ τmove1 P h (AAss null (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([v], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Null], loc, length (compE2 a) + pc, xcp) ([v] @ [Null], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAss_τExecrI2)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Null], loc, length (compE2 a) + pc, xcp) ([] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
    also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v'], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v'] @ [v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans)
    have "exec_move_a P t (ai := e) h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Null] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW NullPointer, loc)  ([v', v, Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1AAssBounds A U len I v)
    hence [simp]: "v1 = Addr A" "e' = THROW ArrayIndexOutOfBounds" "i' = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
      and hA: "typeof_addr h A = Array_type U len" and I: "I <s 0  int len  sint I" by auto
    have τ: "¬ τmove1 P h (addr Ai' := e)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAss_τExecrI2)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
    also from bisim3[of loc] have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans) from hA I
    have "exec_move_a P t (ai := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW ArrayIndexOutOfBounds, loc)  ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1AAssStore A U len I v U')
    hence [simp]: "v1 = Addr A" "e' = THROW ArrayStore" "i' = Val (Intg I)" "xs' = xs" "ta = ε" "h' = h" "e = Val v"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len" 
      and U: "¬ P  U'  U" "typeof⇘hv = U'" by auto
    have τ: "¬ τmove1 P h (addr Ai' := e)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([Intg I], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([Intg I] @ [Addr A], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAss_τExecrI2)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Addr A], loc, length (compE2 a) + pc, xcp) ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None)" by simp
    also from bisim3[of loc] 
    have "τExec_mover_a P t e h ([], loc, 0, None) ([v], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h ([] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + 0, None) ([v] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by(rule AAss_τExecrI3)
    also (rtranclp_trans) from hA I U
    have "exec_move_a P t (ai := e) h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayStore)"
      unfolding exec_move_def by- (rule exec_instr, auto simp add: is_Ref_def compP2_def)
    moreover have "τmove2 (compP2 P) h [v, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW ArrayStore, loc)  ([v, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayStore)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto fast
  next
    case (AAss1Throw2 A)
    note [simp] = i' = Throw A ta = ε e' = Throw A h' = h xs' = xs
    have τ: "τmove1 P h (Val v1Throw A := e)" by(rule τmove1AAssThrow2)
    from bisim2 have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim2
      have "P, ai := e, h  (Throw A, xs)  (stk @ [v1], loc, length (compE2 a) + pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc' where "τExec_mover_a P t i h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        and bisim': "P, i, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (ai := e) h (stk @ [v1], loc, length (compE2 a) + pc, None) ([Addr A] @ [v1], loc, length (compE2 a) + pc', A)"
        by-(rule AAss_τExecrI2)
      moreover from bisim'
      have "P, ai := e, h  (Throw A, xs)  ([Addr A] @ [v1], loc, length (compE2 a) +  pc', A)"
        by(rule bisim1_bisims1.bisim1AAssThrow2)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (AAss1Throw3 vi ad)
    note [simp] = i' = Val vi e = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t i h (stk, loc, pc, xcp) ([vi], loc, length (compE2 i), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := Throw ad) h (stk @ [v1], loc, length (compE2 a) + pc, xcp) ([vi] @ [v1], loc, length (compE2 a) + length (compE2 i), None)"
      by-(rule AAss_τExecrI2)
    also have "τExec_mover_a P t (ai:=Throw ad) h ([vi] @ [v1], loc, length (compE2 a) + length (compE2 i), None) ([Addr ad, vi, v1], loc, Suc (length (compE2 a) + length (compE2 i)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,ai:=Throw ad,h  (Throw ad, loc)  ([Addr ad] @ [vi, v1], loc, (length (compE2 a) + length (compE2 i) + length (compE2 (addr ad))), ad)"
      by(rule bisim1AAssThrow3[OF bisim1Throw2])
    moreover have "τmove1 P h (AAss (Val v1) (Val vi) (Throw ad))" by(auto intro: τmove1AAssThrow3)
    ultimately show ?thesis using s by auto
  qed auto
next
  case (bisim1AAss3 e n ee xs stk loc pc xcp a i v v')
  note IH3 = bisim1AAss3.IH(2)
  note bisim3 = P,e,h  (ee, xs)  (stk, loc, pc, xcp)
  note bsok = bsok (ai := e) n
  from True,P,t ⊢1 Val vVal v' := ee,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (AAss1Red3 E')
    note [simp] = e' = Val vVal v' := E'
      and red = True,P,t ⊢1 ee,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val vVal v' := ee) = τmove1 P h ee" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e ee E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "no_call2 e pc  no_call2 (ai := e) (length (compE2 a) + length (compE2 i) +  pc)" 
      by(auto simp add: no_call2_def)
    hence "?exec ta (ai := e) (Val vVal v' := ee) (Val vVal v' := E') h (stk @ [v', v]) loc (length (compE2 a) + length (compE2 i) + pc) xcp h' (length (compE2 a) + length (compE2 i) + pc'') (stk'' @ [v', v]) loc'' xcp''"
      using exec' τ
      apply(cases "τmove1 P h (Val vVal v' := ee)")
      apply(auto)
      apply(blast intro: AAss_τExecrI3 AAss_τExectI3 exec_move_AAssI3)
      apply(blast intro: AAss_τExecrI3 AAss_τExectI3 exec_move_AAssI3)
      apply(rule exI conjI AAss_τExecrI3 exec_move_AAssI3|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI AAss_τExecrI3 exec_move_AAssI3|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI AAss_τExecrI3 exec_move_AAssI3 rtranclp.rtrancl_refl|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
      done
    moreover from bisim'
    have "P,ai := e,h'  (Val vVal v' := E', xs')  (stk''@[v',v], loc'', length (compE2 a) + length (compE2 i) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1AAss3)
    ultimately show ?thesis using τ by auto blast+
  next
    case (Red1AAss A U len I V U')
    hence [simp]: "v = Addr A" "e' = unit" "v' = Intg I" "xs' = xs" "ee = Val V"
      "ta = WriteMem A (ACell (nat (sint I))) V"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len" 
      and v: "typeof⇘hV = U'" "P  U'  U"
      and h': "heap_write h A (ACell (nat (sint I))) V h'" by auto
    have τ: "¬ τmove1 P h (AAss (addr A) (Val (Intg I)) (Val V))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by-(rule AAss_τExecrI3)
    moreover from hA I v h'
    have "exec_move_a P t (ai := e) h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) 
                                 WriteMem A (ACell (nat (sint I))) V
                                 h' ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
     unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [V, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover 
    have "P, ai := e, h'  (unit, loc)  ([], loc, Suc (length (compE2 a) + length (compE2 i) + length (compE2 e)), None)"
      by(rule bisim1_bisims1.bisim1AAss4)
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (Red1AAssNull V')
    note [simp] = v = Null e' = THROW NullPointer xs' = xs ta = ε h' = h ee = Val V'
    have τ: "¬ τmove1 P h (AAss null (Val v') (Val V'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V'], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [v', Null], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V'] @ [v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by-(rule AAss_τExecrI3)
    moreover
    have "exec_move_a P t (ai := e) h ([V', v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([V', v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [V', v', Null] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW NullPointer, loc)  ([V', v', Null], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1AAssBounds A U len I V)
    hence [simp]: "v = Addr A" "e' = THROW ArrayIndexOutOfBounds" "v' = Intg I" "xs' = xs" "ta = ε" "h' = h" "ee = Val V"
      and hA: "typeof_addr h A = Array_type U len" and I: "I <s 0  int len  sint I" by auto
    have τ: "¬ τmove1 P h (addr AVal (Intg I) := ee)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by-(rule AAss_τExecrI3)
    moreover from hA I
    have "exec_move_a P t (ai := e) h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [V, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW ArrayIndexOutOfBounds, loc)  ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayIndexOutOfBounds)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next 
    case (Red1AAssStore A U len I V U')
    hence [simp]: "v = Addr A" "e' = THROW ArrayStore" "v' = Intg I" "xs' = xs" "ta = ε" "h' = h" "ee = Val V"
      and hA: "typeof_addr h A = Array_type U len" and I: "0 <=s I" "sint I < int len" 
      and U: "¬ P  U'  U" "typeof⇘hV = U'" by auto
    have τ: "¬ τmove1 P h (addr AVal (Intg I) := ee)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e h (stk, loc, pc, xcp) ([V], loc, length (compE2 e), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (ai := e) h (stk @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + pc, xcp) ([V] @ [Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None)"
      by-(rule AAss_τExecrI3)
    moreover from hA I U
    have "exec_move_a P t (ai := e) h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), None) ε
                                 h ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayStore)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def compP2_def)
    moreover have "τmove2 (compP2 P) h [V, Intg I, Addr A] (ai := e) (length (compE2 a) + length (compE2 i) + length (compE2 e)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, ai := e, h'  (THROW ArrayStore, loc)  ([V, Intg I, Addr A], loc, length (compE2 a) + length (compE2 i) + length (compE2 e), addr_of_sys_xcpt ArrayStore)"
      by(rule bisim1_bisims1.bisim1AAssFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (AAss1Throw3 A)
    note [simp] = ee = Throw A ta = ε e' = Throw A h' = h xs' = xs
    have τ: "τmove1 P h (AAss (Val v) (Val v') (Throw A))" by(rule τmove1AAssThrow3)
    from bisim3 have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim3
      have "P, ai := e, h  (Throw A, xs)  (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim3 obtain pc' where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (ai := e) h (stk @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc, None) ([Addr A] @ [v', v], loc, length (compE2 a) + length (compE2 i) + pc', A)"
        by-(rule AAss_τExecrI3)
      moreover from bisim'
      have "P, ai := e, h  (Throw A, xs)  ([Addr A] @ [v', v], loc, length (compE2 a) +  length (compE2 i) + pc', A)"
        by(rule bisim1_bisims1.bisim1AAssThrow3)
      ultimately show ?thesis using τ by auto
    qed
  qed auto
next
  case bisim1AAssThrow1 thus ?case by auto
next
  case bisim1AAssThrow2 thus ?case by auto
next
  case bisim1AAssThrow3 thus ?case by auto
next
  case bisim1AAssFail thus ?case by auto
next
  case bisim1AAss4 thus ?case by auto
next
  case (bisim1ALength a n a' xs stk loc pc xcp)
  note IH = bisim1ALength.IH(2)
  note bisim = P,a,h  (a', xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 a'∙length,(h, xs) -ta e',(h', xs')
  note bsok = bsok (a∙length) n
  from red show ?case
  proof cases
    case (ALength1Red ee')
    note [simp] = e' = ee'∙length
      and red = True,P,t ⊢1 a',(h, xs) -ta ee', (h', xs')
    from red have "τmove1 P h (a'∙length) = τmove1 P h a'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (a'∙length) = call1 a'" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,a,h'  (ee', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta a a' ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim have "P,a∙length,h'  (ee'∙length, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1ALength)
    moreover { 
      assume "no_call2 a pc"
      hence "no_call2 (a∙length) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: ALength_τExecrI ALength_τExectI exec_move_ALengthI)+
  next
    case (Red1ALength A U len)
    hence [simp]: "a' = addr A" "ta = ε" "e' = Val (Intg (word_of_int (int len)))"
      "h' = h" "xs' = xs"
      and hA: "typeof_addr h A = Array_type U len" by auto
    from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    from bisim have "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (a∙length) h (stk, loc, pc, xcp) ([Addr A], loc, length (compE2 a), None)"
      by(rule ALength_τExecrI)
    moreover from hA
    have "exec_move_a P t (a∙length) h ([Addr A], loc, length (compE2 a), None) ε h' ([Intg (word_of_int (int len))], loc, Suc (length (compE2 a)), None)"
      by(auto intro!: exec_instr simp add: is_Ref_def exec_move_def)
    moreover have "τmove2 (compP2 P) h [Addr A] (a∙length) (length (compE2 a)) None  False" by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (addr A∙length)" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover
    have "P, a∙length, h'  (Val (Intg (word_of_int (int len))), loc)  ([Intg (word_of_int (int len))], loc, length (compE2 (a∙length)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s by(auto) blast
  next
    case Red1ALengthNull
    note [simp] = a' = null e' = THROW NullPointer h' = h xs' = xs ta = ε
    have "¬ τmove1 P h (null∙length)" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t a h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (a∙length) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 a), None)"
      by-(rule ALength_τExecrI)
    moreover have "exec_move_a P t (a∙length) h ([Null], loc, length (compE2 a), None) ε h ([Null], loc, length (compE2 a), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [Null] (a∙length) (length (compE2 a)) None  False" by(simp add: τmove2_iff)
    moreover 
    have "P,a∙length,h  (THROW NullPointer, loc)  ([Null], loc, length (compE2 a), addr_of_sys_xcpt NullPointer)"
      by(auto intro!: bisim1_bisims1.bisim1ALengthNull)
    ultimately show ?thesis using s by auto blast
  next
    case (ALength1Throw A)
    note [simp] = a' = Throw A h' = h xs' = xs ta = ε e' = Throw A
    have τ: "τmove1 P h (Throw A∙length)" by(auto intro: τmove1ALengthThrow)
    from bisim have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim have "P,a∙length, h  (Throw A, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.bisim1ALengthThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_a P t a h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        and bisim': "P, a, h  (Throw A, xs)  ([Addr A], loc, pc', A)" and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (a∙length) h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        by-(rule ALength_τExecrI)
      moreover from bisim' have "P, a∙length, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        by(rule bisim1_bisims1.bisim1ALengthThrow)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1ALengthThrow thus ?case by auto
next
  case bisim1ALengthNull thus ?case by auto
next
  case (bisim1FAcc E n e xs stk loc pc xcp F D)
  note IH = bisim1FAcc.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 eF{D},(h, xs) -ta e',(h', xs')
  note bsok = bsok (EF{D}) n
  from red show ?case
  proof cases
    case (FAcc1Red ee')
    note [simp] = e' = ee'F{D}
      and red = True,P,t ⊢1 e,(h, xs) -ta ee', (h', xs')
    from red have "τmove1 P h (eF{D}) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (eF{D}) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (ee', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e ee' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,EF{D},h'  (ee'F{D}, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1FAcc)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (EF{D}) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: FAcc_τExecrI FAcc_τExectI exec_move_FAccI)+
  next
    case (Red1FAcc a v)
    hence [simp]: "e = addr a" "ta = ReadMem a (CField D F) v" "e' = Val v" "h' = h" "xs' = xs"
      and read: "heap_read h a (CField D F) v" by auto
    from bisim have s: "xcp = None" "xs = loc" by(auto dest: bisim_Val_loc_eq_xcp_None)
    from bisim have "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (EF{D}) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 E), None)"
      by(rule FAcc_τExecrI)
    moreover from read 
    have "exec_move_a P t (EF{D}) h ([Addr a], loc, length (compE2 E), None) 
                     ReadMem a (CField D F) v h' ([v], loc, Suc (length (compE2 E)), None)"
      unfolding exec_move_def by(auto intro!: exec_instr)
    moreover have "τmove2 (compP2 P) h [Addr a] (EF{D}) (length (compE2 E)) None  False" by(simp add: τmove2_iff)
    moreover have "¬ τmove1 P h (addr aF{D})" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover
    have "P, EF{D}, h'  (Val v, loc)  ([v], loc, length (compE2 (EF{D})), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s by(auto simp add: ta_upd_simps) blast
  next
    case Red1FAccNull
    note [simp] = e = null e' = THROW NullPointer h' = h xs' = xs ta = ε
    have "¬ τmove1 P h (nullF{D})" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (EF{D}) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
      by-(rule FAcc_τExecrI)
    moreover
    have "exec_move_a P t (EF{D}) h ([Null], loc, length (compE2 E), None) ε h ([Null], loc, length (compE2 E), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by -(rule exec_instr, auto simp add: compP2_def dest: sees_field_idemp)
    moreover have "τmove2 (compP2 P) h [Null] (EF{D}) (length (compE2 E)) None  False" by(simp add: τmove2_iff)
    moreover
    have "P,EF{D},h  (THROW NullPointer, loc)  ([Null], loc, length (compE2 E), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1FAccNull)
    ultimately show ?thesis using s by auto blast
  next
    case (FAcc1Throw a)
    note [simp] = e = Throw a h' = h xs' = xs ta = ε e' = Throw a
    have τ: "τmove1 P h (eF{D})" by(auto intro: τmove1FAccThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P,EF{D}, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.bisim1FAccThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (EF{D}) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule FAcc_τExecrI)
      moreover from bisim' have "P, EF{D}, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(rule bisim1_bisims1.bisim1FAccThrow)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1FAccThrow thus ?case by auto
next
  case bisim1FAccNull thus ?case by auto
next
  case (bisim1FAss1 e1 n e1' xs stk loc pc xcp e2 F D)
  note IH1 = bisim1FAss1.IH(2)
  note IH2 = bisim1FAss1.IH(4)
  note bisim1 = P,e1,h  (e1', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bsok = bsok (e1F{D} := e2) n
  from True,P,t ⊢1 e1'F{D} := e2,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (FAss1Red1 E')
    note [simp] = e' = E'F{D} := e2
      and red = True,P,t ⊢1 e1',(h, xs) -ta E',(h', xs')
    from red have "τmove1 P h (e1'F{D} := e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (e1'F{D} := e2) = call1 e1'" by auto
    moreover from IH1[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,e1F{D} := e2,h'  (E'F{D} := e2, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1FAss1)
    moreover { 
      assume "no_call2 e1 pc"
      hence "no_call2 (e1F{D} := e2) pc  pc = length (compE2 e1)" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: FAss_τExecrI1 FAss_τExectI1 exec_move_FAssI1)+
  next
    case (FAss1Red2 E' v)
    note [simp] = e1' = Val v e' = Val vF{D} := E'
      and red = True,P,t ⊢1 e2,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val vF{D} := e2) = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (e1F{D} := e2) h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
      by(rule FAss_τExecrI1)
    moreover
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (e1F{D} := e2) (Val vF{D} := e2) (Val vF{D} := E') h ([] @ [v]) xs (length (compE2 e1) + 0) None h' (length (compE2 e1) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val vF{D} := e2)")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move e2 E' P t e2 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val vF{D} := e2) (Val vF{D} := E') P t (e1F{D} := e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
        by(fastforce dest: FAss_τExecrI2 FAss_τExectI2 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e2 h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'" 
        and call: "call1 e2 = None  no_call2 e2 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (e1F{D} := e2) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk' @ [v], loc', length (compE2 e1) + pc', xcp')"
        by(rule FAss_τExecrI2)
      moreover from e' have "exec_move_a P t (e1F{D} := e2) h (stk' @ [v], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
        by(rule exec_move_FAssI2)
      moreover from e' have "pc' < length (compE2 e2)" by(auto elim: exec_meth.cases)
      with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (e1F{D} := e2) (length (compE2 e1) + pc') xcp'"
        by(auto simp add: τmove2_iff τinstr_stk_drop_exec_move)
      moreover have "call1 (e1'F{D} := e2) = call1 e2" by simp
      moreover have "no_call2 e2 0  no_call2 (e1F{D} := e2) (length (compE2 e1))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,e1F{D} := e2,h'  (Val vF{D} := E', xs')  ((stk'' @ [v]), loc'', length (compE2 e1) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1FAss2)
    moreover from bisim1 have "pc  length (compE2 e1)  no_call2 (e1F{D} := e2) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (Red1FAss a v)
    note [simp] = e1' = addr a e2 = Val v ta = WriteMem a (CField D F) v e' = unit xs' = xs
      and "write" = heap_write h a (CField D F) v h'
    have τ: "¬ τmove1 P h (e1'F{D} := e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1F{D} := e2) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)"
      by-(rule FAss_τExecrI1)
    also have "τmove2 (compP2 P) h [Addr a] (e1F{D} := Val v) (length (compE2 e1)) None" by(simp add: τmove2_iff)
    hence "τExec_mover_a P t (e1F{D} := e2) h ([Addr a], loc, length (compE2 e1), None) ([v, Addr a], loc, Suc (length (compE2 e1)), None)"
      by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
    also (rtranclp_trans) from "write"
    have "exec_move_a P t (e1F{D} := e2) h ([v, Addr a], loc, Suc (length (compE2 e1)), None) WriteMem a (CField D F) v
                                      h' ([], loc, Suc (Suc (length (compE2 e1))), None)"
      unfolding exec_move_def by(auto intro!: exec_instr)
    moreover have "τmove2 (compP2 P) h [v, Addr a] (e1F{D} := e2) (Suc (length (compE2 e1))) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1F{D} := e2, h'  (unit, loc)  ([], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
      by(rule bisim1_bisims1.bisim1FAss3)
    ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply simp add: ta_upd_simps) blast
  next
    case (Red1FAssNull v)
    note [simp] = e1' = null e2 = Val v xs' = xs ta = ε e' = THROW NullPointer h' = h
    have τ: "¬ τmove1 P h (e1'F{D} := e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1F{D} := e2) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)"
      by-(rule FAss_τExecrI1)
    also have "τmove2 (compP2 P) h [Null] (e1F{D} := Val v) (length (compE2 e1)) None" by(simp add: τmove2_iff)
    hence "τExec_mover_a P t (e1F{D} := e2) h ([Null], loc, length (compE2 e1), None) ([v, Null], loc, Suc (length (compE2 e1)), None)"
      by-(rule τExecr1step, auto intro!: exec_instr simp add: exec_move_def compP2_def)
    also (rtranclp_trans)
    have "exec_move_a P t (e1F{D} := e2) h ([v, Null], loc, Suc (length (compE2 e1)), None) ε
                                      h' ([v, Null], loc, Suc (length (compE2 e1)), addr_of_sys_xcpt NullPointer)"
      by(auto intro!: exec_instr simp add: exec_move_def)
    moreover have "τmove2 (compP2 P) h [v, Null] (e1F{D} := e2) (Suc (length (compE2 e1))) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1F{D} := e2, h  (THROW NullPointer, loc)  ([v, Null], loc, length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1FAssNull)
    ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply) blast
  next
    case (FAss1Throw1 a)
    note [simp] = e1' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (Throw aF{D} := e2)" by(rule τmove1FAssThrow1)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1
      have "P, e1F{D} := e2, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1F{D} := e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule FAss_τExecrI1)
      moreover from bisim'
      have "P, e1F{D} := e2, h (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(rule bisim1_bisims1.bisim1FAssThrow1)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (FAss1Throw2 v ad)
    note [simp] = e1' = Val v e2 = Throw ad e' = Throw ad h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1F{D} := Throw ad) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by-(rule FAss_τExecrI1)
    also have "τExec_mover_a P t (e1F{D} := Throw ad) h ([v], loc, length (compE2 e1), None) ([Addr ad, v], loc, Suc (length (compE2 e1)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,e1F{D}:=Throw ad,h  (Throw ad, loc)  ([Addr ad] @ [v], loc, (length (compE2 e1) + length (compE2 (addr ad))), ad)"
      by(rule bisim1FAssThrow2[OF bisim1Throw2])
    moreover have "τmove1 P h (FAss e1' F D (Throw ad))" by(auto intro: τmove1FAssThrow2)
    ultimately show ?thesis using s by auto
  qed
next
  case (bisim1FAss2 e2 n e2' xs stk loc pc xcp e1 F D v1)
  note IH2 = bisim1FAss2.IH(2)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note bsok = bsok (e1F{D} := e2) n
  note red = True,P,t ⊢1 Val v1F{D} := e2',(h, xs) -ta e',(h', xs')
  from red show ?case
  proof cases
    case (FAss1Red2 E')
    note [simp] = e' = Val v1F{D} := E'
      and red = True,P,t ⊢1 e2',(h, xs) -ta E',(h', xs')
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from red have τ: "τmove1 P h (Val v1F{D} := e2') = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
    have "no_call2 e2 pc  no_call2 (e1F{D} := e2) (length (compE2 e1) + pc)" by(auto simp add: no_call2_def)
    hence "?exec ta (e1F{D} := e2) (Val v1F{D} := e2') (Val v1F{D} := E') h (stk @ [v1]) loc (length (compE2 e1) + pc) xcp h' (length (compE2 e1) + pc'') (stk'' @ [v1]) loc'' xcp''"
      using exec' τ
      apply(cases "τmove1 P h (Val v1F{D} := e2')")
      apply(auto)
      apply(blast intro: FAss_τExecrI2 FAss_τExectI2 exec_move_FAssI2)
      apply(blast intro: FAss_τExecrI2 FAss_τExectI2 exec_move_FAssI2)
      apply(rule exI conjI FAss_τExecrI2 exec_move_FAssI2|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI FAss_τExecrI2 exec_move_FAssI2|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI FAss_τExecrI2 exec_move_FAssI2 rtranclp.rtrancl_refl|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
      done
    moreover from bisim'
    have "P,e1F{D} := e2,h'  (Val v1F{D} := E', xs')  (stk''@[v1], loc'', length (compE2 e1) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1FAss2)
    ultimately show ?thesis using τ by auto blast+
  next
    case (Red1FAss a v)
    note [simp] = v1 = Addr a e2' = Val v ta = WriteMem a (CField D F) v e' = unit xs' = xs
      and ha = heap_write h a (CField D F) v h'
    have τ: "¬ τmove1 P h (addr aF{D} := e2')" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc" 
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1F{D} := e2) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule FAss_τExecrI2)
    moreover from ha
    have "exec_move_a P t (e1F{D} := e2) h ([v, Addr a], loc, length (compE2 e1) + length (compE2 e2), None) WriteMem a (CField D F) v
                                      h' ([], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
      by(auto intro!: exec_instr simp add: exec_move_def)
    moreover have "τmove2 (compP2 P) h [v, Addr a] (e1F{D} := e2) (length (compE2 e1) + length (compE2 e2)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1F{D} := e2, h'  (unit, loc)  ([], loc, Suc (length (compE2 e1) + length (compE2 e2)), None)"
      by(rule bisim1_bisims1.bisim1FAss3)
    ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply simp add: ta_upd_simps) blast
  next
    case (Red1FAssNull v)
    note [simp] = v1 = Null e2' = Val v xs' = xs ta = ε e' = THROW NullPointer h' = h
    have τ: "¬ τmove1 P h (nullF{D} := e2')" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc" 
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1F{D} := e2) h (stk @ [Null], loc, length (compE2 e1) + pc, xcp) ([v] @ [Null], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule FAss_τExecrI2)
    moreover have "exec_move_a P t (e1F{D} := e2) h ([v, Null], loc, length (compE2 e1) + length (compE2 e2), None) ε
                                      h' ([v, Null], loc, length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt NullPointer)"
      by(auto intro!: exec_instr simp add: exec_move_def)
    moreover have "τmove2 (compP2 P) h [v, Null] (e1F{D} := e2) (length (compE2 e1) + length (compE2 e2)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1F{D} := e2, h  (THROW NullPointer, loc)  ([v, Null], loc, length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1FAssNull)
    ultimately show ?thesis using s τ by(auto simp del: fun_upd_apply) blast
  next
    case (FAss1Throw2 a)
    note [simp] = e2' = Throw a ta = ε h' = h xs' = xs e' = Throw a
    have τ: "τmove1 P h (FAss (Val v1) F D (Throw a))" by(rule τmove1FAssThrow2)
    from bisim2 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim2
      have "P, e1F{D} := e2, h  (Throw a, xs)  (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
        by(auto intro: bisim1FAssThrow2)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1F{D} := e2) h (stk @ [v1], loc, length (compE2 e1) + pc, None) ([Addr a] @ [v1], loc, length (compE2 e1) + pc', a)"
        by-(rule FAss_τExecrI2)
      moreover from bisim'
      have "P, e1F{D} := e2, h  (Throw a, xs)  ([Addr a]@[v1], loc, length (compE2 e1) + pc', a)"
        by-(rule bisim1FAssThrow2, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed auto
next
  case bisim1FAssThrow1 thus ?case by fastforce
next
  case bisim1FAssThrow2 thus ?case by fastforce
next
  case bisim1FAssNull thus ?case by fastforce
next
  case bisim1FAss3 thus ?case by fastforce
next
  case (bisim1CAS1 e1 n e1' xs stk loc pc xcp e2 e3 D F)
  note IH1 = bisim1CAS1.IH(2)
  note IH2 = bisim1CAS1.IH(4)
  note IH3 = bisim1CAS1.IH(6)
  note bisim1 = P,e1,h  (e1', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bisim3 = xs. P,e3,h  (e3, xs)  ([], xs, 0, None)
  note bsok = bsok _ n
  from True,P,t ⊢1 _,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (CAS1Red1 E')
    note [simp] = e' = E'∙compareAndSwap(DF, e2, e3)
      and red = True,P,t ⊢1 e1',(h, xs) -ta E',(h', xs')
    from red have "τmove1 P h (e1'∙compareAndSwap(DF, e2, e3)) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (e1'∙compareAndSwap(DF, e2, e3)) = call1 e1'" by auto
    moreover from IH1[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim 
    have "P,e1∙compareAndSwap(DF, e2, e3),h'  (E'∙compareAndSwap(DF, e2, e3), xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CAS1)
    moreover { 
      assume "no_call2 e1 pc"
      hence "no_call2 (e1∙compareAndSwap(DF, e2, e3)) pc  pc = length (compE2 e1)" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: CAS_τExecrI1 CAS_τExectI1 exec_move_CASI1)+
  next
    case (CAS1Red2 E' v)
    note [simp] = e1' = Val v e' = Val v∙compareAndSwap(DF, E', e3)
      and red = True,P,t ⊢1 e2,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v∙compareAndSwap(DF, e2, e3)) = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk, loc, pc, None) ([v], xs, length (compE2 e1), None)"
      by(rule CAS_τExecrI1)
    moreover
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (e1∙compareAndSwap(DF, e2, e3)) (Val v∙compareAndSwap(DF, e2, e3)) (Val v∙compareAndSwap(DF, E', e3)) h ([] @ [v]) xs (length (compE2 e1) + 0) None h' (length (compE2 e1) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v∙compareAndSwap(DF, e2, e3))")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move e2 E' P t e2 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (e1∙compareAndSwap(DF, e2, e3)) (e1∙compareAndSwap(DF, E', e3)) P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
        by(fastforce dest: CAS_τExecrI2 CAS_τExectI2)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e2 h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'" 
        and call: "call1 e2 = None  no_call2 e2 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v], xs, length (compE2 e1) + 0, None) (stk' @ [v], loc', length (compE2 e1) + pc', xcp')" by(rule CAS_τExecrI2)
      moreover from e' have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk' @ [v], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e1) + pc'', xcp'')"
        by(rule exec_move_CASI2)
      moreover from e' have "pc' < length (compE2 e2)" by(auto elim: exec_meth.cases)
      with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v]) (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (e1'∙compareAndSwap(DF, e2, e3)) = call1 e2" by auto
      moreover have "no_call2 e2 0  no_call2 (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,e1∙compareAndSwap(DF, e2, e3),h'  (Val v∙compareAndSwap(DF, E', e3), xs')  ((stk'' @ [v]), loc'', length (compE2 e1) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CAS2)
    moreover from bisim1 have "pc  length (compE2 e1)  no_call2 (e1∙compareAndSwap(DF, e2, e3)) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (CAS1Red3 E' v v')
    note [simp] = e2 = Val v' e1' = Val v e' = Val v∙compareAndSwap(DF, Val v', E')
      and red = True,P,t ⊢1 e3,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v∙compareAndSwap(DF, Val v', e3)) = τmove1 P h e3" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e1 h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 e1) + 0, None)"
      by(auto dest: bisim1Val2D1)
    from exec1 have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk, loc, pc, None) ([] @ [v], xs, length (compE2 e1) + 0, None)"
      by(rule CAS_τExecrI1)
    also from bisim2[of xs] 
    have "τExec_mover_a P t e2 h ([], xs, 0, None) ([v'], xs, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v], xs, length (compE2 e1) + 0, None) ([v'] @ [v], xs, length (compE2 e1) + length (compE2 e2), None)"
      by(rule CAS_τExecrI2)
    also (rtranclp_trans) from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e3,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e3 e3 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (e1∙compareAndSwap(DF, e2, e3)) (Val v∙compareAndSwap(DF, Val v', e3)) (Val v∙compareAndSwap(DF, Val v', E')) h ([] @ [v', v]) xs (length (compE2 e1) + length (compE2 e2) + 0) None h' (length (compE2 e1) + length (compE2 e2) + pc'') (stk'' @ [v', v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v∙compareAndSwap(DF, Val v', e3))")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move e3 E' P t e3 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val v∙compareAndSwap(DF, Val v', e3)) (Val v∙compareAndSwap(DF, Val v', E')) P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v', v], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk'' @ [v', v], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
        by(fastforce dest: CAS_τExectI3 CAS_τExecrI3 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e3 h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e3 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e3 pc' xcp'" 
        and call: "call1 e3 = None  no_call2 e3 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v', v], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk' @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp')" by(rule CAS_τExecrI3)
      moreover from e' have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk' @ [v', v], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
        by(rule exec_move_CASI3)
      moreover from e' τ'
      have "¬ τmove2 (compP2 P) h (stk' @ [v', v]) (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover have "call1 (e1'∙compareAndSwap(DF, e2, e3)) = call1 e3" by simp
      moreover have "no_call2 e3 0  no_call2 (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim'
    have "P,e1∙compareAndSwap(DF, e2, e3),h'  (Val v∙compareAndSwap(DF, Val v', E'), xs')  ((stk'' @ [v', v]),  loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CAS3) 
    moreover from bisim1 have "pc  length (compE2 e1) + length (compE2 e2)  no_call2 (e1∙compareAndSwap(DF, e2, e3)) pc"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (CAS1Null v v')
    note [simp] = e1' = null e' = THROW NullPointer e2 = Val v xs' = xs ta = ε h' = h e3 = Val v'
    have τ: "¬ τmove1 P h (AAss null (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 e1) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk, loc, pc, xcp) ([] @ [Null], loc, length (compE2 e1) + 0, None)"
      by-(rule CAS_τExecrI1)
    also from bisim2[of loc] have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v], loc, length (compE2 e2) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [Null], loc, length (compE2 e1) + 0, None) ([v] @ [Null], loc, length (compE2 e1) + (length (compE2 e2) + 0), None)"
      by(rule CAS_τExecrI2)
    also (rtranclp_trans) have "[v] @ [Null] = [] @ [v, Null]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by(rule CAS_τExecrI3)
    also (rtranclp_trans)
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) ε
                                 h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Null] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (THROW NullPointer, loc)  ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1CASFail)
    ultimately show ?thesis using s τ by(auto simp add: τmove1.simps) blast
  next
    case (Red1CASSucceed a v v')
    hence [simp]: "e1' = addr a" "e' = true" "e2 = Val v"
      "ta = ReadMem a (CField D F) v, WriteMem a (CField D F) v'" "xs' = xs" "e3 = Val v'"
      and read: "heap_read h a (CField D F) v"
      and "write": "heap_write h a (CField D F) v' h'" by auto
    have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
      by-(rule CAS_τExecrI1)
    also from bisim2[of loc]
    have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v], loc, length (compE2 e2) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [Addr a], loc, length (compE2 e1) + 0, None) ([v] @ [Addr a], loc, length (compE2 e1) + (length (compE2 e2) + 0), None)"
      by(rule CAS_τExecrI2)
    also (rtranclp_trans) have "[v] @ [Addr a] = [] @ [v, Addr a]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by(rule CAS_τExecrI3)
    also (rtranclp_trans) from read "write"
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
                                  ReadMem a (CField D F) v, WriteMem a (CField D F) v' 
                                 h' ([Bool True], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (true, loc)  ([Bool True], loc, length (compE2 (e1∙compareAndSwap(DF, e2, e3))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (Red1CASFail a v'' v v')
    hence [simp]: "e1' = addr a" "e' = false" "e2 = Val v" "h' = h"
      "ta = ReadMem a (CField D F) v''" "xs' = xs" "e3 = Val v'"
      and read: "heap_read h a (CField D F) v''" "v  v''" by auto
    have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk, loc, pc, xcp) ([] @ [Addr a], loc, length (compE2 e1) + 0, None)"
      by-(rule CAS_τExecrI1)
    also from bisim2[of loc]
    have "τExec_mover_a P t e2 h ([], loc, 0, None) ([v], loc, length (compE2 e2) + 0, None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [Addr a], loc, length (compE2 e1) + 0, None) ([v] @ [Addr a], loc, length (compE2 e1) + (length (compE2 e2) + 0), None)"
      by(rule CAS_τExecrI2)
    also (rtranclp_trans) have "[v] @ [Addr a] = [] @ [v, Addr a]" by simp
    also note add.assoc[symmetric]
    also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by(rule CAS_τExecrI3)
    also (rtranclp_trans) from read
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
                                  ReadMem a (CField D F) v'' 
                                 h ([Bool False], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h  (false, loc)  ([Bool False], loc, length (compE2 (e1∙compareAndSwap(DF, e2, e3))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps)blast
  next
    case (CAS1Throw a)
    hence [simp]: "e1' = Throw a" "ta = ε" "e' = Throw a" "h' = h" "xs' = xs" by auto
    have τ: "τmove1 P h (Throw a∙compareAndSwap(DF, e2, e3))" by(rule τmove1CASThrow1)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1 have "P, e1∙compareAndSwap(DF, e2, e3), h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule CAS_τExecrI1)
      moreover from bisim' 
      have "P, e1∙compareAndSwap(DF, e2, e3), h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(auto intro: bisim1_bisims1.bisim1CASThrow1)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (CAS1Throw2 v ad)
    note [simp] = e1' = Val v e2 = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, Throw ad, e3)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by-(rule CAS_τExecrI1)
    also have "τExec_mover_a P t (e1∙compareAndSwap(DF, Throw ad, e3)) h ([v], loc, length (compE2 e1), None) ([Addr ad, v], loc, Suc (length (compE2 e1)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,e1∙compareAndSwap(DF, Throw ad, e3),h  (Throw ad, loc)  ([Addr ad] @ [v], loc, (length (compE2 e1) + length (compE2 (addr ad))), ad)"
      by(rule bisim1CASThrow2[OF bisim1Throw2])
    moreover have "τmove1 P h (e1'∙compareAndSwap(DF, Throw ad, e3))" by(auto intro: τmove1CASThrow2)
    ultimately show ?thesis using s by auto
  next
    case (CAS1Throw3 v v' ad)
    note [simp] = e1' = Val v e2 = Val v' e3 = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, Throw ad)) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by-(rule CAS_τExecrI1)
    also from bisim2[of loc] 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 v]
    have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, Throw ad)) h ([v], loc, length (compE2 e1), None) ([v', v], loc, length (compE2 e1) + length (compE2 e2), None)" by simp
    also (rtranclp_trans)
    have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, Throw ad)) h ([v', v], loc, length (compE2 e1) + length (compE2 e2), None) ([Addr ad, v', v], loc, Suc (length (compE2 e1) + length (compE2 e2)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,e1∙compareAndSwap(DF, e2, Throw ad),h  (Throw ad, loc)  ([Addr ad] @ [v', v], loc, (length (compE2 e1) + length (compE2 e2) + length (compE2 (addr ad))), ad)"
      by(rule bisim1CASThrow3[OF bisim1Throw2])
    moreover have "τmove1 P h (Val v∙compareAndSwap(DF, Val v', Throw ad))" by(auto intro: τmove1CASThrow3)
    ultimately show ?thesis using s by auto
  qed
next
  case (bisim1CAS2 e2 n e2' xs stk loc pc xcp e1 e3 D F v1)
  note IH2 = bisim1CAS2.IH(2)
  note IH3 = bisim1CAS2.IH(6)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bisim3 = xs. P,e3,h  (e3, xs)  ([], xs, 0, None)
  note bsok = bsok (e1∙compareAndSwap(DF, e2, e3)) n
  from True,P,t ⊢1 Val v1∙compareAndSwap(DF, e2', e3),(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (CAS1Red2 E')
    note [simp] = e' = Val v1∙compareAndSwap(DF, E', e3)
      and red = True,P,t ⊢1 e2',(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v1∙compareAndSwap(DF, e2', e3)) = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (e1∙compareAndSwap(DF, e2, e3)) (Val v1∙compareAndSwap(DF, e2', e3)) (Val v1∙compareAndSwap(DF, E', e3)) h (stk @ [v1]) loc (length (compE2 e1) + pc) xcp h' (length (compE2 e1) + pc'') (stk'' @ [v1]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v1∙compareAndSwap(DF, e2', e3))")
      case True
      with exec' τ have [simp]: "h = h'" and e: "sim_move e2' E' P t e2 h (stk, loc, pc, xcp) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val v1∙compareAndSwap(DF, e2', e3)) (Val v1∙compareAndSwap(DF, E', e3)) P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) (stk'' @ [v1], loc'', length (compE2 e1) + pc'', xcp'')"
        by(fastforce dest: CAS_τExecrI2 CAS_τExectI2 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'" 
        and call: "call1 e2' = None  no_call2 e2 pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp" by auto
      from e have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) (stk' @ [v1], loc', length (compE2 e1) + pc', xcp')" by(rule CAS_τExecrI2)
      moreover from e' have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk' @ [v1], loc', length (compE2 e1) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v1], loc'', length (compE2 e1) + pc'', xcp'')"
        by(rule exec_move_CASI2)
      moreover from e' have "pc' < length (compE2 e2)" by(auto elim: exec_meth.cases)
      with τ' e' have "¬ τmove2 (compP2 P) h (stk' @ [v1]) (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (Val v1∙compareAndSwap(DF, e2', e3)) = call1 e2'" by auto
      moreover have "no_call2 e2 pc  no_call2 (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + pc)"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) 
    qed
    moreover from bisim'
    have "P,e1∙compareAndSwap(DF, e2, e3),h'  (Val v1∙compareAndSwap(DF, E', e3), xs')  ((stk'' @ [v1]),  loc'', length (compE2 e1) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CAS2)
    ultimately show ?thesis
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans)+
      done
  next
    case (CAS1Red3 E' v')
    note [simp] = e2' = Val v' e' = Val v1∙compareAndSwap(DF, Val v', E')
      and red = True,P,t ⊢1 e3,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v1∙compareAndSwap(DF, Val v', e3)) = τmove1 P h e3"
      by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v'], xs, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v'] @ [v1], xs, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule CAS_τExecrI2)
    moreover from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e3,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e3 e3 E' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (e1∙compareAndSwap(DF, e2, e3)) (Val v1∙compareAndSwap(DF, Val v', e3)) (Val v1Val v' := E') h ([] @ [v', v1]) xs (length (compE2 e1) + length (compE2 e2) + 0) None h' (length (compE2 e1) + length (compE2 e2) + pc'') (stk'' @ [v', v1]) loc'' xcp''"
    proof(cases "τmove1 P h (Val v1∙compareAndSwap(DF, Val v', e3))")
      case True
      with exec' τ have [simp]: "h = h'"
        and e: "sim_move e3 E' P t e3 h ([], xs, 0, None) (stk'', loc'', pc'', xcp'')" by auto
      from e have "sim_move (Val v1∙compareAndSwap(DF, Val v', e3)) (Val v1∙compareAndSwap(DF, Val v', E')) P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v', v1], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk'' @ [v', v1], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
        by(fastforce dest: CAS_τExectI3 CAS_τExecrI3 simp del: compE2.simps compEs2.simps)
      with True show ?thesis by auto
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e3 h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e3 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e3 pc' xcp'" 
        and call: "call1 e3 = None  no_call2 e3 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from e have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v', v1], xs, length (compE2 e1) + length (compE2 e2) + 0, None) (stk' @ [v', v1], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp')" by(rule CAS_τExecrI3)
      moreover from e' have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk' @ [v', v1], loc', length (compE2 e1) + length (compE2 e2) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v', v1], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
        by(rule exec_move_CASI3)
      moreover from e' τ' have "¬ τmove2 (compP2 P) h (stk' @ [v', v1]) (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + pc') xcp'"
        by(auto simp add: τinstr_stk_drop_exec_move τmove2_iff)
      moreover from red have "call1 (Val v1∙compareAndSwap(DF, Val v', e3)) = call1 e3" by auto
      moreover have "no_call2 e3 0  no_call2 (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast 
    qed
    moreover from bisim'
    have "P,e1∙compareAndSwap(DF, e2, e3),h'  (Val v1∙compareAndSwap(DF, Val v', E'), xs')  ((stk'' @ [v', v1]),  loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CAS3)
    moreover from bisim2 have "pc  length (compE2 e2)  no_call2 (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + pc)"
      by(auto simp add: no_call2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_trans|fastforce elim!: τExec_mover_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  next
    case (CAS1Null v v')
    note [simp] = v1 = Null e' = THROW NullPointer e2' = Val v xs' = xs ta = ε h' = h e3 = Val v'
    have τ: "¬ τmove1 P h (CompareAndSwap null D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [Null], loc, length (compE2 e1) + pc, xcp) ([v] @ [Null], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule CAS_τExecrI2)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [Null], loc, length (compE2 e1) + pc, xcp) ([] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + 0, None)" by simp
    also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by(rule CAS_τExecrI3)
    also (rtranclp_trans)
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) ε
                                 h ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Null] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (THROW NullPointer, loc)  ([v', v, Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1CASFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1CASSucceed a v v')
    hence [simp]: "v1 = Addr a" "e' = true" "e2' = Val v"
      "ta = ReadMem a (CField D F) v, WriteMem a (CField D F) v'" "xs' = xs" "e3 = Val v'"
      and read: "heap_read h a (CField D F) v"
      and "write": "heap_write h a (CField D F) v' h'" by auto
    have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([v] @ [Addr a], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule CAS_τExecrI2)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None)" by simp
    also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by(rule CAS_τExecrI3)
    also (rtranclp_trans) from read "write"
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
                                  ReadMem a (CField D F) v, WriteMem a (CField D F) v' 
                                 h' ([Bool True], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (true, loc)  ([Bool True], loc, length (compE2 (e1∙compareAndSwap(DF, e2, e3))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (Red1CASFail a v'' v v')
    hence [simp]: "v1 = Addr a" "e' = false" "e2' = Val v" "h' = h"
      "ta = ReadMem a (CField D F) v''" "xs' = xs" "e3 = Val v'"
      and read: "heap_read h a (CField D F) v''" "v  v''" by auto
    have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v) (Val v'))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([v] @ [Addr a], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule CAS_τExecrI2)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [Addr a], loc, length (compE2 e1) + pc, xcp) ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None)" by simp
    also from bisim3[of loc] have "τExec_mover_a P t e3 h ([], loc, 0, None) ([v'], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + 0, None) ([v'] @ [v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by(rule CAS_τExecrI3)
    also (rtranclp_trans) from read 
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v', v, Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)
                                  ReadMem a (CField D F) v'' 
                                 h' ([Bool False], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v', v, Addr a] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (false, loc)  ([Bool False], loc, length (compE2 (e1∙compareAndSwap(DF, e2, e3))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps) blast
  next
    case (CAS1Throw2 ad)
    note [simp] = e2' = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    have τ: "τmove1 P h (Val v1∙compareAndSwap(DF, Throw ad, e3))" by(rule τmove1CASThrow2)
    from bisim2 have "xcp = ad  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = ad"
      with bisim2
      have "P, e1∙compareAndSwap(DF, e2, e3), h  (Throw ad, xs)  (stk @ [v1], loc, length (compE2 e1) + pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc' where "τExec_mover_a P t e2 h (stk, loc, pc, None) ([Addr ad], loc, pc', ad)"
        and bisim': "P, e2, h  (Throw ad, xs)  ([Addr ad], loc, pc', ad)"
        and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v1], loc, length (compE2 e1) + pc, None) ([Addr ad] @ [v1], loc, length (compE2 e1) + pc', ad)"
        by-(rule CAS_τExecrI2)
      moreover from bisim'
      have "P, e1∙compareAndSwap(DF, e2, e3), h  (Throw ad, xs)  ([Addr ad] @ [v1], loc, length (compE2 e1) +  pc', ad)"
        by(rule bisim1_bisims1.bisim1CASThrow2)
      ultimately show ?thesis using τ by auto
    qed
  next
    case (CAS1Throw3 v' ad)
    note [simp] = e2' = Val v' e3 = Throw ad ta = ε e' = Throw ad h' = h xs' = xs
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v'], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, Throw ad)) h (stk @ [v1], loc, length (compE2 e1) + pc, xcp) ([v'] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None)"
      by-(rule CAS_τExecrI2)
    also have "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, Throw ad)) h ([v'] @ [v1], loc, length (compE2 e1) + length (compE2 e2), None) ([Addr ad, v', v1], loc, Suc (length (compE2 e1) + length (compE2 e2)), ad)"
      by(rule τExecr2step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff τmove1.simps τmoves1.simps)
    also (rtranclp_trans)
    have "P,e1∙compareAndSwap(DF, e2, Throw ad),h  (Throw ad, loc)  ([Addr ad] @ [v', v1], loc, (length (compE2 e1) + length (compE2 e2) + length (compE2 (addr ad))), ad)"
      by(rule bisim1CASThrow3[OF bisim1Throw2])
    moreover have "τmove1 P h (CompareAndSwap (Val v1) D F (Val v') (Throw ad))" by(auto intro: τmove1CASThrow3)
    ultimately show ?thesis using s by auto
  qed auto
next
  case (bisim1CAS3 e3 n e3' xs stk loc pc xcp e1 e2 D F v v')
  note IH3 = bisim1CAS3.IH(2)
  note bisim3 = P,e3,h  (e3', xs)  (stk, loc, pc, xcp)
  note bsok = bsok (e1∙compareAndSwap(DF, e2, e3)) n
  from True,P,t ⊢1 Val v∙compareAndSwap(DF, Val v', e3'),(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (CAS1Red3 E')
    note [simp] = e' = Val v∙compareAndSwap(DF, Val v', E')
      and red = True,P,t ⊢1 e3',(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h (Val v∙compareAndSwap(DF, Val v', e3')) = τmove1 P h e3'" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH3[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e3,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e3 e3' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "no_call2 e3 pc  no_call2 (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) +  pc)" 
      by(auto simp add: no_call2_def)
    hence "?exec ta (e1∙compareAndSwap(DF, e2, e3)) (Val v∙compareAndSwap(DF, Val v', e3')) (Val v∙compareAndSwap(DF, Val v', E')) h (stk @ [v', v]) loc (length (compE2 e1) + length (compE2 e2) + pc) xcp h' (length (compE2 e1) + length (compE2 e2) + pc'') (stk'' @ [v', v]) loc'' xcp''"
      using exec' τ
      apply(cases "τmove1 P h (Val v∙compareAndSwap(DF, Val v', e3'))")
      apply(auto)
      apply(blast intro: CAS_τExecrI3 CAS_τExectI3 exec_move_CASI3)
      apply(blast intro: CAS_τExecrI3 CAS_τExectI3 exec_move_CASI3)
      apply(rule exI conjI CAS_τExecrI3 exec_move_CASI3|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI CAS_τExecrI3 exec_move_CASI3|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)
      apply(rule exI conjI CAS_τExecrI3 exec_move_CASI3 rtranclp.rtrancl_refl|assumption)+
      apply(fastforce simp add: τinstr_stk_drop_exec_move τmove2_iff split: if_split_asm)+
      done
    moreover from bisim'
    have "P,e1∙compareAndSwap(DF, e2, e3),h'  (Val v∙compareAndSwap(DF, Val v', E'), xs')  (stk''@[v',v], loc'', length (compE2 e1) + length (compE2 e2) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CAS3)
    ultimately show ?thesis using τ by auto blast+
  next
    case (CAS1Null v'')
    note [simp] = v = Null e' = THROW NullPointer xs' = xs ta = ε h' = h e3' = Val v''
    have τ: "¬ τmove1 P h (CompareAndSwap null D F (Val v') (Val v''))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e3 h (stk, loc, pc, xcp) ([v''], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v', Null], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp) ([v''] @ [v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by-(rule CAS_τExecrI3)
    moreover
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v'', v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) ε
                                 h ([v'', v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by-(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v'', v', Null] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (THROW NullPointer, loc)  ([v'', v', Null], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1_bisims1.bisim1CASFail)
    ultimately show ?thesis using s τ by auto blast
  next
    case (Red1CASSucceed a v'')
    hence [simp]: "v = Addr a" "e' = true" "e3' = Val v''"
      "ta = ReadMem a (CField D F) v', WriteMem a (CField D F) v''" "xs' = xs" 
      and read: "heap_read h a (CField D F) v'"
      and "write": "heap_write h a (CField D F) v'' h'" by auto
    have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v') (Val v''))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e3 h (stk, loc, pc, xcp) ([v''], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp) ([v''] @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by-(rule CAS_τExecrI3)
    moreover from read "write"
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v'', v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) 
                                 ReadMem a (CField D F) v', WriteMem a (CField D F) v''
                                 h' ([Bool True], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
     unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v'', v', Addr a] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover 
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (true, loc)  ([Bool True], loc, length (compE2 (e1∙compareAndSwap(DF, e2, e3))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps ac_simps) blast
  next
    case (Red1CASFail a v'' v''')
    hence [simp]: "v = Addr a" "e' = false" "e3' = Val v'''" "h' = h"
      "ta = ReadMem a (CField D F) v''" "xs' = xs"
      and read: "heap_read h a (CField D F) v''" "v'  v''" by auto
    have τ: "¬ τmove1 P h (CompareAndSwap (addr a) D F (Val v') (Val v'''))" by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim3 have s: "xcp = None" "xs = loc"
      and exec1: "τExec_mover_a P t e3 h (stk, loc, pc, xcp) ([v'''], loc, length (compE2 e3), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp) ([v'''] @ [v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None)"
      by-(rule CAS_τExecrI3)
    moreover from read
    have "exec_move_a P t (e1∙compareAndSwap(DF, e2, e3)) h ([v''', v', Addr a], loc, length (compE2 e1) + length (compE2 e2) + length (compE2 e3), None) 
                                 ReadMem a (CField D F) v''
                                 h' ([Bool False], loc, Suc (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)), None)"
     unfolding exec_move_def by-(rule exec_instr, auto simp add: compP2_def is_Ref_def)
    moreover have "τmove2 (compP2 P) h [v''', v', Addr a] (e1∙compareAndSwap(DF, e2, e3)) (length (compE2 e1) + length (compE2 e2) + length (compE2 e3)) None  False"
      by(simp add: τmove2_iff)
    moreover 
    have "P, e1∙compareAndSwap(DF, e2, e3), h'  (false, loc)  ([Bool False], loc, length (compE2 (e1∙compareAndSwap(DF, e2, e3))), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto simp add: ta_upd_simps ac_simps) blast
  next
    case (CAS1Throw3 A)
    note [simp] = e3' = Throw A ta = ε e' = Throw A h' = h xs' = xs
    have τ: "τmove1 P h (CompareAndSwap (Val v) D F (Val v') (Throw A))" by(rule τmove1CASThrow3)
    from bisim3 have "xcp = A  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = A"
      with bisim3
      have "P, e1∙compareAndSwap(DF, e2, e3), h  (Throw A, xs)  (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, xcp)"
        by(auto intro: bisim1_bisims1.intros)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim3 obtain pc' where "τExec_mover_a P t e3 h (stk, loc, pc, None) ([Addr A], loc, pc', A)"
        and bisim': "P, e3, h  (Throw A, xs)  ([Addr A], loc, pc', A)"
        and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1∙compareAndSwap(DF, e2, e3)) h (stk @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc, None) ([Addr A] @ [v', v], loc, length (compE2 e1) + length (compE2 e2) + pc', A)"
        by-(rule CAS_τExecrI3)
      moreover from bisim'
      have "P, e1∙compareAndSwap(DF, e2, e3), h  (Throw A, xs)  ([Addr A] @ [v', v], loc, length (compE2 e1) +  length (compE2 e2) + pc', A)"
        by(rule bisim1_bisims1.bisim1CASThrow3)
      ultimately show ?thesis using τ by auto
    qed
  qed auto
next
  case bisim1CASThrow1 thus ?case by auto
next
  case bisim1CASThrow2 thus ?case by auto
next
  case bisim1CASThrow3 thus ?case by auto
next
  case bisim1CASFail thus ?case by auto
next
  case (bisim1CallParams ps n ps' xs stk loc pc xcp obj M' v)
  note IHparam = bisim1CallParams.IH(2)
  note bisim1 = xs. P,obj,h  (obj, xs)  ([], xs, 0, None)
  note bisim2 = P,ps,h  (ps', xs) [↔] (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 Val vM'(ps'),(h, xs) -ta e',(h', xs')
  note bsok = bsok (objM'(ps)) n
  from bisim2 ps  [] have ps': "ps'  []" by(auto dest: bisims1_lengthD)
  from red show ?case
  proof cases
    case (Call1Params es')
    note [simp] = e' = Val vM'(es')
      and red = True,P,t ⊢1 ps', (h, xs) [-ta→] es', (h', xs')
    from red have τ: "τmove1 P h (Val vM'(ps')) = τmoves1 P h ps'" by(auto simp add: τmove1.simps τmoves1.simps)
    from IHparam[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,ps,h'  (es', xs') [↔] (stk'', loc'', pc'', xcp'')"
      and exec': "?execs ta ps ps' es' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (objM'(ps)) (Val vM'(ps')) (Val vM'(es')) h (stk @ [v]) loc (length (compE2 obj) + pc) xcp  h' (length (compE2 obj) + pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmove1 P h (Val vM'(ps'))")
      case True
      with exec' τ show ?thesis by (auto intro: Call_τExecrI2 Call_τExectI2)
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_movesr_a P t ps h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and e': "exec_moves_a P t ps h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmoves2 (compP2 P) h stk' ps pc' xcp'" 
        and call: "(calls1 ps' = None  no_calls2 ps pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp)" by auto
      from e have "τExec_mover_a P t (objM'(ps)) h (stk @ [v], loc, length (compE2 obj) + pc, xcp) (stk' @ [v], loc', length (compE2 obj) + pc', xcp')" by(rule Call_τExecrI2)
      moreover from e' have "exec_move_a P t (objM'(ps)) h (stk' @ [v], loc', length (compE2 obj) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 obj) + pc'', xcp'')"
        by(rule exec_move_CallI2)
      moreover from τ' e' have "τmove2 (compP2 P) h (stk' @ [v]) (objM'(ps)) (length (compE2 obj) + pc') xcp'  False"
        by(auto simp add: τmove2_iff τmoves2_iff τinstr_stk_drop_exec_moves split: if_split_asm)
      moreover from red have "call1 (Val vM'(ps')) = calls1 ps'" by(auto simp add: is_vals_conv)
      moreover from red have "no_calls2 ps pc  no_call2 (objM'(ps)) (length (compE2 obj) + pc)  pc = length (compEs2 ps)"
        by(auto simp add: no_call2_def no_calls2_def)
      ultimately show ?thesis using False call e
        by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast+
    qed
    moreover from bisim'
    have "P,objM'(ps),h'  (Val vM'(es'), xs')  ((stk'' @ [v]), loc'', length (compE2 obj) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1CallParams)
    ultimately show ?thesis using τ
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split) blast+
  next
    case (Red1CallNull vs)
    note [simp] = h' = h xs' = xs ta = ε v = Null ps' = map Val vs e' = THROW NullPointer
    from bisim2 have length: "length ps = length vs" by(auto dest: bisims1_lengthD)
    have "xs = loc  xcp = None  τExec_movesr_a P t ps h (stk, loc, pc, xcp) (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
      with bisim2 have "pc = length (compEs2 ps)"
        by(auto dest: bisims1_pc_length_compEs2)
      with bisim2 show ?thesis by(auto dest: bisims1_Val_length_compEs2D)
    qed
    hence s: "xs = loc" "xcp = None"
      and "τExec_movesr_a P t ps h (stk, loc, pc, xcp) (rev vs, loc, length (compEs2 ps), None)" by auto
    hence "τExec_mover_a P t (objM'(ps)) h (stk @ [Null], loc, length (compE2 obj) + pc, xcp) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), None)"
      by -(rule Call_τExecrI2)
    also {
      from length have "exec_move_a P t (objM'(ps)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), None) ε h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), addr_of_sys_xcpt NullPointer)"
        unfolding exec_move_def by(cases ps)(auto intro: exec_instr)
      moreover have "τmove2 P h (rev vs @ [Null]) (objM'(ps)) (length (compE2 obj) + length (compEs2 ps)) None"
        using length by(simp add: τmove2_iff)
      ultimately have "τExec_movet_a P t (objM'(ps)) h (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), None) (rev vs @ [Null], loc, length (compE2 obj) + length (compEs2 ps), addr_of_sys_xcpt NullPointer)"
        by(auto intro: τexec_moveI) }
    also have "τmove1 P h (nullM'(map Val vs))"
      by(auto simp add: τmove1.simps τmoves1.simps map_eq_append_conv)
    moreover
    from length have "P,objM'(ps),h  (THROW NullPointer, loc)  ((rev vs @ [Null]), loc, length (compE2 obj) + length (compEs2 ps), addr_of_sys_xcpt NullPointer)"
      by-(rule bisim1CallThrow, simp)
    ultimately show ?thesis using s by auto
  next
    case (Call1ThrowParams vs a es')
    note [simp] =  ta = ε e' = Throw a ps' = map Val vs @ Throw a # es' h' = h xs' = xs
    have τ: "τmove1 P h (Val vM'(map Val vs @ Throw a # es'))" by(rule τmove1CallThrowParams)
    from bisim2 have [simp]: "xs = loc" and "xcp = a  xcp = None" by(auto dest: bisims1_ThrowD)
    from xcp = a  xcp = None show ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim2
      have "P,objM'(ps),h  (Throw a, loc)  (stk @ [v], loc, length (compE2 obj) + pc, a)"
        by -(rule bisim1CallThrowParams, auto)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc'
        where exec: "τExec_movesr_a P t ps h (stk, loc, pc, None) (Addr a # rev vs, loc, pc', a)"
        and bisim': "P, ps, h  (map Val vs @ Throw a # es', loc) [↔] (Addr a # rev vs, loc, pc', a)"
        by(auto dest: bisims1_Throw_τExec_movesr)
      from bisim'
      have "P,objM'(ps),h  (Throw a, loc)  ((Addr a # rev vs) @ [v], loc, length (compE2 obj) + pc', a)"
        by(rule bisim1CallThrowParams)
      with Call_τExecrI2[OF exec, of obj M' v] τ
      show ?thesis by auto
    qed
  next
    case (Red1CallExternal a Ta Ts Tr D vs va H')
    hence [simp]: "v = Addr a" "ps' = map Val vs" "e' = extRet2J (addr aM'(map Val vs)) va" "H' = h'" "xs' = xs"
      and Ta: "typeof_addr h a = Ta"
      and iec: "P  class_type_of Ta sees M': TsTr = Native in D"
      and redex: "P,t  aM'(vs),h -ta→ext va,h'" by auto
    from bisim2 have [simp]: "xs = loc" by(auto dest: bisims_Val_loc_eq_xcp_None)
    moreover from bisim2 have "length ps = length ps'"
      by(rule bisims1_lengthD)
    hence τ: "τmove1 P h (addr aM'(map Val vs) :: 'addr expr1) = τmove2 (compP2 P) h (rev vs @ [Addr a]) (objM'(ps)) (length (compE2 obj) + length (compEs2 ps)) None"
      using Ta iec by(auto simp add: τmove1.simps τmoves1.simps map_eq_append_conv τmove2_iff compP2_def)
    obtain s: "xcp = None" "xs = loc"
      and "τExec_movesr_a P t ps h (stk, loc, pc, xcp) (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 intro: that)
    next
      case False
      with bisim2 have "pc = length (compEs2 ps)" by(auto dest: bisims1_pc_length_compEs2)
      with bisim2 show ?thesis by -(rule that, auto dest!: bisims1_pc_length_compEs2D)
    qed
    from Call_τExecrI2[OF this(3), of obj M' v]
    have "τExec_mover_a P t (objM'(ps)) h (stk @ [Addr a], loc, length (compE2 obj) + pc, xcp) (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None)" by simp
    moreover from bisim2 have "pc  length (compEs2 ps)" by(rule bisims1_pc_length_compEs2)
    hence "no_call2 (objM'(ps)) (length (compE2 obj) + pc)  pc = length (compEs2 ps)"
      using bisim2 by(auto simp add: no_call2_def neq_Nil_conv dest: bisims_Val_pc_not_Invoke)
    moreover { 
      assume "pc = length (compEs2 ps)"
      with τExec_movesr_a P t ps h (stk, loc, pc, xcp) (rev vs, loc, length (compEs2 ps), None)
      have "stk = rev vs" "xcp = None" by auto }
    moreover
    let ?ret = "extRet2JVM (length ps) h' (rev vs @ [Addr a]) loc undefined undefined (length (compE2 obj) + length (compEs2 ps)) [] va"
    let ?stk' = "fst (hd (snd (snd ?ret)))"
    let ?xcp' = "fst ?ret"
    let ?pc' = "snd (snd (snd (snd (hd (snd (snd ?ret))))))"
    from bisim2 have [simp]: "length ps = length vs" by(auto dest: bisims1_lengthD)
    from redex have redex': "(ta, va, h')  red_external_aggr (compP2 P) t a M' vs h"
      by -(rule red_external_imp_red_external_aggr, simp add: compP2_def)
    with Ta iec
    have "exec_move_a P t (objM'(ps)) h (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None) (extTA2JVM (compP2 P) ta) h' (?stk', loc, ?pc', ?xcp')"
      unfolding exec_move_def
      by -(rule exec_instr,cases va,(force simp add: compP2_def is_Ref_def simp del: split_paired_Ex intro: external_WT'.intros)+)
    moreover have "P,objM'(ps),h'  (extRet2J1 (addr aM'(map Val vs)) va, loc)  (?stk', loc, ?pc', ?xcp')"
    proof(cases va)
      case (RetVal v)
      have "P,objM'(ps),h'  (Val v, loc)  ([v], loc, length (compE2 (objM'(ps))), None)"
        by(rule bisim1Val2) simp
      thus ?thesis unfolding RetVal by simp
    next
      case (RetExc ad) thus ?thesis by(auto intro: bisim1CallThrow)
    next
      case RetStaySame
      from bisims1_map_Val_append[OF bisims1Nil, of ps vs P h' loc]
      have "P,ps,h'  (map Val vs, loc) [↔] (rev vs, loc, length (compEs2 ps), None)" by simp
      hence "P,objM'(ps),h'  (addr aM'(map Val vs), loc)  (rev vs @ [Addr a], loc, length (compE2 obj) + length (compEs2 ps), None)"
        by(rule bisim1_bisims1.bisim1CallParams)
      thus ?thesis using RetStaySame by simp
    qed
    moreover from redex Ta iec
    have "τmove1 P h (addr aM'(map Val vs) :: 'addr expr1)  ta = ε  h' = h"
      by(fastforce simp add: τmove1.simps τmoves1.simps map_eq_append_conv τexternal'_def τexternal_def dest: τexternal'_red_external_TA_empty τexternal'_red_external_heap_unchanged sees_method_fun)
    ultimately show ?thesis using τ
      apply(cases "τmove1 P h (addr aM'(map Val vs) :: 'addr expr1)")
      apply(auto simp del: split_paired_Ex simp add: compP2_def)
      apply(blast intro: rtranclp.rtrancl_into_rtrancl rtranclp_into_tranclp1 τexec_moveI)+
      done
  qed(insert ps', auto)
next
  case bisim1CallThrowObj thus ?case by fastforce
next
  case bisim1CallThrowParams thus ?case by auto
next
  case bisim1CallThrow thus ?case by fastforce
next
  case (bisim1BlockSome1 e n V Ty v xs e')
  from True,P,t ⊢1 {V:Ty=v; e},(h, xs) -ta e',(h', xs') show ?case
  proof(cases)
    case Block1Some
    note [simp] = ta = ε e' = {V:Ty=None; e} h' = h xs' = xs[V := v]
      and len = V < length xs
    from len have exec: "τExec_movet_a P t {V:Ty=v; e} h ([], xs, 0, None) ([], xs[V := v], Suc (Suc 0), None)"
      by-(rule τExect2step, auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    moreover have "P,{V:Ty=v; e},h  ({V:Ty=None; e}, xs[V := v])  ([], xs[V := v], Suc (Suc 0), None)"
      by(rule bisim1BlockSome4)(rule bisim1_refl)
    moreover have "τmove1 P h {V:Ty=v; e}" by(auto intro: τmove1BlockSome)
    ultimately show ?thesis by auto
  qed
next
  case (bisim1BlockSome2 e n V Ty v xs)
  from True,P,t ⊢1 {V:Ty=v; e},(h, xs) -ta e',(h', xs') show ?case
  proof(cases)
    case Block1Some
    note [simp] = ta = ε e' = {V:Ty=None; e} h' = h xs' = xs[V := v]
      and len = V < length xs
    from len have exec: "τExec_movet_a P t {V:Ty=v; e} h ([v], xs, Suc 0, None) ([], xs[V := v], Suc (Suc 0), None)"
      by-(rule τExect1step, auto intro: exec_instr τmove2BlockSome2 simp: exec_move_def)
    moreover have "P,{V:Ty=v; e},h  ({V:Ty=None; e}, xs[V := v])  ([], xs[V := v], Suc (Suc 0), None)"
      by(rule bisim1BlockSome4)(rule bisim1_refl)
    moreover have "τmove1 P h {V:Ty=v; e}" by(auto intro: τmove1BlockSome)
    ultimately show ?thesis by auto
  qed
next
  case (bisim1BlockSome4 E n e xs stk loc pc xcp V Ty v)
  note IH = bisim1BlockSome4.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note bsok = bsok {V:Ty=v; E} n
  hence [simp]: "n = V" by simp
  from True,P,t ⊢1 {V:Ty=None; e},(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Block1Red E')
    note [simp] = e' = {V:Ty=None; E'}
      and red = True,P,t ⊢1 e,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h {V:Ty=None; e} = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,E,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "no_call2 E pc  no_call2 ({V:Ty=v; E}) (Suc (Suc pc))" by(auto simp add: no_call2_def)
    hence "?exec ta {V:Ty=v; E} {V:Ty=None; e} {V:Ty=None; E'} h stk loc (Suc (Suc pc)) xcp h' (Suc (Suc pc'')) stk'' loc'' xcp''"
      using exec' τ
      by(cases "τmove1 P h {V:Ty=None; e}")(auto, (blast intro: exec_move_BlockSomeI Block_τExecrI_Some Block_τExectI_Some)+)
    with bisim' τ show ?thesis by auto(blast intro: bisim1_bisims1.bisim1BlockSome4)+
  next
    case (Red1Block u)
    note [simp] = e = Val u ta = ε e' = Val u h' = h xs' = xs
    have "τmove1 P h {V:Ty=None; Val u}" by(rule τmove1BlockRed)
    moreover from bisim have [simp]: "xcp = None" "loc = xs"
      and exec: "τExec_mover_a P t E h (stk, loc, pc, xcp) ([u], loc, length (compE2 E), None)" by(auto dest: bisim1Val2D1)
    moreover
    have "P,{V:Ty=v; E},h  (Val u, xs)  ([u], xs, length (compE2 {V:Ty=v; E}), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis by(fastforce elim!: Block_τExecrI_Some)
  next
    case (Block1Throw a)
    note [simp] = e = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h {V:Ty=None; e}" by(auto intro: τmove1BlockThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P, {V:Ty=v; E}, h  (Throw a, xs)  (stk, loc, Suc (Suc pc), xcp)"
        by(auto intro: bisim1BlockThrowSome)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t {V:Ty=v; E} h (stk, loc, Suc (Suc pc), None) ([Addr a], loc, Suc (Suc pc'), a)"
        by(auto intro: Block_τExecrI_Some)
      moreover from bisim' have "P, {V:Ty=v; E}, h  (Throw a, xs)  ([Addr a], loc, Suc (Suc pc'), a)"
        by(auto intro: bisim1_bisims1.bisim1BlockThrowSome)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1BlockThrowSome thus ?case by auto
next
  case (bisim1BlockNone E n e xs stk loc pc xcp V Ty)
  note IH = bisim1BlockNone.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note bsok = bsok {V:Ty=None; E} n
  hence [simp]: "n = V" by simp
  from True,P,t ⊢1 {V:Ty=None; e},(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Block1Red E')
    note [simp] = e' = {V:Ty=None; E'}
      and red = True,P,t ⊢1 e,(h, xs) -ta E',(h', xs')
    from red have τ: "τmove1 P h {V:Ty=None; e} = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 ({V:Ty=None; e}) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,{V:Ty=None; E},h'  ({V:Ty=None; E'}, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1BlockNone)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 {V:Ty=None; E} pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp add: exec_move_BlockNone simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Block_τExecrI_None Block_τExectI_None)+
  next
    case (Red1Block u)
    note [simp] = e = Val u ta = ε e' = Val u h' = h xs' = xs
    have "τmove1 P h {V:Ty=None; Val u}" by(rule τmove1BlockRed)
    moreover from bisim have [simp]: "xcp = None" "loc = xs"
      and exec: "τExec_mover_a P t E h (stk, loc, pc, xcp) ([u], loc, length (compE2 E), None)" by(auto dest: bisim1Val2D1)
    moreover
    have "P,{V:Ty=None; E},h  (Val u, xs)  ([u], xs, length (compE2 {V:Ty=None; E}), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis by(fastforce intro: Block_τExecrI_None)
  next
    case (Block1Throw a)
    note [simp] = e = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h {V:Ty=None; e}" by(auto intro: τmove1BlockThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim have "P, {V:Ty=None; E}, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1BlockThrowNone)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t {V:Ty=None; E} h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by(auto intro: Block_τExecrI_None)
      moreover from bisim' have "P, {V:Ty=None; E}, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(auto intro: bisim1_bisims1.bisim1BlockThrowNone)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1BlockThrowNone thus ?case by auto
next
  case (bisim1Sync1 e1 n e1' xs stk loc pc xcp e2 V)
  note IH = bisim1Sync1.IH(2)
  note bisim1 = P,e1,h  (e1', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note red = True,P,t ⊢1 sync⇘V(e1') e2,(h, xs) -ta e',(h', xs')
  note bsok = bsok (sync⇘V(e1) e2) n
  hence [simp]: "n = V" by simp
  from red show ?case
  proof cases
    case (Synchronized1Red1 E1')
    note [simp] = e' = sync⇘V(E1') e2
      and red = True,P,t ⊢1 e1', (h, xs) -ta E1', (h', xs')
    from red have τ: "τmove1 P h (sync⇘V(e1') e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (sync⇘V(e1') e2) = call1 e1'" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h'  (E1', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta e1 e1' E1' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,sync⇘V(e1) e2,h'  (sync⇘V(E1') e2, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Sync1)
    moreover { 
      assume "no_call2 e1 pc"
      hence "no_call2 (sync⇘V(e1) e2) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Sync_τExecrI Sync_τExectI exec_move_SyncI1)+
  next
    case Synchronized1Null
    note [simp] = e1' = null e' = THROW NullPointer ta = ε h' = h xs' = xs[V := Null] 
      and V = V < length xs
    from bisim1 have [simp]: "xcp = None" "xs = loc"
      and exec: "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    from Sync_τExecrI[OF exec]
    have "τExec_mover_a P t (sync⇘V(e1) e2) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 e1), None)" by simp
    also from V
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Null], loc, length (compE2 e1), None) ([Null], loc[V := Null], Suc (Suc (length (compE2 e1))), None)"
      by -(rule τExecr2step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
    also (rtranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Null], loc[V := Null], Suc (Suc (length (compE2 e1))), None) ε
                        h ([Null], loc[V := Null], Suc (Suc (length (compE2 e1))), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr) auto
    moreover have "¬ τmove2 (compP2 P) h [Null] (sync⇘V(e1) e2) (Suc (Suc (length (compE2 e1)))) None"
      by(simp add: τmove2_iff)
    moreover
    have "P,sync⇘V(e1) e2,h  (THROW NullPointer, loc[V := Null])  ([Null], (loc[V := Null]), Suc (Suc (length (compE2 e1))), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1Sync11)
    moreover have "¬ τmove1 P h (sync⇘V(null) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by auto blast
  next
    case (Lock1Synchronized a)
    note [simp] = e1' = addr a ta = Locka, SyncLock a e' = insync⇘V(a) e2 h' = h xs' = xs[V := Addr a] 
      and V = V < length xs
    from bisim1 have [simp]: "xcp = None" "xs = loc"
      and exec: "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    from Sync_τExecrI[OF exec]
    have "τExec_mover_a P t (sync⇘V(e1) e2) h (stk, loc, pc, xcp) ([Addr a], loc, length (compE2 e1), None)" by simp
    also from V
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Addr a], loc, length (compE2 e1), None) ([Addr a], loc[V := Addr a], Suc (Suc (length (compE2 e1))), None)"
      by -(rule τExecr2step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
    also (rtranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a], loc[V := Addr a], Suc (Suc (length (compE2 e1))), None)
                        (Locka, SyncLock a)
                        h ([], loc[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)"
      unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a] (sync⇘V(e1) e2) (Suc (Suc (length (compE2 e1)))) None"
      by(simp add: τmove2_iff)
    moreover
    from bisim1Sync4[OF bisim1_refl, of P h V e1 e2 a "loc[V := Addr a]"]
    have "P,sync⇘V(e1) e2,h  (insync⇘V(a) e2, loc[V := Addr a])  ([], loc[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)" by simp
    moreover have "¬ τmove1 P h (sync⇘V(addr a) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: eval_nat_numeral ta_upd_simps) blast
  next
    case (Synchronized1Throw1 a)
    note [simp] = e1' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (sync⇘V(Throw a) e2)" by(rule τmove1SyncThrow)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1
      have "P, sync⇘V(e1) e2, h  (Throw a, xs)  (stk, loc, pc, a)"
        by(auto intro: bisim1SyncThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (sync⇘V(e1) e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Sync_τExecrI)
      moreover from bisim'
      have "P, sync⇘V(e1) e2, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by -(rule bisim1_bisims1.bisim1SyncThrow, auto)
      ultimately show ?thesis using τ by fastforce
    qed
  qed
next
  case (bisim1Sync2 e1 n e2 V v xs)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 sync⇘V(Val v) e2,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Lock1Synchronized a)
    note [simp] = v = Addr a ta = Locka, SyncLock a e' = insync⇘V(a) e2
      h' = h xs' = xs[V := Addr a] 
      and V = V < length xs
    from V
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Addr a, Addr a], xs, Suc (length (compE2 e1)), None) ([Addr a], xs[V := Addr a], Suc (Suc (length (compE2 e1))), None)"
      by -(rule τExecr1step,auto intro: exec_instr simp add: τmove2_iff exec_move_def)
    moreover
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a], xs[V := Addr a], Suc (Suc (length (compE2 e1))), None)
                        (Locka, SyncLock a)
                        h ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)"
      unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a] (sync⇘V(e1) e2) (Suc (Suc (length (compE2 e1)))) None"
      by(simp add: τmove2_iff)
    moreover
    from bisim1Sync4[OF bisim1_refl, of P h V e1 e2 a "xs[V := Addr a]"]
    have "P,sync⇘V(e1) e2,h  (insync⇘V(a) e2, xs[V := Addr a])  ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)" by simp
    moreover have "¬ τmove1 P h (sync⇘V(addr a) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: eval_nat_numeral ta_upd_simps) blast
  next
    case Synchronized1Null
    note [simp] = v = Null e' = THROW NullPointer ta = ε h' = h xs' = xs[V := Null]
      and V = V < length xs
    from V
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Null, Null], xs, Suc (length (compE2 e1)), None) ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), None)"
      by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    also have "exec_move_a P t (sync⇘V(e1) e2) h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), None) ε
                        h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr) auto
    moreover have "¬ τmove2 (compP2 P) h [Null] (sync⇘V(e1) e2) (Suc (Suc (length (compE2 e1)))) None"
      by(simp add: τmove2_iff)
    moreover 
    have "P,sync⇘V(e1) e2,h  (THROW NullPointer, xs[V := Null])  ([Null], (xs[V := Null]), Suc (Suc (length (compE2 e1))), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1Sync11)
    moreover have "¬ τmove1 P h (sync⇘V(null) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: eval_nat_numeral) blast
  qed auto
next
  case (bisim1Sync3 e1 n e2 V v xs)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 sync⇘V(Val v) e2,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Lock1Synchronized a)
    note [simp] = v = Addr a ta = Locka, SyncLock a e' = insync⇘V(a) e2 h' = h xs' = xs[V := Addr a] 
      and V = V < length xs
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a], xs[V := Addr a], Suc (Suc (length (compE2 e1))), None)
                        (Locka, SyncLock a)
                        h ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)"
      unfolding exec_move_def by -(rule exec_instr, auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a] (sync⇘V(e1) e2) (Suc (Suc (length (compE2 e1)))) None"
      by(simp add: τmove2_iff)
    moreover
    from bisim1Sync4[OF bisim1_refl, of P h V e1 e2 a "xs[V := Addr a]"]
    have "P,sync⇘V(e1) e2,h  (insync⇘V(a) e2, xs[V := Addr a])  ([], xs[V := Addr a], Suc (Suc (Suc (length (compE2 e1)))), None)" by simp
    moreover have "¬ τmove1 P h (sync⇘V(addr a) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: eval_nat_numeral ta_upd_simps) blast
  next
    case Synchronized1Null
    note [simp] = v = Null e' = THROW NullPointer ta = ε h' = h xs' = xs[V := Null] 
      and V = V < length xs
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), None) ε
                        h ([Null], xs[V := Null], Suc (Suc (length (compE2 e1))), addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr) auto
    moreover have "¬ τmove2 (compP2 P) h [Null] (sync⇘V(e1) e2) (Suc (Suc (length (compE2 e1)))) None"
      by(simp add: τmove2_iff)
    moreover
    have "P,sync⇘V(e1) e2,h  (THROW NullPointer, xs[V := Null])  ([Null], (xs[V := Null]), Suc (Suc (length (compE2 e1))), addr_of_sys_xcpt NullPointer)"
      by(rule bisim1Sync11)
    moreover have "¬ τmove1 P h (sync⇘V(null) e2)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: eval_nat_numeral) blast
  qed auto
next
  case (bisim1Sync4 e2 n e2' xs stk loc pc xcp e1 V a)
  note IH = bisim1Sync4.IH(2)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bsok = bsok (sync⇘V(e1) e2) n
  note red = True,P,t ⊢1 insync⇘V(a) e2',(h, xs) -ta e',(h', xs')
  from red show ?case
  proof cases
    case (Synchronized1Red2 E')
    note [simp] = e' = insync⇘V(a) E'
      and red = True,P,t ⊢1 e2', (h, xs) -ta E', (h', xs')
    from red have τ: "τmove1 P h (insync⇘V(a) e2') = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "no_call2 e2 pc  no_call2 (sync⇘V(e1) e2) (Suc (Suc (Suc (length (compE2 e1) + pc))))"
      by(auto simp add: no_call2_def)
    hence "?exec ta (sync⇘V(e1) e2) (insync⇘V(a) e2') (insync⇘V(a) E') h stk loc (Suc (Suc (Suc (length (compE2 e1) + pc)))) xcp h' (Suc (Suc (Suc (length (compE2 e1) + pc'')))) stk'' loc'' xcp''"
      using exec' τ
      by(cases "τmove1 P h (insync⇘V(a) e2')")(auto,(blast intro: exec_move_SyncI2 Insync_τExecrI Insync_τExectI)+)
    moreover from bisim'
    have "P,sync⇘V(e1) e2,h'  (insync⇘V(a) E', xs')  (stk'', loc'', (Suc (Suc (Suc (length (compE2 e1) + pc'')))), xcp'')"
      by(rule bisim1_bisims1.bisim1Sync4)
    ultimately show ?thesis using τ by auto blast+
  next
    case (Unlock1Synchronized a' v)
    note [simp] = e2' = Val v e' = Val v ta = Unlocka', SyncUnlock a' h' = h xs' = xs
      and V = V < length xs and xsV = xs ! V = Addr a'
    from bisim2 have [simp]: "xcp = None" "xs = loc"
      and exec: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    let ?pc1 = "(Suc (Suc (Suc (length (compE2 e1) + length (compE2 e2)))))"
    note Insync_τExecrI[OF exec, of V e1]
    also from V xsV have "τExec_mover_a P t (sync⇘V(e1) e2) h ([v], loc, ?pc1, None) ([Addr a', v], loc, Suc ?pc1, None)"
      by -(rule τExecr1step,auto simp add: exec_move_def intro: exec_instr τmove2_τmoves2.intros)
    also (rtranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', v], loc, Suc ?pc1, None) (Unlocka', SyncUnlock a') h ([v], loc, Suc (Suc ?pc1), None)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V(e1) e2) (Suc ?pc1) None" by(simp add: τmove2_iff)
    moreover
    from bisim1Sync6[of P h V e1 e2 v xs]
    have "P,sync⇘V(e1) e2,h  (Val v, xs)  ([v], xs, Suc (Suc ?pc1), None)"
      by(auto simp add: eval_nat_numeral)
    moreover have "¬ τmove1 P h (insync⇘V(a) e2')" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: ta_upd_simps) blast
  next
    case (Unlock1SynchronizedNull v)
    note [simp] = e2' = Val v e' = THROW NullPointer ta = ε h' = h xs' = xs
      and V = V < length xs and xsV = xs ! V = Null
    from bisim2 have [simp]: "xcp = None" "xs = loc"
      and exec: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    let ?pc1 = "(Suc (Suc (Suc (length (compE2 e1) + length (compE2 e2)))))"
    note Insync_τExecrI[OF exec, of V e1]
    also from V xsV have "τExec_mover_a P t (sync⇘V(e1) e2) h ([v], loc, ?pc1, None) ([Null, v], loc, Suc ?pc1, None)"
      by -(rule τExecr1step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
    also (rtranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Null, v], loc, Suc ?pc1, None) ε h ([Null, v], loc, Suc ?pc1, addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Null, v] (sync⇘V(e1) e2) (Suc ?pc1) None" by(simp add: τmove2_iff)
    moreover 
    from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt NullPointer" xs]
    have "P,sync⇘V(e1) e2,h  (THROW NullPointer,xs)  ([Null, v],xs,Suc ?pc1,addr_of_sys_xcpt NullPointer)"
      by(auto simp add: eval_nat_numeral)
    moreover have "¬ τmove1 P h (insync⇘V(a) e2')" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by auto blast
  next
    case (Unlock1SynchronizedFail a' v)
    note [simp] = e2' = Val v e' = THROW IllegalMonitorState ta = UnlockFaila' xs' = xs h' = h
      and V = V < length xs and xsV = xs ! V = Addr a'
    from bisim2 have [simp]: "xcp = None" "xs = loc"
      and exec: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    let ?pc1 = "(Suc (Suc (Suc (length (compE2 e1) + length (compE2 e2)))))"
    note Insync_τExecrI[OF exec, of V e1]
    also from V xsV have "τExec_mover_a P t (sync⇘V(e1) e2) h ([v], loc, ?pc1, None) ([Addr a', v], loc, Suc ?pc1, None)"
      by -(rule τExecr1step,auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
    also (rtranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', v], loc, Suc ?pc1, None) UnlockFaila' h ([Addr a', v], loc, Suc ?pc1, addr_of_sys_xcpt IllegalMonitorState)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V(e1) e2) (Suc ?pc1) None" by(simp add: τmove2_iff)
    moreover
    from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt IllegalMonitorState" xs "Addr a'" v]
    have "P,sync⇘V(e1) e2,h  (THROW IllegalMonitorState,xs)  ([Addr a', v],xs,Suc ?pc1,addr_of_sys_xcpt IllegalMonitorState)"
      by(auto simp add: eval_nat_numeral)
    moreover have "¬ τmove1 P h (insync⇘V(a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: ta_upd_simps) blast
  next
    case (Synchronized1Throw2 a' ad)
    note [simp] = e2' = Throw ad ta = Unlocka', SyncUnlock a' e' = Throw ad
      h' = h xs' = xs and xsV = xs ! V = Addr a' and V = V < length xs
    let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
    let ?stk = "Addr ad # drop (size stk - 0) stk"
    from bisim2 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
    from bisim2
    have "τExec_movet_a P t (sync⇘V(e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, ?pc, None)"    
      by(auto intro: bisim1_insync_Throw_exec)
    also from xsV V 
    have "τExec_movet_a P t (sync⇘V(e1) e2) h ([Addr ad], loc, ?pc, None) ([Addr a', Addr ad], loc, Suc ?pc, None)"
      by -(rule τExect1step,auto intro: exec_instr τmove2Sync7 simp add: exec_move_def)
    also (tranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', Addr ad], loc, Suc ?pc, None) (Unlocka', SyncUnlock a') h ([Addr ad], loc, Suc (Suc ?pc), None)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V(e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
    moreover
    hence "P, sync⇘V(e1) e2, h  (Throw ad, loc)  ([Addr ad], loc, 8 + length (compE2 e1) + length (compE2 e2), None)"
      by(auto intro: bisim1Sync9)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: add.assoc ta_upd_simps)(blast intro: tranclp_into_rtranclp)
  next
    case (Synchronized1Throw2Fail a' ad)
    note [simp] = e2' = Throw ad ta = UnlockFaila' e' = THROW IllegalMonitorState h' = h xs' = xs
      and xsV = xs ! V = Addr a' and V = V < length xs
    let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
    let ?stk = "Addr ad # drop (size stk - 0) stk"
    from bisim2 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
    from bisim2
    have "τExec_movet_a P t (sync⇘V(e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, ?pc, None)"
      by(auto intro: bisim1_insync_Throw_exec)
    also from xsV V
    have "τExec_movet_a P t (sync⇘V(e1) e2) h ([Addr ad], loc, ?pc, None) ([Addr a', Addr ad], loc, Suc ?pc, None)"
      by -(rule τExect1step,auto intro: exec_instr τmove2Sync7 simp add: exec_move_def)
    also (tranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', Addr ad], loc, Suc ?pc, None) UnlockFaila' h ([Addr a', Addr ad], loc, Suc ?pc, addr_of_sys_xcpt IllegalMonitorState)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V(e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
    moreover
    hence "P, sync⇘V(e1) e2, h  (THROW IllegalMonitorState, loc)  ([Addr a', Addr ad], loc, 7 + length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt IllegalMonitorState)"
      by(auto intro: bisim1Sync14)
    moreover have "¬ τmove1 P h (insync⇘V(a) e2')"  by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: add.assoc ta_upd_simps)(blast intro: tranclp_into_rtranclp)
  next
    case (Synchronized1Throw2Null ad)
    note [simp] = e2' = Throw ad ta = ε e' = THROW NullPointer h' = h xs' = xs
      and xsV = xs ! V = Null and V = V < length xs
    let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
    let ?stk = "Addr ad # drop (size stk - 0) stk"
    from bisim2 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
    from bisim2
    have "τExec_movet_a P t (sync⇘V(e1) e2) h (stk, loc, Suc (Suc (Suc (length (compE2 e1) + pc))), xcp) ([Addr ad], loc, ?pc, None)"
      by(auto intro: bisim1_insync_Throw_exec)
    also from xsV V 
    have "τExec_movet_a P t (sync⇘V(e1) e2) h ([Addr ad], loc, ?pc, None) ([Null, Addr ad], loc, Suc ?pc, None)"
      by -(rule τExect1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    also (tranclp_trans)
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Null, Addr ad], loc, Suc ?pc, None) ε h ([Null, Addr ad], loc, Suc ?pc, addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Null, Addr ad] (sync⇘V(e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
    moreover
    hence "P, sync⇘V(e1) e2, h  (THROW NullPointer, loc)  ([Null, Addr ad], loc, 7 + length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt NullPointer)"
      by(auto intro: bisim1Sync14)
    moreover have "¬ τmove1 P h (insync⇘V(a) e2')"  by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: add.assoc)(blast intro: tranclp_into_rtranclp)
  qed
next
  case (bisim1Sync5 e1 n e2 V a v xs)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 insync⇘V(a) Val v,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Unlock1Synchronized a')
    note [simp] = e' = Val v ta = Unlocka', SyncUnlock a' h' = h xs' = xs
      and V = V < length xs and xsV = xs ! V = Addr a'
    let ?pc1 = "4 + length (compE2 e1) + length (compE2 e2)"
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', v], xs, ?pc1, None) Unlocka', SyncUnlock a' h ([v], xs, Suc ?pc1, None)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V(e1) e2) ?pc1 None" by(simp add: τmove2_iff)
    moreover 
    from bisim1Sync6[of P h V e1 e2 v xs]
    have "P,sync⇘V(e1) e2,h  (Val v, xs)  ([v], xs, Suc ?pc1, None)"
      by(auto simp add: eval_nat_numeral)
    moreover have "¬ τmove1 P h (insync⇘V(a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis using xsV by(auto simp add: eval_nat_numeral ta_upd_simps) blast
  next
    case Unlock1SynchronizedNull
    note [simp] = e' = THROW NullPointer ta = ε h' = h xs' = xs
      and V = V < length xs and xsV = xs ! V = Null
    let ?pc1 = "4 + length (compE2 e1) + length (compE2 e2)"
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Null, v], xs, ?pc1, None) ε h ([Null, v], xs, ?pc1, addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Null, v] (sync⇘V(e1) e2) ?pc1 None" by(simp add: τmove2_iff)
    moreover 
    from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt NullPointer" xs Null v]
    have "P,sync⇘V(e1) e2,h  (THROW NullPointer,xs)  ([Null, v],xs,?pc1,addr_of_sys_xcpt NullPointer)"
      by(auto simp add: eval_nat_numeral)
    moreover have "¬ τmove1 P h (insync⇘V(a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis using xsV by(auto simp add: eval_nat_numeral) blast
  next
    case (Unlock1SynchronizedFail a')
    note [simp] = e' = THROW IllegalMonitorState ta = UnlockFaila' xs' = xs h' = h
      and V = V < length xs and xsV = xs ! V = Addr a'
    let ?pc1 = "4 + length (compE2 e1) + length (compE2 e2)"
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', v], xs, ?pc1, None) UnlockFaila' h ([Addr a', v], xs, ?pc1, addr_of_sys_xcpt IllegalMonitorState)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', v] (sync⇘V(e1) e2) ?pc1 None" by(simp add: τmove2_iff)
    moreover 
    from bisim1Sync12[of P h V e1 e2 "addr_of_sys_xcpt IllegalMonitorState" xs "Addr a'" v]
    have "P,sync⇘V(e1) e2,h  (THROW IllegalMonitorState,xs)  ([Addr a', v],xs,?pc1,addr_of_sys_xcpt IllegalMonitorState)"
      by(auto simp add: eval_nat_numeral)
    moreover have "¬ τmove1 P h (insync⇘V(a) Val v)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis using xsV by(auto simp add: eval_nat_numeral ta_upd_simps) blast
  qed auto
next
  case bisim1Sync6 thus ?case by auto
next
  case (bisim1Sync7 e1 n e2 V a ad xs)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 insync⇘V(a) Throw ad,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Synchronized1Throw2 a')
    note [simp] = ta = Unlocka', SyncUnlock a' e' = Throw ad h' = h xs' = xs
      and xsV = xs ! V = Addr a' and V = V < length xs
    let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
    from xsV V
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Addr ad], xs, ?pc, None) ([Addr a', Addr ad], xs, Suc ?pc, None)"
      by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    moreover have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', Addr ad], xs, Suc ?pc, None) Unlocka', SyncUnlock a' h ([Addr ad], xs, Suc (Suc ?pc), None)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V(e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
    moreover
    have "P, sync⇘V(e1) e2, h  (Throw ad, xs)  ([Addr ad], xs, 8 + length (compE2 e1) + length (compE2 e2), None)"
      by(auto intro: bisim1Sync9)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: add.assoc eval_nat_numeral ta_upd_simps) blast
  next
    case (Synchronized1Throw2Fail a')
    note [simp] = ta = UnlockFaila' e' = THROW IllegalMonitorState h' = h xs' = xs
      and xsV = xs ! V = Addr a' and V = V < length xs
    let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
    from xsV V
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Addr ad], xs, ?pc, None) ([Addr a', Addr ad], xs, Suc ?pc, None)"
      by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    moreover have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', Addr ad], xs, Suc ?pc, None) UnlockFaila' h ([Addr a', Addr ad], xs, Suc ?pc, addr_of_sys_xcpt IllegalMonitorState)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V(e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
    moreover
    have "P, sync⇘V(e1) e2, h  (THROW IllegalMonitorState, xs)  ([Addr a', Addr ad], xs, 7 + length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt IllegalMonitorState)"
      by(auto intro: bisim1Sync14)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: add.assoc ta_upd_simps) blast
  next
    case Synchronized1Throw2Null
    note [simp] = ta = ε e' = THROW NullPointer h' = h xs' = xs
      and xsV = xs ! V = Null and V = V < length xs
    let ?pc = "6 + length (compE2 e1) + length (compE2 e2)"
    from xsV V 
    have "τExec_mover_a P t (sync⇘V(e1) e2) h ([Addr ad], xs, ?pc, None) ([Null, Addr ad], xs, Suc ?pc, None)"
      by -(rule τExecr1step,auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    moreover have "exec_move_a P t (sync⇘V(e1) e2) h ([Null, Addr ad], xs, Suc ?pc, None) ε h ([Null, Addr ad], xs, Suc ?pc, addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Null, Addr ad] (sync⇘V(e1) e2) (Suc ?pc) None" by(simp add: τmove2_iff)
    moreover 
    have "P, sync⇘V(e1) e2, h  (THROW NullPointer, xs)  ([Null, Addr ad], xs, 7 + length (compE2 e1) + length (compE2 e2), addr_of_sys_xcpt NullPointer)"
      by(auto intro: bisim1Sync14)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis by(auto simp add: add.assoc) blast
  qed auto 
next
  case (bisim1Sync8 e1 n e2 V a ad xs)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 insync⇘V(a) Throw ad,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Synchronized1Throw2 a')
    note [simp] = ta = Unlocka', SyncUnlock a' e' = Throw ad h' = h xs' = xs
      and xsV = xs ! V = Addr a' and V = V < length xs
    let ?pc = "7 + length (compE2 e1) + length (compE2 e2)"
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', Addr ad], xs, ?pc, None) Unlocka', SyncUnlock a' h ([Addr ad], xs, Suc ?pc, None)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V(e1) e2) ?pc None" by(simp add: τmove2_iff)
    moreover
    have "P, sync⇘V(e1) e2, h  (Throw ad, xs)  ([Addr ad], xs, 8 + length (compE2 e1) + length (compE2 e2), None)"
      by(auto intro: bisim1Sync9)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis using xsV by(auto simp add: add.assoc eval_nat_numeral ta_upd_simps) blast
  next
    case (Synchronized1Throw2Fail a')
    note [simp] = ta = UnlockFaila' e' = THROW IllegalMonitorState h' = h xs' = xs 
      and xsV = xs ! V = Addr a' and V = V < length xs
    let ?pc = "7 + length (compE2 e1) + length (compE2 e2)"
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Addr a', Addr ad], xs, ?pc, None) UnlockFaila' h ([Addr a', Addr ad], xs, ?pc, addr_of_sys_xcpt IllegalMonitorState)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Addr a', Addr ad] (sync⇘V(e1) e2) ?pc None" by(simp add: τmove2_iff)
    moreover
    have "P, sync⇘V(e1) e2, h  (THROW IllegalMonitorState, xs)  ([Addr a', Addr ad], xs, ?pc, addr_of_sys_xcpt IllegalMonitorState)"
      by(auto intro: bisim1Sync14)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis using xsV by(auto simp add: add.assoc ta_upd_simps) blast
  next
    case Synchronized1Throw2Null
    note [simp] = ta = ε e' = THROW NullPointer h' = h xs' = xs
      and xsV = xs ! V = Null and V = V < length xs
    let ?pc = "7 + length (compE2 e1) + length (compE2 e2)"
    have "exec_move_a P t (sync⇘V(e1) e2) h ([Null, Addr ad], xs, ?pc, None) ε h ([Null, Addr ad], xs, ?pc, addr_of_sys_xcpt NullPointer)"
      unfolding exec_move_def by(rule exec_instr)(auto simp add: is_Ref_def)
    moreover have "¬ τmove2 (compP2 P) h [Null, Addr ad] (sync⇘V(e1) e2) ?pc None" by(simp add: τmove2_iff)
    moreover
    have "P, sync⇘V(e1) e2, h  (THROW NullPointer, xs)  ([Null, Addr ad], xs, ?pc, addr_of_sys_xcpt NullPointer)"
      by(auto intro: bisim1Sync14)
    moreover have "¬ τmove1 P h (insync⇘V(a) Throw ad)" by(auto simp add: τmove1.simps τmoves1.simps)
    ultimately show ?thesis using xsV by(auto simp add: add.assoc) blast
  qed auto
next
  case bisim1Sync9 thus ?case by auto
next
  case bisim1Sync10 thus ?case by auto
next
  case bisim1Sync11 thus ?case by auto
next
  case bisim1Sync12 thus ?case by auto
next
  case bisim1Sync14 thus ?case by auto
next
  case bisim1SyncThrow thus ?case by auto
next
  case bisim1InSync thus ?case by simp
next
  case (bisim1Seq1 e1 n e1' xs stk loc pc xcp e2)
  note IH = bisim1Seq1.IH(2)
  note bisim1 = P,e1,h  (e1', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note red = True,P,t ⊢1 e1';; e2,(h, xs) -ta e',(h', xs')
  note bsok = bsok (e1;; e2) n
  from red show ?case
  proof cases
    case (Seq1Red E')
    note [simp] = e' = E';;e2
      and red = True,P,t ⊢1 e1', (h, xs) -ta E', (h', xs')
    from red have τ: "τmove1 P h (e1';; e2) = τmove1 P h e1'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (e1';; e2) = call1 e1'" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,e1,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta e1 e1' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim have "P,e1;; e2,h'  (E';; e2, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Seq1)
    moreover { 
      assume "no_call2 e1 pc"
      hence "no_call2 (e1;; e2) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Seq_τExecrI1 Seq_τExectI1 exec_move_SeqI1)+
  next
    case (Red1Seq v)
    note [simp] = e1' = Val v ta = ε h' = h xs' = xs e' = e2
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e1 h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (e1;; e2) h (stk, loc, pc, xcp) ([v], loc, length (compE2 e1), None)"
      by-(rule Seq_τExecrI1)
    moreover have "exec_move_a P t (e1;; e2) h ([v], loc, length (compE2 e1), None) ε h ([], loc, Suc (length (compE2 e1)), None)"
      unfolding exec_move_def by(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [v] (e1;;e2) (length (compE2 e1)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_mover_a P t (e1;; e2) h (stk, loc, pc, xcp) ([], loc, Suc (length (compE2 e1)), None)"
      by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
    moreover from bisim1_refl
    have "P, e1;; e2, h  (e2, xs)  ([], loc, Suc (length (compE2 e1) + 0), None)"
      unfolding s by(rule bisim1Seq2)
    moreover have "τmove1 P h (Val v;; e2)" by(rule τmove1SeqRed)
    ultimately show ?thesis by(auto)
  next
    case (Seq1Throw a)
    note [simp] = e1' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (Throw a;; e2)" by(rule τmove1SeqThrow)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1 have "P, e1;; e2, h  (Throw a, xs)  (stk, loc, pc, xcp)"
        by(auto intro: bisim1SeqThrow1)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (e1;;e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Seq_τExecrI1)
      moreover from bisim'
      have "P, e1;;e2, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(rule bisim1SeqThrow1)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1SeqThrow1 thus ?case by fastforce
next
  case (bisim1Seq2 e2 n e2' xs stk loc pc xcp e1)
  note IH = bisim1Seq2.IH(2)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note red = True,P,t ⊢1 e2',(h, xs) -ta e',(h', xs')
  note bsok = bsok (e1;; e2) n
  from IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
    where bisim': "P,e2,h'  (e', xs')  (stk'', loc'', pc'', xcp'')"
    and exec': "?exec ta e2 e2' e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
  have "no_call2 e2 pc  no_call2 (e1;; e2) (Suc (length (compE2 e1) + pc))"
      by(auto simp add: no_call2_def)
  hence "?exec ta (e1;; e2) e2' e' h stk loc (Suc (length (compE2 e1) + pc)) xcp h' (Suc (length (compE2 e1) + pc'')) stk'' loc'' xcp''"
    using exec' by(cases "τmove1 P h e2'")(auto, (blast intro: Seq_τExecrI2 Seq_τExectI2 exec_move_SeqI2)+)
  moreover from bisim'
  have "P,e1;;e2,h'  (e', xs')  (stk'', loc'', Suc (length (compE2 e1) + pc''), xcp'')"
    by(rule bisim1_bisims1.bisim1Seq2)
  ultimately show ?case by(auto split: if_split_asm) blast+
next
  case (bisim1Cond1 E n e xs stk loc pc xcp e1 e2)
  note IH = bisim1Cond1.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bsok = bsok (if (E) e1 else e2) n
  from True,P,t ⊢1 if (e) e1 else e2,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Cond1Red b')
    note [simp] = e' = if (b') e1 else e2
      and red = True,P,t ⊢1 e,(h, xs) -ta b',(h', xs')
    from red have "τmove1 P h (if (e) e1 else e2) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (if (e) e1 else e2) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (b', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e b' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,if (E) e1 else e2,h'  (if (b') e1 else e2, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Cond1)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (if (E) e1 else e2) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Cond_τExecrI1 Cond_τExectI1 exec_move_CondI1)+
  next
    case Red1CondT
    note [simp] = e = true e' = e1 ta = ε h' = h xs' = xs 
    from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 E), None)"
      by-(rule Cond_τExecrI1)
    moreover have "exec_move_a P t (if (E) e1 else e2) h ([Bool True], loc, length (compE2 E), None) ε h ([], loc, Suc (length (compE2 E)), None)"
      unfolding exec_move_def by(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [Bool True] (if (E) e1 else e2) (length (compE2 E)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_movet_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([], loc, Suc (length (compE2 E)), None)"
      by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
    moreover have "τmove1 P h (if (true) e1 else e2)" by(rule τmove1CondRed)
    moreover
    from bisim1_refl
    have "P, if (E) e1 else e2, h  (e1, xs)  ([], loc, Suc (length (compE2 E) + 0), None)"
      unfolding s by(rule bisim1CondThen)
    ultimately show ?thesis by (fastforce)
  next
    case Red1CondF
    note [simp] = e = false e' = e2 ta = ε h' = h xs' = xs
    from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 E), None)"
      by-(rule Cond_τExecrI1)
    moreover have "exec_move_a P t (if (E) e1 else e2) h ([Bool False], loc, length (compE2 E), None) ε h ([], loc, Suc (Suc (length (compE2 E) + length (compE2 e1))), None)"
      unfolding exec_move_def by(rule exec_instr)(auto)
    moreover have "τmove2 (compP2 P) h [Bool False] (if (E) e1 else e2) (length (compE2 E)) None" by(rule τmove2CondRed)
    ultimately have "τExec_movet_a P t (if (E) e1 else e2) h (stk, loc, pc, xcp) ([], loc, Suc (Suc (length (compE2 E) + length (compE2 e1))), None)"
      by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
    moreover have "τmove1 P h (if (false) e1 else e2)" by(rule τmove1CondRed)
    moreover 
    from bisim1_refl
    have "P, if (E) e1 else e2, h  (e2, loc)  ([], loc, (Suc (Suc (length (compE2 E) + length (compE2 e1) + 0))), None)"
      unfolding s by(rule bisim1CondElse)
    ultimately show ?thesis using s by auto(blast intro: tranclp_into_rtranclp)
  next
    case (Cond1Throw a)
    note [simp] = e = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (if (Throw a) e1 else e2)" by(rule τmove1CondThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim
      have "P, if (E) e1 else e2, h  (Throw a, xs)  (stk, loc, pc, a)"
        by(auto intro: bisim1_bisims1.bisim1CondThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (if (E) e1 else e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Cond_τExecrI1)
      moreover from bisim'
      have "P, if (E) e1 else e2, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by-(rule bisim1CondThrow, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case (bisim1CondThen e1 n e1' xs stk loc pc xcp e e2)
  note IH = bisim1CondThen.IH(2)
  note bisim1 = P,e1,h  (e1', xs)  (stk, loc, pc, xcp)
  note bisim = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note bsok = bsok (if (e) e1 else e2) n
  from IH[OF True,P,t ⊢1 e1',(h, xs) -ta e',(h', xs')] bsok obtain pc'' stk'' loc'' xcp''
    where bisim': "P,e1,h'  (e', xs')  (stk'', loc'', pc'', xcp'')"
    and exec': "?exec ta e1 e1' e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
  have "no_call2 e1 pc  no_call2 (if (e) e1 else e2) (Suc (length (compE2 e) + pc))"
      by(auto simp add: no_call2_def)
    hence "?exec ta (if (e) e1 else e2) e1' e' h stk loc (Suc (length (compE2 e) + pc)) xcp h' (Suc (length (compE2 e) + pc'')) stk'' loc'' xcp''"
    using exec' by(cases "τmove1 P h e1'")(auto, (blast intro: Cond_τExecrI2 Cond_τExectI2 exec_move_CondI2)+)
  moreover from bisim'
  have "P,if (e) e1 else e2,h'  (e', xs')  (stk'', loc'', Suc (length (compE2 e) + pc''), xcp'')"
    by(rule bisim1_bisims1.bisim1CondThen)
  ultimately show ?case
    by(auto split: if_split_asm) blast+
next
  case (bisim1CondElse e2 n e2' xs stk loc pc xcp e e1)
  note IH = bisim1CondElse.IH(2)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note bisim = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  note bisim1 = xs. P,e1,h  (e1, xs)  ([], xs, 0, None)
  from IH[OF True,P,t ⊢1 e2',(h, xs) -ta e',(h', xs')] bsok (if (e) e1 else e2) n 
  obtain pc'' stk'' loc'' xcp''
    where bisim': "P,e2,h'  (e', xs')  (stk'', loc'', pc'', xcp'')"
    and exec': "?exec ta e2 e2' e' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
  have "no_call2 e2 pc  no_call2 (if (e) e1 else e2) (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc)))"
      by(auto simp add: no_call2_def)
  hence "?exec ta (if (e) e1 else e2) e2' e' h stk loc (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc))) xcp h' (Suc (Suc (length (compE2 e) + length (compE2 e1) + pc''))) stk'' loc'' xcp''"
    using exec' by(cases "τmove1 P h e2'")(auto, (blast intro: Cond_τExecrI3 Cond_τExectI3 exec_move_CondI3)+)
  moreover from bisim'
  have "P,if (e) e1 else e2,h'  (e', xs')  (stk'', loc'', Suc (Suc (length (compE2 e) + length (compE2 e1) + pc'')), xcp'')"
    by(rule bisim1_bisims1.bisim1CondElse)
  ultimately show ?case
    by(auto split: if_split_asm) blast+
next
  case bisim1CondThrow thus ?case by auto
next
  case (bisim1While1 c n e xs)
  note bisim1 = xs. P,c,h  (c, xs)  ([], xs, 0, None)
  note bisim2 = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 while (c) e,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case Red1While
    note [simp] = ta = ε e' = if (c) (e;; while (c) e) else unit h' = h xs' = xs 
    have "τmove1 P h (while (c) e)" by(rule τmove1WhileRed)
    moreover
    have "P,while (c) e,h  (if (c) (e;; while (c) e) else unit, xs)  ([], xs, 0, None)"
      by(rule bisim1_bisims1.bisim1While3[OF bisim1_refl])
    moreover have "sim12_size (while (c) e) > sim12_size e'" by(simp)
    ultimately show ?thesis by auto
  qed
next
  case (bisim1While3 c n c' xs stk loc pc xcp e)
  note IH = bisim1While3.IH(2)
  note bisim1 = P,c,h  (c', xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e,h (e, xs)  ([], xs, 0, None)
  note bsok = bsok (while (c) e) n
  from True,P,t ⊢1 if (c') (e;; while (c) e) else unit,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Cond1Red b')
    note [simp] = e' = if (b') (e;; while (c) e) else unit
      and red = True,P,t ⊢1 c',(h, xs) -ta b',(h', xs')
    from red have "τmove1 P h (if (c') (e;; while (c) e) else unit) = τmove1 P h c'" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from red have "call1 (if (c') (e;;while (c) e) else unit) = call1 c'" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,c,h'  (b', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta c c' b' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,while (c) e,h'  (if (b') (e;; while (c) e) else unit, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1While3)
    moreover { 
      assume "no_call2 c pc"
      hence "no_call2 (while (c) e) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: While_τExecrI1 While_τExectI1 exec_move_WhileI1)+
  next
    case Red1CondT
    note [simp] = c' = true e' = e;; while (c) e ta = ε h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t c h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 c), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (while (c) e) h (stk, loc, pc, xcp) ([Bool True], loc, length (compE2 c), None)"
      by-(rule While_τExecrI1)
    moreover have "exec_move_a P t (while (c) e) h ([Bool True], loc, length (compE2 c), None) ε h ([], loc, Suc (length (compE2 c)), None)"
      unfolding exec_move_def by(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [Bool True] (while (c) e) (length (compE2 c)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_movet_a P t (while (c) e) h (stk, loc, pc, xcp) ([], loc, Suc (length (compE2 c)), None)"
      by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
    moreover have "τmove1 P h (if (c') (e;; while (c) e) else unit)" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from bisim1_refl
    have "P, while (c) e, h  (e;; while (c) e, xs)  ([], loc, Suc (length (compE2 c) + 0), None)"
      unfolding s by(rule bisim1While4)
    ultimately show ?thesis by (fastforce)
  next
    case Red1CondF
    note [simp] = c' = false e' = unit ta = ε h' = h xs' = xs
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t c h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 c), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (while (c) e) h (stk, loc, pc, xcp) ([Bool False], loc, length (compE2 c), None)"
      by-(rule While_τExecrI1)
    moreover have "exec_move_a P t (while (c) e) h ([Bool False], loc, length (compE2 c), None) ε h ([], loc, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)"
      by(auto intro!: exec_instr simp add: exec_move_def)
    moreover have "τmove2 (compP2 P) h [Bool False] (while (c) e) (length (compE2 c)) None" by(simp add: τmove2_iff)
    ultimately have "τExec_mover_a P t (while (c) e) h (stk, loc, pc, xcp) ([], loc, Suc (Suc (Suc (length (compE2 c) + length (compE2 e)))), None)"
      by(auto intro: rtranclp.rtrancl_into_rtrancl τexec_moveI simp add: compP2_def)
    moreover have "τmove1 P h (if (false) (e;;while (c) e) else unit)" by(rule τmove1CondRed)
    moreover have "P, while (c) e, h  (unit, xs)  ([], loc, (Suc (Suc (Suc (length (compE2 c) + length (compE2 e))))), None)"
      unfolding s by(rule bisim1While7)
    ultimately show ?thesis using s by auto
  next
    case (Cond1Throw a)
    note [simp] = c' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (if (c') (e;; while (c) e) else unit)" by(auto intro: τmove1CondThrow)
    from bisim1 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1
      have "P, while (c) e, h  (Throw a, xs)  (stk, loc, pc, a)"
        by(auto intro: bisim1_bisims1.bisim1WhileThrow1)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc'
        where "τExec_mover_a P t c h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        and bisim': "P, c, h  (Throw a, xs)  ([Addr a], loc, pc', a)" and [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (while (c) e) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule While_τExecrI1)
      moreover from bisim'
      have "P, while (c) e, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by-(rule bisim1WhileThrow1, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed 
next
  case (bisim1While4 E n e xs stk loc pc xcp c)
  note IH = bisim1While4.IH(2)
  note bisim2 = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,c,h  (c, xs)  ([], xs, 0, None)
  note bsok = bsok (while (c) E) n
  from True,P,t ⊢1 e;; while (c) E,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case (Seq1Red E')
    note [simp] = e' = E';;while (c) E
      and red = True,P,t ⊢1 e, (h, xs) -ta E', (h', xs')
    from red have τ: "τmove1 P h (e;; while (c) E) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    with IH[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim: "P,E,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (while (c) E) (e;;while (c) E) (E';;while (c) E) h stk loc (Suc (length (compE2 c) + pc)) xcp h' (Suc (length (compE2 c) + pc'')) stk'' loc'' xcp''"
    proof(cases "τmove1 P h (e;; while (c) E)")
      case True
      with exec' show ?thesis using τ by(fastforce intro: While_τExecrI2 While_τExectI2)
    next
      case False
      with exec' τ obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t E h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t E h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' E pc' xcp'" 
        and call: "(call1 e = None  no_call2 E pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp)" by auto
      from e have "τExec_mover_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), xcp) (stk', loc', Suc (length (compE2 c) + pc'), xcp')" by(rule While_τExecrI2)
      moreover
      from e' have "exec_move_a P t (while (c) E) h (stk', loc', Suc (length (compE2 c) + pc'), xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', Suc (length (compE2 c) + pc''), xcp'')"
        by(rule exec_move_WhileI2)
      moreover from τ' e' have "¬ τmove2 (compP2 P) h stk' (while (c) E) (Suc (length (compE2 c) + pc')) xcp'"
        by(auto simp add: τmove2_iff)
      moreover have "call1 (e;; while (c) E) = call1 e" by simp
      moreover have "no_call2 E pc  no_call2 (while (c) E) (Suc (length (compE2 c) + pc))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
    qed
    with bisim τ show ?thesis by auto (blast intro: bisim1_bisims1.bisim1While4)+
  next
    case (Red1Seq v)
    note [simp] = e = Val v ta = ε e' = while (c) E h' = h xs' = xs
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), xcp) ([v], loc, Suc (length (compE2 c) + length (compE2 E)), None)"
      by-(rule While_τExecrI2)
    moreover
    have "exec_move_a P t (while (c) E) h ([v], loc, Suc (length (compE2 c) + length (compE2 E)), None) ε h ([], loc, Suc (Suc (length (compE2 c) + length (compE2 E))), None)"
      unfolding exec_move_def by(rule exec_instr, auto)
    moreover have "τmove2 (compP2 P) h [v] (while (c) E) (Suc (length (compE2 c) + length (compE2 E))) None" by(simp add: τmove2_iff)
    ultimately have "τExec_movet_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), xcp) ([], loc, Suc (Suc (length (compE2 c) + length (compE2 E))), None)"
      by(auto intro: rtranclp_into_tranclp1 τexec_moveI simp add: compP2_def)
    moreover
    have "P, while (c) E, h  (while (c) E, xs)  ([], xs, (Suc (Suc (length (compE2 c) + length (compE2 E)))), None)"
      unfolding s by(rule bisim1While6)
    moreover have "τmove1 P h (e;; while (c) E)" by(auto intro: τmove1SeqRed)
    ultimately show ?thesis using s by(auto)(blast intro: tranclp_into_rtranclp)
  next
    case (Seq1Throw a)
    note [simp] = e = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (e;; while (c) E)" by(auto intro: τmove1SeqThrow)
    from bisim2 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim2
      have "P, while (c) E, h  (Throw a, xs)  (stk, loc, Suc (length (compE2 c) + pc), xcp)"
        by(auto intro: bisim1WhileThrow2)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc'
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (while (c) E) h (stk, loc, Suc (length (compE2 c) + pc), None) ([Addr a], loc, Suc (length (compE2 c) + pc'), a)"
        by-(rule While_τExecrI2)
      moreover from bisim'
      have "P, while (c) E, h  (Throw a, xs)  ([Addr a], loc, Suc (length (compE2 c) + pc'), a)"
        by-(rule bisim1WhileThrow2, auto)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case (bisim1While6 c n e xs)
  note bisim1 = xs. P,c,h  (c, xs)  ([], xs, 0, None)
  note bisim2 = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  from True,P,t ⊢1 while (c) e,(h, xs) -ta e',(h', xs') show ?case
  proof cases
    case Red1While
    note [simp] = ta = ε e' = if (c) (e;; while (c) e) else unit h' = h xs' = xs
    have "τmove1 P h (while (c) e)" by(rule τmove1WhileRed)
    moreover 
    have "P,while (c) e,h  (if (c) (e;; while (c) e) else unit, xs)  ([], xs, 0, None)"
      by(rule bisim1_bisims1.bisim1While3[OF bisim1_refl])
    moreover have "τExec_movet_a P t (while (c) e) h ([], xs, Suc (Suc (length (compE2 c) + length (compE2 e))), None) ([], xs, 0, None)"
      by(rule τExect1step)(auto simp add: exec_move_def τmove2_iff intro: exec_instr)
    ultimately show ?thesis by(fastforce)
  qed
next
  case bisim1While7 thus ?case by fastforce
next
  case bisim1WhileThrow1 thus ?case by auto
next
  case bisim1WhileThrow2 thus ?case by auto
next
  case (bisim1Throw1 E n e xs stk loc pc xcp)
  note IH = bisim1Throw1.IH(2)
  note bisim = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note red = True,P,t ⊢1 throw e,(h, xs) -ta e',(h', xs')
  note bsok = bsok (throw E) n
  from red show ?case
  proof cases
    case (Throw1Red E')
    note [simp] = e' = throw E'
      and red = True,P,t ⊢1 e, (h, xs) -ta E', (h', xs')
    from red have "τmove1 P h (throw e) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (throw e) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim
    have "P,throw E,h'  (throw E', xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Throw1)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (throw E) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Throw_τExecrI Throw_τExectI exec_move_ThrowI)+
  next
    case Red1ThrowNull
    note [simp] = e = null ta = ε e' = THROW NullPointer h' = h xs' = xs
    from bisim have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (throw E) h (stk, loc, pc, xcp) ([Null], loc, length (compE2 E), None)"
      by-(rule Throw_τExecrI)
    also have "τExec_movet_a P t (throw E) h ([Null], loc, length (compE2 E), None) ([Null], loc, length (compE2 E), addr_of_sys_xcpt NullPointer)"
      by(rule τExect1step)(auto intro: exec_instr τmove2_τmoves2.intros simp add: exec_move_def)
    also have "P, throw E, h  (THROW NullPointer, xs)  ([Null], loc, length (compE2 E), addr_of_sys_xcpt NullPointer)"
      unfolding s by(rule bisim1ThrowNull)
    moreover have "τmove1 P h (throw e)" by(auto intro: τmove1ThrowNull)
    ultimately show ?thesis by auto
  next
    case (Throw1Throw a)
    note [simp] = e = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h (throw (Throw a))" by(rule τmove1ThrowThrow)
    from bisim have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume "xcp = a"
      with bisim show ?thesis using τ by(fastforce intro: bisim1ThrowThrow)
    next
      assume [simp]: "xcp = None"
      from bisim obtain pc'
        where "τExec_mover_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 dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (throw E) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by -(rule Throw_τExecrI)
      moreover from bisim have "P, throw E, h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(rule bisim1ThrowThrow)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1Throw2 thus ?case by auto
next
  case bisim1ThrowNull thus ?case by auto
next
  case bisim1ThrowThrow thus ?case by auto
next
  case (bisim1Try E n e xs stk loc pc xcp e2 C' V)
  note IH = bisim1Try.IH(2)
  note bisim1 = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note red = True,P,t ⊢1 try e catch(C' V) e2,(h, xs) -ta e',(h', xs')
  note bsok = bsok (try E catch(C' V) e2) n
  from red show ?case
  proof cases
    case (Try1Red E')
    note [simp] = e' = try E' catch(C' V) e2
      and red = True,P,t ⊢1 e, (h, xs) -ta E', (h', xs')
    from red have "τmove1 P h (try e catch(C' V) e2) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover have "call1 (try e catch(C' V) e2) = call1 e" by auto
    moreover from IH[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim 
    have "P,try E catch(C' V) e2,h'  (try E' catch(C' V) e2, xs')  (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisim1Try)
    moreover { 
      assume "no_call2 E pc"
      hence "no_call2 (try E catch(C' V) e2) pc" by(auto simp add: no_call2_def) }
    ultimately show ?thesis using redo
      by(auto simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)(blast intro: Try_τExecrI1 Try_τExectI1 exec_move_TryI1)+
  next
    case (Red1Try v)
    note [simp] = e = Val v ta = ε e' = Val v h' = h xs' = xs
    have τ: "τmove1 P h (try Val v catch(C' V) e2)" by(rule τmove1TryRed)
    from bisim1 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by-(rule Try_τExecrI1)
    also have "τExec_mover_a P t (try E catch(C' V) e2) h ([v], loc, length (compE2 E), None) ([v], loc, length (compE2 (try E catch(C' V) e2)), None)"
      by(rule τExecr1step)(auto intro: exec_instr simp add: exec_move_def τmove2_iff)
    also (rtranclp_trans)
    have "P, try E catch(C' V) e2, h  (Val v, xs)  ([v], xs, length (compE2 (try E catch(C' V) e2)), None)"
      by(rule bisim1Val2) simp
    ultimately show ?thesis using s τ by(auto)
  next
    case (Red1TryCatch a D)
    hence [simp]: "e = Throw a" "ta = ε" "e' = {V:Class C'=None; e2}" "h' = h" "xs' = xs[V := Addr a]"
      and ha: "typeof_addr h a = Class_type D" and sub: "P  D * C'"
      and V: "V < length xs" by auto
    from bisim1 have [simp]: "xs = loc" and xcp: "xcp = a  xcp = None" 
      by(auto dest: bisim1_ThrowD)
    from xcp have "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, xcp) ([Addr a], loc, Suc (length (compE2 E)), None)"
    proof
      assume [simp]: "xcp = a"
      with bisim1 have "match_ex_table (compP2 P) (cname_of h a) pc (compxE2 E 0 0) = None"
        by(auto dest: bisim1_xcp_Some_not_caught[where pc'=0] simp add: compP2_def)
      moreover from bisim1 have "pc < length (compE2 E)"
        by(auto dest: bisim1_ThrowD)
      ultimately show ?thesis using ha sub unfolding xcp = a
        by-(rule τExecr1step[unfolded exec_move_def, OF exec_catch[where d=0, simplified]],
            auto simp add: τmove2_iff matches_ex_entry_def compP2_def match_ex_table_append_not_pcs cname_of_def)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' where "τExec_mover_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 dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Try_τExecrI1)
      also from bisim' have "match_ex_table (compP2 P) (cname_of h a) pc' (compxE2 E 0 0) = None"
        by(auto dest: bisim1_xcp_Some_not_caught[where pc'=0] simp add: compP2_def)
      with ha sub bisim1_ThrowD[OF bisim']
      have "τExec_mover_a P t (try E catch(C' V) e2) h ([Addr a], loc, pc', a) ([Addr a], loc, Suc (length (compE2 E)), None)"
        by-(rule τExecr1step[unfolded exec_move_def, OF exec_catch[where d=0, simplified]], auto simp add: τmove2_iff matches_ex_entry_def compP2_def match_ex_table_append_not_pcs cname_of_def)
      finally (rtranclp_trans) show ?thesis by simp
    qed
    also let ?pc' = "Suc (length (compE2 E))" from V
    have exec: "τExec_movet_a P t (try E catch(C' V) e2) h ([Addr a], loc, ?pc', None) ([], loc[V := Addr a], Suc ?pc', None)"
      by-(rule τExect1step[unfolded exec_move_def, OF exec_instr], auto simp add: nth_append intro: τmove2_τmoves2.intros)
    also (rtranclp_tranclp_tranclp)
    have bisim': "P,try E catch(C' V) e2, h  ({V:Class C'=None; e2}, xs[V := Addr a])  ([], loc[V := Addr a], Suc ?pc', None)"
      unfolding xs = loc by(rule bisim1TryCatch2[OF bisim1_refl, simplified]) 
    moreover have "τmove1 P h (try Throw a catch(C' V) e2)" by(rule τmove1TryThrow)
    ultimately show ?thesis by(auto)(blast intro: tranclp_into_rtranclp)
  next
    case (Red1TryFail a D)
    hence [simp]: "e = Throw a" "ta = ε" "e' = Throw a" "h' = h" "xs' = xs"
      and ha: "typeof_addr h a = Class_type D" and sub: "¬ P  D * C'" by auto
    have τ: "τmove1 P h (try Throw a catch(C' V) e2)" by(rule τmove1TryThrow)
    from bisim1 have [simp]:  "xs = loc" and "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    from bisim1 have pc: "pc  length (compE2 E)" by(rule bisim1_pc_length_compE2)
    from xcp = a  xcp = None show ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim1 ha sub
      have "P,try E catch(C' V) e2,h  (Throw a, xs)  (stk, loc, pc, a)"
        by(auto intro: bisim1TryFail)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim1 obtain pc' 
        where "τExec_mover_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)"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (try E catch(C' V) e2) h (stk, loc, pc, None) ([Addr a], loc, pc', a)"
        by-(rule Try_τExecrI1)
      moreover from bisim' ha sub
      have "P,try E catch(C' V) e2,h  (Throw a, xs)  ([Addr a], loc, pc', a)"
        by(auto intro: bisim1TryFail)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case (bisim1TryCatch1 e n a xs stk loc pc D C' e2 V)
  note bisim1 = P,e,h  (Throw a, xs)  (stk, loc, pc, a)
  note bisim2 = xs. P,e2,h  (e2, xs)  ([], xs, 0, None)
  note IH2 = bisim1TryCatch1.IH(6)
  note ha = typeof_addr h a = Class_type D
  note sub = P  D * C'
  note red = True,P,t ⊢1 {V:Class C'=None; e2},(h, xs[V := Addr a]) -ta e',(h', xs')
  note bsok = bsok (try e catch(C' V) e2) n
  from bisim1 have [simp]: "xs = loc" by(auto dest: bisim1_ThrowD)
  from red show ?case
  proof cases
    case (Block1Red E')
    note [simp] = e' = {V:Class C'=None; E'}
      and red = True,P,t ⊢1 e2, (h, xs[V := Addr a]) -ta E', (h', xs')
    from red have τ: "τmove1 P h {V:Class C'=None; e2} = τmove1 P h e2" by(auto simp add: τmove1.simps τmoves1.simps)
    have exec: "τExec_mover_a P t (try e catch(C' V) e2) h ([Addr a], xs, Suc (length (compE2 e) + 0), None) ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None)"
      by -(rule τExecr1step, auto simp add: exec_move_def τmove2_iff intro: exec_instr)
    moreover from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2 E' h [] (xs[V := Addr a]) 0 None h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (try e catch(C' V) e2) {V:Class C'=None; e2} {V:Class C'=None; E'} h [] (xs[V := Addr a]) (Suc (Suc (length (compE2 e))))  None h' (Suc (Suc (length (compE2 e) + pc''))) stk'' loc'' xcp''"
    proof(cases "τmove1 P h {V:Class C'=None; e2}")
      case True with τ exec' show ?thesis
        by(fastforce dest: Try_τExecrI2 Try_τExectI2 simp del: compE2.simps compEs2.simps)
    next
      case False
      with τ exec' obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e2 h ([], xs[V := Addr a], 0, None) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'" 
        and call: "call1 e2 = None  no_call2 e2 0  pc' = 0  stk' = []  loc' = xs[V := Addr a]  xcp' = None" by auto
      from e have "τExec_mover_a P t (try e catch(C' V) e2) h ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None) (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp')"
        by(rule Try_τExecrI2)
      moreover from e'
      have "exec_move_a P t (try e catch(C' V) e2) h (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
        by(rule exec_move_TryI2)
      moreover from τ' have "τmove2 (compP2 P) h stk' (try e catch(C' V) e2) (Suc (Suc (length (compE2 e) + pc'))) xcp'  False"
        by(simp add: τmove2_iff)
      moreover have "call1 {V:Class C'=None; e2} = call1 e2" by simp
      moreover have "no_call2 e2 0  no_call2 (try e catch(C' V) e2) (Suc (Suc (length (compE2 e))))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim' 
    have "P, try e catch(C' V) e2, h'  ({V:Class C'=None; E'}, xs')  (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
      by(rule bisim1TryCatch2)
    moreover have "no_call2 (try e catch(C' V) e2) (Suc (length (compE2 e)))" by(simp add: no_call2_def)
    ultimately show ?thesis using τ 
      by auto(blast intro: rtranclp_trans rtranclp_tranclp_tranclp)+
  next
    case (Red1Block u)
    note [simp] = e2 = Val u ta = ε e' = Val u h' = h xs' = xs[V := Addr a]
    have "τExec_mover_a P t (try e catch(C' V) Val u) h ([Addr a], xs, Suc (length (compE2 e) + 0), None) ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None)"
      by -(rule τExecr1step, auto simp add: exec_move_def τmove2_iff intro: exec_instr)
    also have "τExec_mover_a P t (try e catch(C' V) Val u) h ([], xs[V := Addr a], Suc (Suc (length (compE2 e) + 0)), None) ([u], xs[V := Addr a], Suc (Suc (length (compE2 e) + 1)), None)"
      by -(rule Try_τExecrI2[OF τExecr1step[unfolded exec_move_def, OF exec_instr]], auto simp add: τmove2_iff)
    also (rtranclp_trans)
    have "P, try e catch(C' V) Val u, h  (Val u, xs[V := Addr a])  ([u], xs[V := Addr a], length (compE2 (try e catch(C' V) Val u)), None)"
      by(rule bisim1Val2) simp
    moreover have "τmove1 P h {V:Class C'=None; Val u}" by(rule τmove1BlockRed)
    ultimately show ?thesis by(auto)
  next
    case (Block1Throw a')
    note [simp] = e2 = Throw a' h' = h ta = ε e' = Throw a' xs' = xs[V := Addr a]
    have "τmove1 P h {V:Class C'=None; Throw a'}" by(rule τmove1BlockThrow)
    moreover have "τExec_mover_a P t (try e catch(C' V) e2) h ([Addr a], loc, Suc (length (compE2 e)), None)
                                 ([Addr a'], xs', Suc (Suc (Suc (length (compE2 e)))), a')"
      by(rule τExecr3step)(auto simp add: exec_move_def exec_meth_instr τmove2_iff)
    moreover have "P, try e catch(C' V) Throw a', h  (Throw a', xs')  ([Addr a'], xs', Suc (Suc (length (compE2 e) + length (compE2 (addr a')))), a')"
      by(rule bisim1TryCatchThrow)(rule bisim1Throw2)
    ultimately show ?thesis by auto
  qed
next
  case (bisim1TryCatch2 e2 n e2' xs stk loc pc xcp e C' V)
  note bisim2 = P,e2,h  (e2', xs)  (stk, loc, pc, xcp)
  note bisim1 = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  note IH2 = bisim1TryCatch2.IH(2)
  note red = True,P,t ⊢1 {V:Class C'=None; e2'},(h, xs) -ta e',(h', xs')
  note bsok = bsok (try e catch(C' V) e2) n
  from red show ?case
  proof cases
    case (Block1Red E')
    note [simp] = e' = {V:Class C'=None; E'}
      and red = True,P,t ⊢1 e2', (h, xs) -ta E', (h', xs')
    from red have τ: "τmove1 P h {V:Class C'=None; e2'} = τmove1 P h e2'" by(auto simp add: τmove1.simps τmoves1.simps)
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,e2,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and exec': "?exec ta e2 e2' E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have "?exec ta (try e catch(C' V) e2) {V:Class C'=None; e2'} {V:Class C'=None; E'} h stk loc (Suc (Suc (length (compE2 e) + pc))) xcp h' (Suc (Suc (length (compE2 e) + pc''))) stk'' loc'' xcp''"
    proof (cases "τmove1 P h {V:Class C'=None; e2'}")
      case True with τ exec' show ?thesis by(auto intro: Try_τExecrI2 Try_τExectI2)
    next
      case False
      with τ exec' obtain pc' stk' loc' xcp'
        where e: "τExec_mover_a P t e2 h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and e': "exec_move_a P t e2 h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmove2 (compP2 P) h stk' e2 pc' xcp'" 
        and call: "call1 e2' = None  no_call2 e2 pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp" by auto
      from e have "τExec_mover_a P t (try e catch(C' V) e2) h (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp) (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp')"
        by(rule Try_τExecrI2)
      moreover from e'
      have "exec_move_a P t (try e catch(C' V) e2) h (stk', loc', Suc (Suc (length (compE2 e) + pc')), xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', Suc (Suc (length (compE2 e) +  pc'')), xcp'')"
        by(rule exec_move_TryI2)
      moreover from τ' have "τmove2 (compP2 P) h stk' (try e catch(C' V) e2) (Suc (Suc (length (compE2 e) + pc'))) xcp'  False"
        by(simp add: τmove2_iff)
      moreover have "call1 {V:Class C'=None; e2'} = call1 e2'" by simp
      moreover have "no_call2 e2 pc  no_call2 (try e catch(C' V) e2) (Suc (Suc (length (compE2 e) + pc)))"
        by(auto simp add: no_call2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps)
    qed
    moreover from bisim'
    have "P, try e catch(C' V) e2, h'  ({V:Class C'=None; E'}, xs')  (stk'', loc'', Suc (Suc (length (compE2 e) + pc'')), xcp'')"
      by(rule bisim1_bisims1.bisim1TryCatch2)
    ultimately show ?thesis using τ by auto blast+
  next
    case (Red1Block u)
    note [simp] = e2' = Val u ta = ε e' = Val u h' = h xs' = xs
    from bisim2 have s: "xcp = None" "xs = loc"
      and "τExec_mover_a P t e2 h (stk, loc, pc, xcp) ([u], loc, length (compE2 e2), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_mover_a P t (try e catch(C' V) e2) h (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp) ([u], loc, Suc (Suc (length (compE2 e) + length (compE2 e2))), None)"
      by -(rule Try_τExecrI2)
    moreover
    have "P, try e catch(C' V) e2, h  (Val u, xs)  ([u], xs, length (compE2 (try e catch(C' V) e2)), None)"
      by(rule bisim1Val2) simp
    moreover have "τmove1 P h {V:Class C'=None; Val u}" by(rule τmove1BlockRed)
    ultimately show ?thesis using s by auto
  next
    case (Block1Throw a)
    note [simp] = e2' = Throw a ta = ε e' = Throw a h' = h xs' = xs
    have τ: "τmove1 P h {V:Class C'=None; e2'}"  by(auto simp add: τmove1.simps τmoves1.simps)
    from bisim2 have "xcp = a  xcp = None" by(auto dest: bisim1_ThrowD)
    thus ?thesis
    proof
      assume [simp]: "xcp = a"
      with bisim2 
      have "P, try e catch(C' V) e2, h  (Throw a, xs)  (stk, loc, Suc (Suc (length (compE2 e) + pc)), xcp)"
        by(auto intro: bisim1TryCatchThrow)
      thus ?thesis using τ by(fastforce)
    next
      assume [simp]: "xcp = None"
      with bisim2 obtain pc' 
        where "τExec_mover_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 [simp]: "xs = loc"
        by(auto dest: bisim1_Throw_τExec_mover)
      hence "τExec_mover_a P t (try e catch(C' V) e2) h (stk, loc, Suc (Suc (length (compE2 e) + pc)), None) ([Addr a], loc, Suc (Suc (length (compE2 e) + pc')), a)"
        by-(rule Try_τExecrI2)
      moreover from bisim'
      have "P, try e catch(C' V) e2, h  (Throw a, xs)  ([Addr a], loc, Suc (Suc (length (compE2 e) + pc')), a)"
        by(rule bisim1TryCatchThrow)
      ultimately show ?thesis using τ by auto
    qed
  qed
next
  case bisim1TryFail thus ?case by auto
next
  case bisim1TryCatchThrow thus ?case by auto
next
  case bisims1Nil thus ?case by(auto elim!: reds1.cases)
next
  case (bisims1List1 E n e xs stk loc pc xcp es)
  note IH1 = bisims1List1.IH(2)
  note IH2 = bisims1List1.IH(4)
  note bisim1 = P,E,h  (e, xs)  (stk, loc, pc, xcp)
  note bisim2 = xs. P,es,h  (es, xs) [↔] ([], xs, 0, None)
  note bsok = bsoks (E # es) n
  from True,P,t ⊢1 e # es,(h, xs) [-ta→] es',(h', xs') show ?case
  proof cases
    case (List1Red1 E')
    note [simp] = es' = E' # es
      and red = True,P,t ⊢1 e,(h, xs) -ta E',(h', xs')
    from red have τ: "τmoves1 P h (e # es) = τmove1 P h e" by(auto simp add: τmove1.simps τmoves1.simps)
    moreover from IH1[OF red] bsok
    obtain pc'' stk'' loc'' xcp'' where bisim: "P,E,h'  (E', xs')  (stk'', loc'', pc'', xcp'')"
      and redo: "?exec ta E e E' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    from bisim 
    have "P,E#es,h'  (E'#es, xs') [↔] (stk'', loc'', pc'', xcp'')"
      by(rule bisim1_bisims1.bisims1List1)
    moreover { 
      assume "no_call2 E pc"
      hence "no_calls2 (E # es) pc  pc = length (compE2 E)" by(auto simp add: no_call2_def no_calls2_def) }
    moreover from red have "calls1 (e # es) = call1 e" by auto
    ultimately show ?thesis using redo
      apply(auto simp add: exec_move_def exec_moves_def simp del: call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_mover_τExec_movesr τExec_movet_τExec_movest intro!: bisim1_bisims1.bisims1List1 elim: τmoves2.cases)+
      done
  next
    case (List1Red2 ES' v)
    note [simp] = es' = Val v # ES' e = Val v
      and red = True,P,t ⊢1 es,(h, xs) [-ta→] ES',(h', xs')
    from bisim1 have s: "xs = loc" "xcp = None"
      and exec1: "τExec_mover_a P t E h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by(auto dest: bisim1Val2D1)
    hence "τExec_movesr_a P t (E # es) h (stk, loc, pc, xcp) ([v], loc, length (compE2 E), None)"
      by -(rule τExec_mover_τExec_movesr)
    moreover from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,es,h'  (ES', xs') [↔] (stk'', loc'', pc'', xcp'')"
      and exec': "?execs ta es es ES' h [] xs 0 None h' pc'' stk'' loc'' xcp''" by auto
    have τ: "τmoves1 P h (Val v # es) = τmoves1 P h es" by(auto simp add: τmove1.simps τmoves1.simps)
    have "?execs ta (E # es) (Val v # es) (Val v # ES') h [v] xs (length (compE2 E)) None h' (length (compE2 E) +  pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmoves1 P h (Val v # es)")
      case True with τ exec' show ?thesis
        using append_τExec_movesr[of "[v]" "[E]" _ P t es h "[]" xs 0 None stk'' loc'' pc'' xcp'']
          append_τExec_movest[of "[v]" "[E]" _ P t es h "[]" xs 0 None stk'' loc'' pc'' xcp''] by auto 
    next
      case False with τ exec' obtain pc' stk' loc' xcp'
        where e: "τExec_movesr_a P t es h ([], xs, 0, None) (stk', loc', pc', xcp')"
        and e': "exec_moves_a P t es h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmoves2 (compP2 P) h stk' es pc' xcp'" 
        and call: "calls1 es = None  no_calls2 es 0  pc' = 0  stk' = []  loc' = xs  xcp' = None" by auto
      from append_τExec_movesr[OF _ e, where vs="[v]" and es' = "[E]"]
      have "τExec_movesr_a P t (E # es) h ([v], xs, length (compE2 E), None) (stk' @ [v], loc', length (compE2 E) + pc', xcp')" by simp
      moreover from append_exec_moves[OF _ e', of "[v]" "[E]"]
      have "exec_moves_a P t (E # es) h (stk' @ [v], loc', length (compE2 E) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 E) + pc'', xcp'')"
        by simp
      moreover from τ' e'
      have "τmoves2 (compP2 P) h (stk' @ [v]) (E # es) (length (compE2 E) + pc') xcp'  False"
        by(auto simp add: τmoves2_iff τinstr_stk_drop_exec_moves)
      moreover have "calls1 (Val v # es) = calls1 es" by simp
      moreover have "no_calls2 es 0  no_calls2 (E # es) (length (compE2 E))"
        by(auto simp add: no_calls2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) blast
    qed
    moreover from bisim' 
    have "P,E # es,h'  (Val v # ES', xs') [↔] (stk'' @ [v], loc'', length (compE2 E) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisims1List2)
    moreover from bisim1 have "pc  length (compE2 E)  no_calls2 (E # es) pc"
      by(auto simp add: no_calls2_def dest: bisim_Val_pc_not_Invoke bisim1_pc_length_compE2)
    ultimately show ?thesis using τ exec1 s
      apply(auto simp del: split_paired_Ex call1.simps calls1.simps split: if_split_asm split del: if_split)
      apply(blast intro: τExec_movesr_trans|fastforce elim!: τExec_movesr_trans simp del: split_paired_Ex call1.simps calls1.simps)+
      done
  qed
next
  case (bisims1List2 ES n es xs stk loc pc xcp e v)
  note IH2 = bisims1List2.IH(2)
  note bisim1 = xs. P,e,h  (e, xs)  ([], xs, 0, None)
  note bisim2 = P,ES,h  (es, xs) [↔] (stk, loc, pc, xcp)
  note bsok = bsoks (e # ES) n
  from True,P,t ⊢1 Val v # es,(h, xs) [-ta→] es',(h', xs') show ?case
  proof cases
    case (List1Red2 ES')
    note [simp] = es' = Val v # ES'
      and red = True,P,t ⊢1 es,(h, xs) [-ta→] ES',(h', xs')
    from IH2[OF red] bsok obtain pc'' stk'' loc'' xcp''
      where bisim': "P,ES,h'  (ES', xs') [↔] (stk'', loc'', pc'', xcp'')"
      and exec': "?execs ta ES es ES' h stk loc pc xcp h' pc'' stk'' loc'' xcp''" by auto
    have τ: "τmoves1 P h (Val v # es) = τmoves1 P h es" by(auto simp add: τmove1.simps τmoves1.simps)
    have "?execs ta (e # ES) (Val v # es) (Val v # ES') h (stk @ [v]) loc (length (compE2 e) + pc) xcp h' (length (compE2 e) +  pc'') (stk'' @ [v]) loc'' xcp''"
    proof(cases "τmoves1 P h (Val v # es)")
      case True with τ exec' show ?thesis
        using append_τExec_movesr[of "[v]" "[e]" _ P t ES h stk]
          append_τExec_movest[of "[v]" "[e]" _ P t ES h stk] by auto
    next
      case False with τ exec' obtain pc' stk' loc' xcp'
        where e: "τExec_movesr_a P t ES h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and e': "exec_moves_a P t ES h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'', loc'', pc'', xcp'')"
        and τ': "¬ τmoves2 (compP2 P) h stk' ES pc' xcp'" 
        and call: "calls1 es = None  no_calls2 ES pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp" by auto
      from append_τExec_movesr[OF _ e, where vs="[v]" and es' = "[e]"]
      have "τExec_movesr_a P t (e # ES) h (stk @ [v], loc, length (compE2 e) + pc, xcp) (stk' @ [v], loc', length (compE2 e) + pc', xcp')" by simp
      moreover from append_exec_moves[OF _ e', of "[v]" "[e]"]
      have "exec_moves_a P t (e # ES) h (stk' @ [v], loc', length (compE2 e) + pc', xcp') (extTA2JVM (compP2 P) ta) h' (stk'' @ [v], loc'', length (compE2 e) + pc'', xcp'')" by simp
      moreover from τ' e'
      have "τmoves2 (compP2 P) h (stk' @ [v]) (e # ES) (length (compE2 e) + pc') xcp'  False"
        by(auto simp add: τmoves2_iff τinstr_stk_drop_exec_moves)
      moreover have "calls1 (Val v # es) = calls1 es" by simp
      moreover have "no_calls2 ES pc  no_calls2 (e # ES) (length (compE2 e) + pc)"
        by(auto simp add: no_calls2_def)
      ultimately show ?thesis using False call by(auto simp del: split_paired_Ex call1.simps calls1.simps) 
    qed
    moreover from bisim'
    have "P,e # ES,h'  (Val v # ES', xs') [↔] (stk'' @ [v], loc'', length (compE2 e) + pc'', xcp'')"
      by(rule bisim1_bisims1.bisims1List2)
    ultimately show ?thesis using τ by auto blast+
  qed auto
qed

end


context J1_JVM_conf_read begin

lemma exec_1_simulates_Red1_τ:
  assumes wf: "wf_J1_prog P"
  and Red1: "True,P,t ⊢1 (e, xs)/exs, h -ta (e', xs')/exs', h"
  and bisim: "bisim1_list1 t h (e, xs) exs xcp frs"
  and τ: "τMove1 P h ((e, xs), exs)"
  shows "xcp' frs'. (if sim12_size e' < sim12_size e then τExec_1_dr else τExec_1_dt) (compP2 P) t (xcp, h, frs) (xcp', h, frs')  bisim1_list1 t h (e',xs') exs' xcp' frs'"
proof -
  from wf have wt: "wf_jvm_prog⇘compTP P(compP2 P)" by(rule wt_compTP_compP2)
  from Red1 show ?thesis
  proof(cases)
    case (red1Red TA)
    note [simp] = ta = extTA2J1 P TA exs' = exs
      and red = True,P,t ⊢1 e,(h, xs) -TA e',(h, xs')
    from τ red have τ': "τmove1 P h e" by(auto elim: red1_cases)
    from bisim show ?thesis
    proof(cases)
      case (bl1_Normal stk loc C M pc FRS Ts T body D)
      hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
        and conf: "compTP P  t: (xcp, h, frs) "
        and sees: "P  C sees M: TsT = body in D"
        and bisim: "P,blocks1 0 (Class D#Ts) body,h  (e, xs)  (stk, loc, pc, xcp)"
        and bisims: "list_all2 (bisim1_fr P h) exs FRS"
        and lenxs: "max_vars e  length xs"
        by auto
      from sees wf have "bsok (blocks1 0 (Class D # Ts) body) 0"
        by(auto dest!: sees_wf_mdecl WT1_expr_locks simp add: wf_J1_mdecl_def wf_mdecl_def bsok_def)
      from exec_instr_simulates_red1[OF wf bisim red this] τ' obtain pc' stk' loc' xcp'
        where exec: "(if sim12_size e' < sim12_size e then τExec_mover_a else τExec_movet_a) P t body h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
        and b': "P,blocks1 0 (Class D#Ts) body,h  (e', xs')  (stk', loc', pc', xcp')"
        by(auto split: if_split_asm simp del: blocks1.simps)
      from exec sees have "(if sim12_size e' < sim12_size e then τExec_1r else τExec_1t) (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
        by(auto intro: τExec_mover_τExec_1r τExec_movet_τExec_1t)
      from wt this conf have execd: "(if sim12_size e' < sim12_size e then τExec_1_dr else τExec_1_dt) (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
        by(auto intro: τExec_1r_τExec_1_dr τExec_1t_τExec_1_dt)
      moreover from wt execd conf
      have "compTP P  t: (xcp', h, (stk', loc', C, M, pc') # FRS) "
        by(auto intro: τExec_1_dr_preserves_correct_state τExec_1_dt_preserves_correct_state split: if_split_asm)
      hence "bisim1_list1 t h (e', xs') exs xcp' ((stk', loc', C, M, pc') # FRS)"
        using sees b' 
      proof
        from red have "max_vars e'  max_vars e" by(rule red1_max_vars)
        with red1_preserves_len[OF red] lenxs
        show "max_vars e'  length xs'" by simp
      qed fact
      hence "bisim1_list1 t h (e',xs') exs' xcp' ((stk', loc', C, M, pc') # FRS)" by simp
      ultimately show ?thesis by blast
    qed(insert red, auto elim: red1_cases)
  next
    case (red1Call a' M' vs' U' Ts' T' body' D')
    hence [simp]: "ta = ε"
      and exs' [simp]: "exs' = (e, xs) # exs"
      and e': "e' = blocks1 0 (Class D'#Ts') body'"
      and xs': "xs' = Addr a' # vs' @ replicate (max_vars body') undefined_value"
      and ha': "typeof_addr h a' = U'"
      and call: "call1 e = (a', M', vs')" by auto
    note sees' = P  class_type_of U' sees M': Ts'T' = body' in D'
    note lenvs'Ts' = length vs' = length Ts'
    from ha' sees_method_decl_above[OF sees'] 
    have conf: "P,h  Addr a' :≤ ty_of_htype U'" by(auto simp add: conf_def)
    note wt = wt_compTP_compP2[OF wf]
    from bisim show ?thesis
    proof(cases)
      case (bl1_Normal stk loc C M pc FRS Ts T body D)
      hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
        and conf: "compTP P  t: (xcp, h, frs) "
        and sees: "P  C sees M: TsT = body in D"
        and bisim: "P,blocks1 0 (Class D#Ts) body,h  (e, xs)  (stk, loc, pc, xcp)"
        and bisims: "list_all2 (bisim1_fr P h) exs FRS" 
        and lenxs: "max_vars e  length xs" by auto
      from call bisim have [simp]: "xcp = None" by(cases xcp, auto dest: bisim1_call_xcpNone)
      from bisim have b: "P,blocks1 0 (Class D#Ts) body,h  (e, xs)  (stk, loc, pc, None)" by simp
      from bisim have lenloc: "length xs = length loc" by(rule bisim1_length_xs)
      from sees have sees'': "compP2 P  C sees M:TsT = (max_stack body, max_vars body, compE2 body @ [Return], compxE2 body 0 0) in D"
        unfolding compP2_def compMb2_def Let_def by(auto dest: sees_method_compP)
      from sees wf have "¬ contains_insync (blocks1 0 (Class D # Ts) body)"
        by(auto dest!: sees_wf_mdecl WT1_expr_locks simp add: wf_J1_mdecl_def wf_mdecl_def contains_insync_conv)
      with bisim1_call_τExec_move[OF b call, of 0 t] lenxs obtain pc' loc' stk'
        where exec: "τExec_mover_a P t body h (stk, loc, pc, None) (rev vs' @ Addr a' # stk', loc', pc', None)"
        and pc': "pc' < length (compE2 body)" and ins: "compE2 body ! pc' = Invoke M' (length vs')"
        and bisim': "P,blocks1 0 (Class D#Ts) body,h  (e, xs)  (rev vs' @ Addr a' # stk', loc', pc', None)"
        by(auto simp add: blocks1_max_vars simp del: blocks1.simps)
      let ?f = "(rev vs' @ Addr a' # stk', loc', C, M, pc')"
      from exec sees
      have exec1: "τExec_1r (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ?f  # FRS)"
        by(rule τExec_mover_τExec_1r)
      with wt have "τExec_1_dr (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ?f  # FRS)" using conf
        by(simp)(rule τExec_1r_τExec_1_dr)
      also with wt have conf': "compTP P  t: (None, h, ?f  # FRS) " using conf
        by simp (rule τExec_1_dr_preserves_correct_state)
      let ?f' = "([], Addr a' # vs' @ (replicate (max_vars body') undefined_value), D', M', 0)"
      from pc' ins sees sees' ha'
      have "(ε, None, h, ?f' # ?f # FRS)  exec_instr (instrs_of (compP2 P) C M ! pc') (compP2 P) t h (rev vs' @ Addr a' # stk') loc' C M pc' FRS"
        by(auto simp add: compP2_def compMb2_def nth_append split_beta)
      hence "exec_1 (compP2 P) t (None, h, ?f # FRS) ε (None, h, ?f' # ?f # FRS)"
        using exec sees by(simp add: exec_1_iff)
      with conf' have execd: "compP2 P,t  Normal (None, h, ?f # FRS) -ε-jvmd→ Normal (None, h, ?f' # ?f # FRS)"
        by(simp add: welltyped_commute[OF wt])
      hence check: "check (compP2 P) (None, h, ?f # FRS)" by(rule jvmd_NormalE)
      have "τmove2 (compP2 P) h (rev vs' @ Addr a' # stk') body pc' None" using pc' ins ha' sees'
        by(auto simp add: τmove2_iff compP2_def dest: sees_method_fun)
      with sees pc' ins have "τMove2 (compP2 P) (None, h, (rev vs' @ Addr a' # stk', loc', C, M, pc') # FRS)"
        unfolding τMove2_compP2[OF sees] by(auto simp add: compP2_def compMb2_def)
      with exec_1 (compP2 P) t (None, h, ?f # FRS) ε (None, h, ?f' # ?f # FRS) check
      have "τExec_1_dt (compP2 P) t (None, h, ?f # FRS) (None, h, ?f' # ?f # FRS)" by fastforce
      also from execd sees'' sees' ins ha' pc' have "compP2 P,h  vs' [:≤] Ts'" 
        by(auto simp add: check_def compP2_def split: if_split_asm elim!: jvmd_NormalE)
      hence lenvs: "length vs' = length Ts'" by(rule list_all2_lengthD)
      from wt execd conf' have "compTP P  t:(None, h, ?f' # ?f # FRS) "
        by(rule BV_correct_d_1)
      hence "bisim1_list1 t h (blocks1 0 (Class D'#Ts') body', xs') ((e, xs) # exs) None (?f' # ?f # FRS)"
      proof
        from sees' show "P  D' sees M': Ts'T' = body' in D'" by(rule sees_method_idemp)
        show "P,blocks1 0 (Class D'#Ts') body',h  (blocks1 0 (Class D'#Ts') body', xs') 
             ([], Addr a' # vs' @ replicate (max_vars body') undefined_value, 0, None)"
          unfolding xs' by(rule bisim1_refl)
        show "max_vars (blocks1 0 (Class D' # Ts') body')  length xs'"
          unfolding xs' using lenvs by(simp add: blocks1_max_vars)
        from lenxs have "(max_vars e)  length xs" by simp
        with sees bisim' call have "bisim1_fr P h (e, xs) (rev vs' @ Addr a' # stk', loc', C, M, pc')"
          by(rule bisim1_fr.intros)
        thus "list_all2 (bisim1_fr P h) ((e, xs) # exs)
                        ((rev vs' @ Addr a' # stk', loc', C, M, pc') # FRS)"
          using bisims by simp
      qed
      moreover have "ta_bisim wbisim1 ta ε" by simp
      ultimately show ?thesis
        unfolding frs = (stk, loc, C, M, pc) # FRS xcp = None e' exs'
        by auto(blast intro: tranclp_into_rtranclp)
    next
      case bl1_finalVal 
      with call show ?thesis by simp
    next
      case bl1_finalThrow
      with call show ?thesis by simp
    qed
  next
    case (red1Return E)
    note [simp] = exs = (E, xs') # exs' ta = ε e' = inline_call e E
    note wt = wt_compTP_compP2[OF wf]
    from bisim have bisim: "bisim1_list1 t h (e, xs) ((E, xs') # exs') xcp frs" by simp
    thus ?thesis
    proof cases
      case (bl1_Normal stk loc C M pc FRS Ts T body D)
      hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
        and conf: "compTP P  t: (xcp, h, frs) "
        and sees: "P  C sees M: TsT = body in D"
        and bisim: "P,blocks1 0 (Class D#Ts) body,h  (e, xs)  (stk, loc, pc, xcp)"
        and bisims: "list_all2 (bisim1_fr P h) ((E, xs') # exs') FRS" 
        and lenxs: "max_vars e  length xs" by auto
      from bisims obtain f FRS' where [simp]: "FRS = f # FRS'" by(fastforce simp add: list_all2_Cons1)
      from bisims have "bisim1_fr P h (E, xs') f" by simp
      then obtain C0 M0 Ts0 T0 body0 D0 stk0 loc0 pc0 a' M' vs'
        where [simp]: "f = (stk0, loc0, C0, M0, pc0)"
        and sees0: "P  C0 sees M0:Ts0T0=body0 in D0"
        and bisim0: "P,blocks1 0 (Class D0#Ts0) body0,h  (E, xs')  (stk0, loc0, pc0, None)"
        and lenxs0: "max_vars E  length xs'"
        and call0: "call1 E = (a', M', vs')"
        by cases auto
 
      let ?ee = "inline_call e E"
        
      from bisim0 call0 have pc0: "pc0 < length (compE2 (blocks1 0 (Class D0#Ts0) body0))"
        by(rule bisim1_call_pcD)
      hence pc0: "pc0 < length (compE2 body0)" by simp
      with sees_method_compP[OF sees0, where f="λC M Ts T. compMb2"]
        sees_method_compP[OF sees, where f="λC M Ts T. compMb2"] conf
      obtain ST LT where Φ: "compTP P C0 M0 ! pc0 = (ST, LT)"
        and conff: "conf_f (compP (λC M Ts T. compMb2) P) h (ST, LT) (compE2 body0 @ [Return]) (stk0, loc0, C0, M0, pc0)"
        and ins: "(compE2 body0 @ [Return]) ! pc0 = Invoke M (length Ts)"
        by(simp add: correct_state_def)(fastforce simp add: compP2_def compMb2_def dest: sees_method_fun)
      from bisim1_callD[OF bisim0 call0, of M "length Ts"] ins pc0
      have [simp]: "M' = M" by simp
        
      from final e show ?thesis
      proof(cases)
        fix v
        assume [simp]: "e = Val v"
        with bisim have [simp]: "xcp = None" by(auto dest: bisim_Val_loc_eq_xcp_None)
          
        from bisim1Val2D1[OF bisim[unfolded xcp = None e = Val v]]
        have "τExec_mover_a P t body h (stk, loc, pc, None) ([v], loc, length (compE2 body), None)"
          and [simp]: "xs = loc" by(auto simp del: blocks1.simps)
        with sees have "τExec_1r (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
          by-(rule τExec_mover_τExec_1r)
        with conf wt have "τExec_1_dr (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
          by(simp)(rule τExec_1r_τExec_1_dr)
        moreover with conf wt have conf': "compTP P  t:(None, h, ([v], loc, C, M, length (compE2 body)) # FRS) "
          by(simp)(rule τExec_1_dr_preserves_correct_state)
        from sees sees0
        have exec: "exec_1 (compP2 P) t (None, h, ([v], loc, C, M, length (compE2 body)) # FRS) ε (None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
          by(simp add: exec_1_iff compP2_def compMb2_def)
        moreover with conf' wt have "compP2 P,t  Normal (None, h, ([v], loc, C, M, length (compE2 body)) # FRS) -ε-jvmd→ Normal (None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
          by(simp add: welltyped_commute)
        hence "check (compP2 P) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
          by(rule jvmd_NormalE)
        moreover have "τMove2 (compP2 P) (None, h, ([v], loc, C, M, length (compE2 body)) # FRS)"
          unfolding τMove2_compP2[OF sees] by(auto)
        ultimately have "τExec_1_dt (compP2 P) t (None, h, (stk, loc, C, M, pc) # FRS) (None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
          by -(erule rtranclp_into_tranclp1,rule τexec_1_dI)
        moreover from wt conf' exec
        have "compTP P  t:(None, h, (v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS') "
          by(rule BV_correct_1)
        hence "bisim1_list1 t h (?ee, xs') exs' None ((v # drop (Suc (length Ts)) stk0, loc0, C0, M0, Suc pc0) # FRS')"
          using sees0
        proof
          from bisim1_inline_call_Val[OF bisim0 call0, of "length Ts" v] ins pc0
          show "P,blocks1 0 (Class D0#Ts0) body0,h  (?ee, xs')  (v # drop (Suc (length Ts)) stk0, loc0, Suc pc0, None)"
            by simp
          from lenxs0 max_vars_inline_call[of e "E"]
          show "max_vars (inline_call e E)  length xs'" by simp
          from bisims show "list_all2 (bisim1_fr P h) exs' FRS'" by simp
        qed
        ultimately show ?thesis
          by -(rule exI conjI|assumption|simp)+
      next
        fix ad
        assume [simp]: "e = Throw ad"
        
        have "stk' pc'. τExec_mover_a P t body h (stk, loc, pc, xcp) (stk', loc, pc', ad) 
                         P,blocks1 0 (Class D#Ts) body,h  (Throw ad, loc)  (stk', loc, pc', ad)"
        proof(cases xcp)
          case [simp]: None
          from bisim1_Throw_τExec_mover[OF bisim[unfolded None e = Throw ad]] obtain pc'
            where exec: "τExec_mover_a P t body h (stk, loc, pc, None) ([Addr ad], loc, pc', ad)"
            and bisim': "P,blocks1 0 (Class D#Ts) body,h  (Throw ad, xs)  ([Addr ad], loc, pc', ad)"
            and [simp]: "xs = loc" by(auto simp del: blocks1.simps)
          thus ?thesis by fastforce
        next
          case (Some a')
          with bisim have "a' = ad" "xs = loc" by(auto dest: bisim1_ThrowD)
          thus ?thesis using bisim Some by(auto)
        qed
        then obtain stk' pc' where exec: "τExec_mover_a P t body h (stk, loc, pc, xcp) (stk', loc, pc', ad)"
          and bisim': "P,blocks1 0 (Class D#Ts) body,h  (Throw ad, loc)  (stk', loc, pc', ad)" by blast
        with sees have "τExec_1r (compP2 P) t (xcp, h, (stk, loc, C, M, pc) # FRS) (ad, h, (stk', loc, C, M, pc') # FRS)"
          by-(rule τExec_mover_τExec_1r)
        with conf wt have "τExec_1_dr (compP2 P) t (xcp, h, (stk, loc, C, M, pc) # FRS) (ad, h, (stk', loc, C, M, pc') # FRS)"
          by(simp)(rule τExec_1r_τExec_1_dr)
        moreover with conf wt have conf': "compTP P  t: (ad, h, (stk', loc, C, M, pc') # FRS) "
          by(simp)(rule τExec_1_dr_preserves_correct_state)
        from bisim1_xcp_Some_not_caught[OF bisim', of "λC M Ts T. compMb2" 0 0] sees
        have match: "match_ex_table (compP2 P) (cname_of h ad) pc' (ex_table_of (compP2 P) C M) = None"
          by(simp add: compP2_def compMb2_def)
        hence exec: "exec_1 (compP2 P) t (ad, h, (stk', loc, C, M, pc') # FRS) ε (ad, h, FRS)" by(simp add: exec_1_iff)
        moreover
        with conf' wt have "compP2 P,t  Normal (ad, h, (stk', loc, C, M, pc') # FRS) -ε-jvmd→ Normal (ad, h, FRS)"
          by(simp add: welltyped_commute)
        hence "check (compP2 P) (ad, h, (stk', loc, C, M, pc') # FRS)" by(rule jvmd_NormalE)
        moreover from bisim' have "τMove2 (compP2 P) (ad, h, (stk', loc, C, M, pc') # FRS)"
          unfolding τMove2_compP2[OF sees] by(auto dest: bisim1_pc_length_compE2)
        ultimately have "τExec_1_dt (compP2 P) t (xcp, h, (stk, loc, C, M, pc) # FRS) (ad, h, FRS)"
          by -(erule rtranclp_into_tranclp1,rule τexec_1_dI)
        moreover from wt conf' exec
        have "compTP P  t: (ad, h, (stk0, loc0, C0, M0, pc0) # FRS') "
          by(simp)(rule BV_correct_1)
        hence "bisim1_list1 t h (?ee, xs') exs' ad ((stk0, loc0, C0, M0, pc0) # FRS')"
          using sees0
        proof
          from bisim1_inline_call_Throw[OF bisim0 call0] ins pc0
          show "P,blocks1 0 (Class D0#Ts0) body0,h  (?ee, xs')  (stk0, loc0, pc0, ad)" by simp
          from lenxs0 max_vars_inline_call[of e E]
          show "max_vars ?ee  length xs'" by simp
          from bisims Cons show "list_all2 (bisim1_fr P h) exs' FRS'" by simp
        qed
        moreover from call0 have "sim12_size (inline_call (Throw ad) E) > 0" by(cases E) simp_all
        ultimately show ?thesis
          by -(rule exI conjI|assumption|simp)+
      qed
    qed
  qed
qed

lemma exec_1_simulates_Red1_not_τ:
  assumes wf: "wf_J1_prog P"
  and Red1: "True,P,t ⊢1 (e, xs)/exs, h -ta (e', xs')/exs', h'"
  and bisim: "bisim1_list1 t h (e, xs) exs xcp frs"
  and τ: "¬ τMove1 P h ((e, xs), exs)"
  shows "xcp' frs'. τExec_1_dr (compP2 P) t (xcp, h, frs) (xcp', h, frs') 
           (ta' xcp'' frs''. exec_1_d (compP2 P) t (Normal (xcp', h, frs')) ta' (Normal (xcp'', h', frs'')) 
                          ¬ τMove2 (compP2 P) (xcp', h, frs')  ta_bisim wbisim1 ta ta' 
                  bisim1_list1 t h' (e',xs') exs' xcp'' frs'') 
           (call1 e = None 
            (case frs of Nil  False | (stk, loc, C, M, pc) # FRS  M' n. instrs_of (compP2 P) C M ! pc  Invoke M' n) 
            xcp'= xcp  frs' = frs)"
using Red1
proof(cases)
  case (red1Red TA)
  hence [simp]: "ta = extTA2J1 P TA" "exs' = exs"
    and red: "True,P,t ⊢1 e,(h, xs) -TA e',(h', xs')" by simp_all
  from red have hext: "hext h h'" by(auto dest: red1_hext_incr)
  from τ have τ': "¬ τmove1 P h e" by(auto intro: τmove1Block)
  note wt = wt_compTP_compP2[OF wf] 
  from bisim show ?thesis
  proof(cases)
    case (bl1_Normal stk loc C M pc FRS Ts T body D)
    hence [simp]: "frs = (stk, loc, C, M, pc) # FRS"
      and conf: "compTP P  t: (xcp, h, frs) "
      and sees: "P  C sees M: TsT = body in D"
      and bisim: "P,blocks1 0 (Class D#Ts) body,h  (e, xs)  (stk, loc, pc, xcp)"
      and bisims: "list_all2 (bisim1_fr P h) exs FRS" 
      and lenxs: "max_vars e  length xs" by auto
    from sees wf have "bsok (blocks1 0 (Class D # Ts) body) 0"
      by(auto dest!: sees_wf_mdecl WT1_expr_locks simp add: wf_J1_mdecl_def wf_mdecl_def bsok_def)

    from exec_instr_simulates_red1[OF wf bisim red this] τ'
    obtain pc' stk' loc' xcp' pc'' stk'' loc'' xcp''
      where exec1: "τExec_mover_a P t body h (stk, loc, pc, xcp) (stk', loc', pc', xcp')"
      and exec2: "exec_move_a P t body h (stk', loc', pc', xcp') (extTA2JVM (compP2 P) TA) h' (stk'', loc'', pc'', xcp'')"
      and τ2: "¬ τmove2 (compP2 P) h stk' body pc' xcp'"
      and b': "P,blocks1 0 (Class D#Ts) body, h'  (e', xs')  (stk'', loc'', pc'', xcp'')"
      and call: "call1 e = None  no_call2 (blocks1 0 (Class D # Ts) body) pc  pc' = pc  stk' = stk  loc' = loc  xcp' = xcp"
      by(fastforce simp add: exec_move_def simp del: blocks1.simps)
    from exec2 have pc'body: "pc' < length (compE2 body)" by(auto)
    from exec1 sees have exec1': "τExec_1r (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
      by(auto intro: τExec_mover_τExec_1r)
    with wt have execd: "τExec_1_dr (compP2 P) t (xcp, h, frs) (xcp', h, (stk', loc', C, M, pc') # FRS)"
      using conf by(rule τExec_1r_τExec_1_dr)
    moreover { fix a
      assume [simp]: "xcp' = a"
      from exec2 sees_method_compP[OF sees, of "λC M Ts T. compMb2"] pc'body
      have "match_ex_table (compP2 P) (cname_of h a) pc' (ex_table_of (compP2 P) C M)  None"
        by(auto simp add: exec_move_def compP2_def compMb2_def elim!: exec_meth.cases) }
    note xt = this
    with τ2 sees pc'body have τ2': "¬ τMove2 (compP2 P) (xcp', h, (stk', loc', C, M, pc') # FRS)"
      unfolding τMove2_compP2[OF sees] by(auto simp add: compP2_def compMb2_def τmove2_iff)
    moreover from exec2 sees
    have exec2': "exec_1 (compP2 P) t (xcp', h, (stk', loc', C, M, pc') # FRS) (extTA2JVM (compP2 P) TA) (xcp'', h', (stk'', loc'', C, M, pc'') # FRS)"
      by(rule exec_move_exec_1)
    from wt execd conf have conf': "compTP P  t: (xcp', h, (stk', loc', C, M, pc') # FRS) "
      by(rule τExec_1_dr_preserves_correct_state)
    with exec2' wt
    have "exec_1_d (compP2 P) t (Normal (xcp', h, (stk', loc', C, M, pc') # FRS)) (extTA2JVM (compP2 P) TA) (Normal (xcp'', h', (stk'', loc'', C, M, pc'') # FRS))"
      by(simp add: welltyped_commute)
    moreover
    from τ2 sees pc'body xt have τ2': "¬ τMove2 (compP2 P) (xcp', h, (stk', loc', C, M, pc') # FRS)"
      unfolding τMove2_compP2[OF sees] by(auto simp add: compP2_def compMb2_def τmove2_iff)
    moreover from wt conf' exec2'
    have conf'': "compTP P  t: (xcp'', h', (stk'', loc'', C, M, pc'') # FRS) " by(rule BV_correct_1)
    hence "bisim1_list1 t h' (e', xs') exs xcp'' ((stk'', loc'', C, M, pc'') # FRS)" using sees b'
    proof
      from red1_preserves_len[OF red] red1_max_vars[OF red] lenxs
      show "max_vars e'  length xs'" by simp

      from bisims show "list_all2 (bisim1_fr P h') exs FRS"
        by(rule List.list_all2_mono)(rule bisim1_fr_hext_mono[OF _ hext])
    qed
    moreover from conf'' have "hconf h'" "preallocated h'" by(auto simp add: correct_state_def)
    with wf red
    have "ta_bisim wbisim1 ta (extTA2JVM (compP2 P) TA)"
      by(auto intro: ta_bisim_red_extTA2J1_extTA2JVM)
    moreover from call sees_method_compP[OF sees, of "λC M Ts T. compMb2"]
    have "call1 e = None  (case frs of []  False | (stk, loc, C, M, pc) # FRS  M' n. instrs_of (compP2 P) C M ! pc  Invoke M' n)  xcp' = xcp  (stk', loc', C, M, pc') # FRS = frs"
      by(auto simp add: no_call2_def compP2_def compMb2_def)
    ultimately show ?thesis by -(rule exI conjI|assumption|simp)+
  next
    case bl1_finalVal
    with red show ?thesis by auto
  next
    case bl1_finalThrow
    with red show ?thesis by(auto elim: red1_cases)
  qed
next
  case red1Call
  with τ have False
    by(auto simp add: synthesized_call_def dest!: τmove1_not_call1[where P=P and h=h] dest: sees_method_fun)
  thus ?thesis ..
next
  case red1Return
  with τ have False by auto
  thus ?thesis ..
qed

end

end