(*  Title:      HOL/Auth/n_g2kAbsAfter_lemma_inv__81_on_rules.thy
    Author:     Yongjian Li and Kaiqiang Duan, State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
    Copyright    2016 State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
*)

header{*The n_g2kAbsAfter Protocol Case Study*}

theory n_g2kAbsAfter_lemma_inv__81_on_rules imports n_g2kAbsAfter_lemma_on_inv__81
begin
section{*All lemmas on causal relation between inv__81*}
lemma lemma_inv__81_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(f=inv__81  )"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> d. d\<le>N\<and>r=n_n_Store_i1  d)\<or>
    (\<exists> d. d\<le>N\<and>r=n_n_AStore_i1  d)\<or>
    (r=n_n_SendReqS_j1  )\<or>
    (r=n_n_SendReqEI_i1  )\<or>
    (r=n_n_SendReqES_i1  )\<or>
    (r=n_n_RecvReq_i1  )\<or>
    (r=n_n_SendInvE_i1  )\<or>
    (r=n_n_SendInvS_i1  )\<or>
    (r=n_n_SendInvAck_i1  )\<or>
    (r=n_n_RecvInvAck_i1  )\<or>
    (r=n_n_SendGntS_i1  )\<or>
    (r=n_n_SendGntE_i1  )\<or>
    (r=n_n_RecvGntS_i1  )\<or>
    (r=n_n_RecvGntE_i1  )\<or>
    (r=n_n_ASendReqIS_j1  )\<or>
    (r=n_n_ASendReqSE_j1  )\<or>
    (r=n_n_ASendReqEI_i1  )\<or>
    (r=n_n_ASendReqES_i1  )\<or>
    (r=n_n_SendReqEE_i1  )\<or>
    (r=n_n_ARecvReq_i1  )\<or>
    (r=n_n_ASendInvE_i1  )\<or>
    (r=n_n_ASendInvS_i1  )\<or>
    (r=n_n_ASendInvAck_i1  )\<or>
    (r=n_n_ARecvInvAck_i1  )\<or>
    (r=n_n_ASendGntS_i1  )\<or>
    (r=n_n_ASendGntE_i1  )\<or>
    (r=n_n_ARecvGntS_i1  )\<or>
    (r=n_n_ARecvGntE_i1  )"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> d. d\<le>N\<and>r=n_n_Store_i1  d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_Store_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(\<exists> d. d\<le>N\<and>r=n_n_AStore_i1  d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_AStore_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqS_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqS_j1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqEI_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqEI_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqES_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqES_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_RecvReq_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvReq_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvE_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvS_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvAck_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_RecvInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvInvAck_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendGntS_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendGntE_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_RecvGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvGntS_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_RecvGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvGntE_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqIS_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqIS_j1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqSE_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqSE_j1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqEI_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqEI_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqES_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqES_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqEE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqEE_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvReq_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvReq_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvE_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvS_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvAck_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvInvAck_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendGntS_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ASendGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendGntE_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvGntS_i1Vsinv__81) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvGntE_i1Vsinv__81) done
    }

  ultimately show "invHoldForRule s f r (invariants N)"
  by satx
qed

end


(*  Title:      HOL/Auth/n_g2kAbsAfter_lemma_inv__44_on_rules.thy
    Author:     Yongjian Li and Kaiqiang Duan, State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
    Copyright    2016 State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
*)

header{*The n_g2kAbsAfter Protocol Case Study*}

theory n_g2kAbsAfter_lemma_inv__44_on_rules imports n_g2kAbsAfter_lemma_on_inv__44
begin
section{*All lemmas on causal relation between inv__44*}
lemma lemma_inv__44_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(f=inv__44  )"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> d. d\<le>N\<and>r=n_n_Store_i1  d)\<or>
    (\<exists> d. d\<le>N\<and>r=n_n_AStore_i1  d)\<or>
    (r=n_n_SendReqS_j1  )\<or>
    (r=n_n_SendReqEI_i1  )\<or>
    (r=n_n_SendReqES_i1  )\<or>
    (r=n_n_RecvReq_i1  )\<or>
    (r=n_n_SendInvE_i1  )\<or>
    (r=n_n_SendInvS_i1  )\<or>
    (r=n_n_SendInvAck_i1  )\<or>
    (r=n_n_RecvInvAck_i1  )\<or>
    (r=n_n_SendGntS_i1  )\<or>
    (r=n_n_SendGntE_i1  )\<or>
    (r=n_n_RecvGntS_i1  )\<or>
    (r=n_n_RecvGntE_i1  )\<or>
    (r=n_n_ASendReqIS_j1  )\<or>
    (r=n_n_ASendReqSE_j1  )\<or>
    (r=n_n_ASendReqEI_i1  )\<or>
    (r=n_n_ASendReqES_i1  )\<or>
    (r=n_n_SendReqEE_i1  )\<or>
    (r=n_n_ARecvReq_i1  )\<or>
    (r=n_n_ASendInvE_i1  )\<or>
    (r=n_n_ASendInvS_i1  )\<or>
    (r=n_n_ASendInvAck_i1  )\<or>
    (r=n_n_ARecvInvAck_i1  )\<or>
    (r=n_n_ASendGntS_i1  )\<or>
    (r=n_n_ASendGntE_i1  )\<or>
    (r=n_n_ARecvGntS_i1  )\<or>
    (r=n_n_ARecvGntE_i1  )"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> d. d\<le>N\<and>r=n_n_Store_i1  d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_Store_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(\<exists> d. d\<le>N\<and>r=n_n_AStore_i1  d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_AStore_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqS_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqS_j1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqEI_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqEI_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqES_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqES_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_RecvReq_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvReq_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvE_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvS_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvAck_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_RecvInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvInvAck_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendGntS_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendGntE_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_RecvGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvGntS_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_RecvGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvGntE_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqIS_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqIS_j1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqSE_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqSE_j1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqEI_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqEI_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqES_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqES_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqEE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqEE_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvReq_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvReq_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvE_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvS_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvAck_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvInvAck_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendGntS_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ASendGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendGntE_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvGntS_i1Vsinv__44) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvGntE_i1Vsinv__44) done
    }

  ultimately show "invHoldForRule s f r (invariants N)"
  by satx
qed

end


theory RA_seL4
imports Main
begin

datatype PC = P0 | P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 | P10 | P11 | P12 | P13 | P14 | Idle
datatype PC_SETUP = L1 | L2 | L3 | L4
type_synonym Time = nat
type_synonym Process = nat
type_synonym MRange = "nat \<times> nat"
type_synonym Mac = nat

datatype Cap =
 CSCap Process  | VSCap Process  | TCBCap Process
 | TCap | KeyCap  | EPCap | GrantCap | IQCap  | NetCap  | SendCap  | ReceiveCap | BadgeCap Process

datatype Object = P Process | INITTIME | KEY | IRQ | NONCE | MEM
datatype Predicate = Read | Write | Grant | Control | AsyncSend | Receive
consts Policy :: "(Process \<times> Predicate \<times> Object) set"

consts P\<^sub>A :: Process
consts P\<^sub>1 :: Process
consts P\<^sub>N :: Process

definition "P_distinct \<equiv> P\<^sub>A \<noteq> P\<^sub>1 \<and>  P\<^sub>A \<noteq> P\<^sub>N \<and>  P\<^sub>N \<noteq> P\<^sub>1"

datatype Message =
           Req Time Mac MRange Process
         | Res Time Mac Mac
         | Empty

fun isReq :: "Message \<Rightarrow> bool" where
  "isReq (Req _ _ _ _) = True"
| "isReq _ = False"

fun isRes :: "Message \<Rightarrow> bool" where
    "isRes (Res _ _ _) = True"
  | "isRes _ = False"

fun getMTime :: "Message \<Rightarrow> Time " where
    "getMTime (Req t  _ _ _) =  t"
  | "getMTime (Res t  _ _) =  t"
  | "getMTime _ = 0 "

fun getMProcess :: "Message \<Rightarrow> Process option" where
    "getMProcess (Req _ _ _ p) = Some p"
  | "getMProcess (Res _ _ _) = None"
  | "getMProcess _ = None "

fun getMRange :: "Message \<Rightarrow> MRange option" where
    "getMRange (Req _ _ r _) = Some r"
   | "getMRange (Res _ _ _) = None"
   | "getMRange _ = None "

fun getFMac :: "Message \<Rightarrow> Mac " where
     "getFMac (Req _ fm _ _) =  fm"
   | "getFMac (Res _ fm _) =  fm"
   | "getFMac _ = 0 "

fun getSMac :: "Message \<Rightarrow> Mac option" where
    "getSMac (Req _ _ _ _) = None"
  | "getSMac (Res _ _ sm) = Some sm"
  | "getSMac _ = None "

record Message_req =
  time_req :: Time (*Treq, Tres, ...*)
  mac_req :: nat
  mrang_req :: MRange (*a'b'*)
  proc_req :: Process (*Pa, P1, ...*)

record Message_resp =
  time_resp :: Time (*Treq, Tres, ...*)
  (*proc_resp :: Process Pa, P1, ...*)
  mac1_resp :: nat
  mac2_resp :: nat

record CSpace_rec =
  Caps :: "Cap set"
  EP :: Message

record TCB_rec =
  VSpace :: nat
  CSpace :: CSpace_rec

