(*  Title:      JinjaThreads/Framework/FWDeadlock.thy
    Author:     Andreas Lochbihler
*)

header {* \isaheader{Deadlock formalisation} *}

theory FWDeadlock
imports
  FWProgressAux
begin

context final_thread begin

definition all_final_except :: "('l,'t,'x,'m,'w) state \<Rightarrow> 't set \<Rightarrow> bool" where
  "all_final_except s Ts \<equiv> \<forall>t. not_final_thread s t \<longrightarrow> t \<in> Ts"

lemma all_final_except_mono [mono]:
  "(\<And>x. x \<in> A \<longrightarrow> x \<in> B) \<Longrightarrow> all_final_except ts A \<longrightarrow> all_final_except ts B"
by(auto simp add: all_final_except_def)

lemma all_final_except_mono':
  "\<lbrakk> all_final_except ts A; \<And>x. x \<in> A \<Longrightarrow> x \<in> B \<rbrakk> \<Longrightarrow> all_final_except ts B"
by(blast intro: all_final_except_mono[rule_format])

lemma all_final_exceptI:
  "(\<And>t. not_final_thread s t \<Longrightarrow> t \<in> Ts) \<Longrightarrow> all_final_except s Ts"
by(auto simp add: all_final_except_def)

lemma all_final_exceptD:
  "\<lbrakk> all_final_except s Ts; not_final_thread s t \<rbrakk> \<Longrightarrow> t \<in> Ts"
by(auto simp add: all_final_except_def)

inductive must_wait :: "('l,'t,'x,'m,'w) state \<Rightarrow> 't \<Rightarrow> ('l + 't + 't) \<Rightarrow> 't set \<Rightarrow> bool"
  for s :: "('l,'t,'x,'m,'w) state" and t :: "'t" where
  -- "Lock l"
  "\<lbrakk> has_lock (locks s $ l) t'; t' \<noteq> t; t' \<in> Ts \<rbrakk> \<Longrightarrow> must_wait s t (Inl l) Ts"
| -- "Join t'"
  "\<lbrakk> not_final_thread s t'; t' \<in> Ts \<rbrakk> \<Longrightarrow> must_wait s t (Inr (Inl t')) Ts"
| -- "IsInterrupted t' True"
  "\<lbrakk> all_final_except s Ts; t' \<notin> interrupts s \<rbrakk> \<Longrightarrow> must_wait s t (Inr (Inr t')) Ts"

declare must_wait.cases [elim]
declare must_wait.intros [intro]

inductive_cases must_wait_elims2 [elim!]:
  "must_wait s t (Inl l) Ts"
  "must_wait s t (Inr (Inl t'')) Ts"
  "must_wait s t (Inr (Inr t'')) Ts"

lemma must_wait_iff:
  "must_wait s t lt Ts \<longleftrightarrow>
  (case lt of Inl l \<Rightarrow> \<exists>t'\<in>Ts. t \<noteq> t' \<and> has_lock (locks s $ l) t'
     | Inr (Inl t') \<Rightarrow> not_final_thread s t' \<and> t' \<in> Ts
     | Inr (Inr t') \<Rightarrow> all_final_except s Ts \<and> t' \<notin> interrupts s)"
by(auto simp add: must_wait.simps split: sum.splits)

end

text{* Deadlock as a system-wide property *}

context multithreaded_base begin

definition
  deadlock :: "('l,'t,'x,'m,'w) state \<Rightarrow> bool"
where
  "deadlock s
   \<equiv>   (\<forall>t x. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<and> \<not> final x \<and> wset s t = None
        \<longrightarrow> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (dom (thr s)))))
     \<and> (\<forall>t x ln. thr s t = \<lfloor>(x, ln)\<rfloor> \<and> (\<exists>l. ln $ l > 0) \<and> \<not> waiting (wset s t)
        \<longrightarrow> (\<exists>l t'. ln $ l > 0 \<and> t \<noteq> t' \<and> thr s t' \<noteq> None \<and> has_lock (locks s $ l) t'))
     \<and> (\<forall>t x w. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<longrightarrow> wset s t \<noteq> \<lfloor>PostWS w\<rfloor>)"

lemma deadlockI:
  "\<lbrakk> \<And>t x. \<lbrakk> thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>; \<not> final x; wset s t = None \<rbrakk>
    \<Longrightarrow> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (dom (thr s))));
    \<And>t x ln l. \<lbrakk> thr s t = \<lfloor>(x, ln)\<rfloor>; ln $ l > 0; \<not> waiting (wset s t) \<rbrakk>
    \<Longrightarrow> \<exists>l t'. ln $ l > 0 \<and> t \<noteq> t' \<and> thr s t' \<noteq> None \<and> has_lock (locks s $ l) t';
    \<And>t x w. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<Longrightarrow> wset s t \<noteq> \<lfloor>PostWS w\<rfloor> \<rbrakk>
  \<Longrightarrow> deadlock s"
by(auto simp add: deadlock_def)

lemma deadlockE:
  assumes "deadlock s"
  obtains "\<forall>t x. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<and> \<not> final x \<and> wset s t = None
        \<longrightarrow> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (dom (thr s))))"
  and "\<forall>t x ln. thr s t = \<lfloor>(x, ln)\<rfloor> \<and> (\<exists>l. ln $ l > 0) \<and> \<not> waiting (wset s t)
                \<longrightarrow> (\<exists>l t'. ln $ l > 0 \<and> t \<noteq> t' \<and> thr s t' \<noteq> None \<and> has_lock (locks s $ l) t')"
  and "\<forall>t x w. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<longrightarrow> wset s t \<noteq> \<lfloor>PostWS w\<rfloor>"
using assms unfolding deadlock_def by(blast)

lemma deadlockD1:
  assumes "deadlock s"
  and "thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>"
  and "\<not> final x"
  and "wset s t = None"
  obtains "t \<turnstile> \<langle>x, shr s\<rangle> \<wrong>"
  and "\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (dom (thr s)))"
using assms unfolding deadlock_def by(blast)

lemma deadlockD2:
  assumes "deadlock s"
  and "thr s t = \<lfloor>(x, ln)\<rfloor>"
  and "ln $ l > 0"
  and "\<not> waiting (wset s t)"
  obtains l' t' where "ln $ l' > 0" "t \<noteq> t'" "thr s t' \<noteq> None" "has_lock (locks s $ l') t'"
using assms unfolding deadlock_def by blast

lemma deadlockD3:
  assumes "deadlock s"
  and "thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>"
  shows "\<forall>w. wset s t \<noteq> \<lfloor>PostWS w\<rfloor>"
using assms unfolding deadlock_def by blast

lemma deadlock_def2:
  "deadlock s \<longleftrightarrow>
    (\<forall>t x. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<and> \<not> final x \<and> wset s t = None
    \<longrightarrow> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (dom (thr s)))))
  \<and> (\<forall>t x ln. thr s t = \<lfloor>(x, ln)\<rfloor> \<and> ln \<noteq> no_wait_locks \<and> \<not> waiting (wset s t)
    \<longrightarrow> (\<exists>l. ln $ l > 0 \<and> must_wait s t (Inl l) (dom (thr s))))
  \<and> (\<forall>t x w. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<longrightarrow> wset s t \<noteq> \<lfloor>PostWS WSNotified\<rfloor> \<and> wset s t \<noteq> \<lfloor>PostWS WSWokenUp\<rfloor>)"
unfolding neq_no_wait_locks_conv
apply(rule iffI)
 apply(intro strip conjI)
     apply(blast dest: deadlockD1)
    apply(blast dest: deadlockD1)
   apply(blast elim: deadlockD2)
  apply(blast dest: deadlockD3)
 apply(blast dest: deadlockD3)
apply(elim conjE exE)
apply(rule deadlockI)
  apply blast
 apply(rotate_tac 1)
 apply(erule allE, rotate_tac -1)
 apply(erule allE, rotate_tac -1)
 apply(erule allE, rotate_tac -1)
 apply(erule impE, blast)
 apply(elim exE conjE)
 apply(erule must_wait.cases)
   apply(clarify)
   apply(rotate_tac 3)
   apply(rule exI conjI|erule not_sym|assumption)+
    apply blast
   apply blast
  apply blast
 apply blast
apply(case_tac w)
 apply blast
apply blast
done

