(*  Title:      JinjaThreads/MM/JMM_Heap.thy
    Author:     Andreas Lochbihler
*)

section \<open>Locales for heap operations with set of allocated addresses\<close>

theory JMM_Heap
imports
  "../Common/WellForm"
  SC_Completion
  HB_Completion
begin

definition w_addrs :: "('addr \<times> addr_loc \<Rightarrow> 'addr val set) \<Rightarrow> 'addr set"
where "w_addrs vs = {a. \<exists>adal. Addr a \<in> vs adal}"

lemma w_addrs_empty [simp]: "w_addrs (\<lambda>_. {}) = {}"
by(simp add: w_addrs_def)

locale allocated_heap_base = heap_base +
  constrains addr2thread_id :: "('addr :: addr) \<Rightarrow> 'thread_id"
  and thread_id2addr :: "'thread_id \<Rightarrow> 'addr"
  and spurious_wakeups :: bool
  and empty_heap :: "'heap"
  and allocate :: "'heap \<Rightarrow> htype \<Rightarrow> ('heap \<times> 'addr) set"
  and typeof_addr :: "'heap \<Rightarrow> 'addr \<rightharpoonup> htype"
  and heap_read :: "'heap \<Rightarrow> 'addr \<Rightarrow> addr_loc \<Rightarrow> 'addr val \<Rightarrow> bool"
  and heap_write :: "'heap \<Rightarrow> 'addr \<Rightarrow> addr_loc \<Rightarrow> 'addr val \<Rightarrow> 'heap \<Rightarrow> bool"
  fixes allocated :: "'heap \<Rightarrow> 'addr set"

locale allocated_heap =
  allocated_heap_base +
  heap +
  constrains addr2thread_id :: "('addr :: addr) \<Rightarrow> 'thread_id"
  and thread_id2addr :: "'thread_id \<Rightarrow> 'addr"
  and spurious_wakeups :: bool
  and empty_heap :: "'heap"
  and allocate :: "'heap \<Rightarrow> htype \<Rightarrow> ('heap \<times> 'addr) set"
  and typeof_addr :: "'heap \<Rightarrow> 'addr \<rightharpoonup> htype"
  and heap_read :: "'heap \<Rightarrow> 'addr \<Rightarrow> addr_loc \<Rightarrow> 'addr val \<Rightarrow> bool"
  and heap_write :: "'heap \<Rightarrow> 'addr \<Rightarrow> addr_loc \<Rightarrow> 'addr val \<Rightarrow> 'heap \<Rightarrow> bool"
  and allocated :: "'heap \<Rightarrow> 'addr set"
  and P :: "'m prog"

  assumes allocated_empty: "allocated empty_heap = {}"
  and allocate_allocatedD:
  "(h', a) \<in> allocate h hT \<Longrightarrow> allocated h' = insert a (allocated h) \<and> a \<notin> allocated h"
  and heap_write_allocated_same:
  "heap_write h a al v h' \<Longrightarrow> allocated h' = allocated h"
begin

lemma allocate_allocated_mono: "(h', a) \<in> allocate h C \<Longrightarrow> allocated h \<subseteq> allocated h'"
by(simp_all add: allocate_allocatedD)

lemma
  shows start_addrs_allocated: "allocated start_heap = set start_addrs"
  and distinct_start_addrs': "distinct start_addrs"
proof -
  { fix h ads b and xs :: "cname list"
    let "?start_addrs h ads b xs" = "fst (snd (foldl create_initial_object (h, ads, b) xs))"
    let "?start_heap h ads b xs" = "fst (foldl create_initial_object (h, ads, b) xs)"
    assume "allocated h = set ads"
    hence "allocated (?start_heap h ads b xs) = set (?start_addrs h ads b xs) \<and>
           (distinct ads \<longrightarrow> distinct (?start_addrs h ads b xs))"
      (is "?concl xs h ads b")
    proof(induct xs arbitrary: h ads b)
      case Nil thus ?case by auto
    next
      case (Cons x xs)
      note ads = \<open>allocated h = set ads\<close>
      show ?case
      proof(cases "b \<and> allocate h (Class_type x) \<noteq> {}")
        case False thus ?thesis using ads
          by(simp add: create_initial_object_simps zip_append1)
      next
        case [simp]: True
        then obtain h' a'
          where h'a': "(SOME ha. ha \<in> allocate h (Class_type x)) = (h', a')"
          and new_obj: "(h', a') \<in> allocate h (Class_type x)"
          by(cases "(SOME ha. ha \<in> allocate h (Class_type x))")(auto simp del: True dest: allocate_Eps)

        from new_obj have "allocated h' = insert a' (allocated h)" "a' \<notin> allocated h"
          by(auto dest: allocate_allocatedD)
        with ads have "allocated h' = set (ads @ [a'])" by auto
        hence "?concl xs h' (ads @ [a']) True" by(rule Cons)
        moreover have "a' \<notin> set ads" using \<open>a' \<notin> allocated h\<close> ads by blast
        ultimately show ?thesis by(simp add: create_initial_object_simps new_obj h'a')
      qed
    qed }
  from this[of empty_heap "[]" True initialization_list]
  show "allocated start_heap = set start_addrs"
    and distinct_start_addrs: "distinct start_addrs"
    unfolding start_heap_def start_addrs_def start_heap_data_def
    by(auto simp add: allocated_empty)
qed