record Proc_rec =
  TCB :: TCB_rec
  Mem :: MRange
  Priority :: nat
  Time :: nat
  Parent :: nat

record State =
 Procs :: "Process set"
 ProcRec :: "Process \<Rightarrow> Proc_rec"
 TInit :: nat
 Key :: nat
 Nonce :: nat
 irq :: bool
 pc :: PC
 policy :: "(Process \<times> Predicate \<times> Object) set"
(*Local*)
 rval :: "Message"
 l_time :: nat
 l_mac1 :: nat
 l_mac2 :: nat
 ep :: Message

definition "P_attest_prop s \<equiv>
               P\<^sub>A\<in>Procs s
             \<and> Priority ((ProcRec s) P\<^sub>A)  = 0
             \<and> Time ((ProcRec s) P\<^sub>A)  = TInit s
             \<and> Parent ((ProcRec s) P\<^sub>A)  = 0
             \<and> Caps (CSpace (TCB ((ProcRec s) P\<^sub>A))) =
                  {VSCap P\<^sub>A, CSCap P\<^sub>A, TCBCap P\<^sub>A, TCap, KeyCap , EPCap, GrantCap, IQCap, SendCap,BadgeCap P\<^sub>A, BadgeCap P\<^sub>N}"

definition "Spawned_prop p s \<equiv>
            p \<noteq> P\<^sub>A \<and> p \<in> Procs s
          \<and> Priority ((ProcRec s) p) > 0
          \<and> Time ((ProcRec s) p) > TInit s
          \<and> Caps (CSpace (TCB ((ProcRec s) p))) = {VSCap p, CSCap p, TCBCap p}"

definition "Net_prop p s \<equiv>
            p \<noteq> P\<^sub>A \<and> p \<in> Procs s
          \<and> Priority ((ProcRec s) p) > 0
          \<and> Time ((ProcRec s) p) > TInit s
          \<and> Caps (CSpace (TCB ((ProcRec s) p))) = {VSCap p, CSCap p, TCBCap p, NetCap, ReceiveCap, BadgeCap P\<^sub>N, BadgeCap P\<^sub>A}"

record SetupState =
   ss_pc :: PC_SETUP

definition "CreateProcess tcb mem  pri t par\<equiv>
             \<lparr>
              TCB = tcb,
              Mem = mem,
              Priority = pri,
              Time = t,
              Parent = par
             \<rparr>"

definition "CreateProcessTCB vs cs\<equiv>
             \<lparr>
              VSpace = vs,
              CSpace = cs
             \<rparr>"

definition "CreateProcessCSpace caps \<equiv>
             \<lparr>
                Caps = caps,
                EP = Empty
             \<rparr>"

definition "MAC data::nat \<equiv> SOME n. 1 \<le> n \<and> n \<le> data * data * data"

definition "getTime now \<equiv> SOME t . t > now"

definition update_pc :: "PC \<Rightarrow> State \<Rightarrow> State" ("`pc := _" [200])
  where
  "update_pc v \<equiv> \<lambda> s. s \<lparr>pc := v\<rparr>"

definition update_local_ep :: "Message \<Rightarrow> State \<Rightarrow> State" ("`ep := _" [200])
  where
  "update_local_ep v \<equiv> \<lambda> s. s \<lparr>ep := v\<rparr>"

definition update_irq :: "bool \<Rightarrow> State \<Rightarrow> State" ("`irq := _" [200])
  where
  "update_irq v \<equiv> \<lambda> s. s \<lparr>irq := v\<rparr>"

definition update_rval :: "Message  \<Rightarrow> State \<Rightarrow> State" ("`rval := _" [200])
  where
  "update_rval v \<equiv> \<lambda> s. s \<lparr>rval := v\<rparr>"

(*definition update_badge :: "bool \<Rightarrow> Proc_rec \<Rightarrow> Proc_rec" ("`badge := _" [100])
  where
  "update_badge v \<equiv> \<lambda> s. s \<lparr>Badge := v\<rparr>"*)

definition update_time :: "Time \<Rightarrow> State \<Rightarrow> State" ("`time := _" [100])
  where
  "update_time v \<equiv> \<lambda> s. s \<lparr>l_time := v\<rparr>"

definition update_mac1 :: "nat \<Rightarrow> State \<Rightarrow> State" ("`mac1 := _" [200])
  where
  "update_mac1 v \<equiv> \<lambda> s. s \<lparr>l_mac1 := v\<rparr>"

definition update_mac2 :: "nat \<Rightarrow> State \<Rightarrow> State" ("`mac2 := _" [200])
  where
  "update_mac2 v \<equiv> \<lambda> s. s \<lparr>l_mac2 := v\<rparr>"

definition update_nonce :: "nat \<Rightarrow> State \<Rightarrow> State" ("`nonce := _" [200])
  where
  "update_nonce v \<equiv> \<lambda> s. s \<lparr>Nonce := v\<rparr>"

definition Setup :: "SetupState \<Rightarrow> State \<Rightarrow> SetupState \<Rightarrow> State \<Rightarrow> bool" where
   "Setup ss s ss' s'  \<equiv>
             (case (ss_pc ss) of
                L1 \<Rightarrow>  let csp = CreateProcessCSpace {VSCap P\<^sub>A, CSCap P\<^sub>A, TCBCap P\<^sub>A, TCap, KeyCap , EPCap, GrantCap, IQCap, SendCap, BadgeCap P\<^sub>A, BadgeCap P\<^sub>N};
                           tcb = CreateProcessTCB 0 csp;
                           pr = CreateProcess tcb (0,1) 0  (TInit s) 0  in
                        s' = s\<lparr>Procs := Procs s \<union> {P\<^sub>A}, ProcRec := (ProcRec s)(P\<^sub>A := pr), policy := policy s \<union> {(P\<^sub>A, Read, KEY),(P\<^sub>A, Read, INITTIME), (P\<^sub>A, Control,P P\<^sub>A),(P\<^sub>A, Control, IRQ), (P\<^sub>A, Control, NONCE), (P\<^sub>A, Control, MEM)}\<rparr>
                 \<and>  (ss_pc ss' = L2)
              | L2 \<Rightarrow>  let csp = CreateProcessCSpace {VSCap P\<^sub>1, CSCap P\<^sub>1, TCBCap P\<^sub>1};
                           tcb = CreateProcessTCB 0 csp;
                           pr = CreateProcess tcb (1,2) 1  (TInit s) 1  in
                        s' = s\<lparr>Procs := Procs s \<union> {P\<^sub>1}, ProcRec := (ProcRec s)(P\<^sub>1 := pr),policy := policy s \<union> {(P\<^sub>1, Control,P P\<^sub>1) , (P\<^sub>A, Control,P P\<^sub>1)}\<rparr>
                 \<and>  (ss_pc ss' = L3)
              | L3 \<Rightarrow>  let csp = CreateProcessCSpace {VSCap P\<^sub>N, CSCap P\<^sub>N, TCBCap P\<^sub>N};
                           tcb = CreateProcessTCB 0 csp;
                           pr = CreateProcess tcb (2,3) 1  (TInit s) 0  in
                        s' = s\<lparr>Procs := Procs s \<union> {P\<^sub>N}, ProcRec := (ProcRec s)(P\<^sub>N := pr), policy := policy s \<union> {(P\<^sub>N, Control,P P\<^sub>N) , (P\<^sub>A, Control,P P\<^sub>N)}\<rparr>
                 \<and>  (ss_pc ss' = L4)
              | L4 \<Rightarrow> False
              )
             "

definition "getEP s p \<equiv>  (EP (CSpace (TCB (ProcRec s p))))"

lemmas simps [simp] = update_nonce_def update_mac2_def update_mac1_def update_time_def (*update_badge_def*)
update_rval_def update_irq_def update_pc_def  MAC_def update_local_ep_def Let_def

definition Prover :: "State \<Rightarrow>  State  \<Rightarrow> bool"
  where
    "Prover s s' \<equiv>
      (case (pc s) of
          P0 \<Rightarrow> if  BadgeCap P\<^sub>A \<in> (Caps (CSpace (TCB ((ProcRec s) P\<^sub>N)))) then s' = (`pc := P1) s else s' = s
        | P1 \<Rightarrow> s' = (`pc := P2  \<circ> `irq := False) s
        | P2 \<Rightarrow> let ep = (EP(CSpace (TCB ((ProcRec s) P\<^sub>N)))) in if isReq ep then
                 s' = (`pc := P3 \<circ> `ep := ep \<circ> (\<lambda> s . s \<lparr>ProcRec := (ProcRec s)(P\<^sub>A := (ProcRec s P\<^sub>A)\<lparr>
                     TCB := (TCB (ProcRec s P\<^sub>A))\<lparr>CSpace := ((CSpace (TCB (ProcRec s P\<^sub>A)))\<lparr>EP := ep\<rparr>)\<rparr>\<rparr>)\<rparr>)) s else s' = s
        | P3 \<Rightarrow> (if(TInit s > (getMTime (ep s)))
                then (s'= (`pc := Idle \<circ> `rval := Empty) s )
                else (s' = (`pc := P4) s))
        | P4 \<Rightarrow> (if  ((getFMac (ep s)) \<noteq> (MAC ((getMTime (ep s)) * fst (Mem ((ProcRec s) P\<^sub>A))  *  snd (Mem ((ProcRec s) P\<^sub>A)) * (P\<^sub>A))))
                then (s' = (`pc := Idle \<circ> `rval := Empty) s)
                else (s' = (`pc := P5) s))
        | P5 \<Rightarrow> s' = (`pc := P6 \<circ> `nonce := (TInit s + (getMTime (ep s)))) s

        | P6 \<Rightarrow> s' = (`pc := P7  \<circ> `time := (getTime ((getMTime (ep s))))) s

        | P7 \<Rightarrow> s' = (`pc := P8  \<circ> `mac1 := (MAC (fst (Mem ((ProcRec s) P\<^sub>A)) * snd (Mem ((ProcRec s) P\<^sub>A))))) s

        | P8 \<Rightarrow> s' = (`pc := P9  \<circ> `mac2 := (MAC ((l_time s) * (P\<^sub>A) * (l_mac1 s)))) s

        | P9 \<Rightarrow> s' = (`pc := P10  \<circ> `rval := ((Res (l_time s) (l_mac1 s) (l_mac2 s)))) s

        | P10 \<Rightarrow> s' = (`pc := P11  \<circ> (\<lambda> s . s \<lparr>ProcRec := (ProcRec s)(P\<^sub>A := (ProcRec s P\<^sub>A)
                      \<lparr>TCB := (TCB (ProcRec s P\<^sub>A))\<lparr>CSpace := ((CSpace (TCB (ProcRec s P\<^sub>A)))\<lparr>EP := rval s\<rparr>)\<rparr>\<rparr>)\<rparr>)) s

        | P11 \<Rightarrow> s' = (`pc := Idle  \<circ> `irq := True) s

        | Idle \<Rightarrow> False
        | _ \<Rightarrow> False)"

definition Network :: "State   \<Rightarrow> Message  \<Rightarrow>  State  \<Rightarrow> bool"
  where
    "Network s m s'  \<equiv>
       case (pc s) of
        P0 \<Rightarrow> s' = (`pc := P1 \<circ> `ep := m \<circ> (\<lambda> s . s \<lparr>ProcRec := (ProcRec s)(P\<^sub>N := (ProcRec s P\<^sub>N)\<lparr>
                     TCB := (TCB (ProcRec s P\<^sub>N))\<lparr>CSpace := ((CSpace (TCB (ProcRec s P\<^sub>N)))\<lparr>EP := m\<rparr>)\<rparr>\<rparr>)\<rparr>)) s
        | P1 \<Rightarrow> if BadgeCap P\<^sub>N \<in> (Caps (CSpace (TCB ((ProcRec s) P\<^sub>A)))) then s' = (`pc := P2) s else s' = s

        | P2 \<Rightarrow> let ep = (EP(CSpace (TCB ((ProcRec s) P\<^sub>A)))) in
                 s' = (`pc := P3 \<circ> (\<lambda> s . s \<lparr>ProcRec := (ProcRec s)(P\<^sub>N := (ProcRec s P\<^sub>N)\<lparr>
                     TCB := (TCB (ProcRec s P\<^sub>N))\<lparr>CSpace := ((CSpace (TCB (ProcRec s P\<^sub>N)))\<lparr>EP := ep\<rparr>)\<rparr>\<rparr>)\<rparr>)) s
        | _ \<Rightarrow> False"