lemma all_waiting_implies_deadlock:
  assumes "lock_thread_ok (locks s) (thr s)"
  and normal: "\<And>t x. \<lbrakk> thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>; \<not> final x; wset s t = None \<rbrakk>
               \<Longrightarrow> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (dom (thr s))))"
  and acquire: "\<And>t x ln l. \<lbrakk> thr s t = \<lfloor>(x, ln)\<rfloor>; \<not> waiting (wset s t); ln $ l > 0 \<rbrakk>
                 \<Longrightarrow> \<exists>l'. ln $ l' > 0 \<and> \<not> may_lock (locks s $ l') t"
  and wakeup: "\<And>t x w. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<Longrightarrow> wset s t \<noteq> \<lfloor>PostWS w\<rfloor>"
  shows "deadlock s"
proof(rule deadlockI)
  fix T X
  assume "thr s T = \<lfloor>(X, no_wait_locks)\<rfloor>" "\<not> final X" "wset s T = None"
  thus "T \<turnstile> \<langle>X, shr s\<rangle> \<wrong> \<and> (\<forall>LT. T \<turnstile> \<langle>X, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt\<in>LT. must_wait s T lt (dom (thr s))))"
    by(rule normal)
next
  fix T X LN l'
  assume "thr s T = \<lfloor>(X, LN)\<rfloor>"
    and "0 < LN $ l'"
    and wset: "\<not> waiting (wset s T)"
  from acquire[OF `thr s T = \<lfloor>(X, LN)\<rfloor>` wset, OF `0 < LN $ l'`]
  obtain l' where "0 < LN $ l'" "\<not> may_lock (locks s $ l') T" by blast
  then obtain t' where "T \<noteq> t'" "has_lock (locks s $ l') t'"
    unfolding not_may_lock_conv by fastforce
  moreover with `lock_thread_ok (locks s) (thr s)`
  have "thr s t' \<noteq> None" by(auto dest: lock_thread_okD)
  ultimately show "\<exists>l t'. 0 < LN $ l \<and> T \<noteq> t' \<and> thr s t' \<noteq> None \<and> has_lock (locks s $ l) t'"
    using `0 < LN $ l'` by(auto)
qed(rule wakeup)

lemma mfinal_deadlock:
  "mfinal s \<Longrightarrow> deadlock s"
unfolding mfinal_def2
by(rule deadlockI)(auto simp add: final_thread_def)

text {* Now deadlock for single threads *}

lemma must_wait_mono:
  "(\<And>x. x \<in> A \<longrightarrow> x \<in> B) \<Longrightarrow> must_wait s t lt A \<longrightarrow> must_wait s t lt B"
by(auto simp add: must_wait_iff split: sum.split elim: all_final_except_mono')

lemma must_wait_mono':
  "\<lbrakk> must_wait s t lt A; A \<subseteq> B \<rbrakk> \<Longrightarrow> must_wait s t lt B"
using must_wait_mono[of A B s t lt]
by blast

end

lemma UN_mono: "\<lbrakk> x \<in> A \<longrightarrow> x \<in> A'; x \<in> B \<longrightarrow> x \<in> B' \<rbrakk> \<Longrightarrow> x \<in> A \<union> B \<longrightarrow> x \<in> A' \<union> B'"
by blast

lemma Collect_mono_conv [mono]: "x \<in> {x. P x} \<longleftrightarrow> P x"
by blast

context multithreaded_base begin

coinductive_set deadlocked :: "('l,'t,'x,'m,'w) state \<Rightarrow> 't set"
  for s :: "('l,'t,'x,'m,'w) state" where
  deadlockedLock:
    "\<lbrakk> thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>; t \<turnstile> \<langle>x, shr s\<rangle> \<wrong>; wset s t = None;
       \<And>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>lt \<in> LT. must_wait s t lt (deadlocked s \<union> final_threads s) \<rbrakk>
     \<Longrightarrow> t \<in> deadlocked s"

| deadlockedWait:
    "\<lbrakk> thr s t = \<lfloor>(x, ln)\<rfloor>; all_final_except s (deadlocked s); waiting (wset s t) \<rbrakk> \<Longrightarrow> t \<in> deadlocked s"

| deadlockedAcquire:
    "\<lbrakk> thr s t = \<lfloor>(x, ln)\<rfloor>; \<not> waiting (wset s t); ln $ l > 0; has_lock (locks s $ l) t'; t' \<noteq> t;
       t' \<in> deadlocked s \<or> final_thread s t' \<rbrakk>
     \<Longrightarrow> t \<in> deadlocked s"
monos must_wait_mono UN_mono

lemma deadlockedAcquire_must_wait:
  "\<lbrakk> thr s t = \<lfloor>(x, ln)\<rfloor>; \<not> waiting (wset s t); ln $ l > 0; must_wait s t (Inl l) (deadlocked s \<union> final_threads s) \<rbrakk>
  \<Longrightarrow> t \<in> deadlocked s"
apply(erule must_wait_elims)
apply(erule (2) deadlockedAcquire)
apply auto
done

lemma deadlocked_elims [consumes 1, case_names lock wait acquire]:
  assumes "t \<in> deadlocked s"
  obtains (lock) x
    where "thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>" "t \<turnstile> \<langle>x, shr s\<rangle> \<wrong>" "wset s t = None"
    and "\<And>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>lt \<in> LT. must_wait s t lt (deadlocked s \<union> final_threads s)"
  | (wait) x ln
    where "thr s t = \<lfloor>(x, ln)\<rfloor>" "all_final_except s (deadlocked s)" "waiting (wset s t)"
  | (acquire) x ln l t'
    where "thr s t = \<lfloor>(x, ln)\<rfloor>" "\<not> waiting (wset s t)" "0 < ln $ l" "has_lock (locks s $ l) t'" "t \<noteq> t'"
    and "t' \<in> deadlocked s \<or> final_thread s t'"
proof -
  from assms show thesis
    apply cases
    apply(rule lock, blast+)
    apply(rule wait, blast+)
    apply(rule acquire, blast+)
    done
qed

lemma deadlocked_coinduct
  [consumes 1, case_names deadlocked, case_conclusion deadlocked Lock Wait Acquire, coinduct set: deadlocked]:
  assumes major: "t \<in> X"
  and step:
  "\<And>t. t \<in> X \<Longrightarrow>
     (\<exists>x. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<and> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> wset s t = None \<and>
         (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt\<in>LT. must_wait s t lt (X \<union> deadlocked s \<union> final_threads s)))) \<or>
     (\<exists>x ln. thr s t = \<lfloor>(x, ln)\<rfloor> \<and> all_final_except s (X \<union> deadlocked s) \<and> waiting (wset s t)) \<or>
     (\<exists>x ln l t'. thr s t = \<lfloor>(x, ln)\<rfloor> \<and> \<not> waiting (wset s t) \<and> 0 < ln $ l \<and> has_lock (locks s $ l) t' \<and>
         t' \<noteq> t \<and> ((t' \<in> X \<or> t' \<in> deadlocked s) \<or> final_thread s t'))"
  shows "t \<in> deadlocked s"
using major
proof(coinduct)
  case (deadlocked t)
  have "X \<union> deadlocked s \<union> final_threads s = {x. x \<in> X \<or> x \<in> deadlocked s \<or> x \<in> final_threads s}"
    by auto
  moreover have "X \<union> deadlocked s = {x. x \<in> X \<or> x \<in> deadlocked s}" by blast
  ultimately show ?case using step[OF deadlocked] by(elim disjE) simp_all
qed

definition deadlocked' :: "('l,'t,'x,'m,'w) state \<Rightarrow> bool" where
  "deadlocked' s \<equiv> (\<forall>t. not_final_thread s t \<longrightarrow> t \<in> deadlocked s)"

lemma deadlocked'I:
  "(\<And>t. not_final_thread s t \<Longrightarrow> t \<in> deadlocked s) \<Longrightarrow> deadlocked' s"
by(auto simp add: deadlocked'_def)

lemma deadlocked'D2:
  "\<lbrakk> deadlocked' s; not_final_thread s t; t \<in> deadlocked s \<Longrightarrow> thesis \<rbrakk> \<Longrightarrow> thesis"
by(auto simp add: deadlocked'_def)

lemma not_deadlocked'I:
  "\<lbrakk> not_final_thread s t; t \<notin> deadlocked s \<rbrakk> \<Longrightarrow> \<not> deadlocked' s"
by(auto dest: deadlocked'D2)

lemma deadlocked'_intro:
  "\<lbrakk> \<forall>t. not_final_thread s t \<longrightarrow> t \<in> deadlocked s \<rbrakk> \<Longrightarrow> deadlocked' s"
by(rule deadlocked'I)(blast)+

lemma deadlocked_thread_exists:
  assumes "t \<in> deadlocked s"
  obtains x ln where "thr s t = \<lfloor>(x, ln)\<rfloor>"
using assms
by cases blast+

end

context multithreaded begin

lemma red_no_deadlock:
  assumes P: "s -t\<triangleright>ta\<rightarrow> s'"
  and dead: "t \<in> deadlocked s"
  shows False
proof -
  from P show False
  proof(cases)
    case (redT_normal x x' m')
    note red = `t \<turnstile> \<langle>x, shr s\<rangle> -ta\<rightarrow> \<langle>x', m'\<rangle>`
    note tst = `thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>`
    note aok = `actions_ok s t ta`
    show False
    proof(cases "\<exists>w. wset s t = \<lfloor>InWS w\<rfloor>")
      case True with aok show ?thesis by(auto simp add: wset_actions_ok_def split: split_if_asm)
    next
      case False
      with dead tst
      have mle: "t \<turnstile> \<langle>x, shr s\<rangle> \<wrong>"
        and cledead: "\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t lt (deadlocked s \<union> final_threads s))"
        by(cases, auto simp add: waiting_def)+
      let ?LT = "collect_waits ta"
      from red have "t \<turnstile> \<langle>x, shr s\<rangle> ?LT \<wrong>" by(auto intro: can_syncI)
      then obtain lt where lt: "lt \<in> ?LT" and mw: "must_wait s t lt (deadlocked s \<union> final_threads s)"
        by(blast dest: cledead[rule_format])
      from mw show False
      proof(cases rule: must_wait_elims)
        case (lock l t')
        from `lt = Inl l` lt have "l \<in> collect_locks \<lbrace>ta\<rbrace>\<^bsub>l\<^esub>" by(auto)
        with aok have "may_lock (locks s $ l) t"
          by(auto elim!: collect_locksE lock_ok_las_may_lock)
        with `has_lock (locks s $ l) t'` have "t' = t"
          by(auto dest: has_lock_may_lock_t_eq)
        with `t' \<noteq> t` show False by contradiction
      next
        case (join t')
        from `lt = Inr (Inl t')` lt have "Join t' \<in> set \<lbrace>ta\<rbrace>\<^bsub>c\<^esub>" by auto
        from `not_final_thread s t'`  obtain x'' ln''
          where "thr s t' = \<lfloor>(x'', ln'')\<rfloor>" by(rule not_final_thread_existsE)
        moreover with `Join t' \<in> set \<lbrace>ta\<rbrace>\<^bsub>c\<^esub>` aok
        have "final x''" "ln'' = no_wait_locks" "wset s t' = None"
          by(auto dest: cond_action_oks_Join)
        ultimately show False using `not_final_thread s t'` by(auto)
      next
        case (interrupt t')
        from  aok lt `lt = Inr (Inr t')`
        have "t' \<in> interrupts s"
          by(auto intro: collect_interrupts_interrupted)
        with `t' \<notin> interrupts s` show False by contradiction
      qed
    qed
  next
    case (redT_acquire x ln n)
    show False
    proof(cases "\<exists>w. wset s t = \<lfloor>InWS w\<rfloor>")
      case True with `\<not> waiting (wset s t)` show ?thesis
        by(auto simp add: not_waiting_iff)
    next
      case False
      with dead `thr s t = \<lfloor>(x, ln)\<rfloor>` `0 < ln $ n`
      obtain l t' where "0 < ln $ l" "t \<noteq> t'"
        and "has_lock (locks s $ l) t'"
        by(cases)(fastforce simp add: waiting_def)+
      hence "\<not> may_acquire_all (locks s) t ln"
        by(auto elim: may_acquire_allE dest: has_lock_may_lock_t_eq)
      with `may_acquire_all (locks s) t ln` show ?thesis by contradiction
    qed
  qed
qed

lemma deadlocked'_no_red:
  "\<lbrakk> s -t\<triangleright>ta\<rightarrow> s'; deadlocked' s \<rbrakk> \<Longrightarrow> False"
apply(rule red_no_deadlock)
 apply(assumption)
apply(erule deadlocked'D2)
by(rule red_not_final_thread)

lemma not_final_thread_deadlocked_final_thread [iff]:
  "thr s t = \<lfloor>xln\<rfloor> \<Longrightarrow> not_final_thread s t \<or> t \<in> deadlocked s \<or> final_thread s t"
by(auto simp add: not_final_thread_final_thread_conv[symmetric])

lemma all_waiting_deadlocked:
  assumes "not_final_thread s t"
  and "lock_thread_ok (locks s) (thr s)"
  and normal: "\<And>t x. \<lbrakk> thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>; \<not> final x; wset s t = None \<rbrakk>
               \<Longrightarrow> t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<and> (\<forall>LT. t \<turnstile> \<langle>x, shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt\<in>LT. must_wait s t lt (final_threads s)))"
  and acquire: "\<And>t x ln l. \<lbrakk> thr s t = \<lfloor>(x, ln)\<rfloor>; \<not> waiting (wset s t); ln $ l > 0 \<rbrakk>
                \<Longrightarrow> \<exists>l'. ln $ l' > 0 \<and> \<not> may_lock (locks s $ l') t"
  and wakeup: "\<And>t x w. thr s t = \<lfloor>(x, no_wait_locks)\<rfloor> \<Longrightarrow> wset s t \<noteq> \<lfloor>PostWS w\<rfloor>"
  shows "t \<in> deadlocked s"
proof -
  from `not_final_thread s t`
  have "t \<in> {t. not_final_thread s t}" by simp
  thus ?thesis
  proof(coinduct)
    case (deadlocked z)
    hence "not_final_thread s z" by simp
    then obtain x' ln' where "thr s z = \<lfloor>(x', ln')\<rfloor>" by(fastforce elim!: not_final_thread_existsE)
    {
      assume "wset s z = None" "\<not> final x'"
        and [simp]: "ln' = no_wait_locks"
      with `thr s z = \<lfloor>(x', ln')\<rfloor>`
      have "z \<turnstile> \<langle>x', shr s\<rangle> \<wrong> \<and> (\<forall>LT. z \<turnstile> \<langle>x', shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s z lt (final_threads s)))"
        by(auto dest: normal)
      then obtain "z \<turnstile> \<langle>x', shr s\<rangle> \<wrong>"
        and clnml: "\<And>LT. z \<turnstile> \<langle>x', shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>lt \<in> LT. must_wait s z lt (final_threads s)" by(blast)
      { fix LT
        assume "z \<turnstile> \<langle>x', shr s\<rangle> LT \<wrong>"
        then obtain lt where mw: "must_wait s z lt (final_threads s)" and lt: "lt \<in> LT"
          by(blast dest: clnml)
        from mw have "must_wait s z lt ({t. not_final_thread s t} \<union> deadlocked s \<union> final_threads s)"
          by(blast intro: must_wait_mono')
        with lt have "\<exists>lt \<in> LT. must_wait s z lt ({t. not_final_thread s t} \<union> deadlocked s \<union> final_threads s)"
          by blast }
      with `z \<turnstile> \<langle>x', shr s\<rangle> \<wrong>` `thr s z = \<lfloor>(x', ln')\<rfloor>` `wset s z = None` have ?case by(simp) }
    note c1 = this
    {
      assume wsz: "\<not> waiting (wset s z)"
        and "ln' \<noteq> no_wait_locks"
      from `ln' \<noteq> no_wait_locks` obtain l where "0 < ln' $ l"
        by(auto simp add: neq_no_wait_locks_conv)
      with wsz `thr s z = \<lfloor>(x', ln')\<rfloor>`
      obtain l' where "0 < ln' $ l'" "\<not> may_lock (locks s $ l') z"
        by(blast dest: acquire)
      then obtain t'' where "t'' \<noteq> z" "has_lock (locks s $ l') t''"
        unfolding not_may_lock_conv by blast
      with `lock_thread_ok (locks s) (thr s)`
      obtain x'' ln'' where "thr s t'' = \<lfloor>(x'', ln'')\<rfloor>"
        by(auto elim!: lock_thread_ok_has_lockE)
      hence "(not_final_thread s t'' \<or> t'' \<in> deadlocked s) \<or> final_thread s t''"
        by(clarsimp simp add: not_final_thread_iff final_thread_def)
      with wsz `0 < ln' $ l'` `thr s z = \<lfloor>(x', ln')\<rfloor>` `t'' \<noteq> z` `has_lock (locks s $ l') t''`
      have ?Acquire by simp blast
      hence ?case by simp }
    note c2 = this
    { fix w
      assume "waiting (wset s z)"
      with `thr s z = \<lfloor>(x', ln')\<rfloor>`
      have "?Wait" by(clarsimp simp add: all_final_except_def)
      hence ?case by simp }
    note c3 = this
    from `not_final_thread s z` `thr s z = \<lfloor>(x', ln')\<rfloor>` show ?case
    proof(cases rule: not_final_thread_cases2)
      case final show ?thesis
      proof(cases "wset s z")
        case None show ?thesis
        proof(cases "ln' = no_wait_locks")
          case True with None final show ?thesis by(rule c1)
        next
          case False
          from None have "\<not> waiting (wset s z)" by(simp add: not_waiting_iff)
          thus ?thesis using False by(rule c2)
        qed
      next
        case (Some w)
        show ?thesis
        proof(cases w)
          case (InWS w')
          with Some have "waiting (wset s z)" by(simp add: waiting_def)
          thus ?thesis by(rule c3)
        next
          case (PostWS w')
          with Some have "\<not> waiting (wset s z)" by(simp add: not_waiting_iff)
          moreover from PostWS `thr s z = \<lfloor>(x', ln')\<rfloor>` Some
          have "ln' \<noteq> no_wait_locks" by(auto dest: wakeup)
          ultimately show ?thesis by(rule c2)
        qed
      qed
    next
      case wait_locks show ?thesis
      proof(cases "wset s z")
        case None
        hence "\<not> waiting (wset s z)" by(simp add: not_waiting_iff)
        thus ?thesis using wait_locks by(rule c2)
      next
        case (Some w)
        show ?thesis
        proof(cases w)
          case (InWS w')
          with Some have "waiting (wset s z)" by(simp add: waiting_def)
          thus ?thesis by(rule c3)
        next
          case (PostWS w')
          with Some have "\<not> waiting (wset s z)" by(simp add: not_waiting_iff)
          moreover from PostWS `thr s z = \<lfloor>(x', ln')\<rfloor>` Some
          have "ln' \<noteq> no_wait_locks" by(auto dest: wakeup)
          ultimately show ?thesis by(rule c2)
        qed
      qed
    next
      case (wait_set w)
      show ?thesis
      proof(cases w)
        case (InWS w')
        with wait_set have "waiting (wset s z)" by(simp add: waiting_def)
        thus ?thesis by(rule c3)
      next
        case (PostWS w')
        with wait_set have "\<not> waiting (wset s z)" by(simp add: not_waiting_iff)
        moreover from PostWS `thr s z = \<lfloor>(x', ln')\<rfloor>` wait_set
        have "ln' \<noteq> no_wait_locks" by(auto dest: wakeup[simplified])
        ultimately show ?thesis by(rule c2)
      qed
    qed
  qed
qed

text {* Equivalence proof for both notions of deadlock *}

lemma deadlock_implies_deadlocked':
  assumes dead: "deadlock s"
  shows "deadlocked' s"
proof -
  show ?thesis
  proof(rule deadlocked'I)
    fix t
    assume "not_final_thread s t"
    hence "t \<in> {t. not_final_thread s t}" ..
    thus "t \<in> deadlocked s"
    proof(coinduct)
      case (deadlocked t'')
      hence "not_final_thread s t''" ..
      then obtain x'' ln'' where tst'': "thr s t'' = \<lfloor>(x'', ln'')\<rfloor>"
        by(rule not_final_thread_existsE)
      { assume "waiting (wset s t'')"
        moreover
        with tst'' have nfine: "not_final_thread s t''"
          unfolding waiting_def
          by(blast intro: not_final_thread.intros)
        ultimately have ?case using tst''
          by(blast intro: all_final_exceptI not_final_thread_final) }
      note c1 = this
      {
        assume wst'': "\<not> waiting (wset s t'')"
          and "ln'' \<noteq> no_wait_locks"
        then obtain l where l: "ln'' $ l > 0"
          by(auto simp add: neq_no_wait_locks_conv)
        with dead wst'' tst'' obtain l' T
          where "ln'' $ l' > 0" "t'' \<noteq> T"
          and hl: "has_lock (locks s $ l') T"
          and tsT: "thr s T \<noteq> None"
          by - (erule deadlockD2)
        moreover from `thr s T \<noteq> None`
        obtain xln where tsT: "thr s T = \<lfloor>xln\<rfloor>" by auto
        then obtain X LN where "thr s T = \<lfloor>(X, LN)\<rfloor>"
          by(cases xln, auto)
        moreover hence "not_final_thread s T \<or> final_thread s T"
          by(auto simp add: final_thread_def not_final_thread_iff)
        ultimately have ?case using wst'' tst'' by blast }
      note c2 = this
      { assume "wset s t'' = None"
        and [simp]: "ln'' = no_wait_locks"
        moreover
        with `not_final_thread s t''` tst''
        have "\<not> final x''" by(auto)
        ultimately obtain "t'' \<turnstile> \<langle>x'', shr s\<rangle> \<wrong>"
          and clnml: "\<And>LT. t'' \<turnstile> \<langle>x'', shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>t'. thr s t' \<noteq> None \<and> (\<exists>lt\<in>LT. must_wait s t'' lt (dom (thr s)))"
          using `thr s t'' = \<lfloor>(x'', ln'')\<rfloor>` `deadlock s`
          by(blast elim: deadlockD1)
        { fix LT
          assume "t'' \<turnstile> \<langle>x'', shr s\<rangle> LT \<wrong>"
          then obtain lt where lt: "lt \<in> LT"
            and mw: "must_wait s t'' lt (dom (thr s))"
            by(blast dest: clnml)
          note mw
          also have "dom (thr s) = {t. not_final_thread s t} \<union> deadlocked s \<union> final_threads s"
            by(auto simp add: not_final_thread_conv dest: deadlocked_thread_exists elim: final_threadE)
          finally have "\<exists>lt\<in>LT. must_wait s t'' lt ({t. not_final_thread s t} \<union> deadlocked s \<union> final_threads s)"
            using lt by blast }
        with `t'' \<turnstile> \<langle>x'', shr s\<rangle> \<wrong>` tst'' `wset s t'' = None` have ?case by(simp) }
      note c3 = this
      from `not_final_thread s t''` tst'' show ?case
      proof(cases rule: not_final_thread_cases2)
        case final show ?thesis
        proof(cases "wset s t''")
          case None show ?thesis
          proof(cases "ln'' = no_wait_locks")
            case True with None show ?thesis by(rule c3)
          next
            case False
            from None have "\<not> waiting (wset s t'')" by(simp add: not_waiting_iff)
            thus ?thesis using False by(rule c2)
          qed
        next
          case (Some w)
          show ?thesis
          proof(cases w)
            case (InWS w')
            with Some have "waiting (wset s t'')" by(simp add: waiting_def)
            thus ?thesis by(rule c1)
          next
            case (PostWS w')
            hence "\<not> waiting (wset s t'')" using Some by(simp add: not_waiting_iff)
            moreover from PostWS Some tst''
            have "ln'' \<noteq> no_wait_locks" by(auto dest: deadlockD3[OF dead])
            ultimately show ?thesis by(rule c2)
          qed
        qed
      next
        case wait_locks show ?thesis
        proof(cases "waiting (wset s t'')")
          case False
          thus ?thesis using wait_locks by(rule c2)
        next
          case True thus ?thesis by(rule c1)
        qed
      next
        case (wait_set w)
        show ?thesis
        proof(cases w)
          case InWS
          with wait_set have "waiting (wset s t'')" by(simp add: waiting_def)
          thus ?thesis by(rule c1)
        next
          case (PostWS w')
          hence "\<not> waiting (wset s t'')" using wait_set
            by(simp add: not_waiting_iff)
          moreover from PostWS wait_set tst''
          have "ln'' \<noteq> no_wait_locks" by(auto dest: deadlockD3[OF dead])
          ultimately show ?thesis by(rule c2)
        qed
      qed
    qed
  qed
qed

lemma deadlocked'_implies_deadlock:
  assumes dead: "deadlocked' s"
  shows "deadlock s"
proof -
  have deadlocked: "\<And>t. not_final_thread s t \<Longrightarrow> t \<in> deadlocked s"
    using dead by(rule deadlocked'D2)
  show ?thesis
  proof(rule deadlockI)
    fix t' x'
    assume "thr s t' = \<lfloor>(x', no_wait_locks)\<rfloor>"
      and "\<not> final x'"
      and "wset s t' = None"
    hence "not_final_thread s t'" by(auto intro: not_final_thread_final)
    hence "t' \<in> deadlocked s" by(rule deadlocked)
    thus "t' \<turnstile> \<langle>x', shr s\<rangle> \<wrong> \<and> (\<forall>LT. t' \<turnstile> \<langle>x', shr s\<rangle> LT \<wrong> \<longrightarrow> (\<exists>lt \<in> LT. must_wait s t' lt (dom (thr s))))"
    proof(cases rule: deadlocked_elims)
      case (lock x'')
      note lock = `\<And>LT. t' \<turnstile> \<langle>x'', shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>lt \<in> LT. must_wait s t' lt (deadlocked s \<union> final_threads s)`
      from `thr s t' = \<lfloor>(x'', no_wait_locks)\<rfloor>` `thr s t' = \<lfloor>(x', no_wait_locks)\<rfloor>`
      have [simp]: "x' = x''" by auto
      { fix LT
        assume "t' \<turnstile> \<langle>x'', shr s\<rangle> LT \<wrong>"
        from lock[OF this] obtain lt where lt: "lt \<in> LT"
          and mw: "must_wait s t' lt (deadlocked s \<union> final_threads s)" by blast
        have "deadlocked s \<union> final_threads s \<subseteq> dom (thr s)"
          by(auto elim: final_threadE dest: deadlocked_thread_exists)
        with mw have "must_wait s t' lt (dom (thr s))" by(rule must_wait_mono')
        with lt have "\<exists>lt\<in>LT. must_wait s t' lt (dom (thr s))" by blast }
      with `t' \<turnstile> \<langle>x'', shr s\<rangle> \<wrong>` show ?thesis by(auto)
    next
      case (wait x'' ln'')
      from `wset s t' = None` `waiting (wset s t')`
      have False by(simp add: waiting_def)
      thus ?thesis ..
    next
      case (acquire x'' ln'' l'' T)
      from `thr s t' = \<lfloor>(x'', ln'')\<rfloor>` `thr s t' = \<lfloor>(x', no_wait_locks)\<rfloor>` `0 < ln'' $ l''`
      have False by(auto)
      thus ?thesis ..
    qed
  next
    fix t' x' ln' l
    assume "thr s t' = \<lfloor>(x', ln')\<rfloor>"
      and "0 < ln' $ l"
      and wst': "\<not> waiting (wset s t')"
    hence "not_final_thread s t'" by(auto intro: not_final_thread_wait_locks)
    hence "t' \<in> deadlocked s" by(rule deadlocked)
    thus "\<exists>l T. 0 < ln' $ l \<and> t' \<noteq> T \<and> thr s T \<noteq> None \<and> has_lock (locks s $ l) T"
    proof(cases rule: deadlocked_elims)
      case (lock x'')
      from `thr s t' = \<lfloor>(x', ln')\<rfloor>` `thr s t' = \<lfloor>(x'', no_wait_locks)\<rfloor>` `0 < ln' $ l`
      have False by auto
      thus ?thesis ..
    next
      case (wait x' ln')
      from wst' `waiting (wset s t')`
      have False by contradiction
      thus ?thesis ..
    next
      case (acquire x'' ln'' l'' t'')
      from `thr s t' = \<lfloor>(x'', ln'')\<rfloor>` `thr s t' = \<lfloor>(x', ln')\<rfloor>`
      have [simp]: "x' = x''" "ln' = ln''" by auto
      moreover from `t'' \<in> deadlocked s \<or> final_thread s t''`
      have "thr s t'' \<noteq> None"
        by(auto elim: deadlocked_thread_exists simp add: final_thread_def)
      with `0 < ln'' $ l''` `has_lock (locks s $ l'') t''` `t' \<noteq> t''` `thr s t' = \<lfloor>(x'', ln'')\<rfloor>`
      show ?thesis by auto
    qed
  next
    fix t x w
    assume tst: "thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>"
    show "wset s t \<noteq> \<lfloor>PostWS w\<rfloor>"
    proof
      assume "wset s t = \<lfloor>PostWS w\<rfloor>"
      moreover with tst have "not_final_thread s t"
        by(auto simp add: not_final_thread_iff)
      hence "t \<in> deadlocked s" by(rule deadlocked)
      ultimately show False using tst
        by(auto elim: deadlocked.cases simp add: waiting_def)
    qed
  qed
qed

lemma deadlock_eq_deadlocked':
  "deadlock = deadlocked'"
by(rule ext)(auto intro: deadlock_implies_deadlocked' deadlocked'_implies_deadlock)

lemma deadlock_no_red:
  "\<lbrakk> s -t\<triangleright>ta\<rightarrow> s'; deadlock s \<rbrakk> \<Longrightarrow> False"
unfolding deadlock_eq_deadlocked'
by(rule deadlocked'_no_red)

lemma deadlock_no_active_threads:
  assumes dead: "deadlock s"
  shows "active_threads s = {}"
proof(rule equals0I)
  fix t
  assume active: "t \<in> active_threads s"
  then obtain ta s' where "s -t\<triangleright>ta\<rightarrow> s'" by(auto dest: active_thread_ex_red)
  thus False using dead by(rule deadlock_no_red)
qed

end

locale preserve_deadlocked = multithreaded final r convert_RA
  for final :: "'x \<Rightarrow> bool"
  and r :: "('l,'t,'x,'m,'w,'o) semantics" ("_ \<turnstile> _ -_\<rightarrow> _" [50,0,0,50] 80)
  and convert_RA :: "'l released_locks \<Rightarrow> 'o list"
  +
  fixes wf_state :: "('l,'t,'x,'m,'w) state set"
  assumes invariant3p_wf_state: "invariant3p redT wf_state"
  assumes can_lock_preserved:
    "\<lbrakk> s \<in> wf_state; s -t'\<triangleright>ta'\<rightarrow> s';
       thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>; t \<turnstile> \<langle>x, shr s\<rangle> \<wrong> \<rbrakk>
    \<Longrightarrow> t \<turnstile> \<langle>x, shr s'\<rangle> \<wrong>"
  and can_lock_devreserp:
    "\<lbrakk> s \<in> wf_state; s -t'\<triangleright>ta'\<rightarrow> s';
       thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>; t \<turnstile> \<langle>x, shr s'\<rangle> L \<wrong> \<rbrakk>
    \<Longrightarrow> \<exists>L'\<subseteq>L. t \<turnstile> \<langle>x, shr s\<rangle> L' \<wrong>"
begin

lemma redT_deadlocked_subset:
  assumes wfs: "s \<in> wf_state"
  and Red: "s -t\<triangleright>ta\<rightarrow> s'"
  shows "deadlocked s \<subseteq> deadlocked s'"
proof
  fix t'
  assume t'dead: "t' \<in> deadlocked s"
  from Red have tndead: "t \<notin> deadlocked s"
    by(auto dest: red_no_deadlock)
  with t'dead have t't: "t' \<noteq> t" by auto
  { fix t'
    assume "final_thread s t'"
    then obtain x' ln' where tst': "thr s t' = \<lfloor>(x', ln')\<rfloor>" by(auto elim!: final_threadE)
    with `final_thread s t'` have "final x'"
      and "wset s t' = None" and [simp]: "ln' = no_wait_locks"
      by(auto elim: final_threadE)
    with Red tst' have "t \<noteq> t'" by cases(auto dest: final_no_red)
    with Red tst' have "thr s' t' = \<lfloor>(x', ln')\<rfloor>"
      by cases(auto intro: redT_updTs_Some)
    moreover from Red  `t \<noteq> t'` `wset s t' = None`
    have "wset s' t' = None" by cases(auto simp: redT_updWs_None_implies_None)
    ultimately have "final_thread s' t'" using tst' `final x'`
      by(auto simp add: final_thread_def) }
  hence subset: "deadlocked s \<union> final_threads s \<subseteq> deadlocked s \<union> deadlocked s' \<union> final_threads s'" by(auto)

  from Red show "t' \<in> deadlocked s'"
  proof(cases)
    case (redT_normal x x' m')
    note red = `t \<turnstile> \<langle>x, shr s\<rangle> -ta\<rightarrow> \<langle>x', m'\<rangle>`
      and tst = `thr s t = \<lfloor>(x, no_wait_locks)\<rfloor>`
      and aok = `actions_ok s t ta`
      and s' = `redT_upd s t ta x' m' s'`
    from red have "\<not> final x" by(auto dest: final_no_red)
    with tndead tst have nafe: "\<not> all_final_except s (deadlocked s)"
      by(fastforce simp add: all_final_except_def not_final_thread_iff)
    from t'dead show ?thesis
    proof(coinduct)
      case (deadlocked t'')
      note t''dead = this
      with Red have t''t: "t'' \<noteq> t"
        by(auto dest: red_no_deadlock)
      from t''dead show ?case
      proof(cases rule: deadlocked_elims)
        case (lock X)
        hence est'': "thr s t'' = \<lfloor>(X, no_wait_locks)\<rfloor>"
          and msE: "t'' \<turnstile> \<langle>X, shr s\<rangle> \<wrong>"
          and csexdead: "\<And>LT. t'' \<turnstile> \<langle>X, shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>lt \<in> LT. must_wait s t'' lt (deadlocked s \<union> final_threads s)"
          by auto
        from t''t Red est''
        have es't'': "thr s' t'' = \<lfloor>(X, no_wait_locks)\<rfloor>"
          by(cases s)(cases s', auto elim!: redT_ts_Some_inv)
        note es't'' moreover
        from wfs Red est'' msE have msE': "t'' \<turnstile> \<langle>X, shr s'\<rangle> \<wrong>" by(rule can_lock_preserved)
        moreover
        { fix LT
          assume clL'': "t'' \<turnstile> \<langle>X, shr s'\<rangle> LT \<wrong>"
          with est'' have "\<exists>LT'\<subseteq>LT. t'' \<turnstile> \<langle>X, shr s\<rangle> LT' \<wrong>"
            by(rule can_lock_devreserp[OF wfs Red])
          then obtain LT' where clL': "t'' \<turnstile> \<langle>X, shr s\<rangle> LT' \<wrong>"
            and LL': "LT' \<subseteq> LT" by blast
          with csexdead obtain lt
            where lt: "lt \<in> LT" and mw: "must_wait s t'' lt (deadlocked s \<union> final_threads s)"
            by blast
          from mw have "must_wait s' t'' lt (deadlocked s \<union> deadlocked s' \<union> final_threads s')"
          proof(cases rule: must_wait_elims)
            case (lock l t')
            from `t' \<in> deadlocked s \<union> final_threads s` Red have tt': "t \<noteq> t'"
              by(auto dest: red_no_deadlock final_no_redT elim: final_threadE)
            from aok have "lock_actions_ok (locks s $ l) t (\<lbrace>ta\<rbrace>\<^bsub>l\<^esub> $ l)"
              by(auto simp add: lock_ok_las_def)
            with tt' `has_lock (locks s $ l) t'` s'
            have hl't': "has_lock (locks s' $ l) t'" by(auto)
            moreover note `t' \<noteq> t''`
            moreover from `t' \<in> deadlocked s \<union> final_threads s`
            have "t' \<in> (deadlocked s \<union> deadlocked s' \<union> final_threads s')"
              using subset by blast
            ultimately show ?thesis unfolding `lt = Inl l` ..
          next
            case (join t')
            note t'dead = `t' \<in> deadlocked s \<union> final_threads s`
            with Red have tt': "t \<noteq> t'"
              by(auto dest: red_no_deadlock final_no_redT elim: final_threadE)
            note nftt' = `not_final_thread s t'`
            from t'dead Red aok s' tt' have ts't': "thr s' t' = thr s t'"
              by(auto elim!: deadlocked_thread_exists final_threadE intro: redT_updTs_Some)
            from nftt' have "thr s t' \<noteq> None" by auto
            with nftt' t'dead have "t' \<in> deadlocked s"
              by(simp add: not_final_thread_final_thread_conv[symmetric])
            hence "not_final_thread s' t'"
            proof(cases rule: deadlocked_elims)
              case (lock x'')
              from `t' \<turnstile> \<langle>x'', shr s\<rangle> \<wrong>` have "\<not> final x''"
                by(auto elim: must_syncE dest: final_no_red)
              with `thr s t' = \<lfloor>(x'', no_wait_locks)\<rfloor>` ts't' show ?thesis
                by(auto intro: not_final_thread.intros)
            next
              case (wait x'' ln'')
              from `\<not> final x` tst `all_final_except s (deadlocked s)`
              have "t \<in> deadlocked s" by(fastforce dest: all_final_exceptD simp add: not_final_thread_iff)
              with Red have False by(auto dest: red_no_deadlock)
              thus ?thesis ..
            next
              case (acquire x'' ln'' l'' T'')
              from `thr s t' = \<lfloor>(x'', ln'')\<rfloor>` `0 < ln'' $ l''` ts't'
              show ?thesis by(auto intro: not_final_thread.intros(2))
            qed
            moreover from t'dead subset have "t' \<in> deadlocked s \<union> deadlocked s' \<union> final_threads s'" ..
            ultimately show ?thesis unfolding `lt = Inr (Inl t')` ..
          next
            case (interrupt t')
            from tst red aok have "not_final_thread s t"
              by(auto simp add: wset_actions_ok_def not_final_thread_iff split: split_if_asm dest: final_no_red)
            with `all_final_except s (deadlocked s \<union> final_threads s)`
            have "t \<in> deadlocked s \<union> final_threads s" by(rule all_final_exceptD)
            moreover have "t \<notin> deadlocked s" using Red by(blast dest: red_no_deadlock)
            moreover have "\<not> final_thread s t" using red tst by(auto simp add: final_thread_def dest: final_no_red)
            ultimately have False by blast
            thus ?thesis ..
          qed
          with lt have "\<exists>lt\<in>LT. must_wait s' t'' lt (deadlocked s \<union> deadlocked s' \<union> final_threads s')" by blast }
        moreover have "wset s' t'' = None" using s' t''t `wset s t'' = None`
          by(auto intro: redT_updWs_None_implies_None)
        ultimately show ?thesis by(auto)
      next
        case (wait x ln)
        from `all_final_except s (deadlocked s)` nafe have False by simp
        thus ?thesis by simp
      next
        case (acquire X ln l T)
        from t''t Red `thr s t'' = \<lfloor>(X, ln)\<rfloor>` s'
        have es't'': "thr s' t'' = \<lfloor>(X, ln)\<rfloor>"
          by(cases s)(auto dest: redT_ts_Some_inv)
        moreover
        from `T \<in> deadlocked s \<or> final_thread s T`
        have "T \<noteq> t"
        proof(rule disjE)
          assume "T \<in> deadlocked s"
          with Red show ?thesis by(auto dest: red_no_deadlock)
        next
          assume "final_thread s T"
          with Red show ?thesis
            by(auto dest!: final_no_redT simp add: final_thread_def)
        qed
        with s' tst Red `has_lock (locks s $ l) T` have "has_lock (locks s' $ l) T"
          by -(cases s, auto dest: redT_has_lock_inv[THEN iffD2])
        moreover
        from s' `T \<noteq> t` have wset: "wset s T = None \<Longrightarrow> wset s' T = None"
          by(auto intro: redT_updWs_None_implies_None)
        { fix x
          assume "thr s T = \<lfloor>(x, no_wait_locks)\<rfloor>"
          with `T \<noteq> t` Red s' aok tst have "thr s' T = \<lfloor>(x, no_wait_locks)\<rfloor>"
            by(auto intro: redT_updTs_Some) }
        moreover
        hence "final_thread s T \<Longrightarrow> final_thread s' T"
          by(auto simp add: final_thread_def intro: wset)
        moreover from `\<not> waiting (wset s t'')` s' t''t
        have "\<not> waiting (wset s' t'')"
          by(auto simp add: redT_updWs_None_implies_None redT_updWs_PostWS_imp_PostWS not_waiting_iff)
        ultimately have ?Acquire
          using `0 < ln $ l` `t'' \<noteq> T` `T \<in> deadlocked s \<or> final_thread s T` by(auto)
        thus ?thesis by simp
      qed
    qed
  next
    case (redT_acquire x ln n)
    hence [simp]: "ta = (K$ [], [], [], [], [], convert_RA ln)"
      and s': "s' = (acquire_all (locks s) t ln, (thr s(t \<mapsto> (x, no_wait_locks)), shr s), wset s, interrupts s)"
      and tst: "thr s t = \<lfloor>(x, ln)\<rfloor>"
      and wst: "\<not> waiting (wset s t)" by auto
    from t'dead show ?thesis
    proof(coinduct)
      case (deadlocked t'')
      note t''dead = this
      with Red have t''t: "t'' \<noteq> t"
        by(auto dest: red_no_deadlock)
      from t''dead show ?case
      proof(cases rule: deadlocked_elims)
        case (lock X)
        note clnml = `\<And>LT. t'' \<turnstile> \<langle>X, shr s\<rangle> LT \<wrong> \<Longrightarrow> \<exists>lt \<in> LT. must_wait s t'' lt (deadlocked s \<union> final_threads s)`
        note tst'' = `thr s t'' = \<lfloor>(X, no_wait_locks)\<rfloor>`
        with s' t''t have ts't'': "thr s' t'' = \<lfloor>(X, no_wait_locks)\<rfloor>" by simp
        moreover
        { fix LT
          assume "t'' \<turnstile> \<langle>X, shr s'\<rangle> LT \<wrong>"
          hence "t'' \<turnstile> \<langle>X, shr s\<rangle> LT \<wrong>" using s' by simp
          then obtain lt where lt: "lt \<in> LT" and hlnft: "must_wait s t'' lt (deadlocked s \<union> final_threads s)"
            by(blast dest: clnml)
          from hlnft have "must_wait s' t'' lt (deadlocked s \<union> deadlocked s' \<union> final_threads s')"
          proof(cases rule: must_wait_elims)
            case (lock l' T)
            from `has_lock (locks s $ l') T` s'
            have "has_lock (locks s' $ l') T"
              by(auto intro: has_lock_has_lock_acquire_locks)
            moreover note `T \<noteq> t''`
            moreover from `T \<in> deadlocked s \<union> final_threads s`
            have "T \<in> deadlocked s \<union> deadlocked s' \<union> final_threads s'" using subset by blast
            ultimately show ?thesis unfolding `lt = Inl l'` ..
          next
            case (join T)
            from `not_final_thread s T` have "thr s T \<noteq> None"
              by(auto simp add: not_final_thread_iff)
            moreover
            from `T \<in> deadlocked s \<union> final_threads s`
            have "T \<noteq> t"
            proof
              assume "T \<in> deadlocked s"
              with Red show ?thesis by(auto dest: red_no_deadlock)
            next
              assume "T \<in> final_threads s"
              with `0 < ln $ n` tst show ?thesis
                by(auto simp add: final_thread_def)
            qed
            ultimately have "not_final_thread s' T" using `not_final_thread s T` s'
              by(auto simp add: not_final_thread_iff)
            moreover from `T \<in> deadlocked s \<union> final_threads s`
            have "T \<in> deadlocked s \<union> deadlocked s' \<union> final_threads s'" using subset by blast
            ultimately show ?thesis unfolding `lt = Inr (Inl T)` ..
          next
            case (interrupt T)
            from tst wst `0 < ln $ n` have "not_final_thread s t"
              by(auto simp add: waiting_def not_final_thread_iff)
            with `all_final_except s (deadlocked s \<union> final_threads s)`
            have "t \<in> deadlocked s \<union> final_threads s" by(rule all_final_exceptD)
            moreover have "t \<notin> deadlocked s" using Red by(blast dest: red_no_deadlock)
            moreover have "\<not> final_thread s t" using tst `0 < ln $ n` by(auto simp add: final_thread_def)
            ultimately have False by blast
            thus ?thesis ..
          qed
          with lt have "\<exists>lt\<in>LT. must_wait s' t'' lt (deadlocked s \<union> deadlocked s' \<union> final_threads s')" by blast }
        moreover from `wset s t'' = None` s' have "wset s' t'' = None" by simp
        ultimately show ?thesis using `thr s t'' = \<lfloor>(X, no_wait_locks)\<rfloor>` `t'' \<turnstile> \<langle>X, shr s\<rangle> \<wrong>` s' by fastforce
      next
        case (wait X LN)
        have "all_final_except s' (deadlocked s)"
        proof(rule all_final_exceptI)
          fix T
          assume "not_final_thread s' T"
          hence "not_final_thread s T" using wst tst s'
            by(auto simp add: not_final_thread_iff split: split_if_asm)
          with `all_final_except s (deadlocked s)` `thr s t = \<lfloor>(x, ln)\<rfloor>`
          show "T \<in> deadlocked s" by-(erule all_final_exceptD)
        qed
        hence "all_final_except s' (deadlocked s \<union> deadlocked s')"
          by(rule all_final_except_mono') blast
        with t''t `thr s t'' = \<lfloor>(X, LN)\<rfloor>` `waiting (wset s t'')` s'
        have ?Wait by simp
        thus ?thesis by simp
      next
        case (acquire X LN l T)
        from `thr s t'' = \<lfloor>(X, LN)\<rfloor>` t''t s'
        have "thr s' t'' = \<lfloor>(X, LN)\<rfloor>" by(simp)
        moreover from `T \<in> deadlocked s \<or> final_thread s T` s' tst
        have "T \<in> deadlocked s \<or> final_thread s' T"
          by(clarsimp simp add: final_thread_def)
        moreover from `has_lock (locks s $ l) T` s'
        have "has_lock (locks s' $ l) T"
          by(auto intro: has_lock_has_lock_acquire_locks)
        moreover have "\<not> waiting (wset s' t'')" using `\<not> waiting (wset s t'')` s' by simp
        ultimately show ?thesis using `0 < LN $ l` `t'' \<noteq> T` by blast
      qed
    qed
  qed
qed

corollary RedT_deadlocked_subset:
  assumes wfs: "s \<in> wf_state"
  and Red: "s -\<triangleright>ttas\<rightarrow>* s'"
  shows "deadlocked s \<subseteq> deadlocked s'"
using Red
apply(induct rule: RedT_induct')
apply(unfold RedT_def)
apply(blast dest: invariant3p_rtrancl3p[OF invariant3p_wf_state _ wfs] redT_deadlocked_subset)+
done

end

end


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

header{*The n_germanSimp Protocol Case Study*}

theory n_germanSimp_lemma_inv__6_on_rules imports n_germanSimp_lemma_on_inv__6
begin
section{*All lemmas on causal relation between inv__6*}
lemma lemma_inv__6_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv3 p__Inv4. p__Inv3\<le>N\<and>p__Inv4\<le>N\<and>p__Inv3~=p__Inv4\<and>f=inv__6  p__Inv3 p__Inv4)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__0 N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__1 N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_StoreVsinv__6) done
    }

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

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

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

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

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

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

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

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

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

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

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

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

end


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

header{*The n_germanSimp Protocol Case Study*}

theory n_germanSimp_lemma_inv__2_on_rules imports n_germanSimp_lemma_on_inv__2
begin
section{*All lemmas on causal relation between inv__2*}
lemma lemma_inv__2_on_rules:
  assumes b1: "r \<in> rules N" and b2: "(\<exists> p__Inv3 p__Inv4. p__Inv3\<le>N\<and>p__Inv4\<le>N\<and>p__Inv3~=p__Inv4\<and>f=inv__2  p__Inv3 p__Inv4)"
  shows "invHoldForRule s f r (invariants N)"
  proof -
  have c1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__0 N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvReqE__part__1 N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_SendGntE N i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)\<or>
    (\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)"
  apply (cut_tac b1, auto) done
    moreover {
      assume d1: "(\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d)"
      have "invHoldForRule s f r (invariants N)"
      apply (cut_tac b2 d1, metis n_StoreVsinv__2) done
    }

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

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

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

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

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

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

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

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

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

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

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

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

end


theory InferLemma
  imports InferDef FlatLemma
begin

lemma ifl_end_leq_use_env: "\<lbrakk> leq_use_env r_x r_s \<rbrakk> \<Longrightarrow>
  leq_use_env (comp_use_env (drop_use_env r_x) rx) (comp_use_env (comp_use_env (drop_use_env r_s) (infl_use_env r_s r_x)) rx)"
  apply (rule_tac dist_comp_leq_use_env)
   apply (rule_tac comp_leq_use_env1)
   apply (rule_tac comp_leq_use_env1)
   apply (rule_tac dist_drop_leq_use_env)
   apply (simp)
  apply (rule_tac self_comp_leq_use_env2)
  done

lemma cut_comp_leq_use_env: "leq_use_env (cut_use_env (comp_use_env r_s r_x)) (comp_use_env r_s (cut_use_env r_x))"
  apply (simp add: leq_use_env_def)
  apply (simp add: cut_use_env_def)
  apply (simp add: comp_use_env_def)
  apply (auto)
   apply (case_tac "r_s x")
     apply (auto)
  apply (case_tac "r_s x")
    apply (auto)
   apply (case_tac "r_x x")
     apply (auto)
  apply (case_tac "r_x x")
    apply (auto)
  done

lemma ifl_req_leq_use_env: "\<lbrakk> leq_use_env (diff_use_env r_s (comp_use_env r_x r_ex)) rx \<rbrakk> \<Longrightarrow>
  leq_use_env (diff_use_env r_s (comp_use_env r_x (cut_use_env r_ex))) rx"
  apply (rule_tac r_sb="diff_use_env r_s (comp_use_env r_x r_ex)" in trans_leq_use_env)
   apply (simp)
  apply (rule_tac dist_diff_leq_use_env_cut)
   apply (rule_tac id_leq_use_env)
  apply (rule_tac cut_comp_leq_use_env)
  done

lemma infl_leq_use_env_gen: "\<lbrakk> leq_use_env r_x (diff_use_env r_s r_ex); leq_use_env r_ex r_s \<rbrakk> \<Longrightarrow>
  leq_use_env r_ex (comp_use_env (drop_use_env r_s) (infl_use_env r_s r_x))"
  apply (simp add: leq_use_env_def)
  apply (auto)
  apply (erule_tac x="x" in allE)
  apply (erule_tac x="x" in allE)
  apply (simp add: comp_use_env_def)
  apply (simp add: drop_use_env_def)
  apply (simp add: diff_use_env_def)
  apply (simp add: infl_use_env_def)
  apply (auto)
    apply (case_tac "r_s x")
      apply (auto)
   apply (case_tac "r_ex x")
     apply (auto)
   apply (case_tac "r_x x")
     apply (auto)
  apply (case_tac "r_s x")
    apply (auto)
  done

    (* the key that makes this lemma work is that if r_s1 = Own is necessary, but r_s2 = Own,
          then rx = Own as well. for instance, take the lhs of a pair. if the pair requires
          ownership, then normally rx = Own, or r_s2 = None. the only time this doesn't happen is
          when the lhs is primitive, and so it can be removed. however in this case, an
          application must have been performed, since all necessary permissions have been removed.

      so proving this lemma is probably more efficient if we do it with more concrete r_s1, r_s2.
 *)

lemma infer_flat_lemma: "\<lbrakk> well_typed env r_s1 e tau r_s2 rx \<rbrakk> \<Longrightarrow>
  well_typed env (comp_use_env (comp_use_env (drop_use_env r_s1) (infl_use_env r_s1 r_s2)) rx) e tau
    (comp_use_env (drop_use_env r_s2) rx) rx"
  apply (induct e arbitrary: env r_s1 tau r_s2 rx)
        apply (auto)
    (* const case *)
           apply (rule_tac ifl_end_leq_use_env)
           apply (simp)
          apply (rule_tac self_comp_leq_use_env2)
    (* op case *)
         apply (rule_tac ifl_end_leq_use_env)
         apply (simp)
        apply (rule_tac self_comp_leq_use_env2)
    (* var case p1. *)
       apply (rule_tac r_sb="comp_use_env rx (infl_use_env r_s1 r_s2)" in trans_leq_use_env)
        apply (rule_tac dist_comp_leq_use_env)
         apply (rule_tac self_comp_leq_use_env2)
        apply (rule_tac comp_leq_use_env1)
        apply (rule_tac self_comp_leq_use_env2)
       apply (rule_tac st_diff_comp_leq_use_env)
       apply (rule_tac r_sb="diff_use_env (ereq_use_env (owner_name x) tau_x) (comp_use_env (ereq_use_env (owner_name x) tau_x) r_ex)" in trans_leq_use_env)
        apply (simp)
       apply (rule_tac dist_diff_leq_use_env_cut)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac infl_leq_use_env)
        apply (simp)
       apply (rule_tac dist_comp_leq_use_env)
        apply (simp_all)
    (* var case p2. *)
      apply (rule_tac x="cut_use_env r_ex" in exI)
      apply (auto)
         apply (rule_tac mini_disj_diff_leq_use_env2)
          apply (rule_tac ifl_end_leq_use_env)
          apply (rule_tac r_sb="diff_use_env r_s1 (comp_use_env (ereq_use_env (owner_name x) tau_x) r_ex)" in trans_leq_use_env)
           apply (rule_tac self_diff_leq_use_env)
          apply (simp)
         apply (rule_tac r_s="comp_use_env (ereq_use_env (owner_name x) tau_x) r_ex" in mini_disj_leq_use_env1)
          apply (rule_tac r_s="diff_use_env r_s1 (comp_use_env (ereq_use_env (owner_name x) tau_x) r_ex)" in mini_disj_leq_use_env2)
           apply (rule_tac mini_disj_diff_use_env)
          apply (rule_tac r_sb="r_s2" in trans_leq_use_env)
           apply (simp)
          apply (rule_tac dist_comp_leq_use_env)
           apply (rule_tac self_drop_leq_use_env)
          apply (simp)
         apply (rule_tac dist_comp_leq_use_env)
          apply (rule_tac self_comp_leq_use_env1)
         apply (rule_tac comp_leq_use_env2)
         apply (rule_tac self_cut_leq_use_env)
        apply (rule_tac self_comp_leq_use_env2)
       apply (rule_tac comp_leq_use_env1)
       apply (rule_tac comp_leq_use_env2)
       apply (rule_tac infl_leq_use_env)
        apply (rule_tac r_sb="diff_use_env r_s1 (comp_use_env (ereq_use_env (owner_name x) tau_x) r_ex)" in trans_leq_use_env)
         apply (rule_tac dist_diff_leq_use_env_gen)
          apply (rule_tac id_leq_use_env)
         apply (rule_tac self_comp_leq_use_env2)
        apply (simp_all)
      apply (rule_tac ifl_req_leq_use_env)
      apply (simp)
    (* pair case *)
     apply (cut_tac r_sc="r_s3" and r_sb="r_s2a" and r_sa="r_s1" in trans_leq_use_env)
       apply (rule_tac well_typed_perm_leq)
       apply (auto)
      apply (rule_tac well_typed_perm_leq)
      apply (auto)
     apply (rule_tac x="comp_use_env (drop_use_env r_s2a) rx1" in exI)
     apply (rule_tac x="comp_use_env (drop_use_env r_s3) rx2" in exI)
     apply (rule_tac x="rx1" in exI)
     apply (auto)
      apply (rule_tac ?r_s1.0="comp_use_env (comp_use_env (drop_use_env r_s1) (infl_use_env r_s1 r_s2a)) rx1" in well_typed_incr_start_perm)
       apply (simp)
      apply (rule_tac dist_comp_leq_use_env)
       apply (rule_tac comp_leq_use_env1)
       apply (rule_tac dist_comp_leq_use_env)
        apply (rule_tac self_comp_leq_use_env1)
       apply (rule_tac comp_leq_use_env2)
       apply (rule_tac dist_infl_leq_use_env)
        apply (rule_tac id_leq_use_env)
       apply (rule_tac r_sb="diff_use_env r_s3 r_ex" in trans_leq_use_env)
        apply (rule_tac diff_leq_use_env)
        apply (rule_tac well_typed_perm_leq)
        apply (auto)
      apply (rule_tac comp_leq_use_env1)
      apply (rule_tac infl_leq_use_env_gen)
    apply (rule_tac diff_

end


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

header{*The n_germanSymIndex Protocol Case Study*}

theory n_germanSymIndex_lemma_on_inv__40 imports n_germanSymIndex_base
begin
section{*All lemmas on causal relation between inv__40 and some rule r*}
lemma n_RecvReqSVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqS N i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvReqS N i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv2) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv2) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv2) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_RecvReqEVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvReqE N i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvReqE N i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv2) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv2) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const true)) (eqn (IVar (Field (Para (Ident ''Chan2'') p__Inv2) ''Cmd'')) (Const GntE))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendInv__part__0Vsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__0  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendInv__part__0  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendInv__part__1Vsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendInv__part__1  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendInv__part__1  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendInvAckVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendInvAck  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendInvAck  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendGntSVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendGntS  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendGntS  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendGntEVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_SendGntE N i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_SendGntE N i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P3 s"
  apply (cut_tac a1 a2 b1, simp, rule_tac x="(neg (andForm (eqn (IVar (Para (Ident ''InvSet'') p__Inv0)) (Const true)) (eqn (IVar (Para (Ident ''ShrSet'') p__Inv0)) (Const false))))" in exI, auto) done
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_RecvGntSVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntS  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvGntS  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_RecvGntEVsinv__40:
assumes a1: "(\<exists> i. i\<le>N\<and>r=n_RecvGntE  i)" and
a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
shows "invHoldForRule s f r (invariants N)" (is "?P1 s \<or> ?P2 s \<or> ?P3 s")
proof -
from a1 obtain i where a1:"i\<le>N\<and>r=n_RecvGntE  i" apply fastforce done
from a2 obtain p__Inv0 p__Inv2 where a2:"p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2" apply fastforce done
have "(i=p__Inv2)\<or>(i=p__Inv0)\<or>(i~=p__Inv0\<and>i~=p__Inv2)" apply (cut_tac a1 a2, auto) done
moreover {
  assume b1: "(i=p__Inv2)"
  have "?P1 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i=p__Inv0)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
moreover {
  assume b1: "(i~=p__Inv0\<and>i~=p__Inv2)"
  have "?P2 s"
  proof(cut_tac a1 a2 b1, auto) qed
  then have "invHoldForRule s f r (invariants N)" by auto
}
ultimately show "invHoldForRule s f r (invariants N)" by satx
qed

lemma n_SendReqE__part__1Vsinv__40:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendReqE__part__1  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_StoreVsinv__40:
  assumes a1: "\<exists> i d. i\<le>N\<and>d\<le>N\<and>r=n_Store  i d" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_RecvInvAckVsinv__40:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_RecvInvAck  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_SendReqE__part__0Vsinv__40:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendReqE__part__0  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

lemma n_SendReqSVsinv__40:
  assumes a1: "\<exists> i. i\<le>N\<and>r=n_SendReqS  i" and
  a2: "(\<exists> p__Inv0 p__Inv2. p__Inv0\<le>N\<and>p__Inv2\<le>N\<and>p__Inv0~=p__Inv2\<and>f=inv__40  p__Inv0 p__Inv2)"
  shows "invHoldForRule s f r (invariants N)"
  apply (rule noEffectOnRule, cut_tac a1 a2, auto) done

end


theory flash113Rev imports flashPub
begin
section{*Main defintions*}
lemma NI_FAckVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (NI_FAck ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma NI_InvVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Inv  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_InvAck_1VsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_InvAck_1  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_InvAck_1_HomeVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_InvAck_1_Home  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_InvAck_2VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_InvAck_2 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_GetXVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_GetX  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_Nak1VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_Nak1  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_Nak2VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_Nak2  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_Nak3VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_Nak3  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX1VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX1 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX2VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX2 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX3VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX3 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX4VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX4 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX5VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX5 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX6VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX6 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX7VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX7 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX8VsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX8 N  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX8_homeVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX8_home N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX9VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX9 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX10VsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX10 N  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX10_homeVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX10_home N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_GetX_PutX11VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_GetX_PutX11 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_GetVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Get  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_Nak1VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Nak1  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_Nak2VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Nak2  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_Nak3VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Nak3  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_Put1VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Put1 N  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_Put2VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Put2  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_Get_Put3VsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Local_Get_Put3  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Local_PutVsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (NI_Local_Put ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply( auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_Local_PutXAcksDoneVsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (NI_Local_PutXAcksDone ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply( auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_NakVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Nak  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Nak_ClearVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (NI_Nak_Clear ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma NI_Nak_HomeVsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (NI_Nak_Home ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply( auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_Remote_GetX_NakVsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_GetX_Nak  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Remote_GetX_Nak_HomeVsInv113:
  (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_GetX_Nak_Home  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply(cut_tac  a1 , auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_Remote_GetX_PutXVsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_GetX_PutX  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Remote_GetX_PutX_HomeVsInv113:
  (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_GetX_PutX_Home  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply(cut_tac  a1 , auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_Remote_Get_Nak1VsInv113:
  (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_Get_Nak1  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply(cut_tac  a1 , auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_Remote_Get_Nak2VsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_Get_Nak2  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Remote_Get_Put1VsInv113:
  (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_Get_Put1  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply(cut_tac  a1 , auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma NI_Remote_Get_Put2VsInv113:
    (*Rule2VsPInv0*)
  assumes   a1:"iRule1 \<le> N" and  a2:"iRule2 \<le> N" and  a3:"iRule1~=iRule2  "

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_Get_Put2  iRule1  iRule2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1 a2 a3,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Remote_PutVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_Put  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_Remote_PutXVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Remote_PutX  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_ReplaceVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_Replace  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_ReplaceHomeVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (NI_ReplaceHome ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma NI_ReplaceHomeShrVldVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (NI_ReplaceHomeShrVld ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma NI_ReplaceShrVldVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (NI_ReplaceShrVld  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma NI_ShWbVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (NI_ShWb N ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma NI_WbVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (NI_Wb ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma PI_Local_GetX_GetX1VsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_GetX_GetX1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply( auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma PI_Local_GetX_GetX2VsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_GetX_GetX2 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply( auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma PI_Local_GetX_PutX1VsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_GetX_PutX1 N ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P3 s"

        apply(    simp)

        apply(rule_tac x=" (neg ( andForm ( eqn ( IVar ( Para ''UniMsg_Cmd'' Home) )  ( Const UNI_Get ))    ( eqn ( IVar ( Para ''procCmd'' Home) )  ( Const NODE_None ))  ) ) " in exI,auto)

        done

       then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

        by blast

 qed
lemma PI_Local_GetX_PutX2VsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (PI_Local_GetX_PutX2 N ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma PI_Local_GetX_PutX3VsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_GetX_PutX3 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P3 s"

        apply(    simp)

        apply(rule_tac x=" (neg ( andForm ( eqn ( IVar ( Para ''UniMsg_Cmd'' Home) )  ( Const UNI_Get ))    ( eqn ( IVar ( Para ''procCmd'' Home) )  ( Const NODE_None ))  ) ) " in exI,auto)

        done

       then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

        by blast

 qed
lemma PI_Local_GetX_PutX4VsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_GetX_PutX4 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P3 s"

        apply(    simp)

        apply(rule_tac x=" (neg ( andForm ( eqn ( IVar ( Para ''UniMsg_Cmd'' Home) )  ( Const UNI_Get ))    ( eqn ( IVar ( Para ''procCmd'' Home) )  ( Const NODE_None ))  ) ) " in exI,auto)

        done

       then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

        by blast

 qed
lemma PI_Local_Get_GetVsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_Get_Get ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P1 s"

        apply( auto)

        done

        then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

       by blast

 qed
lemma PI_Local_Get_PutVsInv113:
  (*Rule0VsPInv0*)
  shows  "invHoldForRule' s (inv113 ) (PI_Local_Get_Put ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

      have "?P3 s"

        apply(    simp)

        apply(rule_tac x=" (neg ( andForm ( eqn ( IVar ( Para ''UniMsg_Cmd'' Home) )  ( Const UNI_Get ))    ( eqn ( IVar ( Para ''procCmd'' Home) )  ( Const NODE_None ))  ) ) " in exI,auto)

        done

       then  show "?P1 s\<or> ?P2 s\<or> ?P3 s"

        by blast

 qed
lemma PI_Local_PutXVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (PI_Local_PutX ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma PI_Local_ReplaceVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (PI_Local_Replace ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  lemma PI_Remote_GetVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (PI_Remote_Get  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma PI_Remote_GetXVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (PI_Remote_GetX  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma PI_Remote_PutXVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (PI_Remote_PutX  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma PI_Remote_ReplaceVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (PI_Remote_Replace  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma StoreVsInv113:
    (*Rule1VsPInv0*)
  assumes   a1:"iRule1 \<le> N"

  shows  "invHoldForRule' s (inv113 ) (Store  iRule1 ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

  proof -

     have "?P2 s"

     by (cut_tac a1,auto  )
   then show "?P1 s\<or>?P2 s\<or>?P3 s"
      by auto
 qed
  lemma StoreHomeVsInv113:
    (*Rule0VsPInv0*)

  shows  "invHoldForRule' s (inv113 ) (StoreHome ) (invariants   N)" (is " ?P1 s\<or>?P2 s\<or>?P3 s")

      by( auto)

  end