           (*-------------------------------------------*
            |        CSP-Prover on Isabelle2005         |
            |                  March 2007               |
            |                                           |
            |        CSP-Prover on Isabelle2016         |
            |                    May 2016  (modified)   |
            |                                           |
            |        CSP-Prover on Isabelle2017         |
            |                  April 2018  (modified)   |
            |                                           |
            |        Yoshinao Isobe (AIST JAPAN)        |
            *-------------------------------------------*)

theory CSP_T_law_fix
imports CSP_T_law_fp
begin

(*  The following simplification rules are deleted in this theory file *)
(*  because they unexpectly rewrite UnionT and InterT.                 *)
(*                  Union (B ` A) = (UN x:A. B x)                      *)
(*                  Inter (B ` A) = (INT x:A. B x)                     *)

(*
declare Union_image_eq [simp del]
declare Inter_image_eq [simp del]
*)
(* no simp rules in Isabelle 2017
declare Sup_image_eq [simp del]
declare Inf_image_eq [simp del]
*)

definition
 FIXn :: "nat => ('p => ('p,'a) proc) => ('p => ('p,'a) proc)"
                                                      ("FIX[_] _" [0,1000] 55)
  where
  FIXn_def :  "FIX[n] Pf == ((Pf <<< )^^n) (%q. DIV)"

definition
  FIX  :: "(('p) => ('p,'a) proc) => ('p => ('p,'a) proc)"
                                                      ("FIX _" [1000] 55)
  where
  FIX_def : "FIX Pf == (%p. (!nat n .. ((FIX[n] Pf) p)))"

(* ----- test ----- *
consts
 FIXnrec :: "nat => ('p => ('p,'a) proc) => ('p => ('p,'a) proc)"
                                                      ("FIXrec[_] _" [0,1000] 55)
primrec
     "FIXrec[0] Pf = (%p. DIV)"
 "FIXrec[Suc n] Pf = (%p. (Pf p)<<(FIXrec[n] Pf))"

lemma FIXn_FIXnrec: "FIX[n] Pf = FIXrec[n] Pf"
apply (induct_tac n)
apply (simp_all add: FIXn_def)
done

 * ----- test ----- *)

(*-----------*
 |   noPN    |
 *-----------*)

lemma noPNfun_FIXn: "noPNfun (%p. (FIX[n] Pf)(p))"
apply (simp add: FIXn_def)
apply (induct_tac n)
apply (simp add: noPNfun_def)
apply (simp (no_asm) add: noPNfun_def)
apply (intro allI)
apply (simp add: Subst_procfun_prod_def)
apply (simp add: noPN_Subst_Pf)
done

lemma noPN_FIXn: "noPN ((FIX[n] Pf)p)"
apply (insert noPNfun_FIXn[of _ Pf])
apply (simp add: noPNfun_def)
done

lemma noPN_FIX: "noPN ((FIX Pf) p)"
apply (simp add: FIX_def)
apply (simp add: noPN_FIXn)
done

(*-----------*
 |    Bot    |
 *-----------*)

lemma traces_prod_Bot: "(%p. traces DIV M) = Bot"
apply (simp add: prod_Bot_def)
apply (simp add: fun_eq_iff)
apply (simp add: traces_iff)
apply (simp add: bottom_domT_def)
done

lemma semT_prod_Bot: "(%p. [[DIV]]T) = Bot"
by (simp add: semT_def semTf_def traces_prod_Bot)

(*-----------*
 |   FIX P   |
 *-----------*)

lemma traces_subst_Bot: "traces (P<<(%q. DIV)) M = (traces P) Bot"
apply (induct_tac P)
apply (simp_all add: traces_iff)
apply (simp add: prod_Bot_def)
apply (simp add: bottom_domT_def)
done

lemma traces_iteration_semTfun_Bot:
  "ALL p. traces (((Pf <<<) ^^ n) (%q. DIV) p) M = ([[Pf]]Tfun ^^ n) Bot p"
apply (simp add: semTfun_def)
apply (simp add: semTf_def)
apply (induct_tac n)

(* base *)
apply (simp_all add: traces_iff)
apply (simp add: prod_Bot_def)
apply (simp add: bottom_domT_def)

(* step *)
apply (simp add: Subst_procfun_prod_def)
apply (simp add: traces_subst)
done

lemma traces_FIX:
    "traces ((FIX Pf) p) M
     = UnionT {u. EX n. u = ([[Pf]]Tfun ^^ n) Bot p}"
apply (simp add: FIX_def FIXn_def)
apply (subgoal_tac "{u. EX n. u = ([[Pf]]Tfun ^^ n) Bot p} ~= {}")
apply (rule order_antisym)

 (* <= *)
 apply (rule)
 apply (simp add: in_traces)
 apply (erule disjE, simp)
 apply (elim conjE exE)
 apply (rule_tac x="traces (((Pf <<<) ^^ n) (%q. DIV) p) M" in exI)
 apply (simp)
 apply (rule_tac x="n" in exI)
 apply (simp add: traces_iteration_semTfun_Bot)

 (* => *)
 apply (rule)
 apply (simp add: in_traces)
 apply (rule disjI2)
 apply (elim conjE exE)
 apply (simp)
 apply (rule_tac x="na" in exI)
 apply (simp add: traces_iteration_semTfun_Bot)

by (auto)

(*** [[ ]]T ***)

lemma semT_FIX:
    "[[(FIX Pf) p]]T
     = UnionT {u. EX n. u = ([[Pf]]Tfun ^^ n) Bot p}"
apply (simp add: semT_def semTf_def)
apply (simp add: traces_FIX)
done

(*** FIX is LUB ***)

lemma semT_FIX_isLUB:
   "(%p. [[(FIX Pf) p]]T) isLUB {x. EX n. x = ([[Pf]]Tfun ^^ n) Bot}"
apply (simp add: prod_LUB_decompo)
apply (intro allI)
apply (simp add: proj_fun_def)
apply (simp add: image_def)
apply (simp add: semT_FIX)
apply (subgoal_tac
     "{y. EX x. (EX n. x = ([[Pf]]Tfun ^^ n) Bot) & y = x i} =
      {u. EX n. u = ([[Pf]]Tfun ^^ n) Bot i}")
apply (simp)
apply (rule UnionT_isLUB)
apply (auto)
done

lemma semT_FIX_LUB:
   "(%p. [[(FIX Pf) p]]T) = LUB {x. EX n. x = ([[Pf]]Tfun ^^ n) Bot}"
apply (rule sym)
apply (rule isLUB_LUB)
apply (simp add: semT_FIX_isLUB)
done

lemma semT_FIX_LFP:
   "(%p. [[(FIX Pf) p]]T) = LFP [[Pf]]Tfun"
apply (simp add: semT_FIX_LUB)
apply (simp add: Tarski_thm_LFP_LUB continuous_semTfun)
done

lemma semT_FIX_LFP_p:
   "[[(FIX Pf) p]]T = LFP [[Pf]]Tfun p"
apply (insert semT_FIX_LFP[of Pf])
apply (simp add: fun_eq_iff)
done

lemma semT_FIX_isLFP:
   "(%p. [[(FIX Pf) p]]T) isLFP [[Pf]]Tfun"
apply (simp add: semT_FIX_LFP)
apply (simp add: LFP_is Tarski_thm_EX continuous_semTfun)
done

lemma semT_FIX_LFP_fixed_point:
   "[[Pf]]Tfun (%p. [[(FIX Pf) p]]T) = (%p. [[(FIX Pf) p]]T)"
apply (insert semT_FIX_isLFP[of Pf])
apply (simp add: isLFP_def)
done

lemma semT_FIX_LFP_least:
   "ALL Tf. [[Pf]]Tfun Tf = Tf --> (%p. [[(FIX Pf) p]]T) <= Tf"
apply (insert semT_FIX_isLFP[of Pf])
apply (simp add: isLFP_def)
done

(*=======================================================*
 |                                                       |
 |                        CPO                            |
 |                                                       |
 *=======================================================*)

lemma cspT_FIX_cpo:
  "[| FPmode = CPOmode |
      FPmode = MIXmode ;
      Pf = PNfun |]
  ==> $p =T (FIX Pf)(p)"
apply (simp add: eqT_def)
apply (fold semT_def)
apply (simp add: semT_FIX_LFP_p)
apply (simp add: semT_LFP_cpo)
done

lemma cspT_FIX_cms:
  "[| FPmode = CMSmode ;
      Pf = PNfun ;
      guardedfun (Pf) |]
  ==> $p =T (FIX Pf)(p)"
apply (simp add: eqT_def)
apply (fold semT_def)
apply (simp add: semT_FIX_LFP_p)
apply (simp add: semT_guarded_LFP_UFP)
apply (simp add: semT_UFP_cms)
done

lemma cspT_FIX:
  "[| FPmode = CPOmode |
      FPmode = CMSmode & guardedfun (Pf) |
      FPmode = MIXmode ;
      Pf = PNfun |]
  ==> $p =T (FIX Pf)(p)"
