(*  Title:      HOL/Auth/n_german_lemma_inv__24_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_german Protocol Case Study*}*)

theory n_german_lemma_inv__24_on_rules imports n_german_lemma_on_inv__24
begin
section{*All lemmas on causal relation between inv__24*}
lemma lemma_inv__24_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv2. p__Inv2\<le>N\<and>f=inv__24  p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqE__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqE__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_StoreVsinv__24) done
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

end


(*File: ContextVS.thy*)
(*Authors: Lennart Beringer and Martin Hofmann, LMU Munich 2008*)
theory ContextVS imports VS begin
subsection{*Contextual closure*}

text{*\label{sec:contextVS}We show that the notion of security is closed w.r.t.~low
attacking contexts, i.e.~contextual programs into which a
secure program can be substituted and which itself employs only
\emph{obviously} low variables.*}

text{*Contexts are {\bf IMP} programs with (multiple) designated holes
(represented by constructor $\mathit{Ctxt\_Here}$).*}

datatype CtxtProg =
  Ctxt_Hole
| Ctxt_Skip
| Ctxt_Assign Var Expr
| Ctxt_Comp CtxtProg CtxtProg
| Ctxt_If BExpr CtxtProg CtxtProg
| Ctxt_While BExpr CtxtProg
| Ctxt_Call

text{*We let $C$, $D$ range over contextual programs. The substitution
operation is defined by structural recursion.*}

primrec Fill::"CtxtProg \<Rightarrow> IMP \<Rightarrow> IMP"
where
"Fill Ctxt_Hole c = c" |
"Fill Ctxt_Skip c = Skip" |
"Fill (Ctxt_Assign x e) c = Assign x e" |
"Fill (Ctxt_Comp C1 C2) c = Comp (Fill C1 c) (Fill C2 c)" |
"Fill (Ctxt_If b C1 C2) c = Iff b (Fill C1 c) (Fill C2 c)" |
"Fill (Ctxt_While b C) c = While b (Fill C c)" |
"Fill Ctxt_Call c = Call"

text{*Equally obvious are the definitions of the (syntactically)
mentioned variables of arithmetic and boolean expressions.*}

primrec EVars::"Expr \<Rightarrow> Var set"
where
"EVars (varE x) = {x}" |
"EVars (valE v) = {}" |
"EVars (opE f e1 e2) = EVars e1 \<union> EVars e2"

lemma low_Eval[rule_format]:
 "(\<forall> x . x \<in> EVars e \<longrightarrow> CONTEXT x = low) \<longrightarrow>
  (\<forall> s t . s \<approx> t \<longrightarrow> evalE e s = evalE e t)"
(*<*)
apply (induct e)
apply (simp add: twiddle_def)
apply simp
apply clarsimp
done
(*>*)

primrec BVars::"BExpr \<Rightarrow> Var set"
where
"BVars (compB f e1 e2) = EVars e1 \<union> EVars e2"

lemma low_EvalB[rule_format]:
 "(\<forall> x . x \<in> BVars b \<longrightarrow> CONTEXT x = low) \<longrightarrow>
  (\<forall> s t . s \<approx> t \<longrightarrow> evalB b s = evalB b t)"
(*<*)
apply (induct b)
apply (rename_tac Expr1 Expr2)
apply clarsimp
apply (subgoal_tac "evalE Expr1 s = evalE Expr1 t")
prefer 2 apply (rule low_Eval) apply fast apply assumption
apply (subgoal_tac "evalE Expr2 s = evalE Expr2 t")
prefer 2 apply (rule low_Eval) apply fast apply assumption
apply simp
done
(*>*)

text{*The variables possibly read from during the evaluation of $c$
are denoted by $\mathit{Vars\; c}$. Note that in the clause for
assignments the variable that is assigned to is not included in the
set.*}

primrec Vars::"IMP \<Rightarrow> Var set"
where
"Vars Skip = {}" |
"Vars (Assign x e) = EVars e" |
"Vars (Comp c d) = Vars c \<union> Vars d" |
"Vars (While b c) = BVars b \<union> Vars c" |
"Vars (Iff b c d) = BVars b \<union> Vars c \<union> Vars d" |
"Vars Call = {}"

text{*For contexts, we define when a set $X$ of variables is an upper
bound for the variables read from.*}

primrec CtxtVars::"Var set \<Rightarrow> CtxtProg \<Rightarrow> bool"
where
"CtxtVars X Ctxt_Hole = True" |
"CtxtVars X Ctxt_Skip = True" |
"CtxtVars X (Ctxt_Assign x e) = (EVars e \<subseteq> X)" |
"CtxtVars X (Ctxt_Comp C1 C2) = (CtxtVars X C1 \<and> CtxtVars X C2)" |
"CtxtVars X (Ctxt_If b C1 C2) = (BVars b \<subseteq> X \<and> CtxtVars X C1
                                             \<and>  CtxtVars X C2)" |
"CtxtVars X (Ctxt_While b C) = (BVars b \<subseteq> X \<and> CtxtVars X C)" |
"CtxtVars X Ctxt_Call = True"

(*<*)
lemma Secure_comp: "\<lbrakk>secure c1; secure c2\<rbrakk> \<Longrightarrow> secure (Comp c1 c2)"
apply (unfold secure_def)
apply (rule, rule, rule, rule)
apply (rule, rule, rule)
apply (unfold Sem_def)
apply (erule exE)+
apply (erule Sem_eval_cases)
apply (erule Sem_eval_cases)
apply (erule_tac x=s in allE, rotate_tac -1)
apply (erule_tac x=t in allE, rotate_tac -1)
apply (erule_tac x=r in allE, rotate_tac -1)
apply (erule_tac x=ra in allE)
apply (erule impE, assumption)
apply (erule impE, rule, assumption)
apply (erule impE, rule, assumption)
apply (erule_tac x=r in allE, rotate_tac -1)
apply (erule_tac x=ra in allE, rotate_tac -1)
apply (erule_tac x=ss in allE, rotate_tac -1)
apply (erule_tac x=tt in allE)
apply (erule impE, assumption)
apply (erule impE, rule, assumption)
apply (erule impE, rule, assumption)
apply assumption
done