(* -----------------------------------------------------P\<^sub>A Related Lemmas-------------------------------------------------*)

lemma Setup_P\<^sub>A: "ss_pc ss = L1 \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> P_attest_prop s'"
  apply(simp add: Setup_def P_attest_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)
  done

lemma Setup_P\<^sub>1: "P_distinct \<Longrightarrow> ss_pc ss = L2 \<Longrightarrow> P_attest_prop s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> P_attest_prop s'"
  by(simp add:P_distinct_def Setup_def P_attest_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)
lemma Setup_P\<^sub>N: "P_distinct \<Longrightarrow> ss_pc ss = L3 \<Longrightarrow> P_attest_prop s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> P_attest_prop s'"
  by(simp add:P_distinct_def Setup_def P_attest_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)

lemma Network_P\<^sub>A: "P_attest_prop s \<Longrightarrow> Network s m s' \<Longrightarrow> P_attest_prop s'"
   apply(simp add: Setup_def Prover_def Network_def P_distinct_def Setup_P\<^sub>A P_attest_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)
  apply(cases "pc s", simp_all)
   apply clarsimp
  apply clarsimp
  done

lemma Prover_P\<^sub>A: "P_attest_prop s \<Longrightarrow> Prover s s' \<Longrightarrow> P_attest_prop s'"
   apply(simp add: Setup_def Prover_def P_distinct_def Setup_P\<^sub>A P_attest_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)
  apply(cases " pc s", simp_all)
        apply (case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
       apply(case_tac "isReq (EP (CSpace (TCB (ProcRec s P\<^sub>N))))", simp_all)
      apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) * fst (Mem (ProcRec s P\<^sub>A)) * snd (Mem (ProcRec s P\<^sub>A)) * P\<^sub>A *
                (getMTime (ep s) * fst (Mem (ProcRec s P\<^sub>A)) * snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) * fst (Mem (ProcRec s P\<^sub>A)) * snd (Mem (ProcRec s P\<^sub>A)) * P\<^sub>A))", simp_all)
  done

(* -----------------------------------------------------P\<^sub>N Related Lemmas-------------------------------------------------*)

lemma Network_P\<^sub>N: "P_distinct \<Longrightarrow> pc s = P3 \<Longrightarrow> Net_prop P\<^sub>N  s \<Longrightarrow> Prover s s' \<Longrightarrow> Net_prop P\<^sub>N s'"
  apply(simp add:Prover_def P_distinct_def Setup_def P_attest_prop_def Net_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)
  apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  done

lemma Prover_P\<^sub>N: "P_distinct \<Longrightarrow> pc s = P4 \<Longrightarrow> Net_prop P\<^sub>N s \<Longrightarrow> Network s m s' \<Longrightarrow> Net_prop P\<^sub>N s'"
  by(simp add:Network_def Prover_def P_distinct_def Setup_def P_attest_prop_def Net_prop_def CreateProcessCSpace_def
                                    CreateProcessTCB_def CreateProcess_def)

(* ***********************************        Confidentiality Through AC          *****************************************     *)

definition "KeyConf s \<equiv> \<forall>p. (p, Read, KEY)\<in>policy s \<longrightarrow> p =  P\<^sub>A"
definition "MemConf s \<equiv> \<forall>p. (p, Read, MEM)\<in>policy s \<longrightarrow> p =  P\<^sub>A"
definition "IrqAC s \<equiv> \<forall>p. (p, Control, IRQ)\<in>policy s \<longrightarrow> p =  P\<^sub>A"
definition "TimeConf s \<equiv> \<forall>p. (p, Read, INITTIME)\<in>policy s \<longrightarrow> p =  P\<^sub>A"
definition "NONCE_AC s \<equiv> \<forall>p. (p, Control, NONCE)\<in>policy s \<longrightarrow> p =  P\<^sub>A"
definition "Super s \<equiv>  \<forall>p. p\<in> Procs s \<longrightarrow>  (P\<^sub>A, Control, P p)\<in>policy s"
definition "no_grant s \<equiv> \<forall> p p' .p \<in> Procs s \<and> p'\<in>Procs s \<and>  p \<noteq> P\<^sub>A \<and> p'\<noteq>P\<^sub>A
                                          \<and> (p, Control, P p')\<in>policy s \<longrightarrow> p = p'"

definition "Evolution s ss \<equiv> (ss_pc ss = L1  \<longrightarrow> Procs s = {}) \<and>( ss_pc ss = L2  \<longrightarrow> Procs s = {P\<^sub>A})
                          \<and> ( ss_pc ss = L3  \<longrightarrow> Procs s = {P\<^sub>A , P\<^sub>1}) \<and>
                            ( ss_pc ss = L4  \<longrightarrow> Procs s = {P\<^sub>A , P\<^sub>1 , P\<^sub>N})"

definition "Evolution_Policy s ss \<equiv> (ss_pc ss = L1 \<longrightarrow> policy s = {}) \<and>(ss_pc ss = L2  \<longrightarrow> policy s = {(P\<^sub>A, Read, KEY),(P\<^sub>A, Read, INITTIME), (P\<^sub>A, Control,P P\<^sub>A),(P\<^sub>A, Control, IRQ), (P\<^sub>A, Control, NONCE), (P\<^sub>A, Control, MEM)})
                          \<and> (ss_pc ss = L3  \<longrightarrow> policy s = {(P\<^sub>1, Control,P P\<^sub>1) , (P\<^sub>A, Control,P P\<^sub>1)}) \<and>
                            (ss_pc ss = L4  \<longrightarrow> policy s = {(P\<^sub>N, Control,P P\<^sub>N) , (P\<^sub>A, Control,P P\<^sub>N)})"

definition "Reflect s \<equiv> \<forall>p. p\<in> Procs s \<longrightarrow> (p, Control,P p)\<in>policy s"

lemma Setup_no_Control : "Evolution_Policy s ss \<Longrightarrow> Reflect s \<Longrightarrow> Evolution s ss \<Longrightarrow> P_distinct \<Longrightarrow> no_grant s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> no_grant s'"
  apply(simp add: Setup_def  del:simps)
  apply (cases "ss_pc ss", simp_all)
  apply safe
    apply(simp add: Reflect_def Evolution_def Evolution_Policy_def no_grant_def)
  apply(simp add: Reflect_def Evolution_def Evolution_Policy_def no_grant_def)

   apply blast

  by (simp add: Evolution_Policy_def Evolution_def P_distinct_def Reflect_def)

lemma Prover_no_Control:
  assumes "Prover s s'"
  and "no_grant s"
shows "no_grant  s'"
  using assms
 apply(simp add: Setup_def Prover_def Evolution_def Evolution_Policy_def P_distinct_def Reflect_def P_attest_prop_def CreateProcess_def CSpace_def
                                   CreateProcessTCB_def no_grant_def)
  apply(cases "pc s", simp_all)
     apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply(case_tac " isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst
(Mem (ProcRec s P\<^sub>A)) *
                snd
(Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A) *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A))", simp_all)
  done