apply (erule disjE)
apply (simp add: cspT_FIX_cpo)
apply (erule disjE)
apply (simp add: cspT_FIX_cms)
apply (simp add: cspT_FIX_cpo)
done

(*==============================================================*
 |                                                              |
 | replace process names by infinite repcicated internal choice |
 |                         rmPN   (FIX)                         |
 |                                                              |
 *==============================================================*)

primrec
   rmPN :: "('p,'a) proc => ('p,'a) proc"
where
  "rmPN(STOP)        = STOP"
 |"rmPN(SKIP)        = SKIP"
 |"rmPN(DIV)         = DIV"
 |"rmPN(a -> P)      = a -> (rmPN P)"
 |"rmPN(? :A -> Pf)  = ? a:A -> (rmPN (Pf a))"
 |"rmPN(P [+] Q)     = (rmPN P) [+] (rmPN Q)"
 |"rmPN(P |~| Q)     = (rmPN P) |~| (rmPN Q)"
 |"rmPN(!! :C .. Pf) = !! c:C .. rmPN (Pf c)"
 |"rmPN(IF b THEN P ELSE Q) = (IF b THEN rmPN(P) ELSE rmPN(Q))"
 |"rmPN(P |[X]| Q)   = (rmPN P) |[X]| (rmPN Q)"
 |"rmPN(P -- X)      = (rmPN P) -- X"
 |"rmPN(P [[r]])     = (rmPN P) [[r]]"
 |"rmPN(P ;; Q)      = (rmPN P) ;; (rmPN Q)"
 |"rmPN(P |. n)      = (rmPN P) |. n"
 |"rmPN($p)          = (FIX PNfun)(p)"

lemma noPN_rmPN: "noPN (rmPN P)"
apply (induct_tac P)
apply (simp_all)
apply (simp add: noPN_FIX)
done

lemma cspT_rmPN_eqT:
  "FPmode = CPOmode |
   FPmode = CMSmode & guardedfun (PNfun::('p=>('p,'a) proc)) |
   FPmode = MIXmode
   ==> (P::('p,'a) proc) =T rmPN(P)"
apply (induct_tac P)
apply (simp_all add: cspT_decompo)
apply (rule cspT_FIX)
apply (simp_all)
done

(*-------------------------------------------------------*
 |                                                       |
 |         FIX expansion (CSP-Prover intro rule)         |
 |                                                       |
 *-------------------------------------------------------*)

lemma traces_FIXn_plus_sub_lm:
 "ALL n m p. traces ((FIX[n] Pf) p) M <= traces ((FIX[n+m] Pf) p) M"
apply (rule)
apply (induct_tac n)
apply (simp add: FIXn_def Subst_procfun_prod_def)
apply (intro allI)
apply (rule)
apply (simp add: in_traces)

apply (rule allI)
apply (simp add: FIXn_def Subst_procfun_prod_def)
apply (drule_tac x="m" in spec)
apply (simp add: traces_subst)
apply (rule allI)
apply (fold order_prod_def)
apply (simp add: mono_traces[simplified mono_def])
done

lemma traces_FIXn_plus_sub:
   "traces ((FIX[n] Pf) p) M <= traces ((FIX[n+m] Pf) p) M"
by (simp add: traces_FIXn_plus_sub_lm)

lemma semT_FIXn_plus_sub:
 "[[(FIX[n] Pf) p]]Tf M <= [[(FIX[n+m] Pf) p]]Tf M"
apply (simp add: semTf_def)
apply (simp add: traces_FIXn_plus_sub)
done

lemma in_traces_FIXn_plus_sub:
  "t :t traces ((FIX[n] Pf) p) M ==> t :t traces ((FIX[n+m] Pf) p) M"
apply (insert traces_FIXn_plus_sub[of n Pf p M m])
by (auto)

(*-----------------------------------------------------*
 |  sometimes FIX[n + f n] is useful more than FIX[n]  |
 *-----------------------------------------------------*)

lemma cspT_FIX_plus_eq:
     "ALL f p. (FIX Pf) p =T[M,M] (!nat n .. ((FIX[n + f n] Pf) p))"
apply (simp add: FIX_def)
apply (simp add: eqT_def)
apply (intro allI)
apply (simp add: semTf_def)
apply (rule order_antisym)

 apply (rule)
 apply (simp add: in_traces)
 apply (rule disjI2)
 apply (elim conjE exE disjE, simp)
 apply (rule_tac x="n" in exI)
 apply (simp add: in_traces_FIXn_plus_sub)

 apply (rule)
 apply (simp add: in_traces)
 apply (elim conjE exE disjE)
 apply (simp)
 apply (rule disjI2)
 apply (rule_tac x="n + f n" in exI)
 apply (simp)
done

(****************** to add them again ******************)
(*
declare Union_image_eq [simp]
declare Inter_image_eq [simp]
*)
(* 2017
declare Sup_image_eq [simp]
declare Inf_image_eq [simp]
*)

end


(*******************************************************************************

  Project: Refining Authenticated Key Agreement with Strong Adversaries

  Module:  IK.thy (Isabelle/HOL 2016-1)
  ID:      $Id: IK.thy 132882 2016-12-23 09:03:55Z csprenge $
  Author:  Joseph Lallemand, INRIA Nancy <joseph.lallemand@loria.fr>
           Christoph Sprenger, ETH Zurich <sprenger@inf.ethz.ch>

  State with intruder knowledge and corresponding Dolev-Yao derivation event.
  - This is used a building block for Secrecy model.
  - The attacker event is also used by level-3 models.

  Copyright (c) 2015-2016 Joseph Lallemand and Christoph Sprenger
  Licence: LGPL

*******************************************************************************)

section \<open>Environment: Dolev-Yao Intruder\<close>

theory IK
imports Message_derivation
begin

text \<open>Basic state contains intruder knowledge. The secrecy model and concrete Level 1
states will be record extensions of this state.\<close>

record ik_state =
  ik :: "msg set"

text \<open>Dolev-Yao intruder event adds a derived message.\<close>

definition
  ik_dy :: "msg \<Rightarrow> ('a ik_state_scheme * 'a ik_state_scheme) set"
where
  "ik_dy m \<equiv> {(s, s').
    \<comment> \<open>guard\<close>
    m \<in> synth (analz (ik s)) \<and>

    \<comment> \<open>action\<close>
    s' = s \<lparr>ik := ik s \<union> {m}\<rparr>
  }"

definition
  ik_trans :: "('a ik_state_scheme * 'a ik_state_scheme) set"
where
  "ik_trans \<equiv> (\<Union> m.  ik_dy m)"

lemmas ik_trans_defs = ik_trans_def ik_dy_def

lemma ik_trans_ik_increasing: "(s, s') \<in> ik_trans \<Longrightarrow> ik s \<subseteq> ik s'"
by (auto simp add: ik_trans_defs)

end


theory flash90Bra  imports flash90Rev

  begin
lemma onInv90:

   assumes  a1:"iInv1 \<le> N" and  a2:"iInv2 \<le> N" and  a3:"iInv1~=iInv2  " and

     b1:"r \<in> rules N" and b2:"invf=inv90  iInv1  iInv2 "
   shows  "invHoldForRule' s invf r (invariants   N)"
   proof -
have c1:"ex1P N (% iRule1 .  r=NI_Local_GetX_PutX1 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_GetX  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Replace  iRule1 )\<or>ex0P N (  r=NI_ShWb N )\<or>ex0P N (  r=PI_Local_GetX_GetX2 )\<or>ex0P N (  r=NI_Local_PutXAcksDone )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX7 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Nak2  iRule1 )\<or>ex0P N (  r=NI_ReplaceHomeShrVld )\<or>ex1P N (% iRule1 .  r=NI_Remote_Put  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX5 N  iRule1 )\<or>ex0P N (  r=NI_Wb )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Get  iRule1 )\<or>ex0P N (  r=PI_Local_Replace )\<or>ex1P N (% iRule1 .  r=NI_ReplaceShrVld  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Local_GetX_PutX8 N  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_InvAck_2 N  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_Get_Nak2  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=PI_Remote_Replace  iRule1 )\<or>ex0P N (  r=NI_Nak_Home )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Put2  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_InvAck_1  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX11 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX6 N  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_Get_Put2  iRule1  iRule2 )\<or>ex0P N (  r=PI_Local_Get_Put )\<or>ex0P N (  r=PI_Local_GetX_PutX1 N )\<or>ex1P N (% iRule1 .  r=NI_InvAck_1_Home  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_Get_Nak1  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Nak1  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_Nak2  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX10_home N  iRule1 )\<or>ex1P N (% iRule1 .  r=PI_Remote_Get  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_Nak3  iRule1 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Local_GetX_PutX10 N  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX2 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_Get_Put1  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_PutX  iRule1 )\<or>ex1P N (% iRule1 .  r=Store  iRule1 )\<or>ex0P N (  r=NI_FAck )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX3 N  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_PutX3 )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_GetX_PutX  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX8_home N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Put1 N  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_GetX1 )\<or>ex0P N (  r=StoreHome )\<or>ex2P N (% iRule1  iRule2 .  r=NI_Remote_GetX_Nak  iRule1  iRule2 )\<or>ex1P N (% iRule1 .  r=NI_Inv  iRule1 )\<or>ex1P N (% iRule1 .  r=PI_Remote_PutX  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_PutX4 )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX4 N  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Nak  iRule1 )\<or>ex0P N (  r=PI_Local_GetX_PutX2 N )\<or>ex0P N (  r=NI_Local_Put )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_Nak1  iRule1 )\<or>ex0P N (  r=NI_Nak_Clear )\<or>ex0P N (  r=PI_Local_PutX )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Nak3  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Remote_GetX_Nak_Home  iRule1 )\<or>ex0P N (  r=PI_Local_Get_Get )\<or>ex1P N (% iRule1 .  r=NI_Local_GetX_PutX9 N  iRule1 )\<or>ex1P N (% iRule1 .  r=PI_Remote_GetX  iRule1 )\<or>ex0P N (  r=NI_ReplaceHome )\<or>ex1P N (% iRule1 .  r=NI_Remote_GetX_PutX_Home  iRule1 )\<or>ex1P N (% iRule1 .  r=NI_Local_Get_Put3  iRule1 )"

        apply(cut_tac  b1)
        apply auto
        done      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX1 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX1 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX1 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_GetX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_GetX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_GetX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_GetXVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Replace  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Replace  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Replace  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_ReplaceVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_ShWb N )