lemma w_addrs_start_heap_obs: "w_addrs (w_values P vs (map NormalAction start_heap_obs)) \<subseteq> w_addrs vs"
proof -
  { fix xs
    let ?NewObj = "\<lambda>a C. NewHeapElem a (Class_type C) :: ('addr, 'thread_id) obs_event"
    let "?start_heap_obs xs" = "map (\<lambda>(C, a). ?NewObj a C) xs"
    have "w_addrs (w_values P vs (map NormalAction (?start_heap_obs xs))) \<subseteq> w_addrs vs"
      (is "?concl xs")
    proof(induct xs arbitrary: vs)
      case Nil thus ?case by simp
    next
      case (Cons x xs)
      have "w_addrs (w_values P vs (map NormalAction (map (\<lambda>(C, a). ?NewObj a C) (x # xs))))
        = w_addrs (w_values P (w_value P vs (NormalAction (?NewObj (snd x) (fst x)))) (map NormalAction (map (\<lambda>(C, a). ?NewObj a C) xs)))"
        by(simp add: split_beta)
      also have "\<dots> \<subseteq> w_addrs (w_value P vs (NormalAction (?NewObj (snd x) (fst x))))" by(rule Cons)
      also have "\<dots> \<subseteq> w_addrs vs"
        by(auto simp add: w_addrs_def default_val_not_Addr Addr_not_default_val)
      finally show ?case .
    qed }
  thus ?thesis by(simp add: start_heap_obs_def)
qed

end

context heap_base begin

lemma addr_loc_default_conf:
  "P \<turnstile> class_type_of CTn has F:T (fm) in C
  \<Longrightarrow> P,h \<turnstile> addr_loc_default P CTn (CField C F) :\<le> T"
apply(cases CTn)
 apply simp
apply(frule has_field_decl_above)
apply simp
done

definition vs_conf :: "'m prog \<Rightarrow> 'heap \<Rightarrow> ('addr \<times> addr_loc \<Rightarrow> 'addr val set) \<Rightarrow> bool"
where "vs_conf P h vs \<longleftrightarrow> (\<forall>ad al v. v \<in> vs (ad, al) \<longrightarrow> (\<exists>T. P,h \<turnstile> ad@al : T \<and> P,h \<turnstile> v :\<le> T))"

lemma vs_confD:
  "\<lbrakk> vs_conf P h vs; v \<in> vs (ad, al) \<rbrakk> \<Longrightarrow> \<exists>T. P,h \<turnstile> ad@al : T \<and> P,h \<turnstile> v :\<le> T"
unfolding vs_conf_def by blast

lemma vs_conf_insert_iff:
  "vs_conf P h (vs((ad, al) := insert v (vs (ad, al))))
  \<longleftrightarrow> vs_conf P h vs \<and> (\<exists>T. P,h \<turnstile> ad@al : T \<and> P,h \<turnstile> v :\<le> T)"
by(auto 4 3 elim: vs_confD intro: vs_confI split: if_split_asm)

end

context heap begin

lemma vs_conf_hext: "\<lbrakk> vs_conf P h vs; h \<unlhd> h' \<rbrakk> \<Longrightarrow> vs_conf P h' vs"
by(blast intro!: vs_confI intro: conf_hext addr_loc_type_hext_mono dest: vs_confD)

lemma vs_conf_allocate:
  "\<lbrakk> vs_conf P h vs; (h', a) \<in> allocate h hT; is_htype P hT \<rbrakk>
  \<Longrightarrow> vs_conf P h' (w_value P vs (NormalAction (NewHeapElem a hT)))"
apply(drule vs_conf_hext)
 apply(erule hext_allocate)
apply(auto intro!: vs_confI simp add: addr_locs_def split: if_split_asm htype.split_asm)
apply(auto 3 3 intro: addr_loc_type.intros defval_conf dest: allocate_SomeD elim: has_field_is_class vs_confD)
apply(rule exI conjI addr_loc_type.intros|drule allocate_SomeD|erule has_field_is_class|simp)+
done

end

text \<open>
  \<open>heap_read_typeable\<close> must not be defined in @{term heap_conf_base} (where it should be) because
  this would lead to duplicate definitions of \<open>heap_read_typeable\<close> in contexts where @{term heap_conf_base}
  is imported twice with different parameters, e.g., @{term P} and @{term "J2JVM P"} in @{term "J_JVM_heap_conf_read"}.
\<close>

context heap_base begin

definition heap_read_typeable :: "('heap \<Rightarrow> bool) \<Rightarrow> 'm prog \<Rightarrow> bool"
where "heap_read_typeable hconf P \<longleftrightarrow> (\<forall>h ad al v T. hconf h \<longrightarrow> P,h \<turnstile> ad@al : T \<longrightarrow> P,h \<turnstile> v :\<le> T \<longrightarrow> heap_read h ad al v)"

lemma heap_read_typeableI:
  "(\<And>h ad al v T. \<lbrakk> P,h \<turnstile> ad@al : T; P,h \<turnstile> v :\<le> T; hconf h \<rbrakk> \<Longrightarrow> heap_read h ad al v) \<Longrightarrow> heap_read_typeable hconf P"
unfolding heap_read_typeable_def by blast

lemma heap_read_typeableD:
  "\<lbrakk> heap_read_typeable hconf P; P,h \<turnstile> ad@al : T; P,h \<turnstile> v :\<le> T; hconf h \<rbrakk> \<Longrightarrow> heap_read h ad al v"
unfolding heap_read_typeable_def by blast

end

context heap_base begin

definition heap_read_typed :: "'m prog \<Rightarrow> 'heap \<Rightarrow> 'addr \<Rightarrow> addr_loc \<Rightarrow> 'addr val \<Rightarrow> bool"
where "heap_read_typed P h ad al v \<longleftrightarrow> heap_read h ad al v \<and> (\<forall>T. P,h \<turnstile> ad@al : T \<longrightarrow> P,h \<turnstile> v :\<le> T)"

lemma heap_read_typedI:
  "\<lbrakk> heap_read h ad al v; \<And>T. P,h \<turnstile> ad@al : T \<Longrightarrow> P,h \<turnstile> v :\<le> T \<rbrakk> \<Longrightarrow> heap_read_typed P h ad al v"
unfolding heap_read_typed_def by blast

lemma heap_read_typed_into_heap_read:
  "heap_read_typed P h ad al v \<Longrightarrow> heap_read h ad al v"
unfolding heap_read_typed_def by blast