lemma Setup_Key_conf : "P_distinct \<Longrightarrow> KeyConf s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> KeyConf s'"
  apply(simp add: KeyConf_def Setup_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(cases "ss_pc ss", simp_all)
  done
lemma Prover_Key_conf : "KeyConf s \<Longrightarrow> Prover s s' \<Longrightarrow> KeyConf s'"
 apply(simp add: KeyConf_def Setup_def Prover_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def P_distinct_def)
  apply(cases "pc s", simp_all)
     apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s
    ", simp_all)
      apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst
(Mem (ProcRec s P\<^sub>A)) *
                snd
(Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A) *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A))", simp_all)
  done

 lemma Setup_Time_conf : "TimeConf s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> TimeConf s'"
 apply(simp add: TimeConf_def Setup_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(cases "ss_pc ss", simp_all)
  done

 lemma Prover_Time_conf : "TimeConf s \<Longrightarrow> Prover s s' \<Longrightarrow> TimeConf s'"
 apply(simp add: TimeConf_def Prover_def Setup_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
   apply(cases "pc s", simp_all)
      apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
   apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s", simp_all)
   apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst
(Mem (ProcRec s P\<^sub>A)) *
                snd
(Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A) *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A))", simp_all)
   done

lemma Superiority_Setup : "P_distinct \<Longrightarrow> Super s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> Super s'"
apply(simp add: Super_def Setup_def CreateProcessCSpace_def P_distinct_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(intro allI impI)
  apply(cases "ss_pc ss", simp_all)
    apply auto[1]
   apply blast
  by auto

lemma Superiority_Prover : "P_distinct \<Longrightarrow> Super s \<Longrightarrow> Prover s s' \<Longrightarrow> Super s'"
apply(simp add: Super_def Setup_def Prover_def CreateProcessCSpace_def P_distinct_def
                                   CreateProcessTCB_def CreateProcess_def Network_def)

  apply(cases "pc s", simp_all)
  apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply(case_tac "\<forall>p. p \<in> Procs s \<longrightarrow>
        (P\<^sub>A, Control, P p)
        \<in> policy s ", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem
  (ProcRec s P\<^sub>A)) *
                snd (Mem
  (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))", simp_all)
  done

lemma Setup_Mem_conf : "MemConf s \<Longrightarrow> Setup ss s ss' s' \<Longrightarrow> MemConf s'"
apply(simp add: MemConf_def Setup_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(cases "ss_pc ss", simp_all)
  done

lemma Prover_Mem_conf : "MemConf s \<Longrightarrow> Prover s s' \<Longrightarrow> MemConf s'"
apply(simp add: MemConf_def Setup_def Prover_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(case_tac "\<forall>p. (p, Read, MEM) \<in> policy s \<longrightarrow>
        p = P\<^sub>A",simp_all)
  apply(cases "pc s", simp_all)
     apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem
  (ProcRec s P\<^sub>A)) *
                snd (Mem
  (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))", simp_all)
  done

lemma Prover_IRQ_AC : "IrqAC s \<Longrightarrow> Prover s s' \<Longrightarrow> IrqAC s'"
apply(simp add: Setup_def Prover_def CreateProcessCSpace_def P_distinct_def
                                   CreateProcessTCB_def CreateProcess_def Network_def IrqAC_def)
  apply(cases "pc s", simp_all)
  apply(case_tac "\<forall>p. (p, Control, IRQ)
        \<in> policy s \<longrightarrow>
        p = P\<^sub>A", simp_all)
     apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem
  (ProcRec s P\<^sub>A)) *
                snd (Mem
  (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))", simp_all)

  done

lemma Prover_Nonce_AC : "NONCE_AC s \<Longrightarrow> Prover s s' \<Longrightarrow> NONCE_AC s'"
apply(simp add: NONCE_AC_def Setup_def Prover_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(case_tac "\<forall>p. (p, Control, NONCE)
        \<in> policy s \<longrightarrow>
        p = P\<^sub>A ", simp_all)
  apply(cases "pc s", simp_all)
     apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))",simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s",simp_all)
apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem
  (ProcRec s P\<^sub>A)) *
                snd (Mem
  (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem
   (ProcRec s P\<^sub>A)) *
                 snd (Mem
   (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))",simp_all)
  done

(* ***********************************        Information Flow         *****************************************     *)

definition "inv_rval s \<equiv> pc s \<in> {P10, P11} \<longrightarrow> isRes (rval s) "
definition "inv_req s \<equiv> pc s = P3 \<longrightarrow> isReq (ep s)"

lemma P\<^sub>A_to_P\<^sub>N:
  assumes "Prover s s'"
    and "inv_rval s"
  shows "inv_rval s'"
  using assms
  apply(simp add: Prover_def inv_rval_def)
  apply(cases "pc s", simp_all)
     apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem (ProcRec s P\<^sub>A)) *
                snd (Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))", simp_all)
done

lemma P\<^sub>N_to_P\<^sub>A:
  assumes "Prover s s'"
    and "inv_req s"
  shows "inv_req s'"
using assms
  apply(simp add: P_distinct_def Setup_def Prover_def inv_req_def inv_rval_def CreateProcessCSpace_def
                                   CreateProcessTCB_def CreateProcess_def)
  apply(cases "pc s", simp_all)
   apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
   apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst
(Mem (ProcRec s P\<^sub>A)) *
                snd
(Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A) *
                (getMTime
 (ep s) *
fst (Mem (ProcRec s P\<^sub>A)) *
snd (Mem (ProcRec s P\<^sub>A)) *
P\<^sub>A))", simp_all)
  done