"

         from c1 have c2:" r= NI_ShWb N "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_ShWb N ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_ShWbVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_GetX2 )
"

         from c1 have c2:" r= PI_Local_GetX_GetX2 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_GetX_GetX2 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_GetX2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= NI_Local_PutXAcksDone )
"

         from c1 have c2:" r= NI_Local_PutXAcksDone "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_PutXAcksDone ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Local_PutXAcksDoneVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX7 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX7 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX7 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX7VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Nak2  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Nak2  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Nak2  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Nak2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_ReplaceHomeShrVld )
"

         from c1 have c2:" r= NI_ReplaceHomeShrVld "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_ReplaceHomeShrVld ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_ReplaceHomeShrVldVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_Put  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_Put  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_Put  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_PutVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX5 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX5 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX5 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX5VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_Wb )
"

         from c1 have c2:" r= NI_Wb "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Wb ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_WbVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Get  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Get  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Get  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_GetVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_Replace )
"

         from c1 have c2:" r= PI_Local_Replace "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_Replace ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_ReplaceVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_ReplaceShrVld  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_ReplaceShrVld  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_ReplaceShrVld  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_ReplaceShrVldVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Local_GetX_PutX8 N  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Local_GetX_PutX8 N  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX8 N  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX8VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_InvAck_2 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_InvAck_2 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_InvAck_2 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvAck_2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_Get_Nak2  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_Get_Nak2  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_Get_Nak2  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Nak2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_Replace  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_Replace  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Remote_Replace  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_ReplaceVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_Nak_Home )
"

         from c1 have c2:" r= NI_Nak_Home "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Nak_Home ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Nak_HomeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Put2  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Put2  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Put2  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Put2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_InvAck_1  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_InvAck_1  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_InvAck_1  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvAck_1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX11 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX11 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX11 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX11VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX6 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX6 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX6 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX6VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_Get_Put2  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_Get_Put2  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_Get_Put2  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Put2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_Get_Put )
"

         from c1 have c2:" r= PI_Local_Get_Put "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_Get_Put ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_Get_PutVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX1 N )
"

         from c1 have c2:" r= PI_Local_GetX_PutX1 N "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_GetX_PutX1 N ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_InvAck_1_Home  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_InvAck_1_Home  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_InvAck_1_Home  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvAck_1_HomeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_Get_Nak1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_Get_Nak1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_Get_Nak1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Nak1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Nak1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Nak1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Nak1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Nak1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_Nak2  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_Nak2  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_Nak2  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_Nak2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX10_home N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX10_home N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX10_home N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX10_homeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_Get  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_Get  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Remote_Get  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_GetVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_Nak3  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_Nak3  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_Nak3  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_Nak3VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Local_GetX_PutX10 N  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Local_GetX_PutX10 N  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX10 N  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX10VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX2 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX2 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX2 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_Get_Put1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_Get_Put1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_Get_Put1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_Get_Put1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_PutX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_PutX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_PutX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_PutXVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= Store  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= Store  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (Store  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis StoreVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_FAck )
"

         from c1 have c2:" r= NI_FAck "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_FAck ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_FAckVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX3 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX3 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX3 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX3VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX3 )
"

         from c1 have c2:" r= PI_Local_GetX_PutX3 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_GetX_PutX3 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX3VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_GetX_PutX  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_GetX_PutX  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_GetX_PutX  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_PutXVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX8_home N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX8_home N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX8_home N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX8_homeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Put1 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Put1 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Put1 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Put1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_GetX1 )
"

         from c1 have c2:" r= PI_Local_GetX_GetX1 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_GetX_GetX1 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_GetX1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= StoreHome )
"

         from c1 have c2:" r= StoreHome "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (StoreHome ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis StoreHomeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex2P N (% iRule1  iRule2 .  r= NI_Remote_GetX_Nak  iRule1  iRule2 )
"

         from c1 obtain  iRule1  iRule2  where c2:"  iRule1~=iRule2    \<and>   iRule1 \<le> N \<and>   iRule2 \<le> N \<and>  r= NI_Remote_GetX_Nak  iRule1  iRule2 "
         by (auto simp add: ex2P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_GetX_Nak  iRule1  iRule2 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_NakVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Inv  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Inv  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Inv  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_InvVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_PutX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_PutX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Remote_PutX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_PutXVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX4 )
"

         from c1 have c2:" r= PI_Local_GetX_PutX4 "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_GetX_PutX4 ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX4VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX4 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX4 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX4 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX4VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Nak  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Nak  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Nak  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_NakVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_GetX_PutX2 N )
"

         from c1 have c2:" r= PI_Local_GetX_PutX2 N "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_GetX_PutX2 N ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_GetX_PutX2VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= NI_Local_Put )
"

         from c1 have c2:" r= NI_Local_Put "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Put ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Local_PutVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_Nak1  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_Nak1  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_Nak1  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_Nak1VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_Nak_Clear )
"

         from c1 have c2:" r= NI_Nak_Clear "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Nak_Clear ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_Nak_ClearVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex0P N (  r= PI_Local_PutX )
"

         from c1 have c2:" r= PI_Local_PutX "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_PutX ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_PutXVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Nak3  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Nak3  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Nak3  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Nak3VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_GetX_Nak_Home  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_GetX_Nak_Home  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_GetX_Nak_Home  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_Nak_HomeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= PI_Local_Get_Get )
"

         from c1 have c2:" r= PI_Local_Get_Get "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Local_Get_Get ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis PI_Local_Get_GetVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_GetX_PutX9 N  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_GetX_PutX9 N  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_GetX_PutX9 N  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_GetX_PutX9VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= PI_Remote_GetX  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= PI_Remote_GetX  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (PI_Remote_GetX  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis PI_Remote_GetXVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex0P N (  r= NI_ReplaceHome )
"

         from c1 have c2:" r= NI_ReplaceHome "
         by (auto simp add: ex0P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_ReplaceHome ) (invariants N) "
            apply(cut_tac   a1  a2  a3   b2 c2 )
            by (metis NI_ReplaceHomeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
	}      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Remote_GetX_PutX_Home  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Remote_GetX_PutX_Home  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Remote_GetX_PutX_Home  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Remote_GetX_PutX_HomeVsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }      moreover
        {assume c1: "ex1P N (% iRule1 .  r= NI_Local_Get_Put3  iRule1 )
"

         from c1 obtain  iRule1  where c2:"  iRule1 \<le> N \<and>  r= NI_Local_Get_Put3  iRule1 "
         by (auto simp add: ex1P_def)

         have "invHoldForRule' s (inv90  iInv1  iInv2 ) (NI_Local_Get_Put3  iRule1 ) (invariants N) "
            apply(cut_tac  c2   a1  a2  a3 )
            by (metis NI_Local_Get_Put3VsInv90 )
          then have "invHoldForRule' s invf r (invariants N) "
            by(cut_tac c2 b2, metis)
        }ultimately show "invHoldForRule' s invf r (invariants N) "
          by blast
     qed
end


section {*FUNCTION\_CFG\_ENFORCE\_ACCESSIBILITY\_cfgLM*}
theory
  FUNCTION_CFG_ENFORCE_ACCESSIBILITY_cfgLM

imports
  FUNCTION_CFG_ENFORCE_ACCESSIBILITY_cfgLM_EXTRA