lemma heap_read_typed_typed:
  "\<lbrakk> heap_read_typed P h ad al v; P,h \<turnstile> ad@al : T \<rbrakk> \<Longrightarrow> P,h \<turnstile> v :\<le> T"
unfolding heap_read_typed_def by blast

end

context heap_conf begin

lemma heap_conf_read_heap_read_typed:
  "heap_conf_read addr2thread_id thread_id2addr empty_heap allocate typeof_addr (heap_read_typed P) heap_write hconf P"
proof
  fix h a al v T
  assume "heap_read_typed P h a al v" "P,h \<turnstile> a@al : T"
  thus "P,h \<turnstile> v :\<le> T" by(rule heap_read_typed_typed)
qed

end

context heap begin

lemma start_addrs_dom_w_values:
  assumes wf: "wf_syscls P"
  and a: "a \<in> set start_addrs"
  and adal: "P,start_heap \<turnstile> a@al : T"
  shows "w_values P (\<lambda>_. {}) (map NormalAction start_heap_obs) (a, al) \<noteq> {}"
proof -
  from a obtain CTn where CTn: "NewHeapElem a CTn \<in> set start_heap_obs"
    unfolding in_set_start_addrs_conv_NewHeapElem ..
  then obtain obs obs' where obs: "start_heap_obs = obs @ NewHeapElem a CTn # obs'" by(auto dest: split_list)
  have "w_value P (w_values P (\<lambda>_. {}) (map NormalAction obs)) (NormalAction (NewHeapElem a CTn)) (a, al) \<noteq> {}"
  proof(cases CTn)
    case [simp]: (Class_type C)
    with wf CTn have "typeof_addr start_heap a = \<lfloor>Class_type C\<rfloor>"
      by(auto intro: NewHeapElem_start_heap_obsD)
    with adal show ?thesis by cases auto
  next
    case [simp]: (Array_type T n)
    with wf CTn have "typeof_addr start_heap a = \<lfloor>Array_type T n\<rfloor>"
      by(auto dest: NewHeapElem_start_heap_obsD)
    with adal show ?thesis by cases(auto dest: has_field_decl_above)
  qed
  moreover have "w_value P (w_values P (\<lambda>_. {}) (map NormalAction obs)) (NormalAction (NewHeapElem a CTn :: ('addr, 'thread_id) obs_event))
    (a, al) \<subseteq> w_values P (\<lambda>_. {}) (map NormalAction start_heap_obs) (a, al)"
    by(simp add: obs del: w_value.simps)(rule w_values_mono)
  ultimately show ?thesis by blast
qed

end

end


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

header{*The n_g2kAbsAfter Protocol Case Study*}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

end


theory Proof_3_10
  imports Proofs_3
begin

thm extraInv_def
context
  fixes s2 s0:: state
fixes user_value pressure_value:: bool
assumes toEnvPs2:  "toEnvP s2 \<and> toEnvP s0"
and vc: " env (setVarAny s0 user_value pressure_value) \<and>
        getPstate (setVarAny s0 user_value pressure_value) ERROR = Controller'rotating \<and>