lemma Info_Flow_1: "inv_rval s \<Longrightarrow> pc s = P12 \<Longrightarrow> Badge ((ProcRec s) P\<^sub>A) \<Longrightarrow> Prover s s' \<Longrightarrow>
         isRes (EP(CSpace (TCB ((ProcRec s') P\<^sub>A)))) "
  apply(simp add: Prover_def inv_rval_def)
  done

(* ***********************************        Integrity         *****************************************            *)

definition "Key_AC \<equiv> \<forall>p. (p, Read, KEY)\<in>Policy \<longrightarrow> p =  P\<^sub>A"
definition "Mem_AC \<equiv> \<forall>p. (p, Control, MEM)\<in>Policy \<longrightarrow> p =  P\<^sub>A"

lemma Res_Integrity: "pc s\<in> {P2, P3, P4, P5} \<Longrightarrow> Badge ((ProcRec s) P\<^sub>A) \<Longrightarrow> isReq m \<Longrightarrow>  Network s m s' \<Longrightarrow> pc s' = P5 \<Longrightarrow>
         (EP(CSpace (TCB ((ProcRec s') P\<^sub>A)))) = (EP(CSpace (TCB ((ProcRec s') P\<^sub>N)))) "
  apply(simp add: Network_def)
  apply(case_tac "pc s = P1", simp_all)
  apply(case_tac "pc s = P2", simp_all)
  by auto

lemma EP_Integrity_Prover: "pc s = P2 \<Longrightarrow> BadgeCap P\<^sub>A \<in> (Caps (CSpace (TCB ((ProcRec s) P\<^sub>N)))) \<Longrightarrow> Prover s s' \<Longrightarrow> pc s' = P4 \<Longrightarrow>
         (EP(CSpace (TCB ((ProcRec s') P\<^sub>A)))) = (EP(CSpace (TCB ((ProcRec s') P\<^sub>N)))) "
  apply(simp add: Prover_def)
  apply (case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  done

lemma TInit_Integrity:
  assumes "Prover s  s'"
  and "P_attest_prop s"
  shows "TInit s' = TInit s"
  using assms
  apply(simp add: Prover_def Key_AC_def P_attest_prop_def)
  apply(case_tac "pc s")
  apply simp_all
  apply(case_tac "BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))")
      apply simp_all
    apply(case_tac "getMTime (ep s) < TInit s")
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  apply(case_tac "getMTime (ep s) < TInit s",simp_all)
   apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem (ProcRec s P\<^sub>A)) *
                snd (Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))")
  apply simp_all
  done

lemma Key_Integrity:
  assumes "Prover s  s'"
  and "P_attest_prop s"
  shows "Key s' = Key s"
  using assms
  apply(simp add: Prover_def Key_AC_def P_attest_prop_def)
  apply(cases "pc s", simp_all)
    apply(case_tac " BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))")
     apply simp_all
    apply(case_tac " getMTime (ep s) < TInit s")
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  apply(case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
  apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem (ProcRec s P\<^sub>A)) *
                snd (Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))")
   apply simp_all
  done

lemma Mem_Integrity_Prover:
  assumes "Prover s s'"
  and "P_attest_prop s"
  shows "Mem ((ProcRec s') P\<^sub>A) = Mem ((ProcRec s) P\<^sub>A)"
  using assms
  apply(simp add: Prover_def Key_AC_def P_attest_prop_def)
  apply(cases "pc s", simp_all)
     apply(case_tac " BadgeCap P\<^sub>A \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>N)))", simp_all)
  apply (case_tac "isReq
        (EP (CSpace
              (TCB (ProcRec s
    P\<^sub>N))))", simp_all)
   apply(case_tac "getMTime (ep s) < TInit s", simp_all)
  apply(case_tac "getFMac (ep s) \<noteq>
       (SOME n.
           Suc 0 \<le> n \<and>
           n \<le> getMTime (ep s) *
                fst (Mem (ProcRec s P\<^sub>A)) *
                snd (Mem (ProcRec s P\<^sub>A)) *
                P\<^sub>A *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A) *
                (getMTime (ep s) *
                 fst (Mem (ProcRec s P\<^sub>A)) *
                 snd (Mem (ProcRec s P\<^sub>A)) *
                 P\<^sub>A))", simp_all)
  done

lemma Mem_Integrity_Network:
  assumes "Network s m s'"
 shows "Mem ((ProcRec s') P\<^sub>A) = Mem ((ProcRec s) P\<^sub>A)"
  using assms
  apply(simp add: Setup_def P_attest_prop_def Prover_def Network_def Mem_AC_def)
  apply(case_tac "pc s", simp_all)
  apply(case_tac "BadgeCap P\<^sub>N \<in> Caps (CSpace (TCB (ProcRec s P\<^sub>A)))", simp_all)
  done

end


(*  Title:      HOL/Auth/n_g2kAbsAfter_lemma_inv__7_on_rules.thy
    Author:     Yongjian Li and Kaiqiang Duan, State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
    Copyright    2016 State Key Lab of Computer Science, Institute of Software, Chinese Academy of Sciences
*)

header{*The n_g2kAbsAfter Protocol Case Study*}

theory n_g2kAbsAfter_lemma_inv__7_on_rules imports n_g2kAbsAfter_lemma_on_inv__7
begin
section{*All lemmas on causal relation between inv__7*}
lemma lemma_inv__7_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(f=inv__7  )"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> d. d\<le>N\<and>r=n_n_Store_i1  d)\<or>
    (\<exists> d. d\<le>N\<and>r=n_n_AStore_i1  d)\<or>
    (r=n_n_SendReqS_j1  )\<or>
    (r=n_n_SendReqEI_i1  )\<or>
    (r=n_n_SendReqES_i1  )\<or>
    (r=n_n_RecvReq_i1  )\<or>
    (r=n_n_SendInvE_i1  )\<or>
    (r=n_n_SendInvS_i1  )\<or>
    (r=n_n_SendInvAck_i1  )\<or>
    (r=n_n_RecvInvAck_i1  )\<or>
    (r=n_n_SendGntS_i1  )\<or>
    (r=n_n_SendGntE_i1  )\<or>
    (r=n_n_RecvGntS_i1  )\<or>
    (r=n_n_RecvGntE_i1  )\<or>
    (r=n_n_ASendReqIS_j1  )\<or>
    (r=n_n_ASendReqSE_j1  )\<or>
    (r=n_n_ASendReqEI_i1  )\<or>
    (r=n_n_ASendReqES_i1  )\<or>
    (r=n_n_SendReqEE_i1  )\<or>
    (r=n_n_ARecvReq_i1  )\<or>
    (r=n_n_ASendInvE_i1  )\<or>
    (r=n_n_ASendInvS_i1  )\<or>
    (r=n_n_ASendInvAck_i1  )\<or>
    (r=n_n_ARecvInvAck_i1  )\<or>
    (r=n_n_ASendGntS_i1  )\<or>
    (r=n_n_ASendGntE_i1  )\<or>
    (r=n_n_ARecvGntS_i1  )\<or>
    (r=n_n_ARecvGntE_i1  )"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> d. d\<le>N\<and>r=n_n_Store_i1  d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_Store_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(\<exists> d. d\<le>N\<and>r=n_n_AStore_i1  d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_AStore_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqS_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqS_j1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqEI_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqEI_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqES_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqES_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_RecvReq_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvReq_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvE_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvS_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendInvAck_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_RecvInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvInvAck_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendGntS_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendGntE_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_RecvGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvGntS_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_RecvGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_RecvGntE_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqIS_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqIS_j1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqSE_j1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqSE_j1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqEI_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqEI_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendReqES_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendReqES_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_SendReqEE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_SendReqEE_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvReq_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvReq_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvE_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvS_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendInvAck_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvInvAck_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvInvAck_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendGntS_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ASendGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ASendGntE_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvGntS_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvGntS_i1Vsinv__7) done
    }

    moreover {
      assume d1: "(r=n_n_ARecvGntE_i1  )"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_n_ARecvGntE_i1Vsinv__7) done
    }

  ultimately show "invHoldForRule s f r (invariants N)"
  by satx
qed

end


theory func_cor_OSMboxPend
  imports rg_cond_post (* func_cor_lemma*)
begin

lemma OSMboxPend_pre_stable:" stable (OSMboxPend_pre t) (OSMboxPend_rely t) "
  by(simp add:OSMboxPend_pre_def OSMboxPend_rely_def stable_def gvars_conf_stable_def gvars_conf_def)

lemma OSMboxPend_post_stable:" stable (OSMboxPend_post t) (OSMboxPend_rely t) "
  by(simp add:OSMboxPend_post_def OSMboxPend_rely_def stable_def gvars_conf_stable_def gvars_conf_def)

lemma OSMboxPend_pre_stable_pre1_to_pre2_1:" stable (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>) (OSMboxPend_rely t)"
  by(simp add:OSMboxPend_pre_def OSMboxPend_rely_def stable_def gvars_conf_stable_def gvars_conf_def)

lemma OSMboxPend_pre_stable_pre1_to_pre2_2:" stable (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace>) (OSMboxPend_rely t)"
  apply(rule stable_int2)
   apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_1)
  apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
  apply auto
  done

lemma OSMboxPend_pre_stable_pre2_to_pre3:"stable (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>endt t = NULL\<rbrace>) (OSMboxPend_rely t)"
  apply(rule stable_int2)
   apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_2)
 apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
  apply auto
  done

lemma OSMboxPend_pre_stable_pre4_to_pre5:" stable (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace>) (OSMboxPend_rely t)"
 apply(rule stable_int2)
   apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_2)
 apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
  apply auto
  done

lemma OSMboxPend_pre_stable_pre5_to_pre6:" stable (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> \<inter> \<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace>) (OSMboxPend_rely t)"
apply(rule stable_int2)
   apply(simp add:OSMboxPend_pre_stable_pre4_to_pre5)
 apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
  apply auto
  done

abbreviation " precond1 t pevent timeout \<equiv> OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>"
abbreviation " precond2 t pevent timeout \<equiv> precond1 t pevent timeout \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> "
abbreviation " precond3 t pevent timeout \<equiv> precond2 t pevent timeout \<inter> \<lbrace>\<acute>endt t = NULL\<rbrace> "
abbreviation " precond4 t pevent timeout \<equiv> precond2 t pevent timeout "
abbreviation " precond5 t pevent timeout \<equiv> precond4 t pevent timeout \<inter>\<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> "
abbreviation " precond6 t pevent timeout \<equiv> precond5 t pevent timeout \<inter>\<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace> "
abbreviation " precond7 t pevent timeout \<equiv> precond1 t pevent timeout"
abbreviation " precond8 t pevent timeout \<equiv> OSMboxPend_post t"

lemma precond1_to_precond2 :"  \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN \<acute>tmout := \<acute>tmout(t := timeout)
           END) sat\<^sub>p [OSMboxPend_pre t \<inter>
                       \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace>]"
   apply(rule Await)
               apply(simp add: OSMboxPend_pre_stable_pre1_to_pre2_1)
              apply(simp add: OSMboxPend_pre_stable_pre1_to_pre2_2)
             apply auto
             apply(rule Basic)apply auto
       apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
               apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def) apply auto
              apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma precond2_to_precond3:"
    \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN \<acute>endt := \<acute>endt(t := NULL)
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter>
                       \<lbrace>\<acute>tmout t =
                        timeout\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>endt t = NULL\<rbrace>]"
            apply(rule Await)
  apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_2)
  apply(simp add:OSMboxPend_pre_stable_pre2_to_pre3)
            apply auto
            apply(rule Basic)
 apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
               apply auto
             apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma precond3_to_precond4:"OK < timeout \<Longrightarrow>
    \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN Cond UNIV (\<acute>endt := \<acute>endt(t := \<acute>tick + nat timeout)) SKIP
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter>
                       \<lbrace>\<acute>endt t = NULL\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace>] "
apply(rule Await)
             apply(simp add:OSMboxPend_pre_stable_pre2_to_pre3)
            apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_2)
  apply auto
           apply(rule Cond)
              apply(simp add:stable_id2)
  apply(rule Basic)
 apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
               apply auto
             apply(simp add:stable_id2)
            apply(simp add:stable_id2)
  apply(simp add:Emptyprecond)
  done