begin

definition F_CFG_EASTD_ALT :: "
  ('nonterminal, 'event) cfg
  \<Rightarrow> ('nonterminal, 'event) cfg"
  where
    "F_CFG_EASTD_ALT G \<equiv>
  let
    N = F_CFG_APLM__fp G (cfg_nonterminals G) {cfg_initial G}
  in
    \<lparr>cfg_nonterminals = N,
    cfg_events = cfg_events G,
    cfg_initial = cfg_initial G,
    cfg_productions = {p \<in> cfg_productions G. prod_lhs p \<in> N}\<rparr>"

definition F_CFG_EASTD__SpecInput :: "
  ('nonterminal, 'event) cfg
  \<Rightarrow> bool"
  where
    "F_CFG_EASTD__SpecInput G \<equiv>
  valid_cfg G
  \<and> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G"

definition F_CFG_EASTD__SpecOutput :: "
  ('nonterminal, 'event) cfg
  \<Rightarrow> ('nonterminal, 'event) cfg
  \<Rightarrow> bool"
  where
    "F_CFG_EASTD__SpecOutput Gi Go \<equiv>
  valid_cfg Go
  \<and> cfg_sub Go Gi
  \<and> cfgLM.marked_language Go = cfgLM.marked_language Gi
  \<and> cfgLM.initial_marking_derivations Go = cfgLM.initial_marking_derivations Gi
  \<and> cfg_nonterminals Go = cfgLM_accessible_nonterminals Gi \<inter> cfgSTD_Nonblockingness_nonterminals Gi
  \<and> cfg_nonterminals Go = cfgLM_accessible_nonterminals Go \<inter> cfgSTD_Nonblockingness_nonterminals Go
  \<and> cfg_nonterminals Go = cfgLM_language_relevant_nonterminals Go
  \<and> cfg_productions Go = cfgLM_language_relevant_productions Go
  \<and> cfgLM.marked_language Go \<noteq> {}"