\<not> getVarBool (setVarAny s0 user_value pressure_value) pressure \<and>
\<not> getVarBool (setVarAny s0 user_value pressure_value) user \<and>
\<not> DELAY'TIMEOUT \<le> ltime (setVarAny s0 user_value pressure_value) Controller"
and extraInvs0: "(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'motionless \<longrightarrow>
      (\<forall>s2. toEnvP s2 \<and> substate s2 s1 \<longrightarrow> getPstate s2 ERROR = Controller'motionless \<and> \<not> getVarBool s2 user) \<or>
      (\<exists>s2 s3.
          toEnvP s2 \<and>
          substate s2 s3 \<and>
          substate s3 s1 \<and>
          toEnvNum s2 s3 = ERROR \<and>
          getPstate s2 ERROR = Controller'rotating \<and>
          ltime s2 ERROR = DELAY'TIMEOUT \<and>
          \<not> getVarBool s3 user \<and>
          \<not> getVarBool s3 pressure \<and>
          (\<forall>s4 s5.
              toEnvP s4 \<and> toEnvP s5 \<and> substate s3 s4 \<and> substate s4 s5 \<and> substate s5 s1 \<and> toEnvNum s4 s5 = ERROR \<longrightarrow>
              getPstate s4 ERROR = Controller'motionless \<and> \<not> getVarBool s5 user))) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow> ltime s1 ERROR \<le> DELAY'TIMEOUT) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
      (\<exists>s2 s3.
          toEnvP s2 \<and>
          toEnvP s3 \<and>
          substate s2 s3 \<and>
          substate s3 s1 \<and>
          toEnvNum s2 s3 = ERROR \<and>
          toEnvNum s2 s1 = ltime s1 ERROR \<and>
          ((getPstate s2 ERROR = Controller'motionless \<or> getPstate s2 ERROR = Controller'rotating) \<and>
           getVarBool s3 user \<or>
           getPstate s2 ERROR = Controller'suspended) \<and>
          \<not> getVarBool s3 pressure)) \<and>
(\<forall>s1 s2 s3.
    toEnvP s1 \<and>
    toEnvP s2 \<and>
    toEnvP s3 \<and>
    substate s1 s2 \<and>
    substate s2 s3 \<and>
    substate s3 s0 \<and>
    getPstate s3 ERROR = Controller'rotating \<and> toEnvNum s1 s2 = ERROR \<and> toEnvNum s1 s3 < ltime s3 ERROR \<longrightarrow>
    getPstate s1 ERROR = Controller'rotating \<and> \<not> getVarBool s2 user) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
      (\<exists>s2 s3.
          toEnvP s2 \<and>
          toEnvP s3 \<and>
          substate s2 s3 \<and>
          substate s3 s1 \<and>
          toEnvNum s2 s3 = ERROR \<and>
          (getPstate s2 ERROR = Controller'motionless \<and> getVarBool s3 user \<or>
           getPstate s2 ERROR = Controller'suspended) \<and>
          \<not> getVarBool s3 pressure \<and>
          (\<forall>s4. toEnvP s4 \<and> substate s3 s4 \<and> substate s4 s1 \<longrightarrow> getPstate s4 ERROR = Controller'rotating))) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow> ltime s1 ERROR = DELAY'TIMEOUT) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
      (\<exists>s2 s3.
          toEnvP s2 \<and>
          toEnvP s3 \<and>
          substate s2 s3 \<and>
          substate s3 s1 \<and>
          toEnvNum s2 s3 = ERROR \<and>
          toEnvNum s2 s1 = ltime s1 ERROR \<and>
          (getPstate s2 ERROR \<noteq> Controller'motionless \<or> getVarBool s3 user) \<and> getVarBool s3 pressure)) \<and>
(\<forall>s1 s2 s3.
    toEnvP s1 \<and>
    toEnvP s2 \<and>
    toEnvP s3 \<and>
    substate s1 s2 \<and>
    substate s2 s3 \<and>
    substate s3 s0 \<and>
    toEnvNum s1 s2 = ERROR \<and> toEnvNum s1 s3 < ltime s3 ERROR \<and> getPstate s3 ERROR = Controller'suspended \<longrightarrow>
    getPstate s1 ERROR = Controller'suspended \<and> \<not> getVarBool s2 pressure) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
      (\<exists>s2 s3.
          toEnvP s2 \<and>
          toEnvP s3 \<and>
          substate s2 s3 \<and>
          substate s3 s1 \<and>
          toEnvNum s2 s3 = ERROR \<and>
          (getPstate s2 ERROR = Controller'motionless \<and> getVarBool s3 user \<or>
           getPstate s2 ERROR = Controller'rotating) \<and>
          getVarBool s3 pressure \<and>
          (\<forall>s4. toEnvP s4 \<and> substate s3 s4 \<and> substate s4 s1 \<longrightarrow> getPstate s4 ERROR = Controller'suspended))) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'motionless \<longrightarrow>
      getVarBool s1 rotation = False \<and> getVarBool s1 brake = False) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
      getVarBool s1 rotation = True \<and> getVarBool s1 brake = False) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
      getVarBool s1 rotation = False \<and> getVarBool s1 brake = True) \<and>
(\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<longrightarrow>
      getPstate s1 ERROR = Controller'motionless \<or>
      getPstate s1 ERROR = Controller'rotating \<or> getPstate s1 ERROR = Controller'suspended)"
begin

lemma VC10_R3_ind_step_aux1: " toEnvP s2a \<Longrightarrow>
         substate s2 s2a \<and>
         substate s2a
         (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         s2 \<noteq> s2a \<Longrightarrow>
         substate s1 s2 \<and>
         substate s2
          (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvP s1 \<and>
         toEnvP s2 \<and>
         toEnvNum s1 s2 = ERROR \<and>
         DELAY'TIMEOUT =
         toEnvNum s2
          (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         getVarBool s1 rotation = True \<and>
         \<not> getVarBool s2 user \<and>
         (\<forall>s4. toEnvP s4 \<and> substate s2 s4 \<and> substate s4 s2a \<and> s4 \<noteq> s2a \<longrightarrow>
               getVarBool s4 rotation = True \<and> \<not> getVarBool s4 user) \<longrightarrow>
         (\<exists>s4. toEnvP s4 \<and>
               substate s2a s4 \<and>
               substate s4
                (toEnv (setVarAny s0 user'value pressure'value)) \<and>
               toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
               (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
               (\<forall>s3. toEnvP s3 \<and> substate s2a s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                     getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)) \<Longrightarrow>
         substate s1 s2 \<and>
         substate s2
          (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvP s1 \<and>
         toEnvP s2 \<and>
         toEnvNum s1 s2 = ERROR \<and>
         DELAY'TIMEOUT =
         toEnvNum s2
          (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         getVarBool s1 rotation = True \<and>
         \<not> getVarBool s2 user \<and>
         (\<forall>s4. toEnvP s4 \<and> substate s2 s4 \<and> substate s4 (predEnv s2a) \<and> s4 \<noteq> predEnv s2a \<longrightarrow>
               getVarBool s4 rotation = True \<and> \<not> getVarBool s4 user) \<Longrightarrow>
         \<not> (getVarBool (predEnv s2a) rotation = False \<or> getVarBool (predEnv s2a) user) \<Longrightarrow>
         toEnvP x \<and>
         substate s2a x \<and>
         substate x
          (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 x \<le> DELAY'TIMEOUT \<and>
         (getVarBool x rotation = False \<or> getVarBool x user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2a s3 \<and> substate s3 x \<and> s3 \<noteq> x \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user) \<Longrightarrow>
         \<exists>s4. toEnvP s4 \<and>
              substate (predEnv s2a) s4 \<and>
              substate s4
               (toEnv (setVarAny s0 user'value pressure'value)) \<and>
              toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
              (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
              (\<forall>s3. toEnvP s3 \<and> substate (predEnv s2a) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                    getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"
  apply(rule exI[of _ x])
  by (smt (z3) predEnv_substate predEnv_substate_imp_eq_or_substate substate_trans)

lemma VC10_R3_ind_step: " toEnvP s2a \<Longrightarrow>
           substate s2 s2a \<and>
           substate s2a
            (toEnv (setVarAny s0 user'value pressure'value)) \<and>
           s2 \<noteq> s2a \<Longrightarrow>
           substate s1 s2 \<and>
           substate s2
           (toEnv (setVarAny s0 user'value pressure'value)) \<and>
           toEnvP s1 \<and>
           toEnvP s2 \<and>
           toEnvNum s1 s2 = ERROR \<and>
           DELAY'TIMEOUT =
           toEnvNum s2
            (toEnv (setVarAny s0 user'value pressure'value)) \<and>
           getVarBool s1 rotation = True \<and>
           \<not> getVarBool s2 user \<and>
           (\<forall>s4. toEnvP s4 \<and> substate s2 s4 \<and> substate s4 s2a \<and> s4 \<noteq> s2a \<longrightarrow>
                 getVarBool s4 rotation = True \<and> \<not> getVarBool s4 user) \<longrightarrow>
           (\<exists>s4. toEnvP s4 \<and>
                 substate s2a s4 \<and>
                 substate s4
                 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
                 toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
                 (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
                 (\<forall>s3. toEnvP s3 \<and> substate s2a s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                       getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)) \<Longrightarrow>
           substate s1 s2 \<and>
           substate s2
            (toEnv (setVarAny s0 user'value pressure'value)) \<and>
           toEnvP s1 \<and>
           toEnvP s2 \<and>
           toEnvNum s1 s2 = ERROR \<and>
           DELAY'TIMEOUT =
           toEnvNum s2
            (toEnv (setVarAny s0 user'value pressure'value)) \<and>
           getVarBool s1 rotation = True \<and>
           \<not> getVarBool s2 user \<and>
           (\<forall>s4. toEnvP s4 \<and> substate s2 s4 \<and> substate s4 (predEnv s2a) \<and> s4 \<noteq> predEnv s2a \<longrightarrow>
                 getVarBool s4 rotation = True \<and> \<not> getVarBool s4 user) \<longrightarrow>
           (\<exists>s4. toEnvP s4 \<and>
                 substate (predEnv s2a) s4 \<and>
                 substate s4
                  (toEnv (setVarAny s0 user'value pressure'value)) \<and>
                 toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
                 (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
                 (\<forall>s3. toEnvP s3 \<and> substate (predEnv s2a) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                       getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user))"
  apply(rule impI)
  apply(cases "(getVarBool (predEnv s2a) rotation = False \<or> getVarBool (predEnv s2a) user)")
   apply(rule exI[of _ "predEnv s2a"])
   apply(rule conjI)
    apply(rule toEnvP_substate_pred_imp_toEnvP_pred[of s2])
  using toEnvPs2 substate_eq_or_predEnv apply fast
   apply(rule conjI)
  using substate_refl apply fast
   apply(rule conjI)
  using predEnv_substate substate_trans apply fast
   apply(rule conjI)
    apply(rule cut_rl[of "substate s2 (predEnv s2a) \<and>
 substate (predEnv s2a)
 (toEnv (setVarAny s0 user'value pressure'value))"])
  using toEnvNum3[of s2 "predEnv s2a"
"(toEnv (setVarAny s0 user'value pressure'value))"]
     apply arith
  using substate_eq_or_predEnv predEnv_substate substate_trans apply fast
   apply(rule conjI)
    apply assumption
  using substate_asym apply fast
  apply(rule exE[of "\<lambda> s4. toEnvP s4 \<and>
          substate s2a s4 \<and>
          substate s4
          (toEnv (setVarAny s0 user'value pressure'value)) \<and>
          toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
          (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
          (\<forall>s3. toEnvP s3 \<and> substate s2a s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  using substate_eq_or_predEnv apply blast
  by ((rule VC10_R3_ind_step_aux1);blast)

lemma VC10_R3_ind_base: "substate s1 s2 \<and>
       substate s2 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
       toEnvP s1 \<and>
       toEnvP s2 \<and>
       toEnvNum s1 s2 = ERROR \<and>
       DELAY'TIMEOUT = toEnvNum s2 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
       getVarBool s1 rotation = True \<and>
       \<not> getVarBool s2 user \<and>
       (\<forall>s4. toEnvP s4 \<and>
             substate s2 s4 \<and>
             substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
             s4 \<noteq> toEnv (setVarAny s0 user'value pressure'value) \<longrightarrow>
             getVarBool s4 rotation = True \<and> \<not> getVarBool s4 user) \<Longrightarrow>
       toEnvP s2a \<and>
toEnvP s3 \<and>
       substate s2a s3 \<and>
       substate s3 s0 \<and>
       toEnvNum s2a s0 \<le> ltime s0 ERROR \<and>
       toEnvNum s2a s3 = ERROR \<and> (getVarBool s2a rotation = False \<or> getVarBool s3 user) \<Longrightarrow>
       \<exists>s4. toEnvP s4 \<and>
            substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
            substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
            toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
            (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
            (\<forall>s3. toEnvP s3 \<and>
                  substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                  getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"
  apply(rule cut_rl[of "substate s2 s2a"])
 apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
    apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
apply(drule conjE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
               apply(cases "getVarBool s2a rotation = False")
   apply(drule allE[of _ s2a "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  using substate_trans substate_asym
                  apply (metis less_one not_one_less_zero substate.simps(2) substate.simps(9) toEnvNum_id)
                 apply assumption
  apply(drule allE[of _ s3 "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
                  apply(rule cut_rl[of "getVarBool s3 user"])
  apply(drule impE[of _ _ "\<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
                     apply(rule conjI)
  apply assumption
                     apply(rule conjI)
  using substate_trans apply fast
                     apply(rule conjI)
                      apply auto
    apply(simp split: if_splits)
  using substate_refl  substate_asym[of s0 "(toEnv (setVarAny s0 user'value pressure'value))"] apply auto
   apply(simp split: if_splits)
  apply(rule cut_rl[of "substate s2 s0 \<and> substate s2a s0 "])
  apply(rule cut_rl[of "substate s2 s2a \<or> substate s2a s2"])
    apply(drule disjE[of _ _ "substate s2 s2a"])
      apply assumption
      apply(rule cut_rl[of "toEnvNum s2 s0 < toEnvNum s2a s0"])
       apply(rule cut_rl[of "toEnvNum s2 s0 \<ge> toEnvNum s2a s0"])
  apply simp
  using vc apply simp
      apply (metis linorder_le_less_linear shift_toEnvNum substate_asym substate_shift toEnvPs2)
     apply assumption
  using substate_total apply fast
  using substate_trans apply fast
apply(simp split: if_splits)
  apply(rule cut_rl[of "substate s2 s0 \<and> substate s2a s0 "])
  apply(rule cut_rl[of "substate s2 s2a \<or> substate s2a s2 \<and> s2 \<noteq> s2a"])
    apply(drule disjE[of _ _ "substate s2 s2a"])
      apply assumption
      apply(rule cut_rl[of "toEnvNum s2 s0 < toEnvNum s2a s0"])
      apply(rule cut_rl[of "toEnvNum s2 s0 \<ge> toEnvNum s2a s0"])
       apply simp
  using vc apply simp
     apply (metis linorder_le_less_linear shift_toEnvNum substate_asym substate_shift toEnvPs2)
  apply assumption
  using substate_total apply fast
  using substate_trans by fast

lemma VC10_R3_ind_proof:   "toEnvP s5 \<and>  substate s2 s5 \<and>
 substate s5 (toEnv (setVarAny s0 user'value pressure'value))
 \<longrightarrow> pred3 s1 s2 (toEnv (setVarAny s0 user'value pressure'value))
 s5"
  apply(induction rule: state_down_ind)
  using toEnvPs2 apply simp
   apply(simp only: pred3_def)
   apply(rule impI)
  apply(rule cut_rl[of "\<exists>s2 s3.
   toEnvP s2 \<and>
toEnvP s3 \<and>
   substate s2 s3 \<and>
   substate s3 s0 \<and>
   toEnvNum s2 s0 \<le> ltime s0 ERROR \<and>
   toEnvNum s2 s3 = ERROR \<and> (getVarBool s2 rotation = False \<or> getVarBool s3 user)"])
    apply(drule exE[of _ " \<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
   apply(drule exE[of _ " \<exists>s4. toEnvP s4 \<and>
         substate (toEnv (setVarAny s0 user'value pressure'value)) s4 \<and>
         substate s4 (toEnv (setVarAny s0 user'value pressure'value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate (toEnv (setVarAny s0 user'value pressure'value)) s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
      apply((rule VC10_R3_ind_base);blast)
     apply assumption
    apply assumption
   apply(rule rotating_not_vc3[of s0 s0])
   apply(rule conjI)
  using toEnvPs2 apply fast
   apply(rule conjI)
  using substate_refl apply fast
   apply(rule conjI)
  using vc apply simp
 using  extraInvs0  apply fast
apply(simp only: pred3_def)
  by ((rule VC10_R3_ind_step);fast)

end

lemma VC10_R3_aux1: "DELAY'TIMEOUT < toEnvNum s2 (toEnv (setVarAny s0 user_value pressure_value)) \<Longrightarrow>
 substate s2 (toEnv (setVarAny s0 user_value pressure_value)) \<Longrightarrow>  substate s2 s0 \<and> DELAY'TIMEOUT \<le> toEnvNum s2 s0"
  by (simp split: if_splits)

lemma VC10_R3_aux2: " \<not> DELAY'TIMEOUT \<le> ltime (setVarAny s0 user_value pressure_value) ERROR \<Longrightarrow>
    substate s1 s2 \<Longrightarrow>
    \<not> getVarBool (setVarAny s0 user_value pressure_value) user \<Longrightarrow>
    substate s2 (toEnv (setVarAny s0 user_value pressure_value)) \<Longrightarrow>
    \<not> getVarBool (setVarAny s0 user_value pressure_value) pressure \<Longrightarrow>
    toEnvP s1 \<Longrightarrow>
    getPstate (setVarAny s0 user_value pressure_value) ERROR = Controller'rotating \<Longrightarrow>
    toEnvP s2 \<Longrightarrow>
    env (setVarAny s0 user_value pressure_value) \<Longrightarrow>
    toEnvNum s1 s2 = ERROR \<Longrightarrow>
    DELAY'TIMEOUT \<le> toEnvNum s2 (toEnv (setVarAny s0 user_value pressure_value)) \<Longrightarrow>
    getVarBool s1 rotation = True \<and> \<not> getVarBool s2 user \<Longrightarrow>
    toEnvP s0 \<Longrightarrow>
    \<forall>s1 s2.
       substate s1 s2 \<and>
       substate s2 s0 \<and>
       toEnvP s1 \<and>
       toEnvP s2 \<and>
       toEnvNum s1 s2 = ERROR \<and>
       DELAY'TIMEOUT \<le> toEnvNum s2 s0 \<and> getVarBool s1 rotation = True \<and> \<not> getVarBool s2 user \<longrightarrow>
       (\<exists>s4. toEnvP s4 \<and>
             substate s2 s4 \<and>
             substate s4 s0 \<and>
             toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
             (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
             (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                   getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)) \<Longrightarrow>
    DELAY'TIMEOUT = toEnvNum s2 (toEnv (setVarAny s0 user_value pressure_value)) \<Longrightarrow>
    pred3 s1 s2 (toEnv (setVarAny s0 user_value pressure_value)) s2 \<Longrightarrow>
    \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"
apply(simp only: pred3_def)
  using substate_asym
  by meson

lemma VC10_R3: "  ((((((toEnvP s0 \<and>
             (\<forall>s1 s2.
                 substate s1 s2 \<and>
                 substate s2 s0 \<and>
                 toEnvP s1 \<and>
                 toEnvP s2 \<and>
                 toEnvNum s1 s2 = ERROR \<and>
                 DELAY'TIMEOUT \<le> toEnvNum s2 s0 \<and> getVarBool s1 rotation = True \<and> \<not> getVarBool s2 user \<longrightarrow>
                 (\<exists>s4. toEnvP s4 \<and>
                       substate s2 s4 \<and>
                       substate s4 s0 \<and>
                       toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
                       (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
                       (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                             getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)))) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'motionless \<longrightarrow>
                  (\<forall>s2. toEnvP s2 \<and> substate s2 s1 \<longrightarrow>
                        getPstate s2 ERROR = Controller'motionless \<and> \<not> getVarBool s2 user) \<or>
                  (\<exists>s2 s3.
                      toEnvP s2 \<and>
                      substate s2 s3 \<and>
                      substate s3 s1 \<and>
                      toEnvNum s2 s3 = ERROR \<and>
                      getPstate s2 ERROR = Controller'rotating \<and>
                      ltime s2 ERROR = DELAY'TIMEOUT \<and>
                      \<not> getVarBool s3 user \<and>
                      \<not> getVarBool s3 pressure \<and>
                      (\<forall>s4 s5.
                          toEnvP s4 \<and>
                          toEnvP s5 \<and> substate s3 s4 \<and> substate s4 s5 \<and> substate s5 s1 \<and> toEnvNum s4 s5 = ERROR \<longrightarrow>
                          getPstate s4 ERROR = Controller'motionless \<and> \<not> getVarBool s5 user))) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
                  ltime s1 ERROR \<le> DELAY'TIMEOUT) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
                  (\<exists>s2 s3.
                      toEnvP s2 \<and>
                      toEnvP s3 \<and>
                      substate s2 s3 \<and>
                      substate s3 s1 \<and>
                      toEnvNum s2 s3 = ERROR \<and>
                      toEnvNum s2 s1 = ltime s1 ERROR \<and>
                      ((getPstate s2 ERROR = Controller'motionless \<or> getPstate s2 ERROR = Controller'rotating) \<and>
                       getVarBool s3 user \<or>
                       getPstate s2 ERROR = Controller'suspended) \<and>
                      \<not> getVarBool s3 pressure)) \<and>
            (\<forall>s1 s2 s3.
                toEnvP s1 \<and>
                toEnvP s2 \<and>
                toEnvP s3 \<and>
                substate s1 s2 \<and>
                substate s2 s3 \<and>
                substate s3 s0 \<and>
                getPstate s3 ERROR = Controller'rotating \<and> toEnvNum s1 s2 = ERROR \<and> toEnvNum s1 s3 < ltime s3 ERROR \<longrightarrow>
                getPstate s1 ERROR = Controller'rotating \<and> \<not> getVarBool s2 user) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
                  (\<exists>s2 s3.
                      toEnvP s2 \<and>
                      toEnvP s3 \<and>
                      substate s2 s3 \<and>
                      substate s3 s1 \<and>
                      toEnvNum s2 s3 = ERROR \<and>
                      (getPstate s2 ERROR = Controller'motionless \<and> getVarBool s3 user \<or>
                       getPstate s2 ERROR = Controller'suspended) \<and>
                      \<not> getVarBool s3 pressure \<and>
                      (\<forall>s4. toEnvP s4 \<and> substate s3 s4 \<and> substate s4 s1 \<longrightarrow>
                            getPstate s4 ERROR = Controller'rotating))) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
                  ltime s1 ERROR = DELAY'TIMEOUT) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
                  (\<exists>s2 s3.
                      toEnvP s2 \<and>
                      toEnvP s3 \<and>
                      substate s2 s3 \<and>
                      substate s3 s1 \<and>
                      toEnvNum s2 s3 = ERROR \<and>
                      toEnvNum s2 s1 = ltime s1 ERROR \<and>
                      (getPstate s2 ERROR \<noteq> Controller'motionless \<or> getVarBool s3 user) \<and> getVarBool s3 pressure)) \<and>
            (\<forall>s1 s2 s3.
                toEnvP s1 \<and>
                toEnvP s2 \<and>
                toEnvP s3 \<and>
                substate s1 s2 \<and>
                substate s2 s3 \<and>
                substate s3 s0 \<and>
                toEnvNum s1 s2 = ERROR \<and>
                toEnvNum s1 s3 < ltime s3 ERROR \<and> getPstate s3 ERROR = Controller'suspended \<longrightarrow>
                getPstate s1 ERROR = Controller'suspended \<and> \<not> getVarBool s2 pressure) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
                  (\<exists>s2 s3.
                      toEnvP s2 \<and>
                      toEnvP s3 \<and>
                      substate s2 s3 \<and>
                      substate s3 s1 \<and>
                      toEnvNum s2 s3 = ERROR \<and>
                      (getPstate s2 ERROR = Controller'motionless \<and> getVarBool s3 user \<or>
                       getPstate s2 ERROR = Controller'rotating) \<and>
                      getVarBool s3 pressure \<and>
                      (\<forall>s4. toEnvP s4 \<and> substate s3 s4 \<and> substate s4 s1 \<longrightarrow>
                            getPstate s4 ERROR = Controller'suspended))) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'motionless \<longrightarrow>
                  getVarBool s1 rotation = False \<and> getVarBool s1 brake = False) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'rotating \<longrightarrow>
                  getVarBool s1 rotation = True \<and> getVarBool s1 brake = False) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<and> getPstate s1 ERROR = Controller'suspended \<longrightarrow>
                  getVarBool s1 rotation = False \<and> getVarBool s1 brake = True) \<and>
            (\<forall>s1. toEnvP s1 \<and> substate s1 s0 \<longrightarrow>
                  getPstate s1 ERROR = Controller'motionless \<or>
                  getPstate s1 ERROR = Controller'rotating \<or> getPstate s1 ERROR = Controller'suspended)) \<and>
           env (setVarAny s0 user_value pressure_value)) \<and>
          getPstate (setVarAny s0 user_value pressure_value) ERROR = Controller'rotating) \<and>
         \<not> getVarBool (setVarAny s0 user_value pressure_value) pressure) \<and>
        \<not> getVarBool (setVarAny s0 user_value pressure_value) user) \<and>
       \<not> DELAY'TIMEOUT \<le> ltime (setVarAny s0 user_value pressure_value) ERROR \<Longrightarrow>
       substate s1 s2 \<and>
       substate s2 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
       toEnvP s1 \<and>
       toEnvP s2 \<and>
       toEnvNum s1 s2 = ERROR \<and>
       DELAY'TIMEOUT \<le> toEnvNum s2 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
       getVarBool s1 rotation = True \<and> \<not> getVarBool s2 user \<longrightarrow>
       (\<exists>s4. toEnvP s4 \<and>
             substate s2 s4 \<and>
             substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
             toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
             (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
             (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                   getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user))"

  apply(rule impI)
  apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ " \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ " \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
 apply(drule conjE[of _ _ " \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
                 apply(drule conjE[of _ _ "  \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 (toEnv (setVarAny s0 user_value pressure_value)) \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
  apply(rule disjE[of "DELAY'TIMEOUT < toEnvNum s2 (toEnv (setVarAny s0 user_value pressure_value))"
"DELAY'TIMEOUT = toEnvNum s2 (toEnv (setVarAny s0 user_value pressure_value))"])
  using le_imp_less_or_eq
    apply linarith
                apply(rule cut_rl[of "substate s2 s0 \<and> toEnvNum s2 s0 \<ge> DELAY'TIMEOUT"])
  apply(rule cut_rl[of "(\<exists>s4. toEnvP s4 \<and>
                   substate s2 s4 \<and>
                   substate s4 s0 \<and>
                   toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
                   (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
                   (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
                         getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user))"])
                   apply (metis substate.simps(10) substate.simps(2) substate.simps(3) substate.simps(9))
                    apply(drule allE[of _ s1 " \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 s0 \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
apply(drule allE[of _ s2 " \<exists>s4. toEnvP s4 \<and>
         substate s2 s4 \<and>
         substate s4 s0 \<and>
         toEnvNum s2 s4 \<le> DELAY'TIMEOUT \<and>
         (getVarBool s4 rotation = False \<or> getVarBool s4 user) \<and>
         (\<forall>s3. toEnvP s3 \<and> substate s2 s3 \<and> substate s3 s4 \<and> s3 \<noteq> s4 \<longrightarrow>
               getVarBool s3 rotation = True \<and> \<not> getVarBool s3 user)"])
                   apply fast
                  apply assumption
                 apply assumption
                apply((rule VC10_R3_aux1);assumption)
  apply(rule cut_rl[of "pred3 s1 s2
 (toEnv (setVarAny s0 user_value pressure_value))
s2"])
  apply((rule VC10_R3_aux2);assumption)
   apply(rule mp[of "toEnvP s2 \<and>  substate s2 s2 \<and>
 substate s2 (toEnv (setVarAny s0 user_value pressure_value))"])

  print_state
                apply((rule VC10_R3_ind_proof);fast)
  print_state
  using substate_refl apply fast
              apply assumption
             apply assumption
            apply assumption
           apply assumption
          apply assumption
         apply assumption
        apply assumption
       apply assumption
      apply assumption
     apply assumption
    apply assumption
   apply assumption
  by assumption

theorem proof_3_10: "VC10 inv3 env s0 user_value pressure_value"
  apply(simp only: VC10_def inv3_def R3_def extraInv_def)
  apply(rule impI)
  apply(rule conjI)
  apply(rule conjI)
   apply(simp)
   apply((rule allI);(rule allI))
   apply(rule VC10_R3)
   apply assumption


(*  Title:      JinjaThreads/MM/JMM_Interp.thy
    Author:     Andreas Lochbihler

    Interpret the language specific heap locales with the Java memory model
*)

theory JMM_Interp imports
  "JMM_Compiler"
  "../J/Deadlocked"
  "../BV/JVMDeadlocked"
  "JMM_Type2"
  "DRF_J"
  "DRF_JVM"
begin

lemma jmm'_J_typesafe:
  "J_typesafe addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) (jmm_heap_read_typed P) jmm_heap_write jmm_hconf P"
by unfold_locales

lemma jmm'_JVM_typesafe:
  "JVM_typesafe addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) (jmm_heap_read_typed P) jmm_heap_write jmm_hconf P"
by unfold_locales

lemma jmm_typeof_addr_compP [simp]:
  "jmm_typeof_addr (compP f P) = jmm_typeof_addr P"
by(simp add: jmm_typeof_addr_def fun_eq_iff)

lemma compP2_compP1_convs:
  "is_type (compP2 (compP1 P)) = is_type P"
  "is_class (compP2 (compP1 P)) = is_class P"
  "jmm'_addr_loc_type (compP2 (compP1 P)) = jmm'_addr_loc_type P"
  "jmm'_conf (compP2 (compP1 P)) = jmm'_conf P"
by(simp_all add: compP2_def heap_base.compP_conf heap_base.compP_addr_loc_type fun_eq_iff split: addr_loc.splits)

lemma jmm'_J_JVM_conf_read:
  "J_JVM_conf_read addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) (jmm_heap_read_typed P) jmm_heap_write jmm_hconf P"
apply(rule J_JVM_conf_read.intro)
apply(rule J1_JVM_conf_read.intro)
apply(rule JVM_conf_read.intro)
 prefer 2
 apply(rule JVM_heap_conf.intro)
 apply(rule JVM_heap_conf_base'.intro)
 apply(unfold compP2_def compP1_def compP_heap compP_heap_conf compP_heap_conf_read jmm_typeof_addr_compP)
 apply unfold_locales
done

lemma jmm_J_allocated_progress:
  "J_allocated_progress addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) jmm_heap_read jmm_heap_write jmm_hconf jmm_allocated P"
by unfold_locales

lemma jmm'_J_allocated_progress:
  "J_allocated_progress addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) (jmm_heap_read_typed P) jmm_heap_write jmm_hconf jmm_allocated P"
by(unfold_locales)

lemma jmm_JVM_allocated_progress:
  "JVM_allocated_progress addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) jmm_heap_read jmm_heap_write jmm_hconf jmm_allocated P"
by unfold_locales

lemma jmm'_JVM_allocated_progress:
  "JVM_allocated_progress addr2thread_id thread_id2addr jmm_empty jmm_allocate (jmm_typeof_addr P) (jmm_heap_read_typed P) jmm_heap_write jmm_hconf jmm_allocated P"
by(unfold_locales)

end