lemma precond3_to_precond4_timout_less_OK:" \<not> OK < timeout \<Longrightarrow>
    \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN Cond {} (\<acute>endt := \<acute>endt(t := \<acute>tick)) SKIP
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter>
                       \<lbrace>\<acute>endt t = NULL\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace>] "
apply(rule Await)
             apply(simp add:OSMboxPend_pre_stable_pre2_to_pre3)
            apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_2)
  apply auto
           apply(rule Cond)
              apply(simp add:stable_id2)
  apply(rule Basic)
 apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
               apply auto
             apply(simp add:stable_id2)
   apply(simp add:stable_id2)

  apply(simp add:Skip_def) apply(rule Basic)
     apply auto
    apply(simp add:OSMboxPend_pre_def OSMboxPend_guar_def)
   apply(simp add:stable_def)
  apply(simp add:stable_def)
  done

lemma precond4_to_precond5:"
    \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN \<acute>ret := \<acute>ret(t := ETIMEOUT)
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter>
                       \<lbrace>\<acute>tmout t =
                        timeout\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace>] "

         apply(rule Await)
           apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_2)
          apply(simp add:OSMboxPend_pre_stable_pre4_to_pre5)
         apply auto
         apply(rule Basic)
           apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
               apply auto
             apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma precond5_to_precond6:"
    \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN \<acute>statPend := \<acute>statPend(t := OS_STAT_PEND_OK)
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter>
                       \<lbrace>\<acute>ret t =
                        ETIMEOUT\<rbrace>, OSMboxPend_rely
                                    t, OSMboxPend_guar
                                        t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> \<inter> \<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace>] "

   apply(rule Await)
          apply(simp add:OSMboxPend_pre_stable_pre4_to_pre5)
 apply(simp add:OSMboxPend_pre_stable_pre5_to_pre6)
         apply auto
         apply(rule Basic)
           apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
               apply auto
             apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma test:"
         \<turnstile>\<^sub>I (W\<acute>get_msg := \<acute>get_msg(t := msgPtr (\<acute>OSMailbox_info pevent));; \<acute>ret := \<acute>ret(t := OK);;
                AWAIT \<acute>cur = Some t THEN \<acute>OSMailbox_info := \<acute>OSMailbox_info(pevent := msgPtr_update Map.empty (\<acute>OSMailbox_info pevent))
                END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> \<inter> \<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace> \<inter>
                            \<lbrace>\<acute>cur = Some t\<rbrace> \<inter>
                            {V} \<inter>
                            - \<lbrace>pevent \<notin> \<acute>OSMailBoxs\<rbrace> \<inter>
                            \<lbrace>\<exists>y. msgPtr (\<acute>OSMailbox_info pevent) =
                                 Some y\<rbrace>, {(s, t). s = t}, UNIV, \<lbrace>\<acute>(Pair V) \<in> OSMboxPend_guar t\<rbrace> \<inter> (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>)]
"
  apply(rule Seq [where mid =" let V2 = V\<lparr>get_msg := (get_msg V)(t := msgPtr (OSMailbox_info V pevent))\<rparr> in
                                                      precond1 t pevent timeout \<inter> {V2\<lparr>ret := (ret V2)(t := OK)\<rparr>} "])
   apply(rule Seq [where mid ="precond1 t pevent timeout \<inter> {V\<lparr>get_msg := (get_msg V)(t := msgPtr (OSMailbox_info V pevent))\<rparr>}"])
  apply auto
  apply(rule Basic)
       apply auto
 apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
      apply blast
     apply(simp add:stable_id2)
  apply(simp add:stable_id2)
   apply(rule Basic)
      apply auto
apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def)
     apply blast
  apply(simp add:stable_id2)
   apply(simp add:stable_id2)

  apply(rule Await)
  apply(simp add:stable_id2)
 apply(simp add:stable_id2)
  apply auto
  apply(rule Basic) apply auto
apply(simp add:OSMboxPend_guar_def OSMboxPend_pre_def gvars_conf_stable_def
             lvars_nochange_def gvars_conf_def inv_def inv_cur_def inv_thd_waitq_def gvars_nochange_def)
     apply auto
    apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def) apply auto
  apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma mid:"  cur V = Some t \<Longrightarrow>
    pevent \<in> OSMailBoxs V \<Longrightarrow>
    V \<in> OSMboxPend_pre t \<Longrightarrow>
    msgPtr (OSMailbox_info V pevent) = None \<Longrightarrow>  cur (V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                             OSMailbox_info := (OSMailbox_info V)
                               (pevent := OSMailbox_info V pevent
                                  \<lparr>wait_q :=
                                     wait_q (OSMailbox_info V pevent) @
                                     [t]\<rparr>)\<rparr> ) \<noteq> Some t \<Longrightarrow>   (*It is critical that the cur V'\<noteq> t anymore *)
    V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                             OSMailbox_info := (OSMailbox_info V)
                               (pevent := OSMailbox_info V pevent
                                  \<lparr>wait_q :=
                                     wait_q (OSMailbox_info V pevent) @
                                     [t]\<rparr>)\<rparr> \<in> OSMboxPend_pre t "
  apply(simp add:OSMboxPend_pre_def)
  done

lemma precond6_to_precond7_swap_ifbody_inv:"
          cur V = Some t \<Longrightarrow>
          pevent \<in> OSMailBoxs V \<Longrightarrow>
          statPend V t = OS_STAT_PEND_OK \<Longrightarrow>
          ret V t = ETIMEOUT \<Longrightarrow>
          timeout = tmout V t \<Longrightarrow>
          V \<in> OSMboxPend_pre t \<Longrightarrow>
          msgPtr (OSMailbox_info V pevent) = None \<Longrightarrow>
          (if ta = t then BLOCKED else thd_state V ta) = READY \<Longrightarrow>
          invariant.inv V \<Longrightarrow>
          invariant.inv
           (V\<lparr>OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>),
                cur := Some (SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)),
                thd_state :=
                  \<lambda>x. if x = (SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)) then RUNNING
                      else thd_state
                            (V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                                 OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>),
                                 cur := Some (SOME ta. (ta = t \<longrightarrow> BLOCKED = READY) \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY))\<rparr>)
                            x\<rparr>) "

  apply(subgoal_tac "thd_state V t = RUNNING")
    prefer 2 apply(simp add:inv_def inv_cur_def) apply auto[1]
  apply(subgoal_tac "ta \<noteq> t \<and> thd_state V ta = READY")
    prefer 2 apply auto[1] using Thread_State_Type.distinct(3) apply presburger
  apply(subgoal_tac "(SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)) \<noteq> t")
    prefer 2 using exE_some[where P="\<lambda>tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"
                    and c="SOME tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"] apply auto[1]
  apply(subgoal_tac "thd_state V (SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)) = READY")
    prefer 2 using exE_some[where P="\<lambda>tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"
                    and c="SOME tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"] apply auto[1]

  apply(simp add:inv_def)
  apply(rule conjI) apply(simp add:inv_cur_def) apply auto[1]
 apply(simp add:inv_thd_waitq_def)
    apply(rule conjI) apply auto[1]
    apply(rule conjI) apply auto[1]
    apply(rule conjI) apply (metis (no_types, lifting) Thread_State_Type.distinct(5) diff_is_0_eq'
                        less_Suc_eq less_Suc_eq_le nth_Cons_0 nth_append nth_mem)
  apply auto[1]

done

lemma precond6_to_precond7_swap_inv2:"
          cur V = Some t \<Longrightarrow>
          pevent \<in> OSMailBoxs V \<Longrightarrow>
          statPend V t = OS_STAT_PEND_OK \<Longrightarrow>
          ret V t = ETIMEOUT \<Longrightarrow>
          timeout = tmout V t \<Longrightarrow>
          invariant.inv V \<Longrightarrow>
          msgPtr (OSMailbox_info V pevent) = None \<Longrightarrow>
          (if ta = t then BLOCKED else thd_state V ta) = READY \<Longrightarrow>
          invariant.inv
           (V\<lparr>OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>),
                cur := Some (SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)),
                thd_state :=
                  \<lambda>x. if x = (SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)) then RUNNING
                      else thd_state
                            (V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                                 OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>),
                                 cur := Some (SOME ta. (ta = t \<longrightarrow> BLOCKED = READY) \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY))\<rparr>)
                            x\<rparr>)"

  apply(subgoal_tac "thd_state V t = RUNNING")
    prefer 2 apply(simp add:inv_def inv_cur_def) apply auto[1]
  apply(subgoal_tac "ta \<noteq> t \<and> thd_state V ta = READY")
    prefer 2 apply auto[1] using Thread_State_Type.distinct(3) apply presburger
  apply(subgoal_tac "(SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)) \<noteq> t")
    prefer 2 using exE_some[where P="\<lambda>tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"
                    and c="SOME tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"] apply auto[1]
  apply(subgoal_tac "thd_state V (SOME ta. ta \<noteq> t \<and> (ta \<noteq> t \<longrightarrow> thd_state V ta = READY)) = READY")
    prefer 2 using exE_some[where P="\<lambda>tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"
                    and c="SOME tb. tb \<noteq> t \<and> (tb \<noteq> t \<longrightarrow> thd_state V tb = READY)"] apply auto[1]

  apply(simp add:inv_def)
  apply(rule conjI) apply(simp add:inv_cur_def) apply auto[1]
 apply(simp add:inv_thd_waitq_def)
    apply(rule conjI) apply auto[1]
    apply(rule conjI) apply auto[1]
    apply(rule conjI) apply (metis (no_types, lifting) Thread_State_Type.distinct(5) diff_is_0_eq'
                        less_Suc_eq less_Suc_eq_le nth_Cons_0 nth_append nth_mem)
  apply auto[1]
  done