lemma Secure_iff:
" \<lbrakk>secure c1; secure c2;
   \<forall> s ss. s \<approx> ss \<longrightarrow> evalB b s = evalB b ss\<rbrakk>
  \<Longrightarrow> secure (Iff b c1 c2)"
apply (unfold secure_def)
apply (rule, rule, rule, rule)
apply (rule, rule, rule)
apply (unfold Sem_def)
apply (erule exE)+
apply (erule_tac x=s in allE, erule_tac x=t in allE, erule impE, assumption)
apply (erule Sem_eval_cases)
apply (erule Sem_eval_cases)
apply (erule_tac x=s in allE, rotate_tac -1)
apply (erule_tac x=t in allE, rotate_tac -1)
apply (erule_tac x=ss in allE, rotate_tac -1)
apply (erule_tac x=tt in allE)
apply (erule impE, assumption)
apply (erule impE, rule, assumption)
apply (erule impE, rule, assumption)
apply assumption
apply fast
apply (erule Sem_eval_cases)
apply fast
apply (erule thin_rl)
apply (erule_tac x=s in allE, rotate_tac -1)
apply (erule_tac x=t in allE, rotate_tac -1)
apply (erule_tac x=ss in allE, rotate_tac -1)
apply (erule_tac x=tt in allE)
apply (erule impE, assumption)
apply (erule impE, rule, assumption)
apply (erule impE, rule, assumption)
apply assumption
done

lemma secure_while_aux[rule_format]:
"\<forall> n m . n \<le> k \<longrightarrow> m \<le> k \<longrightarrow>
  (\<forall> s t ss tt . (s , While b c \<rightarrow>\<^sub>n  ss) \<longrightarrow>
                 (t , While b c \<rightarrow>\<^sub>m  tt) \<longrightarrow>
                 secure c \<longrightarrow>
                 (\<forall>s ss. s \<approx> ss \<longrightarrow> evalB b s = evalB b ss) \<longrightarrow>
                 s \<approx> t \<longrightarrow> ss \<approx> tt)"
apply (induct k)
apply clarsimp apply (drule Sem_no_zero_height_derivs, clarsimp)
apply clarsimp
  apply (subgoal_tac "evalB b s = evalB b t")
  prefer 2 apply (erule thin_rl, fast)
  apply (erule Sem_eval_cases)
  prefer 2 apply (erule Sem_eval_cases, simp, simp)
  apply (erule Sem_eval_cases) prefer 2 apply simp
    apply clarsimp
    apply (subgoal_tac "r \<approx> ra", clarsimp)
    apply (erule thin_rl, unfold secure_def Sem_def) apply fast
done

lemma Secure_while:
" \<lbrakk>secure c;
   \<forall> s ss. s \<approx> ss \<longrightarrow> evalB b s = evalB b ss\<rbrakk>
  \<Longrightarrow> secure (While b c)"
apply (simp (no_asm_simp) add: secure_def)
apply (rule, rule, rule, rule)
apply (rule, rule, rule)
apply (unfold Sem_def) apply (erule exE)+
apply (rule secure_while_aux)
prefer 3 apply assumption
prefer 6 apply assumption
prefer 3 apply assumption
prefer 3 apply assumption
prefer 3 apply fast
apply (subgoal_tac "n \<le> n + na", assumption) apply (simp, simp)
done
(*>*)

text{*A constant representing the procedure body with holes.*}

consts Ctxt_Body::CtxtProg

text{*The following predicate expresses that all variables read from
by a command $c$ are contained in the set $X$ of low variables.*}

definition LOW::"Var set \<Rightarrow> CtxtProg \<Rightarrow> bool"
where "LOW X C = (CtxtVars X C \<and> (\<forall> x . x : X \<longrightarrow> CONTEXT x = low))"

(*<*)
lemma secureI_secureFillI_Aux[rule_format]:
"\<forall> n m . n \<le> k \<longrightarrow> m \<le> k \<longrightarrow>
       (\<forall> C d s t ss tt X . (s , d \<rightarrow>\<^sub>n t) \<longrightarrow>
                          (ss , d \<rightarrow>\<^sub>m  tt) \<longrightarrow>
                          s \<approx> ss \<longrightarrow>
                          d = Fill C c \<longrightarrow>
                          LOW X C \<longrightarrow>
                          LOW X Ctxt_Body \<longrightarrow>
                          body = Fill Ctxt_Body c \<longrightarrow> secure c \<longrightarrow> t \<approx> tt)"
apply (induct k)
apply clarsimp apply (drule Sem_no_zero_height_derivs, clarsimp)
apply clarsimp
apply (case_tac C)
(*Ctxt_Hole*)
apply clarsimp defer 1
(*Ctxt_Skip*)
apply clarsimp
  apply (erule Sem_eval_cases)+ apply clarsimp
(*Ctxt_Assign*)
apply clarsimp
  apply (erule thin_rl)
  apply (erule Sem_eval_cases)+ apply clarsimp
  apply (simp add: update_def LOW_def twiddle_def) apply clarsimp apply (rule low_Eval)
      apply fast
    apply (simp add: twiddle_def)
