[STATEMENT]
lemma exec_instr_code [code]:
  "exec_instr (Load n) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, (None, h, ((loc ! n) # stk, loc, C\<^sub>0, M\<^sub>0, pc+1)#frs))}"
  "exec_instr (Store n) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, (None, h, (tl stk, loc[n:=hd stk], C\<^sub>0, M\<^sub>0, pc+1)#frs))}"
  "exec_instr (Push v) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, (None, h, (v # stk, loc, C\<^sub>0, M\<^sub>0, pc+1)#frs))}"
  "exec_instr (New C) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   (let HA = allocate h (Class_type C) in
    if HA = {} then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt OutOfMemory\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)}
    else do { (h', a) \<leftarrow> HA; {(\<lbrace>NewHeapElem a (Class_type C)\<rbrace>, None, h', (Addr a # stk, loc, C\<^sub>0, M\<^sub>0, pc + 1)#frs)} })"
  "exec_instr (NewArray T) P t h stk loc C0 M0 pc frs =
   (let si = the_Intg (hd stk);
        i = nat (sint si)
    in if si <s 0
       then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NegativeArraySize\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
       else let HA = allocate h (Array_type T i) in
         if HA = {} then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt OutOfMemory\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
         else do { (h', a) \<leftarrow> HA; {(\<lbrace>NewHeapElem a (Array_type T i)\<rbrace>, None, h', (Addr a # tl stk, loc, C0, M0, pc + 1) # frs)}})"
  "exec_instr ALoad P t h stk loc C0 M0 pc frs =
   (let va = hd (tl stk)
    in (if va = Null then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
        else
          let i = the_Intg (hd stk);
              a = the_Addr va;
              len = alen_of_htype (the (typeof_addr h a))
          in if i <s 0 \<or> int len \<le> sint i then
               {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt ArrayIndexOutOfBounds\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
             else do {
                 v \<leftarrow> heap_read h a (ACell (nat (sint i)));
                 {(\<lbrace>ReadMem a (ACell (nat (sint i))) v\<rbrace>, None, h, (v # tl (tl stk), loc, C0, M0, pc + 1) # frs)}
               }))"
  "exec_instr AStore P t h stk loc C0 M0 pc frs =
  (let ve = hd stk;
       vi = hd (tl stk);
       va = hd (tl (tl stk))
   in (if va = Null then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
       else (let i = the_Intg vi;
                 idx = nat (sint i);
                 a = the_Addr va;
                 hT = the (typeof_addr h a);
                 T = ty_of_htype hT;
                 len = alen_of_htype hT;
                 U = the (execute.typeof_h h ve)
             in (if i <s 0 \<or> int len \<le> sint i then
                      {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt ArrayIndexOutOfBounds\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
                 else if P \<turnstile> U \<le> the_Array T then
                      do {
                         h' \<leftarrow> heap_write h a (ACell idx) ve;
                         {(\<lbrace>WriteMem a (ACell idx) ve\<rbrace>, None, h', (tl (tl (tl stk)), loc, C0, M0, pc+1) # frs)}
                      }
                 else {(\<epsilon>, (\<lfloor>execute.addr_of_sys_xcpt ArrayStore\<rfloor>, h, (stk, loc, C0, M0, pc) # frs))}))))"
  "exec_instr ALength P t h stk loc C0 M0 pc frs =
   {(\<epsilon>, (let va = hd stk
         in if va = Null
            then (\<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)
            else (None, h, (Intg (word_of_int (int (alen_of_htype (the (typeof_addr h (the_Addr va)))))) # tl stk, loc, C0, M0, pc+1) # frs)))}"
  "exec_instr (Getfield F C) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   (let v = hd stk
    in if v = Null then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)}
       else let a = the_Addr v
            in do {
               v' \<leftarrow> heap_read h a (CField C F);
               {(\<lbrace>ReadMem a (CField C F) v'\<rbrace>, None, h, (v' # (tl stk), loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)}
            })"
  "exec_instr (Putfield F C) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
  (let v = hd stk;
       r = hd (tl stk)
   in if r = Null then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)}
      else let a = the_Addr r
           in do {
                h' \<leftarrow> heap_write h a (CField C F) v;
                {(\<lbrace>WriteMem a (CField C F) v\<rbrace>, None, h', (tl (tl stk), loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)}
              })"
 "exec_instr (Checkcast T) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
  {(\<epsilon>, let U = the (typeof\<^bsub>h\<^esub> (hd stk))
       in if P \<turnstile> U \<le> T then (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)
          else (\<lfloor>execute.addr_of_sys_xcpt ClassCast\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs))}"
  "exec_instr (Instanceof T) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, None, h, (Bool (hd stk \<noteq> Null \<and> P \<turnstile> the (typeof\<^bsub>h\<^esub> (hd stk)) \<le> T) # tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)}"
  "exec_instr (Invoke M n) P t h stk loc C0 M0 pc frs =
   (let r = stk ! n
    in (if r = Null then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}
        else (let ps = rev (take n stk);
                  a = the_Addr r;
                  T = the (typeof_addr h a);
                  (D,M',Ts,meth)= method P (class_type_of T) M
         in case meth of
               Native \<Rightarrow>
                      do {
                        (ta, va, h') \<leftarrow> red_external_aggr P t a M ps h;
                        {(extTA2JVM P ta, extRet2JVM n h' stk loc C0 M0 pc frs va)}
                      }
            | \<lfloor>(mxs,mxl\<^sub>0,ins,xt)\<rfloor> \<Rightarrow>
              let f' = ([],[r]@ps@(replicate mxl\<^sub>0 undefined_value),D,M,0)
              in {(\<epsilon>, None, h, f' # (stk, loc, C0, M0, pc) # frs)})))"
  "exec_instr Return P t h stk\<^sub>0 loc\<^sub>0 C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, (if frs=[] then (None, h, [])
         else
           let v = hd stk\<^sub>0;
               (stk,loc,C,m,pc) = hd frs;
                n = length (fst (snd (method P C\<^sub>0 M\<^sub>0)))
           in (None, h, (v#(drop (n+1) stk),loc,C,m,pc+1)#tl frs)))}"
  "exec_instr Pop P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<epsilon>, (None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc+1)#frs))}"
  "exec_instr Dup P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<epsilon>, (None, h, (hd stk # stk, loc, C\<^sub>0, M\<^sub>0, pc+1)#frs))}"
  "exec_instr Swap P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<epsilon>, (None, h, (hd (tl stk) # hd stk # tl (tl stk), loc, C\<^sub>0, M\<^sub>0, pc+1)#frs))}"
  "exec_instr (BinOpInstr bop) P t h stk loc C0 M0 pc frs =
   {(\<epsilon>,
     case the (execute.binop bop (hd (tl stk)) (hd stk)) of
       Inl v \<Rightarrow> (None, h, (v # tl (tl stk), loc, C0, M0, pc + 1) # frs)
     | Inr a \<Rightarrow> (Some a, h, (stk, loc, C0, M0, pc) # frs))}"
  "exec_instr (IfFalse i) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, (let pc' = if hd stk = Bool False then nat(int pc+i) else pc+1
         in (None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc')#frs)))}"
  "exec_instr (Goto i) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<epsilon>, (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, nat(int pc+i))#frs))}"
  "exec_instr ThrowExc P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(\<epsilon>, (let xp' = if hd stk = Null then \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor> else \<lfloor>the_Addr(hd stk)\<rfloor>
         in (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc)#frs)))}"
  "exec_instr MEnter P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   {(let v = hd stk
     in if v = Null
        then (\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)
        else (\<lbrace>Lock\<rightarrow>the_Addr v, SyncLock (the_Addr v)\<rbrace>, None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs))}"
  "exec_instr MExit P t h stk loc C\<^sub>0 M\<^sub>0 pc frs =
   (let v = hd stk
    in if v = Null
       then {(\<epsilon>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)}
       else {(\<lbrace>Unlock\<rightarrow>the_Addr v, SyncUnlock (the_Addr v)\<rbrace>, None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs),
             (\<lbrace>UnlockFail\<rightarrow>the_Addr v\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt IllegalMonitorState\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)})"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (((exec_instr (Load n) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (loc ! n # stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)} &&& exec_instr (Store n) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (tl stk, loc[n := hd stk], C\<^sub>0, M\<^sub>0, pc + 1) # frs)}) &&& exec_instr (Push v) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (v # stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)} &&& exec_instr (New C) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = (let HA = allocate h (Class_type C) in if HA = {} then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt OutOfMemory\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)} else HA \<bind> (\<lambda>(h', a). {(\<lbrace>NewHeapElem a (Class_type C)\<rbrace>, None, h', (Addr a # stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)})) &&& exec_instr (NewArray T) P t h stk loc C0 M0 pc frs = (let si = the_Intg (hd stk); i = nat (sint si) in if si <s 0 then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NegativeArraySize\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else let HA = allocate h (Array_type T i) in if HA = {} then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt OutOfMemory\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else HA \<bind> (\<lambda>(h', a). {(\<lbrace>NewHeapElem a (Array_type T i)\<rbrace>, None, h', (Addr a # tl stk, loc, C0, M0, pc + 1) # frs)}))) &&& (exec_instr ALoad P t h stk loc C0 M0 pc frs = (let va = hd (tl stk) in if va = Null then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else let i = the_Intg (hd stk); a = the_Addr va; len = alen_of_htype (the (typeof_addr h a)) in if i <s 0 \<or> int len \<le> sint i then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt ArrayIndexOutOfBounds\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else heap_read h a (ACell (nat (sint i))) \<bind> (\<lambda>v. {(\<lbrace>ReadMem a (ACell (nat (sint i))) v\<rbrace>, None, h, (v # tl (tl stk), loc, C0, M0, pc + 1) # frs)})) &&& exec_instr AStore P t h stk loc C0 M0 pc frs = (let ve = hd stk; vi = hd (tl stk); va = hd (tl (tl stk)) in if va = Null then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else let i = the_Intg vi; idx = nat (sint i); a = the_Addr va; hT = the (typeof_addr h a); T = ty_of_htype hT; len = alen_of_htype hT; U = the (typeof\<^bsub>h\<^esub> ve) in if i <s 0 \<or> int len \<le> sint i then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt ArrayIndexOutOfBounds\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else if P \<turnstile> U \<le> the_Array T then heap_write h a (ACell idx) ve \<bind> (\<lambda>h'. {(\<lbrace>WriteMem a (ACell idx) ve\<rbrace>, None, h', (tl (tl (tl stk)), loc, C0, M0, pc + 1) # frs)}) else {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt ArrayStore\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)}) &&& exec_instr ALength P t h stk loc C0 M0 pc frs = {(\<lbrace>\<rbrace>, let va = hd stk in if va = Null then (\<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs) else (None, h, (Intg (word_of_int (int (alen_of_htype (the (typeof_addr h (the_Addr va)))))) # tl stk, loc, C0, M0, pc + 1) # frs))}) &&& exec_instr (Getfield F C) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = (let v = hd stk in if v = Null then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)} else let a = the_Addr v in heap_read h a (CField C F) \<bind> (\<lambda>v'. {(\<lbrace>ReadMem a (CField C F) v'\<rbrace>, None, h, (v' # tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)})) &&& exec_instr (Putfield F C) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = (let v = hd stk; r = hd (tl stk) in if r = Null then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)} else let a = the_Addr r in heap_write h a (CField C F) v \<bind> (\<lambda>h'. {(\<lbrace>WriteMem a (CField C F) v\<rbrace>, None, h', (tl (tl stk), loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)})) &&& exec_instr (Checkcast T) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, let U = the (typeof\<^bsub>h\<^esub> (hd stk)) in if P \<turnstile> U \<le> T then (None, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs) else (\<lfloor>execute.addr_of_sys_xcpt ClassCast\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs))}) &&& ((exec_instr (Instanceof T) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (Bool (hd stk \<noteq> Null \<and> P \<turnstile> the (typeof\<^bsub>h\<^esub> (hd stk)) \<le> T) # tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)} &&& exec_instr (Invoke M n) P t h stk loc C0 M0 pc frs = (let r = stk ! n in if r = Null then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C0, M0, pc) # frs)} else let ps = rev (take n stk); a = the_Addr r; T = the (typeof_addr h a); (D, M', Ts, meth) = method P (class_type_of T) M in case meth of None \<Rightarrow> red_external_aggr P t a M ps h \<bind> (\<lambda>(ta, va, h'). {(extTA2JVM P ta, extRet2JVM n h' stk loc C0 M0 pc frs va)}) | \<lfloor>(mxs, mxl\<^sub>0, ins, xt)\<rfloor> \<Rightarrow> let f' = ([], [r] @ ps @ replicate mxl\<^sub>0 undefined_value, D, M, 0) in {(\<lbrace>\<rbrace>, None, h, f' # (stk, loc, C0, M0, pc) # frs)}) &&& exec_instr Return P t h stk\<^sub>0 loc\<^sub>0 C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, if frs = [] then (None, h, []) else let v = hd stk\<^sub>0; (stk, loc, C, m, pc) = hd frs; n = length (fst (snd (method P C\<^sub>0 M\<^sub>0))) in (None, h, (v # drop (n + 1) stk, loc, C, m, pc + 1) # tl frs))}) &&& exec_instr Pop P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)} &&& exec_instr Dup P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (hd stk # stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)} &&& exec_instr Swap P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (hd (tl stk) # hd stk # tl (tl stk), loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)}) &&& (exec_instr (BinOpInstr bop) P t h stk loc C0 M0 pc frs = {(\<lbrace>\<rbrace>, case the (execute.binop bop (hd (tl stk)) (hd stk)) of Inl v \<Rightarrow> (None, h, (v # tl (tl stk), loc, C0, M0, pc + 1) # frs) | Inr a \<Rightarrow> (\<lfloor>a\<rfloor>, h, (stk, loc, C0, M0, pc) # frs))} &&& exec_instr (IfFalse i) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, let pc' = if hd stk = Bool False then nat (int pc + i) else pc + 1 in (None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc') # frs))} &&& exec_instr (Goto i) P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, None, h, (stk, loc, C\<^sub>0, M\<^sub>0, nat (int pc + i)) # frs)}) &&& exec_instr ThrowExc P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {(\<lbrace>\<rbrace>, let xp' = if hd stk = Null then \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor> else \<lfloor>the_Addr (hd stk)\<rfloor> in (xp', h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs))} &&& exec_instr MEnter P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = {let v = hd stk in if v = Null then (\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs) else (\<lbrace>(Lock, the_Addr v), SyncLock (the_Addr v)\<rbrace>, None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs)} &&& exec_instr MExit P t h stk loc C\<^sub>0 M\<^sub>0 pc frs = (let v = hd stk in if v = Null then {(\<lbrace>\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt NullPointer\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)} else {(\<lbrace>(Unlock, the_Addr v), SyncUnlock (the_Addr v)\<rbrace>, None, h, (tl stk, loc, C\<^sub>0, M\<^sub>0, pc + 1) # frs), (\<lbrace>(UnlockFail, the_Addr v)\<rbrace>, \<lfloor>execute.addr_of_sys_xcpt IllegalMonitorState\<rfloor>, h, (stk, loc, C\<^sub>0, M\<^sub>0, pc) # frs)})
[PROOF STEP]
by(auto 4 4 intro: rev_bexI)


[STATEMENT]
lemma
  fixes p :: "('i::len,'pkt_ext) tagged_packet_scheme"
  shows "no_spoofing TYPE('pkt_ext) ipassmt rs \<Longrightarrow>
      (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<Longrightarrow>
       case ipassmt (Iface (p_iiface p)) of Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips) | None \<Rightarrow> True"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<lbrakk>no_spoofing TYPE('pkt_ext) ipassmt rs; (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply(simp add: no_spoofing_def)
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply(case_tac "Iface (p_iiface p) \<in> dom ipassmt")
[PROOF STATE]
proof (prove)
goal (2 subgoals):
 1. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<in> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
 2. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply(erule_tac x="Iface (p_iiface p)" in ballE)
[PROOF STATE]
proof (prove)
goal (3 subgoals):
 1. \<lbrakk>(common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<in> dom ipassmt; \<forall>pa. (common_matcher, in_doubt_allow),pa\<lparr>p_iiface := iface_sel (Iface (p_iiface p))\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src pa \<in> ipcidr_union_set (set (the (ipassmt (Iface (p_iiface p)))))\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
 2. \<lbrakk>(common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<in> dom ipassmt; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
 3. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply(simp_all)
[PROOF STATE]
proof (prove)
goal (2 subgoals):
 1. \<lbrakk>(common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<in> dom ipassmt; \<forall>pa. (common_matcher, in_doubt_allow),pa\<lparr>p_iiface := p_iiface p\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src pa \<in> ipcidr_union_set (set (the (ipassmt (Iface (p_iiface p)))))\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
 2. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply(erule_tac x="p" in allE)
[PROOF STATE]
proof (prove)
goal (2 subgoals):
 1. \<lbrakk>(common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<in> dom ipassmt; (common_matcher, in_doubt_allow),p\<lparr>p_iiface := p_iiface p\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt (Iface (p_iiface p)))))\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
 2. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply(simp)
[PROOF STATE]
proof (prove)
goal (2 subgoals):
 1. \<lbrakk>(common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<in> dom ipassmt; p_src p \<in> ipcidr_union_set (set (the (ipassmt (Iface (p_iiface p)))))\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
 2. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
apply fastforce
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<lbrakk>\<forall>iface\<in>dom ipassmt. \<forall>p. (common_matcher, in_doubt_allow),p\<lparr>p_iiface := iface_sel iface\<rparr>\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow \<longrightarrow> p_src p \<in> ipcidr_union_set (set (the (ipassmt iface))); (common_matcher, in_doubt_allow),p\<turnstile> \<langle>rs, Undecided\<rangle> \<Rightarrow>\<^sub>\<alpha> Decision FinalAllow; Iface (p_iiface p) \<notin> dom ipassmt\<rbrakk> \<Longrightarrow> case ipassmt (Iface (p_iiface p)) of None \<Rightarrow> True | Some ips \<Rightarrow> p_src p \<in> ipcidr_union_set (set ips)
[PROOF STEP]
by (simp add: domIff)