lemma precond6_to_precond7_swap_inv3:"
    cur V = Some t \<Longrightarrow>
    pevent \<in> OSMailBoxs V \<Longrightarrow>
    statPend V t = OS_STAT_PEND_OK \<Longrightarrow>
    ret V t = ETIMEOUT \<Longrightarrow>
    timeout = tmout V t \<Longrightarrow>
    V \<in> OSMboxPend_pre t \<Longrightarrow>
    msgPtr (OSMailbox_info V pevent) = None \<Longrightarrow>
    \<forall>ta. (if ta = t then BLOCKED else thd_state V ta) \<noteq> READY \<Longrightarrow>
    V \<noteq>
    cur_update Map.empty
     (V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
          OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>)\<rparr>) \<Longrightarrow>
    invariant.inv V \<Longrightarrow>
    invariant.inv
     (cur_update Map.empty
       (V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
            OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>)\<rparr>))  "

  apply(subgoal_tac "thd_state V t = RUNNING")
    prefer 2 apply(simp add:inv_def inv_cur_def) apply auto[1]

  apply(simp add:inv_def)
  apply(rule conjI) apply(simp add:inv_cur_def) apply auto[1]
  apply(simp add:inv_thd_waitq_def)
    apply(rule conjI) apply auto[1]
    apply(rule conjI) apply (metis Thread_State_Type.distinct(6) diff_is_0_eq' less_Suc_eq
                              less_Suc_eq_le nth_Cons_0 nth_append nth_mem)
    apply (metis (no_types, lifting) Thread_State_Type.distinct(5))

  done

lemma precond6_to_precond7_swap_inv4:"
    cur V = Some t \<Longrightarrow>
    pevent \<in> OSMailBoxs V \<Longrightarrow>
    statPend V t = OS_STAT_PEND_OK \<Longrightarrow>
    ret V t = ETIMEOUT \<Longrightarrow>
    timeout = tmout V t \<Longrightarrow>
    invariant.inv V \<Longrightarrow>
    msgPtr (OSMailbox_info V pevent) = None \<Longrightarrow>
    \<forall>ta. (if ta = t then BLOCKED else thd_state V ta) \<noteq> READY \<Longrightarrow>
    invariant.inv
     (cur_update Map.empty
       (V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
            OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>)\<rparr>)) "
  apply(subgoal_tac "thd_state V t = RUNNING")
    prefer 2 apply(simp add:inv_def inv_cur_def) apply auto[1]

  apply(simp add:inv_def)
  apply(rule conjI) apply(simp add:inv_cur_def) apply auto[1]
  apply(simp add:inv_thd_waitq_def)
    apply(rule conjI) apply auto[1]
    apply(rule conjI) apply (metis Thread_State_Type.distinct(6) diff_is_0_eq' less_Suc_eq
                              less_Suc_eq_le nth_Cons_0 nth_append nth_mem)
  apply (metis (no_types, lifting) Thread_State_Type.distinct(5))
  done

(*lemma key is the essential part in proof *)
lemma key:"
         \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN
                Await UNIV
                 (\<acute>thd_state := \<acute>thd_state(the \<acute>cur := BLOCKED);;
                  \<acute>OSMailbox_info := \<acute>OSMailbox_info(pevent := \<acute>OSMailbox_info pevent\<lparr>wait_q := wait_q (\<acute>OSMailbox_info pevent) @ [the \<acute>cur]\<rparr>);;
                  swap)
                END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> \<inter> \<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace> \<inter>
                            \<lbrace>\<acute>cur = Some t\<rbrace> \<inter>
                            {V} \<inter>
                            - \<lbrace>pevent \<notin> \<acute>OSMailBoxs\<rbrace> \<inter>
                            - \<lbrace>\<exists>y. msgPtr (\<acute>OSMailbox_info pevent) =
                                   Some y\<rbrace>, {(s, t). s = t}, UNIV, \<lbrace>\<acute>(Pair V) \<in> OSMboxPend_guar t\<rbrace> \<inter> (OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>)]"
  apply(rule Await)
    apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  apply auto
  apply(rule Await)
  apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  apply clarify
  apply(case_tac "OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> \<inter> \<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace> \<inter>
                           \<lbrace>\<acute>cur = Some t\<rbrace> \<inter>
                           {V} \<inter>
                           - \<lbrace>pevent \<notin> \<acute>OSMailBoxs\<rbrace> \<inter>
                           - \<lbrace>\<exists>y. msgPtr (\<acute>OSMailbox_info pevent) = Some y\<rbrace> \<inter>
                           \<lbrace>\<acute>cur = Some t\<rbrace> \<inter>
                           {Va} \<inter>
                           UNIV \<inter>
                           {Vaa} = {}")
   apply(simp add:Emptyprecond)
  apply auto
  apply(rule Seq [where mid ="let V2 = V\<lparr>thd_state := (thd_state V)(the (cur V) := BLOCKED)\<rparr> in {V2\<lparr>OSMailbox_info := (OSMailbox_info V2)(pevent := (OSMailbox_info V2 pevent)\<lparr>wait_q := (wait_q (OSMailbox_info V2 pevent))@ [the (cur V2)]\<rparr>)\<rparr>}"])
 apply(rule Seq [where mid ="{V\<lparr>thd_state := (thd_state V)(the (cur V) := BLOCKED)\<rparr>}"])apply auto
    apply(rule Basic)
       apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)
       apply auto
     apply(simp add:stable_id2)
    apply(simp add:stable_id2)

   apply(rule Basic)
      apply auto
  apply(simp add:stable_id2)
   apply(simp add:stable_id2)

  apply(simp add:swap_def)
  apply(rule Cond)
     apply(simp add:stable_id2)
  apply(case_tac "{V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                                    OSMailbox_info := (OSMailbox_info V)(pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>)\<rparr>} \<inter>
                               \<lbrace>\<exists>t. \<acute>thd_state t = READY\<rbrace>={} ")
     apply simp using Emptyprecond apply metis
      apply(rule subst[where t="{V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                                OSMailbox_info := (OSMailbox_info V)
                                  (pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>)\<rparr>} \<inter>
                          \<lbrace>\<exists>t. \<acute>thd_state t = READY\<rbrace>" and s="{V\<lparr>thd_state := (thd_state V)(t := BLOCKED),
                                OSMailbox_info := (OSMailbox_info V)
                                  (pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [t]\<rparr>)\<rparr>}"])
  apply simp

 apply(rule Seq [where mid ="let V3 = V\<lparr>thd_state := (thd_state V)(the (cur V) := BLOCKED),
                                    OSMailbox_info := (OSMailbox_info V)
                                      (pevent := OSMailbox_info V pevent\<lparr>wait_q := wait_q (OSMailbox_info V pevent) @ [the (cur V)]\<rparr>)\<rparr>
  in {V3\<lparr>cur := Some (SOME t. (thd_state V3) t = READY) \<rparr>}"])

     apply(rule Basic) (*\<acute>cur :=  Some (SOME t. \<acute>thd_state t =  READY)*)
        apply auto[1] apply simp apply(simp add:stable_def) apply(simp add:stable_def)
 apply(rule Basic) (* swap: \<acute>thd_state := \<acute>thd_state(the \<acute>cur := RUNNING) *)
        apply auto[1]
        apply(simp add:OSMboxPend_guar_def)  (* \<in> Mem_pool_alloc_guar t *)
        apply(rule disjI1)
        apply(rule conjI)
          apply(simp add:gvars_conf_stable_def gvars_conf_def)
        apply(rule conjI)
  apply auto
       apply(simp add:precond6_to_precond7_swap_ifbody_inv)
  apply(simp add:lvars_nochange_def)
     apply(simp add:OSMboxPend_pre_def)
     apply(simp add:precond6_to_precond7_swap_inv2)
    apply(simp add:stable_def)
  apply(simp add:stable_def)
  apply(rule Basic)
     apply auto
     apply(simp add:OSMboxPend_guar_def) (*\<in>OSMboxPend_guar *)
     apply auto
       apply(simp add:gvars_conf_stable_def  gvars_conf_def)
  apply(simp add:precond6_to_precond7_swap_inv3)
     apply(simp add:lvars_nochange_def)
    apply(simp add:OSMboxPend_pre_def)
    apply(simp add:precond6_to_precond7_swap_inv4)
   apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma precond6_to_precond7:"
    \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN
           IF pevent \<notin> \<acute>OSMailBoxs THEN \<acute>ret := \<acute>ret(t := ETIMEOUT)
           ELSE IF \<exists>y. msgPtr (\<acute>OSMailbox_info pevent) = Some y
                THEN \<acute>get_msg := \<acute>get_msg(t := msgPtr (\<acute>OSMailbox_info pevent));; \<acute>ret := \<acute>ret(t := OK);;
                     AWAIT \<acute>cur = Some t THEN \<acute>OSMailbox_info := \<acute>OSMailbox_info(pevent := msgPtr_update Map.empty (\<acute>OSMailbox_info pevent)) END
                ELSE AWAIT \<acute>cur = Some t THEN
                     Await UNIV
                      (\<acute>thd_state := \<acute>thd_state(the \<acute>cur := BLOCKED);;
                       \<acute>OSMailbox_info := \<acute>OSMailbox_info(pevent := \<acute>OSMailbox_info pevent\<lparr>wait_q := wait_q (\<acute>OSMailbox_info pevent) @ [the \<acute>cur]\<rparr>);;
                       swap)
                     END
                FI
           FI
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>tmout t = timeout\<rbrace> \<inter> \<lbrace>\<acute>ret t = ETIMEOUT\<rbrace> \<inter>
                       \<lbrace>\<acute>statPend t = OS_STAT_PEND_OK\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>] "

 apply(rule Await)           (*pre6_to_pre7 *)
         apply(simp add:OSMboxPend_pre_stable_pre5_to_pre6)
        apply(simp add:OSMboxPend_pre_stable_pre1_to_pre2_1)
       apply auto
       apply(rule Cond)
          apply(simp add:stable_id2)
         apply(rule Basic)
            apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
            apply auto
         apply(simp add:stable_id2)
  apply(simp add:stable_id2)
       apply (rule Cond)
          apply(simp add:stable_id2) apply auto
        apply(simp add:test)
  apply(simp add:key)
  done

lemma precond7_to_precond8:"
 \<turnstile>\<^sub>I (W AWAIT \<acute>cur = Some t THEN Await UNIV (IF \<acute>statPend t = OS_STAT_PEND_OK THEN \<acute>ret := \<acute>ret(t := OK) ELSE \<acute>ret := \<acute>ret(t := OS_ERR_TIMEOUT)FI)
           END) sat\<^sub>p [OSMboxPend_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace>, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_post t] "
  apply(rule Await)
        apply(simp add: OSMboxPend_pre_stable_pre1_to_pre2_1)
  apply(simp add: OSMboxPend_post_stable)
      apply auto
      apply(rule Await)
        apply(simp add:stable_def)
  apply(simp add:stable_def)
      apply auto
  apply(rule Cond)
  apply(simp add:stable_def)
         apply auto

       apply(rule Basic)
          apply auto
          apply(simp add:OSMboxPend_guar_def)apply auto
            apply(simp add:gvars_conf_stable_def gvars_conf_def)
           apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
           apply auto
  apply(simp add:lvars_nochange_def)
  apply(simp add:OSMboxPend_post_def)
  apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
  apply auto
              apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)apply auto
             apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)
            apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)
           apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)
  apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)
  apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)
        apply(simp add:stable_def)
        apply(simp add:OSMboxPend_pre_def inv_def inv_cur_def inv_thd_waitq_def)apply auto
       apply(simp add:stable_def)

  apply(rule Basic)
  apply(simp add:OSMboxPend_pre_def OSMboxPend_post_def inv_def inv_cur_def inv_thd_waitq_def)
         apply auto
    apply(simp add:OSMboxPend_guar_def)apply auto
  apply(simp add:gvars_conf_stable_def gvars_conf_def)
           apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
  apply(simp add:lvars_nochange_def)
       apply(simp add:stable_def)
  apply(simp add:OSMboxPend_pre_def OSMboxPend_post_def inv_def inv_cur_def inv_thd_waitq_def)
       apply auto
  apply(simp add:stable_def)
  done