(*Ctxt_Comp*)
apply clarsimp apply (erule Sem_eval_cases) apply (erule Sem_eval_cases) apply clarsimp
  apply (subgoal_tac "r \<approx> ra")
  prefer 2 apply (simp add: LOW_def)
           apply (erule_tac x=na in allE, clarsimp)
  apply (simp add: LOW_def)
           apply (erule_tac x=ma in allE, clarsimp)
(*Ctxt_If*)
apply (rename_tac BExpr u v)
apply clarsimp
  apply (subgoal_tac "evalB BExpr s = evalB BExpr ss")
  prefer 2 apply (erule thin_rl, case_tac BExpr, clarsimp)
           apply (rename_tac Expr1 Expr2)
           apply (subgoal_tac "evalE Expr1 s = evalE Expr1 ss", clarsimp)
           apply (subgoal_tac "evalE Expr2 s = evalE Expr2 ss", clarsimp)
           apply (rule low_Eval) apply (simp add: LOW_def) apply fast apply clarsimp
           apply (rule low_Eval) apply (simp add: LOW_def) apply fast apply clarsimp
  apply (erule Sem_eval_cases) apply (erule Sem_eval_cases) prefer 2 apply clarsimp apply clarsimp
  apply (simp add: LOW_def)
           apply (erule_tac x=na in allE, clarsimp)
  apply (erule Sem_eval_cases) apply clarsimp
  apply (simp add: LOW_def)
           apply (erule_tac x=na in allE, clarsimp)
(*Ctxt_While*)
apply (rename_tac BExpr CtxtProg)
apply clarsimp
  apply (subgoal_tac "evalB BExpr s = evalB BExpr ss")
  prefer 2 apply (erule thin_rl, case_tac BExpr, clarsimp)
           apply (rename_tac Expr1 Expr2)
           apply (subgoal_tac "evalE Expr1 s = evalE Expr1 ss", clarsimp)
           apply (subgoal_tac "evalE Expr2 s = evalE Expr2 ss", clarsimp)
           apply (rule low_Eval) apply (simp add: LOW_def) apply fast apply clarsimp
           apply (rule low_Eval) apply (simp add: LOW_def) apply fast apply clarsimp
  apply (erule Sem_eval_cases) apply (erule Sem_eval_cases) prefer 2 apply clarsimp
  apply (subgoal_tac "r \<approx> ra")
  prefer 2
    apply (simp add: LOW_def)
           apply (erule_tac x=na in allE, clarsimp)
  apply (erule_tac x=ma in allE, clarsimp)
           apply (erule_tac x=mb in allE, clarsimp)
           apply (erule_tac x="Ctxt_While BExpr CtxtProg" in allE)
           apply (erule_tac x="While BExpr (Fill CtxtProg c)" in allE, clarsimp)

  apply (erule Sem_eval_cases) apply clarsimp
  apply clarsimp
(*Ctxt_Call*)
apply clarsimp apply (erule Sem_eval_cases) apply (erule Sem_eval_cases)
  apply (erule_tac x=na in allE, clarsimp)

(*The deferred goal from Ctxt\_Hole*)
  apply (unfold secure_def Sem_def)
  apply (erule thin_rl) apply fast
done
(*>*)

text{*By induction on the maximal height of the operational judgement
(hidden in the definition of $\mathit{secure}$) we can prove that the
security of $c$ implies that of $\mathit{Fill}\ C\ c$, provided that
the context and the procedure-context satisfy the $\mathit{LOW}$
predicate for some $X$, and that the "real" body is obtained by
substituting $c$ into the procedure context.*}

lemma secureI_secureFillI:
  "\<lbrakk>secure c; LOW X C; LOW X Ctxt_Body; body = Fill Ctxt_Body c\<rbrakk>
  \<Longrightarrow> secure (Fill C c)"
(*<*)
apply (simp (no_asm_simp) add: secure_def Sem_def)
apply clarsimp
apply (rule secureI_secureFillI_Aux)
prefer 3 apply assumption
prefer 4 apply assumption
prefer 3 apply assumption
apply (subgoal_tac "n \<le> n+na", assumption)
apply (erule thin_rl, simp)
apply (erule thin_rl, simp)
apply (erule thin_rl,fastforce)
apply assumption
apply assumption
apply assumption
apply assumption
done
(*>*)

text{*Consequently, a (low) variable representing the result of
the attacking context does not leak any unwanted information.*}

consts res::Var

theorem
  "\<lbrakk> secure c; LOW X C;  LOW X Ctxt_Body; s \<approx> ss; s,(Fill C c)\<Down>t;
     ss,(Fill C c)\<Down>tt; body = Fill Ctxt_Body c; CONTEXT res = low\<rbrakk>
  \<Longrightarrow> t res = tt res"
(*<*)
apply (drule secureI_secureFillI) apply assumption apply assumption apply assumption
apply (unfold secure_def)
apply (erule_tac x=s in allE, erule_tac x=ss in allE)
apply (erule_tac x=t in allE, erule_tac x=tt in allE, clarsimp)
apply (simp add: twiddle_def)
done
(*>*)
text{*End of theory ContextVS*}
end


section \<open>Graph Representation\<close>
subsection \<open>IR Graph Nodes\<close>

theory IRNodes
  imports
    Values
begin

text \<open>
The GraalVM IR is represented using a graph data structure.
Here we define the nodes that are contained within the graph.
Each node represents a Node subclass in the GraalVM compiler,
the node classes have annotated fields to indicate input and successor edges.

We represent these classes with each IRNode constructor explicitly labelling
a reference to the node IDs that it stores as inputs and successors.

The inputs\_of and successors\_of functions partition those labelled references
into input edges and successor edges of a node.