lemma F_CFG_EASTD_ALT_preserves_valid_cfg: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G
  \<Longrightarrow> valid_cfg (F_CFG_EASTD_ALT G)"
  apply(simp add: F_CFG_EASTD_ALT_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(simp (no_asm) add: Let_def valid_cfg_def)
  apply(rule conjI)
   apply(simp add: Let_def valid_cfg_def)
  apply(rule conjI)
   apply(rule_tac
      B="cfgLM_accessible_nonterminals G"
      in finite_subset)
    apply(simp (no_asm_simp))
   apply(rule_tac
      B="cfg_nonterminals G"
      in finite_subset)
    apply(simp (no_asm) add: cfgLM_accessible_nonterminals_def)
    apply(force)
   apply(simp add: Let_def valid_cfg_def)
  apply(rule conjI)
   apply(rule_tac
      A="cfgLM_accessible_nonterminals G"
      in set_mp)
    apply(simp (no_asm_simp))
   apply(simp (no_asm) add: cfgLM_accessible_nonterminals_def)
   apply(rule conjI)
    apply(simp add: valid_cfg_def)
   apply(rule_tac
      x="der1 \<lparr>cfg_conf=[teA (cfg_initial G)]\<rparr>"
      in exI)
   apply(rule conjI)
    apply(rule cfgLM.derivation_initialI)
     apply(rule cfgLM.der1_is_derivation)
    apply(clarsimp)
    apply(rename_tac c)(*strict*)
    apply(simp add: get_configuration_def der1_def)
    apply(clarsimp)
    apply(simp add: valid_cfg_def cfg_initial_configurations_def cfg_configurations_def)
   apply(rule_tac
      x="0"
      in exI)
   apply(simp add: get_configuration_def der1_def)
   apply(rule_tac
      x="[]"
      in exI)
   apply(rule_tac
      x="[]"
      in exI)
   apply(force)
  apply(rule conjI)
   apply(simp add: Let_def valid_cfg_def)
  apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
   apply(force)
  apply(thin_tac "cfgLM_accessible_nonterminals G = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}")
  apply(clarsimp)
  apply(rename_tac e)(*strict*)
  apply(rule conjI)
   apply(rename_tac e)(*strict*)
   prefer 2
   apply(simp add: valid_cfg_def)
  apply(rename_tac e)(*strict*)
  apply(rule one_step_preserves_cfgLM_accessible_nonterminals)
     apply(rename_tac e)(*strict*)
     apply(force)+
  done

lemma F_CFG_EASTD_ALT_is_cfg_sub: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G
  \<Longrightarrow> cfg_sub (F_CFG_EASTD_ALT G) G"
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_preserves_valid_cfg)
    apply(force)
   apply(force)
  apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(simp add: cfg_sub_def)
  apply(rule conjI)
   apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
    apply(force)
   apply(rule_tac
      t="cfgSTD_Nonblockingness_nonterminals G"
      and s="cfg_nonterminals G"
      in ssubst)
    apply(force)
   apply(simp (no_asm) add: cfgLM_accessible_nonterminals_def)
   apply(force)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_preserves_language: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G
  \<Longrightarrow> cfgLM.marked_language G = cfgLM.marked_language (F_CFG_EASTD_ALT G)"
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_is_cfg_sub)
    apply(force)
   apply(force)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_preserves_valid_cfg)
    apply(force)
   apply(force)
  apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(rule antisym)
   prefer 2
   apply(clarsimp)
   apply(rename_tac x)(*strict*)
   apply(simp add: cfgLM.marked_language_def)
   apply(clarsimp)
   apply(rename_tac x d)(*strict*)
   apply(subgoal_tac "X" for X)
    apply(rename_tac x d)(*strict*)
    prefer 2
    apply(rule cfg_sub_preserves_cfgLM_derivation_initial)
      apply(rename_tac x d)(*strict*)
      apply(force)
     apply(rename_tac x d)(*strict*)
     apply(force)
    apply(rename_tac x d)(*strict*)
    apply(force)
   apply(rename_tac x d)(*strict*)
   apply(rule_tac
      x="d"
      in exI)
   apply(clarsimp)
   apply(rule conjI)
    apply(rename_tac x d)(*strict*)
    apply(simp add: cfg_marked_effect_def)
   apply(rename_tac x d)(*strict*)
   apply(rule conjI)
    apply(rename_tac x d)(*strict*)
    apply(simp add: cfgLM.derivation_initial_def)
   apply(rename_tac x d)(*strict*)
   apply(simp add: cfg_marked_effect_def)
   apply(clarsimp)
   apply(rename_tac x d e c i)(*strict*)
   apply(simp add: cfg_marking_condition_def)
   apply(clarsimp)
   apply(rename_tac x d e c i ia ea ca)(*strict*)
   apply(simp add: cfg_marking_configuration_def)
   apply(clarsimp)
   apply(rule_tac
      x="i"
      in exI)
   apply(clarsimp)
   apply(rule cfgLM.belongs_configurations)
    apply(rename_tac x d e c i ia ea ca)(*strict*)
    apply(rule cfgLM.derivation_initial_belongs)
     apply(rename_tac x d e c i ia ea ca)(*strict*)
     apply(force)
    apply(rename_tac x d e c i ia ea ca)(*strict*)
    apply(force)
   apply(rename_tac x d e c i ia ea ca)(*strict*)
   apply(force)
  apply(clarsimp)
  apply(rename_tac x)(*strict*)
  apply(simp add: cfgLM.marked_language_def)
  apply(clarsimp)
  apply(rename_tac x d)(*strict*)
  apply(rule_tac
      x="d"
      in exI)
  apply(rule context_conjI)
   apply(rename_tac x d)(*strict*)
   prefer 2
   apply(rule conjI)
    apply(rename_tac x d)(*strict*)
    apply(simp add: cfg_marked_effect_def)
   apply(rename_tac x d)(*strict*)
   apply(rule conjI)
    apply(rename_tac x d)(*strict*)
    apply(simp add: cfgLM.derivation_initial_def)
   apply(rename_tac x d)(*strict*)
   apply(simp add: cfg_marking_condition_def)
   apply(clarsimp)
   apply(rename_tac x d i e c)(*strict*)
   apply(rule_tac
      x="i"
      in exI)
   apply(clarsimp)
   apply(simp add: cfg_marking_configuration_def cfg_configurations_def)
   apply(clarsimp)
  apply(rename_tac x d)(*strict*)
  apply(rule cfg_sub_preserves_derivation_initial_contra)
      apply(rename_tac x d)(*strict*)
      apply(force)
     apply(rename_tac x d)(*strict*)
     apply(force)
    apply(rename_tac x d)(*strict*)
    apply(force)
   apply(rename_tac x d)(*strict*)
   apply(force)
  apply(rename_tac x d)(*strict*)
  apply(rule allI)+
  apply(rename_tac x d i e c)(*strict*)
  apply(rule impI)
  apply(rule cfg_sub_preserves_derivation_initial_contra2)
       apply(rename_tac x d i e c)(*strict*)
       apply(force)
      apply(rename_tac x d i e c)(*strict*)
      apply(force)
     apply(rename_tac x d i e c)(*strict*)
     apply(force)
    apply(rename_tac x d i e c)(*strict*)
    apply(force)
   apply(rename_tac x d i e c)(*strict*)
   prefer 2
   apply(force)
  apply(rename_tac x d i e c)(*strict*)
  apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
   apply(rename_tac x d i e c)(*strict*)
   apply(force)
  apply(rename_tac x d i e c)(*strict*)
  apply(thin_tac "cfgLM_accessible_nonterminals G = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}")
  apply(clarsimp)
  apply(rename_tac x d i e c ea ca c')(*strict*)
  apply(simp add: cfgLM_step_relation_def cfg_configurations_def)
  apply(clarsimp)
  apply(rename_tac x d i e c ea c' l r)(*strict*)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(case_tac c')
  apply(rename_tac x d i e c ea c' l r cfg_confa)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d i e c ea l r)(*strict*)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(rule conjI)
   apply(rename_tac x d i e c ea l r)(*strict*)
   prefer 2
   apply(simp add: cfg_sub_def valid_cfg_def)
  apply(rename_tac x d i e c ea l r)(*strict*)
  apply(rule one_step_preserves_cfgLM_accessible_nonterminals)
     apply(rename_tac x d i e c ea l r)(*strict*)
     apply(force)
    apply(rename_tac x d i e c ea l r)(*strict*)
    apply(force)
   apply(rename_tac x d i e c ea l r)(*strict*)
   apply(force)
  apply(rename_tac x d i e c ea l r)(*strict*)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_idemp_cfgLM_accessible_nonterminals: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G
  \<Longrightarrow> cfgLM_accessible_nonterminals (F_CFG_EASTD_ALT G) = cfgLM_accessible_nonterminals G"
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_is_cfg_sub)
    apply(force)
   apply(force)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_preserves_valid_cfg)
    apply(force)
   apply(force)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(rule antisym)
   apply(simp add: F_CFG_EASTD_ALT_def Let_def)
   apply(clarsimp)
   apply(rename_tac x)(*strict*)
   apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
    apply(rename_tac x)(*strict*)
    apply(force)
   apply(rename_tac x)(*strict*)
   apply(simp add: cfgLM_accessible_nonterminals_def)
  apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(clarsimp)
  apply(rename_tac x)(*strict*)
  apply(subgoal_tac "x \<in> cfgLM_accessible_nonterminals G")
   apply(rename_tac x)(*strict*)
   prefer 2
   apply(rule_tac
      s="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and t="cfgLM_accessible_nonterminals G"
      in ssubst)
    apply(rename_tac x)(*strict*)
    apply(force)
   apply(rename_tac x)(*strict*)
   apply(force)
  apply(rename_tac x)(*strict*)
  apply(thin_tac "x \<in> F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}")
  apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
   apply(rename_tac x)(*strict*)
   apply(force)
  apply(rename_tac x)(*strict*)
  apply(simp (no_asm_use) add: cfgLM_accessible_nonterminals_def)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2)(*strict*)
  apply(rule_tac
      x="d"
      in exI)
  apply(rule conjI)
   apply(rename_tac x d n c w1 w2)(*strict*)
   prefer 2
   apply(rule_tac
      x="n"
      in exI)
   apply(clarsimp)
   apply(force)
  apply(rename_tac x d n c w1 w2)(*strict*)
  apply(rule_tac
      t="\<lparr>cfg_nonterminals = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}, cfg_events = cfg_events G, cfg_initial = cfg_initial G, cfg_productions = {p \<in> cfg_productions G. prod_lhs p \<in> cfgSTD_Nonblockingness_nonterminals G \<and> (\<exists>d. cfgLM.derivation_initial G d \<and> (\<exists>n c. get_configuration (d n) = Some c \<and> (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA (prod_lhs p) # w2)))}\<rparr>"
      and s="\<lparr>cfg_nonterminals = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}, cfg_events = cfg_events G, cfg_initial = cfg_initial G, cfg_productions = {p \<in> cfg_productions G. prod_lhs p \<in> F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}}\<rparr>"
      in ssubst)
   apply(rename_tac x d n c w1 w2)(*strict*)
   apply(simp add: cfgLM_accessible_nonterminals_def)
   apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="{A \<in> cfgSTD_Nonblockingness_nonterminals G. \<exists>d. cfgLM.derivation_initial G d \<and> (\<exists>n c. get_configuration (d n) = Some c \<and> (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA A # w2))}"
      in ssubst)
    apply(rename_tac x d n c w1 w2)(*strict*)
    apply(force)
   apply(rename_tac x d n c w1 w2)(*strict*)
   apply(simp (no_asm))
  apply(rename_tac x d n c w1 w2)(*strict*)
  apply(rule cfg_sub_preserves_derivation_initial_contra)
      apply(rename_tac x d n c w1 w2)(*strict*)
      apply(force)
     apply(rename_tac x d n c w1 w2)(*strict*)
     apply(force)
    apply(rename_tac x d n c w1 w2)(*strict*)
    apply(force)
   apply(rename_tac x d n c w1 w2)(*strict*)
   apply(force)
  apply(rename_tac x d n c w1 w2)(*strict*)
  apply(rule allI)+
  apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
  apply(rule impI)
  apply(rule cfg_sub_preserves_derivation_initial_contra2)
       apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
       apply(force)
      apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
      apply(force)
     apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
     apply(force)
    apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
    apply(force)
   apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
   prefer 2
   apply(force)
  apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
  apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="{A \<in> cfgSTD_Nonblockingness_nonterminals G. \<exists>d. cfgLM.derivation_initial G d \<and> (\<exists>n c. get_configuration (d n) = Some c \<and> (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA A # w2))}"
      in ssubst)
   apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
   apply(force)
  apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
  apply(thin_tac "{A \<in> cfgSTD_Nonblockingness_nonterminals G. \<exists>d. cfgLM.derivation_initial G d \<and> (\<exists>n c. get_configuration (d n) = Some c \<and> (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA A # w2))} = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}")
  apply(rename_tac x d n c w1 w2 i e ca)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2 i e ca ea cb c')(*strict*)
  apply(simp add: cfgLM_step_relation_def cfg_configurations_def)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2 i e ca ea c' l r)(*strict*)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(case_tac c')
  apply(rename_tac x d n c w1 w2 i e ca ea c' l r cfg_confa)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(rule conjI)
   apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
   prefer 2
   apply(simp add: cfg_sub_def valid_cfg_def)
  apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
  apply(rule_tac
      t="{A \<in> cfgSTD_Nonblockingness_nonterminals G. \<exists>d. cfgLM.derivation_initial G d \<and> (\<exists>n c. get_configuration (d n) = Some c \<and> (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA A # w2))}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
   apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
   apply(simp (no_asm_use) add: cfgLM_accessible_nonterminals_def)
   apply(force)
  apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
  apply(rule one_step_preserves_cfgLM_accessible_nonterminals)
     apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
     apply(force)
    apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
    apply(force)
   apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
   apply(force)
  apply(rename_tac x d n c w1 w2 i e ca ea l r da na cb w1a w2a)(*strict*)
  apply(simp (no_asm_use) add: cfgLM_accessible_nonterminals_def)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_preserves_Eliminability: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G
  \<Longrightarrow> cfg_nonterminals (F_CFG_EASTD_ALT G) = cfgLM_accessible_nonterminals (F_CFG_EASTD_ALT G) \<inter> cfgSTD_Nonblockingness_nonterminals (F_CFG_EASTD_ALT G)"
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_idemp_cfgLM_accessible_nonterminals)
    apply(force)
   apply(force)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_is_cfg_sub)
    apply(force)
   apply(force)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_preserves_valid_cfg)
    apply(force)
   apply(force)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(rule inter_eq_intro)
    apply(simp add: F_CFG_EASTD_ALT_def Let_def)
   prefer 2
   apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(clarsimp)
  apply(rename_tac x)(*strict*)
  apply(subgoal_tac "x \<in> {A \<in> cfg_nonterminals G. \<exists>d n c. cfgLM.derivation_initial G d \<and> get_configuration (d n) = Some c \<and> (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA A # w2)}")
   apply(rename_tac x)(*strict*)
   prefer 2
   apply(unfold cfgLM_accessible_nonterminals_def)[1]
   apply(force)
  apply(rename_tac x)(*strict*)
  apply(thin_tac "x \<in> F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}")
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2)(*strict*)
  apply(subgoal_tac "x \<in> {A \<in> cfg_nonterminals G. \<exists>d w'. cfgSTD.derivation_from_to G d {pair None \<lparr>cfg_conf = [teA A]\<rparr>} ({y. (\<exists>x. y = pair x \<lparr>cfg_conf = w'\<rparr>)}) \<and> setA w' = {}}")
   apply(rename_tac x d n c w1 w2)(*strict*)
   prefer 2
   apply(simp (no_asm_use) only: cfgSTD_Nonblockingness_nonterminals_def)
  apply(rename_tac x d n c w1 w2)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2 da w')(*strict*)
  apply(subgoal_tac "\<exists>d n e. cfgSTD.derivation G d \<and> d 0 = Some (pair None \<lparr>cfg_conf = [teA x]\<rparr>) \<and> d n = Some (pair e \<lparr>cfg_conf = w'\<rparr>)")
   apply(rename_tac x d n c w1 w2 da w')(*strict*)
   prefer 2
   apply(rule_tac
      x="da"
      in exI)
   apply(simp add: cfgSTD.derivation_to_def cfgSTD.derivation_from_def cfgSTD.derivation_from_to_def )
   apply(clarsimp)
   apply(rename_tac x d n c w1 w2 da w' na xa)(*strict*)
   apply(case_tac "da 0")
    apply(rename_tac x d n c w1 w2 da w' na xa)(*strict*)
    apply(clarsimp)
   apply(rename_tac x d n c w1 w2 da w' na xa a)(*strict*)
   apply(clarsimp)
   apply(rename_tac x d n c w1 w2 da w' na xa)(*strict*)
   apply(rule_tac
      x="na"
      in exI)
   apply(clarsimp)
  apply(rename_tac x d n c w1 w2 da w')(*strict*)
  apply(thin_tac "cfgSTD.derivation_from_to G da {pair None \<lparr>cfg_conf = [teA x]\<rparr>} ({y. (\<exists>x. y = pair x \<lparr>cfg_conf = w'\<rparr>)})")
  apply(rename_tac x d n c w1 w2 da w')(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2 w' da na e)(*strict*)
  apply(case_tac "d n")
   apply(rename_tac x d n c w1 w2 w' da na e)(*strict*)
   apply(simp add: get_configuration_def)
  apply(rename_tac x d n c w1 w2 w' da na e a)(*strict*)
  apply(clarsimp)
  apply(simp add: get_configuration_def)
  apply(case_tac a)
  apply(rename_tac x d n c w1 w2 w' da na e a option b)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n c w1 w2 w' da na e option)(*strict*)
  apply(case_tac c)
  apply(rename_tac x d n c w1 w2 w' da na e option cfg_confa)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
  apply(subgoal_tac "x \<in> {A \<in> cfg_nonterminals \<lparr>cfg_nonterminals = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}, cfg_events = cfg_events G, cfg_initial = cfg_initial G, cfg_productions = {p \<in> cfg_productions G. prod_lhs p \<in> F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}}\<rparr>. \<exists>d w'. cfgSTD.derivation_from_to \<lparr>cfg_nonterminals = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}, cfg_events = cfg_events G, cfg_initial = cfg_initial G, cfg_productions = {p \<in> cfg_productions G. prod_lhs p \<in> F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}}\<rparr> d {pair None \<lparr>cfg_conf = [teA A]\<rparr>} ({ y. (\<exists>x. y = pair x \<lparr>cfg_conf = w'\<rparr>)}) \<and> setA w' = {}}")
   apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
   apply(simp add: cfgSTD_Nonblockingness_nonterminals_def)
  apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
  apply(clarsimp)
  apply(subgoal_tac "cfgSTD.derivation \<lparr>cfg_nonterminals = F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}, cfg_events = cfg_events G, cfg_initial = cfg_initial G, cfg_productions = {p \<in> cfg_productions G. prod_lhs p \<in> F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}}\<rparr> da ")
   apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
   apply(rule conjI)
    apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
    prefer 2
    apply(rule_tac
      x="da"
      in exI)
    apply(rule_tac
      x="w'"
      in exI)
    apply(simp add: cfgSTD.derivation_to_def cfgSTD.derivation_from_def cfgSTD.derivation_from_to_def )
    apply(rule_tac
      x="na"
      in exI)
    apply(clarsimp)
    apply(case_tac "da (Suc na)")
     apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
     apply(force)
    apply(rename_tac x d n w1 w2 w' da na e option a)(*strict*)
    apply(subgoal_tac "X" for X)
     apply(rename_tac x d n w1 w2 w' da na e option a)(*strict*)
     prefer 2
     apply(rule_tac
      G="G"
      and d="da"
      and n="na"
      and m="Suc na"
      in cfgSTD.step_detail_before_some_position)
       apply(rename_tac x d n w1 w2 w' da na e option a)(*strict*)
       apply(force)
      apply(rename_tac x d n w1 w2 w' da na e option a)(*strict*)
      apply(force)
     apply(rename_tac x d n w1 w2 w' da na e option a)(*strict*)
     apply(force)
    apply(rename_tac x d n w1 w2 w' da na e option a)(*strict*)
    apply(clarsimp)
    apply(rename_tac x d n w1 w2 w' da na e option e2 c2)(*strict*)
    apply(simp add: cfgSTD_step_relation_def)
    apply(clarsimp)
    apply(rename_tac x d n w1 w2 da na e option e2 c2 l r)(*strict*)
    apply(simp add: setAConcat)
   apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
   apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
    apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
   apply(simp (no_asm) only: cfgLM_accessible_nonterminals_def)
   apply(simp (no_asm))
   apply(rule conjI)
    apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
    prefer 2
    apply(rule_tac
      x="d"
      in exI)
    apply(clarsimp)
    apply(rule_tac
      x="n"
      in exI)
    apply(clarsimp)
    apply(simp add: get_configuration_def)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
   apply(simp add: cfgSTD_Nonblockingness_nonterminals_def)
  apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
  apply(rule cfg_sub_preserves_cfg_derivation_contra)
      apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
      apply(force)
     apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
     apply(force)
    apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
   apply(force)
  apply(rename_tac x d n w1 w2 w' da na e option)(*strict*)
  apply(rule allI)+
  apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
  apply(rule impI)
  apply(rule cfg_sub_preserves_cfg_derivation_contra2)
         apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
         apply(force)
        apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
        apply(force)
       apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
       apply(force)
      apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
      apply(force)
     apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
     apply(force)
    apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
    prefer 3
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
   apply(simp add: cfg_configurations_def)
   apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
    apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
   apply(simp (no_asm) only: cfgLM_accessible_nonterminals_def)
   apply(simp (no_asm))
   apply(rule conjI)
    apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
   apply(rule_tac
      x="d"
      in exI)
   apply(rule conjI)
    apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
   apply(rule_tac
      x="n"
      in exI)
   apply(simp add: get_configuration_def)
   apply(force)
  apply(rename_tac x d n w1 w2 w' da na e option i ea c)(*strict*)
  apply(simp add: cfgSTD_step_relation_def cfg_configurations_def)
  apply(clarsimp)
  apply(rename_tac x d n w1 w2 w' da na e option i ea c eb c' l r)(*strict*)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(case_tac c')
  apply(rename_tac x d n w1 w2 w' da na e option i ea c eb c' l r cfg_confa)(*strict*)
  apply(clarsimp)
  apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(rule conjI)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
   prefer 2
   apply(simp add: cfg_sub_def valid_cfg_def)
  apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
  apply(rule_tac
      t="F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G}"
      and s="cfgLM_accessible_nonterminals G"
      in ssubst)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
   apply(force)
  apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
  apply(rule one_step_preserves_cfgLM_accessible_nonterminals)
     apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
     apply(force)
    apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
    apply(force)
   apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
   apply(force)
  apply(rename_tac x d n w1 w2 w' da na e option i ea c eb l r)(*strict*)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_makes_precise_accessible_and_Nonblockingness: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G = cfgSTD_Nonblockingness_nonterminals G
  \<Longrightarrow> cfg_nonterminals (F_CFG_EASTD_ALT G) = cfgLM_accessible_nonterminals G \<inter> cfgSTD_Nonblockingness_nonterminals G"
  apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(clarsimp)
  apply(subgoal_tac "F_CFG_APLM__fp G (cfgSTD_Nonblockingness_nonterminals G) {cfg_initial G} \<subseteq> cfg_nonterminals G")
   apply(blast)
  apply(rule_tac B="cfgLM_accessible_nonterminals G" in subset_trans)
   apply(rule F_CFG_APLM_F_CFG_APLM__fp_invariant_03_unfold)
   apply(simp add: F_CFG_APLM__fp_valid_input_def)
   apply(simp add: valid_cfg_def)
  apply(simp add: cfgLM_accessible_nonterminals_def)
  apply(force)
  done

lemma cfg_with_cfgLM_Nonblockingness_nonterminals_has_nonempty_cfgLM_marked_language: "
  valid_cfg G
  \<Longrightarrow> cfg_nonterminals G \<subseteq> cfgLM_Nonblockingness_nonterminals G
  \<Longrightarrow> cfgLM.marked_language G \<noteq> {}"
  apply(simp add: cfgLM.marked_language_def)
  apply(subgoal_tac "cfg_initial G \<in> cfgLM_Nonblockingness_nonterminals G")
   prefer 2
   apply(simp add: valid_cfg_def)
   apply(force)
  apply(thin_tac "cfg_nonterminals G \<subseteq> cfgLM_Nonblockingness_nonterminals G")
  apply(simp add: cfgLM_Nonblockingness_nonterminals_def)
  apply(clarsimp)
  apply(rule_tac x="filterB w'" in exI)
  apply(rule_tac x="d" in exI)
  apply(clarsimp)
  apply(simp add: cfg_marked_effect_def)
  apply(rule conjI)
   apply(rule_tac x="e" in exI)
   apply(rule_tac x="\<lparr>cfg_conf = w'\<rparr>" in exI)
   apply(clarsimp)
   apply(rule conjI)
    apply(force)
   apply (metis liftBDeConv2)
  apply(rule conjI)
   apply(simp add: cfgLM.derivation_initial_def cfg_initial_configurations_def cfg_configurations_def cfg_marking_condition_def cfg_marking_configuration_def)
  apply(simp add: cfg_marking_condition_def cfg_marking_configuration_def)
  apply(rule_tac x="n" in exI)
  apply(clarsimp)
  apply(rule_tac d="d" in cfgLM.belongs_configurations)
   apply(rule cfgLM.derivation_belongs)
      apply(force)
     apply(force)
    apply(simp add: cfgLM.derivation_initial_def cfg_initial_configurations_def cfg_configurations_def cfg_marking_condition_def cfg_marking_configuration_def)
   apply(force)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_preserves_cfgLM_initial_marking_derivations: "
  valid_cfg Gi
  \<Longrightarrow> valid_cfg Go
  \<Longrightarrow> cfg_sub Go Gi
  \<Longrightarrow> cfg_nonterminals Gi = cfgSTD_Nonblockingness_nonterminals Gi
  \<Longrightarrow> Go = F_CFG_EASTD_ALT Gi
  \<Longrightarrow> cfgLM.initial_marking_derivations Gi \<subseteq> cfgLM.initial_marking_derivations Go"
  apply(simp add: cfgLM.initial_marking_derivations_def)
  apply(clarsimp)
  apply(rename_tac d)
  apply(rule conjI)
   prefer 2
   apply(simp add: cfg_marking_condition_def)
   apply(simp add: cfg_marking_configuration_def cfg_configurations_def cfg_sub_def)
   apply(clarsimp)
   apply(rule_tac x="i" in exI)
   apply(clarsimp)
   apply(simp add: F_CFG_EASTD_ALT_def Let_def)
   apply(force)
  apply(simp add: cfg_marking_condition_def cfg_marking_configuration_def)
  apply(clarsimp)
  apply(case_tac c)
  apply(clarsimp)
  apply(rename_tac w)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_preserves_valid_cfg)
    apply(force)
   apply(force)
  apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_APLMSoundL)
   apply(force)
  apply(rule cfg_sub_preserves_derivation_initial_contra)
      apply(force)
     apply(force)
    apply(force)
   apply(force)
  apply(rule allI)+
  apply(rule impI)
  apply(rule cfg_sub_preserves_derivation_initial_contra2)
       apply(force)
      apply(force)
     apply(force)
    apply(force)
   prefer 2
   apply(force)
  apply(rule_tac
      t="F_CFG_APLM__fp Gi (cfgSTD_Nonblockingness_nonterminals Gi) {cfg_initial Gi}"
      and s="cfgLM_accessible_nonterminals Gi"
      in ssubst)
   apply(force)
  apply(thin_tac "cfgLM_accessible_nonterminals Gi = F_CFG_APLM__fp Gi (cfgSTD_Nonblockingness_nonterminals Gi) {cfg_initial Gi}")
  apply(clarsimp)
  apply(simp add: cfgLM_step_relation_def cfg_configurations_def)
  apply(clarsimp)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(case_tac c')
  apply(clarsimp)
  apply(simp add: setAConcat)
  apply(simp add: setBConcat)
  apply(rule conjI)
   prefer 2
   apply(simp add: cfg_sub_def valid_cfg_def)
  apply(rule one_step_preserves_cfgLM_accessible_nonterminals)
     apply(force)
    apply(force)
   apply(force)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_makes_equal_cfgLM_initial_marking_derivations: "
  valid_cfg Gi
  \<Longrightarrow> valid_cfg Go
  \<Longrightarrow> cfg_sub Go Gi
  \<Longrightarrow> cfg_nonterminals Gi = cfgSTD_Nonblockingness_nonterminals Gi
  \<Longrightarrow> Go = F_CFG_EASTD_ALT Gi
  \<Longrightarrow> cfgLM.initial_marking_derivations Go = cfgLM.initial_marking_derivations Gi"
  apply(rule antisym)
   apply(rule cfg_sub_preserves_cfgLM_initial_marking_derivations)
     apply(force)
    apply(force)
   apply(force)
  apply(rule F_CFG_EASTD_ALT_preserves_cfgLM_initial_marking_derivations)
      apply(force)
     apply(force)
    apply(force)
   apply(force)
  apply(force)
  done

lemma F_CFG_EASTD_ALT_enforces_cfgLM_language_relevant_productions: "
  valid_cfg Gi
  \<Longrightarrow> valid_cfg Go
  \<Longrightarrow> cfg_sub Go Gi
  \<Longrightarrow> cfg_nonterminals Gi = cfgSTD_Nonblockingness_nonterminals Gi
  \<Longrightarrow> Go = F_CFG_EASTD_ALT Gi
  \<Longrightarrow> cfg_productions Go = cfgLM_language_relevant_productions Go"
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac
      G="Gi"
      in F_CFG_EASTD_ALT_preserves_Eliminability)
    apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
   apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac G="Gi" in F_CFG_EASTD_ALT_makes_precise_accessible_and_Nonblockingness)
    apply(simp add: F_CFG_EASTD__SpecInput_def)
   apply(simp add: F_CFG_EASTD__SpecInput_def)
  apply(subgoal_tac "
cfgLM_accessible_nonterminals (F_CFG_EASTD_ALT Gi) \<inter> cfgSTD_Nonblockingness_nonterminals (F_CFG_EASTD_ALT Gi) = cfgLM_language_relevant_nonterminals (F_CFG_EASTD_ALT Gi)")
   prefer 2
   apply(rule cfgLM_language_relevant_nonterminals_vs_cfgLM_accessible_nonterminals_and_cfgSTD_Nonblockingness_nonterminals_in_cfgSTD_Nonblockingness_nonterminals_grammar)
      prefer 2
      apply(force)
     prefer 2
     apply(force)
    apply(force)
   apply(rule antisym)
    apply(force)
   apply(simp (no_asm) add: cfgSTD_Nonblockingness_nonterminals_def)
   apply(force)
  apply(rule antisym)
   prefer 2
   apply(simp add: cfgLM_language_relevant_productions_def)
   apply(clarsimp)
   apply(subgoal_tac "x \<in> cfg_step_labels (F_CFG_EASTD_ALT Gi)")
    prefer 2
    apply(rule cfgLM.belongs_step_labels)
     apply(rule cfgLM.derivation_initial_belongs)
      apply(force)
     apply(force)
    apply(force)
   apply(simp add: cfg_step_labels_def)
  apply(rule_tac t="cfg_productions Go" and s="{p \<in> cfg_productions Gi.
     prod_lhs p
     \<in> F_CFG_APLM__fp Gi (cfgSTD_Nonblockingness_nonterminals Gi) {cfg_initial Gi}}" in ssubst)
   apply(simp add: F_CFG_EASTD_ALT_def Let_def)
  apply(rule_tac
      t="F_CFG_APLM__fp X (cfgSTD_Nonblockingness_nonterminals X) {cfg_initial X}"
      and s="cfgLM_accessible_nonterminals X" for X
      in ssubst)
   apply(subgoal_tac "X" for X)
    prefer 2
    apply(rule F_CFG_APLMSoundL)
    apply(force)
   apply(force)
  apply(simp add: cfgLM_language_relevant_productions_def)
  apply(clarsimp)
  apply(case_tac x)
  apply(clarsimp)
  apply(rename_tac A w)
  apply(subgoal_tac "A \<in> cfgSTD_Nonblockingness_nonterminals Gi \<and>
           (\<exists>d. cfgLM.derivation_initial
                 Gi d \<and>
                (\<exists>n c. get_configuration (d n) = Some c \<and>
                       (\<exists>w1 w2. cfg_conf c = liftB w1 @ teA A # w2)))")
   prefer 2
   apply(simp add: cfgLM_accessible_nonterminals_def)
  apply(clarsimp)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac Go="F_CFG_EASTD_ALT Gi" and Gi="Gi" in F_CFG_EASTD_ALT_makes_equal_cfgLM_initial_marking_derivations)
       apply(force)
      apply(force)
     apply(force)
    apply(force)
   apply(force)
  apply(case_tac "d n")
   apply(simp add: get_configuration_def)
  apply(simp add: get_configuration_def)
  apply(case_tac c)
  apply(clarsimp)
  apply(case_tac a)
  apply(clarsimp)
  apply(rename_tac e)
  apply(subgoal_tac "\<lparr>cfg_conf = liftB w1 @ teA A # w2\<rparr> \<in> SSX" for SSX)
   prefer 2
   apply(rule_tac d="d" in cfgLM.belongs_configurations)
    apply(rule cfgLM.derivation_initial_belongs)
     apply(force)
    apply(force)
   apply(force)
  apply(subgoal_tac "prod_lhs \<lparr>prod_lhs = A, prod_rhs = w\<rparr> \<in> cfgSTD_Nonblockingness_nonterminals Gi \<and>
           setA (prod_rhs \<lparr>prod_lhs = A, prod_rhs = w\<rparr>) \<subseteq> cfgSTD_Nonblockingness_nonterminals Gi \<and>
           setB (prod_rhs \<lparr>prod_lhs = A, prod_rhs = w\<rparr>) \<subseteq> cfg_events Gi")
   prefer 2
   apply(simp add: valid_cfg_def)
   apply(force)
  apply(subgoal_tac "setA (liftB w1 @ w @ w2) \<subseteq> cfg_nonterminals Gi")
   prefer 2
   apply(simp add:  cfg_configurations_def setA_liftB setAConcat)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac w="liftB w1 @ w @ w2" and G="Gi" in construct_elimininating_derivation_prime)
     apply(force)
    apply(rule antisym)
     prefer 2
     apply(simp add: cfgSTD_Nonblockingness_nonterminals_def)
    apply(force)
   apply(force)
  apply(clarsimp)
  apply(subgoal_tac "\<lparr>cfg_conf = liftB v\<rparr> \<in> SSX" for SSX)
   prefer 2
   apply(rule_tac d="da" in cfgLM.belongs_configurations)
    apply(rule cfgLM.derivation_belongs)
       apply(force)
      apply(force)
     apply(simp add: cfg_configurations_def)
     apply(simp add: setBConcat)
    apply(force)
   apply(force)
  apply(subgoal_tac "derivation_append d (derivation_append (der2 \<lparr>cfg_conf = liftB w1 @ [teA A] @ w2\<rparr> \<lparr>prod_lhs = A, prod_rhs = w\<rparr>  \<lparr>cfg_conf = liftB w1 @ w @ w2\<rparr>) da (Suc 0)) n \<in> cfgLM.initial_marking_derivations  (F_CFG_EASTD_ALT Gi)")
   prefer 2
   apply(rule_tac A="cfgLM.initial_marking_derivations  (Gi)" in set_mp)
    apply(force)
   apply(thin_tac "cfgLM.initial_marking_derivations A = VB" for A VB)
   apply(simp add: cfgLM.initial_marking_derivations_def cfg_marking_condition_def)
   apply(rule context_conjI)
    apply(rule cfgLM.derivation_append_preserves_derivation_initial)
      apply(force)
     apply(force)
    apply(rule cfgLM.derivation_append_preserves_derivation)
      apply(simp add: cfgLM.derivation_initial_def)
     apply(rule cfgLM.derivation_append_preserves_derivation)
       apply(rule cfgLM.der2_is_derivation)
       apply(simp add: cfgLM_step_relation_def)
       apply(rule_tac x="liftB w1" in exI)
       apply(clarsimp)
       apply(simp add: setA_liftB)
      apply(force)
     apply(simp add: der2_def)
    apply(clarsimp)
    apply(simp add: derivation_append_def der2_def)
   apply(rule_tac x="n+Suc 0+na" in exI)
   apply(simp add: setA_liftB)
   apply(simp add: derivation_append_def der2_def cfg_marking_configuration_def cfg_configurations_def)
   apply(simp add: setA_liftB)
   apply(clarsimp)
   apply(rule_tac t="liftB w1 @ w @ w2" and s="liftB v" in ssubst)
    apply(force)
   apply(simp (no_asm) add: setA_liftB)
  apply(thin_tac "       ATS_Language0.initial_marking_derivations cfg_initial_configurations
        cfgLM_step_relation cfg_marking_condition (F_CFG_EASTD_ALT Gi) =
       ATS_Language0.initial_marking_derivations cfg_initial_configurations
        cfgLM_step_relation cfg_marking_condition Gi ")
  apply(simp add: cfgLM.initial_marking_derivations_def)
  apply(rule_tac x="derivation_append d
          (derivation_append
            (der2 \<lparr>cfg_conf = liftB w1 @ teA A # w2\<rparr> \<lparr>prod_lhs = A, prod_rhs = w\<rparr>
              \<lparr>cfg_conf = liftB w1 @ w @ w2\<rparr>)
            da (Suc 0))
          n" in exI)
  apply(clarsimp)
  apply(rule_tac x="Suc n" in exI)
  apply(simp add: derivation_append_def der2_def)
  done

theorem SOUND_FUN_CFGLMACX: "
  F_CFG_EASTD__SpecInput G
  \<Longrightarrow> F_CFG_EASTD__SpecOutput G (F_CFG_EASTD_ALT G)"
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule F_CFG_EASTD_ALT_preserves_valid_cfg)
    apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
    apply(force)
   apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac
      G="G"
      in F_CFG_EASTD_ALT_is_cfg_sub)
    apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
   apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac
      G="G"
      in F_CFG_APLMSoundL)
   apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac
      G="G"
      in F_CFG_EASTD_ALT_preserves_language)
    apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
   apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac
      G="G"
      in F_CFG_EASTD_ALT_preserves_Eliminability)
    apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
   apply(simp add: F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "X" for X)
   prefer 2
   apply(rule_tac G="G" in F_CFG_EASTD_ALT_makes_precise_accessible_and_Nonblockingness)
    apply(simp add: F_CFG_EASTD__SpecInput_def)
   apply(simp add: F_CFG_EASTD__SpecInput_def)
  apply(subgoal_tac "
cfgLM_accessible_nonterminals (F_CFG_EASTD_ALT G) \<inter> cfgSTD_Nonblockingness_nonterminals (F_CFG_EASTD_ALT G) = cfgLM_language_relevant_nonterminals (F_CFG_EASTD_ALT G)")
   prefer 2
   apply(rule cfgLM_language_relevant_nonterminals_vs_cfgLM_accessible_nonterminals_and_cfgSTD_Nonblockingness_nonterminals_in_cfgSTD_Nonblockingness_nonterminals_grammar)
      prefer 2
      apply(force)
     prefer 2
     apply(force)
    apply(simp add: F_CFG_EASTD_ALT_def F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
   apply(rule antisym)
    apply(force)
   apply(simp add: cfgSTD_Nonblockingness_nonterminals_def)
   apply(force)
  apply(subgoal_tac "cfgLM.initial_marking_derivations (F_CFG_EASTD_ALT G) = cfgLM.initial_marking_derivations G")
   prefer 2
   apply(rule F_CFG_EASTD_ALT_makes_equal_cfgLM_initial_marking_derivations)
       apply(simp add: F_CFG_EASTD_ALT_def F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
      apply(force)
     apply(simp add: F_CFG_EASTD_ALT_def F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
    apply(simp add: F_CFG_EASTD_ALT_def F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
   apply(simp add: F_CFG_EASTD_ALT_def F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  apply(subgoal_tac "cfgLM.marked_language (F_CFG_EASTD_ALT G) \<noteq> {}")
   prefer 2
   apply(rule cfg_with_cfgLM_Nonblockingness_nonterminals_has_nonempty_cfgLM_marked_language)
    apply(force)
   apply(rule_tac t="cfgLM_Nonblockingness_nonterminals (F_CFG_EASTD_ALT G)" and s="cfgSTD_Nonblockingness_nonterminals (F_CFG_EASTD_ALT G)" in ssubst)
    prefer 2
    apply(force)
   apply (metis cfgLM_Nonblockingness_nonterminals_vs_cfgSTD_Nonblockingness_nonterminals)
  apply(subgoal_tac "cfg_productions (F_CFG_EASTD_ALT G) = cfgLM_language_relevant_productions (F_CFG_EASTD_ALT G)")
   prefer 2
   apply(rule F_CFG_EASTD_ALT_enforces_cfgLM_language_relevant_productions)
       prefer 2
       apply(force)
      prefer 2
      apply(force)
     apply(simp add: F_CFG_EASTD__SpecInput_def)
    apply(simp add: F_CFG_EASTD__SpecInput_def)
   apply(force)
  apply(simp add: F_CFG_EASTD_ALT_def F_CFG_EASTD__SpecInput_def F_CFG_EASTD__SpecOutput_def)
  done

end