lemma precond8_to_post:" \<turnstile>\<^sub>I (W IF \<acute>tmout t \<noteq>
              ETIMEOUT THEN AWAIT \<acute>cur = Some t THEN \<acute>tmout := \<acute>tmout(t := int (\<acute>endt t) - int \<acute>tick) END;;
                            IF \<acute>tmout t
                               < OK THEN AWAIT \<acute>cur = Some t THEN \<acute>ret := \<acute>ret(t := OS_ERR_TIMEOUT)
                                         END FI FI) sat\<^sub>p [OSMboxPend_post t, OSMboxPend_rely t, OSMboxPend_guar t, OSMboxPend_post t] "

  apply(rule Cond)
  apply(simp add:OSMboxPend_post_stable)
       apply(rule Seq [where mid ="precond8 t pevent timeout"])

        apply(rule Await)
 apply(rule stable_int2)
   apply(simp add:OSMboxPend_post_stable)
  apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
  apply auto
  apply(simp add:OSMboxPend_post_stable)

        apply(rule Basic)
             apply(simp add:OSMboxPend_guar_def)apply auto
            apply(simp add:gvars_conf_stable_def gvars_conf_def)
            apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
            apply auto
           apply(simp add:lvars_nochange_def)
          apply(simp add:OSMboxPend_post_def)
  apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
          apply auto
         apply(simp add:stable_def)
        apply(simp add:stable_def)

  apply(rule Cond)
  apply(simp add:OSMboxPend_post_stable)
  apply(rule Await)
apply(rule stable_int2)
   apply(simp add:OSMboxPend_post_stable)
  apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
           apply auto
          apply(simp add:OSMboxPend_post_stable)

  apply(rule Basic)
             apply(simp add:OSMboxPend_guar_def)apply auto
            apply(simp add:gvars_conf_stable_def gvars_conf_def)
            apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
            apply auto
           apply(simp add:lvars_nochange_def)
          apply(simp add:OSMboxPend_post_def)
  apply(simp add:inv_def inv_cur_def inv_thd_waitq_def)
          apply auto
         apply(simp add:stable_def)
         apply(simp add:stable_def)

        apply(simp add:Skip_def)apply(rule Basic)
           apply auto
          apply(simp add:OSMboxPend_guar_def)
 apply(rule stable_int2)
   apply(simp add:OSMboxPend_post_stable)
  apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
  apply(simp add:lvars_nochange_def)
        apply(simp add:OSMboxPend_post_stable)
       apply(simp add:OSMboxPend_guar_def)

apply(simp add:Skip_def)apply(rule Basic)
           apply auto
          apply(simp add:OSMboxPend_guar_def)
 apply(rule stable_int2)
   apply(simp add:OSMboxPend_post_stable)
  apply(simp add:stable_def) apply clarify
  apply(simp add:OSMboxPend_rely_def gvars_conf_stable_def gvars_conf_def)
  apply(simp add:stable_def OSMboxPend_rely_def lvars_nochange_rel_def gvars_conf_stable_def)
       apply(simp add:lvars_nochange_def)
       apply auto

      apply(simp add:OSMboxPend_post_stable)
     apply(simp add:OSMboxPend_guar_def)
  done

lemma OSMboxPend_satRG: "\<Gamma> (OSMboxPend t pevent timeout) \<turnstile> OSMboxPend_RGCond t"
  apply (simp add:Evt_sat_RG_def)
  apply (simp add:OSMboxPend_def OSMboxPend_RGCond_def)
  apply(simp add:body_def Pre\<^sub>f_def Post\<^sub>f_def guard_def
                 Rely\<^sub>f_def Guar\<^sub>f_def getrgformula_def)
  apply(unfold stm_def)
    apply auto  apply (rule BasicEvt)
     apply(simp add:body_def guard_def)
      apply(rule Seq [where mid ="precond8 t pevent timeout"])
       apply(rule Seq [where mid ="precond7 t pevent timeout"])
        apply(rule Seq [where mid ="precond6 t pevent timeout"])
         apply(rule Seq [where mid ="precond5 t pevent timeout"])
          apply(rule Seq [where mid ="precond4 t pevent timeout"])
           apply(rule Seq [where mid ="precond3 t pevent timeout"])
            apply(rule Seq [where mid ="precond2 t pevent timeout"])

             apply(simp add:precond1_to_precond2)
            apply(simp add:precond2_to_precond3)
          apply(simp add:precond3_to_precond4)
         apply(simp add:precond4_to_precond5)
        apply(simp add:precond5_to_precond6)
       apply(simp add:precond6_to_precond7)
      apply(simp add:precond7_to_precond8)
     apply(simp add:precond8_to_post)
  apply(simp add:OSMboxPend_pre_stable)
   apply(simp add:OSMboxPend_guar_def)

    apply (rule BasicEvt)
     apply(simp add:body_def guard_def)
      apply(rule Seq [where mid ="precond8 t pevent timeout"])
       apply(rule Seq [where mid ="precond7 t pevent timeout"])
        apply(rule Seq [where mid ="precond6 t pevent timeout"])
         apply(rule Seq [where mid ="precond5 t pevent timeout"])
          apply(rule Seq [where mid ="precond4 t pevent timeout"])
           apply(rule Seq [where mid ="precond3 t pevent timeout"])
            apply(rule Seq [where mid ="precond2 t pevent timeout"])

           apply(simp add:precond1_to_precond2)
            apply(simp add:precond2_to_precond3)
         apply(simp add:precond3_to_precond4_timout_less_OK)
         apply(simp add:precond4_to_precond5)
        apply(simp add:precond5_to_precond6)
       apply(simp add:precond6_to_precond7)
      apply(simp add:precond7_to_precond8)
     apply(simp add:precond8_to_post)
  apply(simp add:OSMboxPend_pre_stable)
  apply(simp add:OSMboxPend_guar_def)

  done

end