To identify each Node, we use a simple natural number index.
Zero is always the start node in a graph.
For human readability, within nodes we write
INPUT (or special case thereof) instead of ID for input edges, and
SUCC instead of ID for control-flow successor edges.
Optional edges are handled as "INPUT option" etc.
\<close>

type_synonym ID = "nat"
type_synonym INPUT = "ID"   (* InputType.Value is the default *)
type_synonym INPUT_ASSOC = "ID" (* InputType.Association *)
type_synonym INPUT_STATE = "ID" (* InputType.State *)
type_synonym INPUT_GUARD = "ID" (* InputType.Guard *)
type_synonym INPUT_COND = "ID"  (* InputType.Condition *)
type_synonym INPUT_EXT = "ID"  (* InputType.Extension *)
type_synonym SUCC = "ID"

(* nodeout: isabelle-datatypes *)
datatype (discs_sels) IRNode =
  AbsNode (ir_value: "INPUT")
  | AddNode (ir_x: "INPUT") (ir_y: "INPUT")
  | AndNode (ir_x: "INPUT") (ir_y: "INPUT")
  | BeginNode (ir_next: "SUCC")
  | BytecodeExceptionNode (ir_arguments: "INPUT list") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | ConditionalNode (ir_condition: "INPUT_COND") (ir_trueValue: "INPUT") (ir_falseValue: "INPUT")
  | ConstantNode (ir_const: Value)
  | DynamicNewArrayNode (ir_elementType: "INPUT") (ir_length: "INPUT") (ir_voidClass_opt: "INPUT option") (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | EndNode
  | ExceptionObjectNode (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | FrameState (ir_monitorIds: "INPUT_ASSOC list") (ir_outerFrameState_opt: "INPUT_STATE option") (ir_values_opt: "INPUT list option") (ir_virtualObjectMappings_opt: "INPUT_STATE list option")
  | IfNode (ir_condition: "INPUT_COND") (ir_trueSuccessor: "SUCC") (ir_falseSuccessor: "SUCC")
  | IntegerBelowNode (ir_x: "INPUT") (ir_y: "INPUT")
  | IntegerEqualsNode (ir_x: "INPUT") (ir_y: "INPUT")
  | IntegerLessThanNode (ir_x: "INPUT") (ir_y: "INPUT")
  | InvokeNode (ir_nid: ID) (ir_callTarget: "INPUT_EXT") (ir_classInit_opt: "INPUT option") (ir_stateDuring_opt: "INPUT_STATE option") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | InvokeWithExceptionNode (ir_nid: ID) (ir_callTarget: "INPUT_EXT") (ir_classInit_opt: "INPUT option") (ir_stateDuring_opt: "INPUT_STATE option") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC") (ir_exceptionEdge: "SUCC")
  | IsNullNode (ir_value: "INPUT")
  | KillingBeginNode (ir_next: "SUCC")
  | LeftShiftNode (ir_x: "INPUT") (ir_y: "INPUT")
  | LoadFieldNode (ir_nid: ID) (ir_field: string) (ir_object_opt: "INPUT option") (ir_next: "SUCC")
  | LogicNegationNode (ir_value: "INPUT_COND")
  | LoopBeginNode (ir_ends: "INPUT_ASSOC list") (ir_overflowGuard_opt: "INPUT_GUARD option") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | LoopEndNode (ir_loopBegin: "INPUT_ASSOC")
  | LoopExitNode (ir_loopBegin: "INPUT_ASSOC") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | MergeNode (ir_ends: "INPUT_ASSOC list") (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | MethodCallTargetNode (ir_targetMethod: string) (ir_arguments: "INPUT list")
  | MulNode (ir_x: "INPUT") (ir_y: "INPUT")
  | NarrowNode (ir_inputBits: nat) (ir_resultBits: nat) (ir_value: "INPUT")
  | NegateNode (ir_value: "INPUT")
  | NewArrayNode (ir_length: "INPUT") (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | NewInstanceNode (ir_nid: ID) (ir_instanceClass: string) (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | NotNode (ir_value: "INPUT")
  | OrNode (ir_x: "INPUT") (ir_y: "INPUT")
  | ParameterNode (ir_index: nat)
  | PiNode (ir_object: "INPUT") (ir_guard_opt: "INPUT_GUARD option")
  | ReturnNode (ir_result_opt: "INPUT option") (ir_memoryMap_opt: "INPUT_EXT option")
  | RightShiftNode (ir_x: "INPUT") (ir_y: "INPUT")
  | ShortCircuitOrNode (ir_x: "INPUT_COND") (ir_y: "INPUT_COND")
  | SignExtendNode (ir_inputBits: nat) (ir_resultBits: nat) (ir_value: "INPUT")
  | SignedDivNode (ir_nid: ID) (ir_x: "INPUT") (ir_y: "INPUT") (ir_zeroCheck_opt: "INPUT_GUARD option") (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | SignedRemNode (ir_nid: ID) (ir_x: "INPUT") (ir_y: "INPUT") (ir_zeroCheck_opt: "INPUT_GUARD option") (ir_stateBefore_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | StartNode (ir_stateAfter_opt: "INPUT_STATE option") (ir_next: "SUCC")
  | StoreFieldNode (ir_nid: ID) (ir_field: string) (ir_value: "INPUT") (ir_stateAfter_opt: "INPUT_STATE option") (ir_object_opt: "INPUT option") (ir_next: "SUCC")
  | SubNode (ir_x: "INPUT") (ir_y: "INPUT")
  | UnsignedRightShiftNode (ir_x: "INPUT") (ir_y: "INPUT")
  | UnwindNode (ir_exception: "INPUT")
  | ValuePhiNode (ir_nid: ID) (ir_values: "INPUT list") (ir_merge: "INPUT_ASSOC")
  | ValueProxyNode (ir_value: "INPUT") (ir_loopExit: "INPUT_ASSOC")
  | XorNode (ir_x: "INPUT") (ir_y: "INPUT")
  | ZeroExtendNode (ir_inputBits: nat) (ir_resultBits: nat) (ir_value: "INPUT")
  | NoNode
(* nodeout *)

  (* Manually added *)
  | RefNode (ir_ref:ID)

(* Surely this must exist already?  I cannot find it in option or list theory. *)
fun opt_to_list :: "'a option \<Rightarrow> 'a list" where
  "opt_to_list None = []" |
  "opt_to_list (Some v) = [v]"

fun opt_list_to_list :: "'a list option \<Rightarrow> 'a list" where
  "opt_list_to_list None = []" |
  "opt_list_to_list (Some x) = x"

text \<open>
The following functions, inputs\_of and successors\_of, are automatically generated
from the GraalVM compiler.
Their purpose is to partition the node edges into input or successor edges.
\<close>
(* nodeout: isabelle-inputs *)
fun inputs_of :: "IRNode \<Rightarrow> ID list" where
  inputs_of_AbsNode:
  "inputs_of (AbsNode value) = [value]" |
  inputs_of_AddNode:
  "inputs_of (AddNode x y) = [x, y]" |
  inputs_of_AndNode:
  "inputs_of (AndNode x y) = [x, y]" |
  inputs_of_BeginNode:
  "inputs_of (BeginNode next) = []" |
  inputs_of_BytecodeExceptionNode:
  "inputs_of (BytecodeExceptionNode arguments stateAfter next) = arguments @ (opt_to_list stateAfter)" |
  inputs_of_ConditionalNode:
  "inputs_of (ConditionalNode condition trueValue falseValue) = [condition, trueValue, falseValue]" |
  inputs_of_ConstantNode:
  "inputs_of (ConstantNode const) = []" |
  inputs_of_DynamicNewArrayNode:
  "inputs_of (DynamicNewArrayNode elementType length0 voidClass stateBefore next) = [elementType, length0] @ (opt_to_list voidClass) @ (opt_to_list stateBefore)" |
  inputs_of_EndNode:
  "inputs_of (EndNode) = []" |
  inputs_of_ExceptionObjectNode:
  "inputs_of (ExceptionObjectNode stateAfter next) = (opt_to_list stateAfter)" |
  inputs_of_FrameState:
  "inputs_of (FrameState monitorIds outerFrameState values virtualObjectMappings) = monitorIds @ (opt_to_list outerFrameState) @ (opt_list_to_list values) @ (opt_list_to_list virtualObjectMappings)" |
  inputs_of_IfNode:
  "inputs_of (IfNode condition trueSuccessor falseSuccessor) = [condition]" |
  inputs_of_IntegerBelowNode:
  "inputs_of (IntegerBelowNode x y) = [x, y]" |
  inputs_of_IntegerEqualsNode:
  "inputs_of (IntegerEqualsNode x y) = [x, y]" |
  inputs_of_IntegerLessThanNode:
  "inputs_of (IntegerLessThanNode x y) = [x, y]" |
  inputs_of_InvokeNode:
  "inputs_of (InvokeNode nid0 callTarget classInit stateDuring stateAfter next) = callTarget # (opt_to_list classInit) @ (opt_to_list stateDuring) @ (opt_to_list stateAfter)" |
  inputs_of_InvokeWithExceptionNode:
  "inputs_of (InvokeWithExceptionNode nid0 callTarget classInit stateDuring stateAfter next exceptionEdge) = callTarget # (opt_to_list classInit) @ (opt_to_list stateDuring) @ (opt_to_list stateAfter)" |
  inputs_of_IsNullNode:
  "inputs_of (IsNullNode value) = [value]" |
  inputs_of_KillingBeginNode:
  "inputs_of (KillingBeginNode next) = []" |
  inputs_of_LeftShiftNode:
  "inputs_of (LeftShiftNode x y) = [x, y]" |
  inputs_of_LoadFieldNode:
  "inputs_of (LoadFieldNode nid0 field object next) = (opt_to_list object)" |
  inputs_of_LogicNegationNode:
  "inputs_of (LogicNegationNode value) = [value]" |
  inputs_of_LoopBeginNode:
  "inputs_of (LoopBeginNode ends overflowGuard stateAfter next) = ends @ (opt_to_list overflowGuard) @ (opt_to_list stateAfter)" |
  inputs_of_LoopEndNode:
  "inputs_of (LoopEndNode loopBegin) = [loopBegin]" |
  inputs_of_LoopExitNode:
  "inputs_of (LoopExitNode loopBegin stateAfter next) = loopBegin # (opt_to_list stateAfter)" |
  inputs_of_MergeNode:
  "inputs_of (MergeNode ends stateAfter next) = ends @ (opt_to_list stateAfter)" |
  inputs_of_MethodCallTargetNode:
  "inputs_of (MethodCallTargetNode targetMethod arguments) = arguments" |
  inputs_of_MulNode:
  "inputs_of (MulNode x y) = [x, y]" |
  inputs_of_NarrowNode:
  "inputs_of (NarrowNode inputBits resultBits value) = [value]" |
  inputs_of_NegateNode:
  "inputs_of (NegateNode value) = [value]" |
  inputs_of_NewArrayNode:
  "inputs_of (NewArrayNode length0 stateBefore next) = length0 # (opt_to_list stateBefore)" |
  inputs_of_NewInstanceNode:
  "inputs_of (NewInstanceNode nid0 instanceClass stateBefore next) = (opt_to_list stateBefore)" |
  inputs_of_NotNode:
  "inputs_of (NotNode value) = [value]" |
  inputs_of_OrNode:
  "inputs_of (OrNode x y) = [x, y]" |
  inputs_of_ParameterNode:
  "inputs_of (ParameterNode index) = []" |
  inputs_of_PiNode:
  "inputs_of (PiNode object guard) = object # (opt_to_list guard)" |
  inputs_of_ReturnNode:
  "inputs_of (ReturnNode result memoryMap) = (opt_to_list result) @ (opt_to_list memoryMap)" |
  inputs_of_RightShiftNode:
  "inputs_of (RightShiftNode x y) = [x, y]" |
  inputs_of_ShortCircuitOrNode:
  "inputs_of (ShortCircuitOrNode x y) = [x, y]" |
  inputs_of_SignExtendNode:
  "inputs_of (SignExtendNode inputBits resultBits value) = [value]" |
  inputs_of_SignedDivNode:
  "inputs_of (SignedDivNode nid0 x y zeroCheck stateBefore next) = [x, y] @ (opt_to_list zeroCheck) @ (opt_to_list stateBefore)" |
  inputs_of_SignedRemNode:
  "inputs_of (SignedRemNode nid0 x y zeroCheck stateBefore next) = [x, y] @ (opt_to_list zeroCheck) @ (opt_to_list stateBefore)" |
  inputs_of_StartNode:
  "inputs_of (StartNode stateAfter next) = (opt_to_list stateAfter)" |
  inputs_of_StoreFieldNode:
  "inputs_of (StoreFieldNode nid0 field value stateAfter object next) = value # (opt_to_list stateAfter) @ (opt_to_list object)" |
  inputs_of_SubNode:
  "inputs_of (SubNode x y) = [x, y]" |
  inputs_of_UnsignedRightShiftNode:
  "inputs_of (UnsignedRightShiftNode x y) = [x, y]" |
  inputs_of_UnwindNode:
  "inputs_of (UnwindNode exception) = [exception]" |
  inputs_of_ValuePhiNode:
  "inputs_of (ValuePhiNode nid0 values merge) = merge # values" |
  inputs_of_ValueProxyNode:
  "inputs_of (ValueProxyNode value loopExit) = [value, loopExit]" |
  inputs_of_XorNode:
  "inputs_of (XorNode x y) = [x, y]" |
  inputs_of_ZeroExtendNode:
  "inputs_of (ZeroExtendNode inputBits resultBits value) = [value]" |
  inputs_of_NoNode: "inputs_of (NoNode) = []" |
(* nodeout *)

  inputs_of_RefNode: "inputs_of (RefNode ref) = [ref]"

(* nodeout: isabelle-succs *)
fun successors_of :: "IRNode \<Rightarrow> ID list" where
  successors_of_AbsNode:
  "successors_of (AbsNode value) = []" |
  successors_of_AddNode:
  "successors_of (AddNode x y) = []" |
  successors_of_AndNode:
  "successors_of (AndNode x y) = []" |
  successors_of_BeginNode:
  "successors_of (BeginNode next) = [next]" |
  successors_of_BytecodeExceptionNode:
  "successors_of (BytecodeExceptionNode arguments stateAfter next) = [next]" |
  successors_of_ConditionalNode:
  "successors_of (ConditionalNode condition trueValue falseValue) = []" |
  successors_of_ConstantNode:
  "successors_of (ConstantNode const) = []" |
  successors_of_DynamicNewArrayNode:
  "successors_of (DynamicNewArrayNode elementType length0 voidClass stateBefore next) = [next]" |
  successors_of_EndNode:
  "successors_of (EndNode) = []" |
  successors_of_ExceptionObjectNode:
  "successors_of (ExceptionObjectNode stateAfter next) = [next]" |
  successors_of_FrameState:
  "successors_of (FrameState monitorIds outerFrameState values virtualObjectMappings) = []" |
  successors_of_IfNode:
  "successors_of (IfNode condition trueSuccessor falseSuccessor) = [trueSuccessor, falseSuccessor]" |
  successors_of_IntegerBelowNode:
  "successors_of (IntegerBelowNode x y) = []" |
  successors_of_IntegerEqualsNode:
  "successors_of (IntegerEqualsNode x y) = []" |
  successors_of_IntegerLessThanNode:
  "successors_of (IntegerLessThanNode x y) = []" |
  successors_of_InvokeNode:
  "successors_of (InvokeNode nid0 callTarget classInit stateDuring stateAfter next) = [next]" |
  successors_of_InvokeWithExceptionNode:
  "successors_of (InvokeWithExceptionNode nid0 callTarget classInit stateDuring stateAfter next exceptionEdge) = [next, exceptionEdge]" |
  successors_of_IsNullNode:
  "successors_of (IsNullNode value) = []" |
  successors_of_KillingBeginNode:
  "successors_of (KillingBeginNode next) = [next]" |
  successors_of_LeftShiftNode:
  "successors_of (LeftShiftNode x y) = []" |
  successors_of_LoadFieldNode:
  "successors_of (LoadFieldNode nid0 field object next) = [next]" |
  successors_of_LogicNegationNode:
  "successors_of (LogicNegationNode value) = []" |
  successors_of_LoopBeginNode:
  "successors_of (LoopBeginNode ends overflowGuard stateAfter next) = [next]" |
  successors_of_LoopEndNode:
  "successors_of (LoopEndNode loopBegin) = []" |
  successors_of_LoopExitNode:
  "successors_of (LoopExitNode loopBegin stateAfter next) = [next]" |
  successors_of_MergeNode:
  "successors_of (MergeNode ends stateAfter next) = [next]" |
  successors_of_MethodCallTargetNode:
  "successors_of (MethodCallTargetNode targetMethod arguments) = []" |
  successors_of_MulNode:
  "successors_of (MulNode x y) = []" |
  successors_of_NarrowNode:
  "successors_of (NarrowNode inputBits resultBits value) = []" |
  successors_of_NegateNode:
  "successors_of (NegateNode value) = []" |
  successors_of_NewArrayNode:
  "successors_of (NewArrayNode length0 stateBefore next) = [next]" |
  successors_of_NewInstanceNode:
  "successors_of (NewInstanceNode nid0 instanceClass stateBefore next) = [next]" |
  successors_of_NotNode:
  "successors_of (NotNode value) = []" |
  successors_of_OrNode:
  "successors_of (OrNode x y) = []" |
  successors_of_ParameterNode:
  "successors_of (ParameterNode index) = []" |
  successors_of_PiNode:
  "successors_of (PiNode object guard) = []" |
  successors_of_ReturnNode:
  "successors_of (ReturnNode result memoryMap) = []" |
  successors_of_RightShiftNode:
  "successors_of (RightShiftNode x y) = []" |
  successors_of_ShortCircuitOrNode:
  "successors_of (ShortCircuitOrNode x y) = []" |
  successors_of_SignExtendNode:
  "successors_of (SignExtendNode inputBits resultBits value) = []" |
  successors_of_SignedDivNode:
  "successors_of (SignedDivNode nid0 x y zeroCheck stateBefore next) = [next]" |
  successors_of_SignedRemNode:
  "successors_of (SignedRemNode nid0 x y zeroCheck stateBefore next) = [next]" |
  successors_of_StartNode:
  "successors_of (StartNode stateAfter next) = [next]" |
  successors_of_StoreFieldNode:
  "successors_of (StoreFieldNode nid0 field value stateAfter object next) = [next]" |
  successors_of_SubNode:
  "successors_of (SubNode x y) = []" |
  successors_of_UnsignedRightShiftNode:
  "successors_of (UnsignedRightShiftNode x y) = []" |
  successors_of_UnwindNode:
  "successors_of (UnwindNode exception) = []" |
  successors_of_ValuePhiNode:
  "successors_of (ValuePhiNode nid0 values merge) = []" |
  successors_of_ValueProxyNode:
  "successors_of (ValueProxyNode value loopExit) = []" |
  successors_of_XorNode:
  "successors_of (XorNode x y) = []" |
  successors_of_ZeroExtendNode:
  "successors_of (ZeroExtendNode inputBits resultBits value) = []" |
  successors_of_NoNode: "successors_of (NoNode) = []" |
(* nodeout *)

  successors_of_RefNode: "successors_of (RefNode ref) = [ref]"

lemma "inputs_of (FrameState x (Some y) (Some z) None) = x @ [y] @ z"
  unfolding inputs_of_FrameState by simp
lemma "successors_of (FrameState x (Some y) (Some z) None) = []"
  unfolding inputs_of_FrameState by simp

lemma "inputs_of (IfNode c t f) = [c]"
  unfolding inputs_of_IfNode by simp
lemma "successors_of (IfNode c t f) = [t, f]"
  unfolding successors_of_IfNode by simp

lemma "inputs_of (EndNode) = [] \<and> successors_of (EndNode) = []"
  unfolding inputs_of_EndNode successors_of_EndNode by simp

end


theory RoboChart_Examples
  imports "RoboChart.RoboChart" "HOL.Transcendental"
begin

text \<open> We can't use braces, because they are both designated as major keywords in Isar. \<close>

interface itf1 =
  clock
    myclk
  var
    x :: int = "1"
    y :: int = 1
  const
    z :: int
  var
    a :: "string list"
  opdecl
    myop(x :: int, y :: nat) [terminates]
  opdecl
    myop2(v :: string)
  broadcast event ev1 :: "int \<times> string" ev2 :: "bool"

context itf1
begin

end

robotic_platform rp1 =
  var x :: int
  requires f

(* Linking this to the Circus semantics should be two step:
   outer-syntax transitions with uninterpreted terms -->
   inner-syntax transitions with compiled actions and expressions (+ alphabet / channel context) -->
   state machine via semantic function *)

stm stm1 =
  var
    x :: int = "1"
    y :: int = 1
  initial s1
  final s2
  final s3
  state s4
  [ initial i1
    state s5 [state s6]
    transition t1 [frm i1 to s5]
  ]

context stm1
begin

ML \<open> Proof_Context.get_thms @{context} @{named_theorems sm_defs}\<close>

thm sm_defs

thm transitions

thm nodes

thm machine

term s1

term machine

thm machine_def

end

typedecl Intensity
typedecl Status
typedecl GasSensor

stm GasAnalysis =
  const thr :: Intensity
  var sts::Status gs::"GasSensor list"  ins::Intensity  anl::real
  event resume stop  turn::real  gas::"GasSensor list"
  initial InitState
  state NoGas
  state Reading
  final FinalState
  state Analysis
  state GasDetected
  transition t1 [frm InitState to NoGas]
  transition t2 [frm NoGas to Analysis]
  transition t3 [frm Analysis to NoGas]

context GasAnalysis
begin

thm transitions
thm nodes
thm machine

end

controller c1 =
  sref s1 = stm1
  connection stm1 on x to stm1 on x async
  connection stm1 on x to stm2 on y mult

module rpm1 =
  cref c1 = c1
  rref rp1 = rp1
  connection c1 on x to rp1 on x

operation op1(x :: int) =
  var y :: int
  precondition "x > 1"
  postcondition "y > x"
  terminates

stm s2 =
  var v1 :: int
  uses itf1
  initial i1
  final f
  var v2 :: real
  broadcast event e1 :: real e2 :: int e3 :: string
  state ms [entry "True \<and> False" exit "True"]
  transition t1 [frm i1 to act trigger "True" probability "0.5" condition "True \<and> False"]
  transition t2 [frm p1 to act trigger "False" probability "0.1" condition "False"]
  probabilistic p1
  event e4 :: string

controller c1 =
  sref s1 = stm1
  connection stm1 on x to stm1 on x async
  connection stm1 on x to stm2 on y

module rpm1 =
  cref ctrl_ref1 = c1
  rref rp1 = rp1
  connection c1 on x to rp1 on x

context s2
begin

thm machine_def
thm t1_def

end

func sqrt_alt(x :: real) :: real
  precondition "x \<ge> 0"
  postcondition "result \<ge> 0"
  postcondition "result\<^sup>2 = x"

lemma sqrt_alt: "x \<ge> 0 \<Longrightarrow> sqrt_alt x = sqrt x"
  by (auto simp add: sqrt_alt_def)

func f2(x :: int, y :: int) :: int
  precondition "x > y"
  postcondition "result = x + 1"

func f3(x :: int) :: int
  postcondition "result = x + 1"

lemma "f3 = (\<lambda> x \<bullet> x + 1)"
  by (simp add: f3_def pfun_spec_def)

end


(*  Title:      HOL/Auth/n_german_lemma_inv__42_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_german Protocol Case Study*}

theory n_german_lemma_inv__42_on_rules imports n_german_lemma_on_inv__42
begin
section{*All lemmas on causal relation between inv__42*}
lemma lemma_inv__42_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv4. p__Inv4\<le>N\<and>f=inv__42  p__Inv4)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> j. j\<le>N\<and>r=n_SendReqS  j)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqEI  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqES  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReq N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvE  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)\<or>
    (\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> j. j\<le>N\<and>r=n_SendReqS  j)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendReqSVsinv__42) done
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

end


(*  Title:      HOL/Auth/n_german_lemma_inv__29_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_german Protocol Case Study*}

theory n_german_lemma_inv__29_on_rules imports n_german_lemma_on_inv__29
begin
section{*All lemmas on causal relation between inv__29*}
lemma lemma_inv__29_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv4. p__Inv4\<le>N\<and>f=inv__29  p__Inv4)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> j. j\<le>N\<and>r=n_SendReqS  j)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqEI  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendReqES  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReq N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvE  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)\<or>
    (\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> j. j\<le>N\<and>r=n_SendReqS  j)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_SendReqSVsinv__29) done
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

end


theory func_cor_OSMboxAccept
  imports rg_cond
begin

lemma OSMboxAccept_stable_pevent :  "stable \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> (OSMboxAccept_rely t)"
  by (simp add: OSMboxAccept_rely_def gvars_conf_def gvars_conf_stable_def stable_def)

lemma OSMboxAccept_satRG_h1:"
   \<turnstile>\<^sub>I (W\<acute>get_msg := \<acute>get_msg(t := msgPtr (\<acute>OSMailbox_info pevent));;
               \<acute>OSMailbox_info := \<acute>OSMailbox_info
               (pevent :=
                  msgPtr_update Map.empty
                   (\<acute>OSMailbox_info
                     pevent))) sat\<^sub>p [OSMboxAccept_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>cur = Some t\<rbrace> \<inter>
                                      {V}, {(x, y). x = y}, UNIV, \<lbrace>\<acute>(Pair V) \<in> OSMboxAccept_guar t\<rbrace> \<inter> OSMboxAccept_post t]"

apply(case_tac "OSMboxAccept_pre t \<inter> \<lbrace>pevent \<in> \<acute>OSMailBoxs\<rbrace> \<inter> \<lbrace>\<acute>cur = Some t\<rbrace> \<inter>
                                      {V} = {}")
     apply(simp add:Emptyprecond)
  apply(rule Seq[where mid = "{V\<lparr>get_msg := (get_msg V)(t := msgPtr (OSMailbox_info V pevent))\<rparr>}"])
   apply(rule Basic)
      apply auto[1]
    apply(simp add:stable_id2)
    apply(simp add:stable_id2)
  apply (simp add: stable_id2)
  apply(rule Basic)
     apply(simp add:OSMboxAccept_pre_def OSMboxAccept_guar_def gvars_conf_stable_def gvars_conf_def)
     apply (simp add: OSMboxAccept_post_def lvars_nochange_def)
     apply (simp add:  inv_def inv_cur_def inv_OS_Mem_info_def inv_OS_Mem_info_mp_def inv_thd_waitq_def)
  apply auto[1]
    apply simp
  apply(simp add:stable_id2)
  apply(simp add:stable_id2)
  done

lemma OSMboxAccept_satRG: "\<Gamma> (OSMboxAccept t pevent) \<turnstile> OSMboxAccept_RGCond t"
  apply (simp add:Evt_sat_RG_def)
  apply (simp add:OSMboxAccept_def OSMboxAccept_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 (rule BasicEvt)
     apply(simp add:body_def guard_def)
  apply(rule Await)
      apply (metis OSMboxAccept_pre_stable inf_set_def stable_int2 OSMboxAccept_stable_pevent)
  apply (simp add: OSMboxAccept_post_stable)
    apply auto
         apply(rule Await)
    apply(simp add:stable_id2)
  apply(simp add:stable_id2)
    apply auto
    apply(case_tac "{V} \<inter> {Va}={}")
   apply auto
     apply(simp add:Emptyprecond)      (* satRG_h1*)
    apply(simp add:OSMboxAccept_satRG_h1)
   apply(simp add:OSMboxAccept_pre_stable)
  apply(simp add:OSMboxAccept_guar_def)
  done

end