header {* \isaheader{Entry Point for the Automatic Refinement Tool} *}
theory Automatic_Refinement
imports
  "Tool/Autoref_Tool"
  "Autoref_Bindings_HOL"
begin
  text {* The automatic refinement tool should be used by
    importing this theory *}

subsection {* Convenience *}

text {* The following lemmas can be used to add tags to theorems *}
lemma PREFER_I: "P x \<Longrightarrow> PREFER P x" by simp
lemma PREFER_D: "PREFER P x \<Longrightarrow> P x" by simp

lemmas PREFER_sv_D = PREFER_D[of single_valued]
lemma PREFER_id_D: "PREFER_id R \<Longrightarrow> R=Id" by simp

abbreviation "PREFER_RUNIV \<equiv> PREFER (\<lambda>R. Range R = UNIV)"
lemmas PREFER_RUNIV_D = PREFER_D[of "(\<lambda>R. Range R = UNIV)"]

lemma SIDE_GEN_ALGO_D: "SIDE_GEN_ALGO P \<Longrightarrow> P" by simp

lemma GEN_OP_D: "GEN_OP c a R \<Longrightarrow> (c,a)\<in>R"
  by simp

lemma MINOR_PRIO_TAG_I: "P \<Longrightarrow> (MINOR_PRIO_TAG p \<Longrightarrow> P)" by auto
lemma MAJOR_PRIO_TAG_I: "P \<Longrightarrow> (MAJOR_PRIO_TAG p \<Longrightarrow> P)" by auto
lemma PRIO_TAG_I: "P \<Longrightarrow> (PRIO_TAG ma mi \<Longrightarrow> P)" by auto

end


section\<open>Cohen forcing notions\<close>

theory Cohen_Posets_Relative
  imports
    Forcing_Notions
    Transitive_Models.Delta_System_Relative
    Transitive_Models.Partial_Functions_Relative
begin

locale cohen_data =
  fixes \<kappa> I J::i
  assumes zero_lt_kappa: "0<\<kappa>"
begin

lemmas zero_lesspoll_kappa = zero_lesspoll[OF zero_lt_kappa]

end \<comment> \<open>\<^locale>\<open>cohen_data\<close>\<close>

abbreviation
  inj_dense :: "[i,i,i,i]\<Rightarrow>i" where
  "inj_dense(I,J,w,x) \<equiv>
    { p\<in>Fn(\<omega>,I\<times>\<omega>,J) . (\<exists>n\<in>\<omega>. \<langle>\<langle>w,n\<rangle>,1\<rangle> \<in> p \<and> \<langle>\<langle>x,n\<rangle>,0\<rangle> \<in> p) }"

lemma dense_inj_dense:
  assumes "w \<in> I" "x \<in> I" "w \<noteq> x" "p\<in>Fn(\<omega>,I\<times>\<omega>,J)" "0\<in>J" "1\<in>J"
  shows "\<exists>d\<in>inj_dense(I,J,w,x). \<langle>d ,p\<rangle> \<in> Fnle(\<omega>,I\<times>\<omega>,J)"
proof -
  obtain n where "\<langle>w,n\<rangle> \<notin> domain(p)" "\<langle>x,n\<rangle> \<notin> domain(p)" "n \<in> \<omega>"
  proof -
    {
      assume "\<langle>w,n\<rangle> \<in> domain(p) \<or> \<langle>x,n\<rangle> \<in> domain(p)" if "n \<in> \<omega>" for n
      then
      have "\<omega> \<subseteq> range(domain(p))" by blast
      then
      have "\<not> Finite(p)"
        using Finite_range Finite_domain subset_Finite nat_not_Finite
        by auto
      with \<open>p \<in> _\<close>
      have False
        using Fn_nat_eq_FiniteFun FiniteFun.dom_subset[of "I\<times>\<omega>" J]
          Fin_into_Finite by auto
    }
    with that\<comment> \<open>the shape of the goal puts assumptions in this variable\<close>
    show ?thesis by auto
  qed
  moreover
  note \<open>p \<in> _\<close> assms
  moreover from calculation
  have "cons(\<langle>\<langle>x,n\<rangle>,0\<rangle>, p) \<in> Fn(\<omega>,I\<times>\<omega>,J)"
    using FiniteFun.consI[of "\<langle>x,n\<rangle>" "I\<times>\<omega>" 0 J p]
      Fn_nat_eq_FiniteFun by auto
  ultimately
  have "cons(\<langle>\<langle>w,n\<rangle>,1\<rangle>, cons(\<langle>\<langle>x,n\<rangle>,0\<rangle>, p) ) \<in> Fn(\<omega>,I\<times>\<omega>,J)"
    using FiniteFun.consI[of "\<langle>w,n\<rangle>" "I \<times> \<omega>" 1 J "cons(\<langle>\<langle>x,n\<rangle>,0\<rangle>, p)"]
      Fn_nat_eq_FiniteFun by auto
  with \<open>n \<in> \<omega>\<close>
  show ?thesis
    using \<open>p \<in> _\<close> by (intro bexI) auto
qed

locale add_reals = cohen_data nat _ 2

subsection\<open>Combinatorial results on Cohen posets\<close>

sublocale cohen_data \<subseteq> forcing_notion "Fn(\<kappa>,I,J)" "Fnle(\<kappa>,I,J)" 0
proof
  show "0 \<in> Fn(\<kappa>, I, J)"
    using zero_lt_kappa zero_in_Fn by simp
  then
  show "\<forall>p\<in>Fn(\<kappa>, I, J). \<langle>p, 0\<rangle> \<in> Fnle(\<kappa>, I, J)"
    unfolding preorder_on_def refl_def trans_on_def
    by auto
next
  show "preorder_on(Fn(\<kappa>, I, J), Fnle(\<kappa>, I, J))"
    unfolding preorder_on_def refl_def trans_on_def
    by blast
qed

context cohen_data
begin

lemma compat_imp_Un_is_function:
  assumes "G \<subseteq> Fn(\<kappa>, I, J)" "\<And>p q. p \<in> G \<Longrightarrow> q \<in> G \<Longrightarrow> compat(p,q)"
  shows "function(\<Union>G)"
  unfolding function_def
proof (intro allI ballI impI)
  fix x y y'
  assume "\<langle>x, y\<rangle> \<in> \<Union>G" "\<langle>x, y'\<rangle> \<in> \<Union>G"
  then
  obtain p q where "\<langle>x, y\<rangle> \<in> p" "\<langle>x, y'\<rangle> \<in> q" "p \<in> G" "q \<in> G"
    by auto
  moreover from this and assms
  obtain r where "r \<in> Fn(\<kappa>, I, J)" "r \<supseteq> p" "r \<supseteq> q"
    using compatD[of p q] by force
  moreover from this
  have "function(r)"
    using Fn_is_function by simp
  ultimately
  show "y = y'"
    unfolding function_def by fastforce
qed

lemma Un_filter_is_function: "filter(G) \<Longrightarrow> function(\<Union>G)"
  using compat_imp_Un_is_function filter_imp_compat[of G]
    filter_subset_notion
  by simp

end \<comment> \<open>\<^locale>\<open>cohen_data\<close>\<close>

locale M_cohen = M_delta +
  assumes
    countable_lepoll_assms2:
    "M(A') \<Longrightarrow> M(A) \<Longrightarrow> M(b) \<Longrightarrow> M(f) \<Longrightarrow> separation(M, \<lambda>y. \<exists>x\<in>A'. y = \<langle>x, \<mu> i. x \<in> if_range_F_else_F(\<lambda>a. {p \<in> A . domain(p) = a}, b, f, i)\<rangle>)"
    and
    countable_lepoll_assms3:
    "M(A) \<Longrightarrow> M(f) \<Longrightarrow> M(b) \<Longrightarrow> M(D) \<Longrightarrow> M(r') \<Longrightarrow> M(A')\<Longrightarrow>
        separation(M, \<lambda>y. \<exists>x\<in>A'. y = \<langle>x, \<mu> i. x \<in> if_range_F_else_F(drSR_Y(r', D, A), b, f, i)\<rangle>)"

lemma (in M_library) Fnle_rel_Aleph_rel1_closed[intro,simp]:
  "M(Fnle\<^bsup>M\<^esup>(\<aleph>\<^bsub>1\<^esub>\<^bsup>M\<^esup>, \<aleph>\<^bsub>1\<^esub>\<^bsup>M\<^esup>, \<omega> \<rightarrow>\<^bsup>M\<^esup> 2))"
  by simp

locale M_add_reals = M_cohen + add_reals
begin

lemmas zero_lesspoll_rel_kappa = zero_lesspoll_rel[OF zero_lt_kappa]

end \<comment> \<open>\<^locale>\<open>M_add_reals\<close>\<close>

(* MOVE THIS to some appropriate place. Notice that in Forcing_Notions
we don't import anything relative. *)
relativize relational "compat_in" "is_compat_in" external
synthesize "compat_in" from_definition "is_compat_in" assuming "nonempty"
context
  notes Un_assoc[simp] Un_trasposition_aux2[simp]
begin
arity_theorem for "compat_in_fm"
end

lemma (in M_trivial) compat_in_abs[absolut]:
  assumes
    "M(A)" "M(r)" "M(p)" "M(q)"
  shows
    "is_compat_in(M,A,r,p,q) \<longleftrightarrow> compat_in(A,r,p,q)"
  using assms unfolding is_compat_in_def compat_in_def by simp

definition
  antichain :: "i\<Rightarrow>i\<Rightarrow>i\<Rightarrow>o" where
  "antichain(P,leq,A) \<equiv> A\<subseteq>P \<and> (\<forall>p\<in>A. \<forall>q\<in>A. p\<noteq>q \<longrightarrow> \<not>compat_in(P,leq,p,q))"

relativize relational  "antichain" "antichain_rel"

definition
  ccc :: "i \<Rightarrow> i \<Rightarrow> o" where
  "ccc(P,leq) \<equiv> \<forall>A. antichain(P,leq,A) \<longrightarrow> |A| \<le> nat"

abbreviation
  antichain_rel_abbr :: "[i\<Rightarrow>o,i,i,i] \<Rightarrow> o" (\<open>antichain\<^bsup>_\<^esup>'(_,_,_')\<close>) where
  "antichain\<^bsup>M\<^esup>(P,leq,A) \<equiv> antichain_rel(M,P,leq,A)"

abbreviation
  antichain_r_set :: "[i,i,i,i] \<Rightarrow> o" (\<open>antichain\<^bsup>_\<^esup>'(_,_,_')\<close>) where
  "antichain\<^bsup>M\<^esup>(P,leq,A) \<equiv> antichain_rel(##M,P,leq,A)"

context M_trivial
begin

lemma antichain_abs [absolut]:
  "\<lbrakk> M(A); M(P); M(leq) \<rbrakk> \<Longrightarrow> antichain\<^bsup>M\<^esup>(P,leq,A) \<longleftrightarrow> antichain(P,leq,A)"
  unfolding antichain_rel_def antichain_def by (simp add:absolut)

end \<comment> \<open>\<^locale>\<open>M_trivial\<close>\<close>

relativize relational "ccc" "ccc_rel"

abbreviation
  ccc_rel_abbr :: "[i\<Rightarrow>o,i,i]\<Rightarrow>o" (\<open>ccc\<^bsup>_\<^esup>'(_,_')\<close>) where
  "ccc_rel_abbr(M) \<equiv> ccc_rel(M)"

abbreviation
  ccc_r_set :: "[i,i,i]\<Rightarrow>o" (\<open>ccc\<^bsup>_\<^esup>'(_,_')\<close>) where
  "ccc_r_set(M) \<equiv> ccc_rel(##M)"

context M_cardinals
begin

lemma def_ccc_rel:
  shows
    "ccc\<^bsup>M\<^esup>(P,leq) \<longleftrightarrow> (\<forall>A[M]. antichain\<^bsup>M\<^esup>(P,leq,A) \<longrightarrow> |A|\<^bsup>M\<^esup> \<le> \<omega>)"
  using is_cardinal_iff
  unfolding ccc_rel_def by (simp add:absolut)

end \<comment> \<open>\<^locale>\<open>M_cardinals\<close>\<close>

context M_FiniteFun
begin

lemma Fnle_nat_closed[intro,simp]:
  assumes "M(I)" "M(J)"
  shows "M(Fnle(\<omega>,I,J))"
  unfolding Fnle_def Fnlerel_def Rrel_def
  using supset_separation FiniteFun_closed Fn_nat_eq_FiniteFun assms by simp

lemma Fn_nat_closed:
  assumes "M(A)" "M(B)" shows "M(Fn(\<omega>,A,B))"
  using assms Fn_nat_eq_FiniteFun
  by simp

end \<comment> \<open>\<^locale>\<open>M_FiniteFun\<close>\<close>

context M_add_reals
begin

lemma lam_replacement_drSR_Y: "M(A) \<Longrightarrow> M(D) \<Longrightarrow> M(r') \<Longrightarrow> lam_replacement(M, drSR_Y(r',D,A))"
  using lam_replacement_drSR_Y
  by simp

lemma (in M_trans) mem_F_bound3:
  fixes F A
  defines "F \<equiv> dC_F"
  shows "x\<in>F(A,c) \<Longrightarrow> c \<in> (range(f) \<union> {domain(x). x\<in>A})"
  using apply_0 unfolding F_def
  by (cases "M(c)", auto simp:F_def drSR_Y_def dC_F_def)

lemma ccc_rel_Fn_nat:
  assumes "M(I)"
  shows "ccc\<^bsup>M\<^esup>(Fn(nat,I,2), Fnle(nat,I,2))"
proof -
  have repFun_dom_closed:"M({domain(p) . p \<in> A})" if "M(A)" for A
    using RepFun_closed domain_replacement_simp transM[OF _ \<open>M(A)\<close>] that
    by auto
  from assms
  have "M(Fn(nat,I,2))" using Fn_nat_eq_FiniteFun by simp
  {
    fix A
    assume "\<not> |A|\<^bsup>M\<^esup> \<le> nat" "M(A)" "A \<subseteq> Fn(nat, I, 2)"
    moreover from this
    have "countable_rel(M,{p\<in>A. domain(p) = d})" if "M(d)" for d
    proof (cases "d\<prec>\<^bsup>M\<^esup>nat \<and> d \<subseteq> I")
      case True
      with \<open>A \<subseteq> Fn(nat, I, 2)\<close> \<open>M(A)\<close>
      have "{p \<in> A . domain(p) = d} \<subseteq> d \<rightarrow>\<^bsup>M\<^esup> 2"
        using domain_of_fun function_space_rel_char[of _ 2]
        by (auto,subgoal_tac "M(domain(x))",simp_all add:transM[of _ A],force)
      moreover from True \<open>M(d)\<close>
      have "Finite(d \<rightarrow>\<^bsup>M\<^esup> 2)"
        using Finite_Pi[THEN [2] subset_Finite, of _ d "\<lambda>_. 2"]
          lesspoll_rel_nat_is_Finite_rel function_space_rel_char[of _ 2]
        by auto
      moreover from \<open>M(d)\<close>
      have "M(d \<rightarrow>\<^bsup>M\<^esup> 2)"
        by simp
      moreover from \<open>M(A)\<close>
      have "M({p \<in> A . domain(p) = d})"
        using separation_closed domain_eq_separation[OF \<open>M(d)\<close>] by simp
      ultimately
      show ?thesis using subset_Finite[of _ "d\<rightarrow>\<^bsup>M\<^esup>2" ]
        by (auto intro!:Finite_imp_countable_rel)
    next
      case False
      with \<open>A \<subseteq> Fn(nat, I, 2)\<close> \<open>M(A)\<close>
      have "domain(p) \<noteq> d" if "p\<in>A" for p
      proof -
        note False that \<open>M(A)\<close>
        moreover from this
        obtain d' where "d' \<subseteq> I" "p\<in>d' \<rightarrow> 2" "d' \<prec> \<omega>"
          using FnD[OF subsetD[OF \<open>A\<subseteq>_\<close> \<open>p\<in>A\<close>]]
          by auto
        moreover from this
        have "p \<approx> d'" "domain(p) = d'"
          using function_eqpoll Pi_iff
          by auto
        ultimately
        show ?thesis
          using lesspoll_nat_imp_lesspoll_rel transM[of p]
          by auto
      qed
      then
      show ?thesis
        using empty_lepoll_relI by auto
    qed
    have 2:"M(x) \<Longrightarrow> x \<in> dC_F(X, i) \<Longrightarrow> M(i)" for x X i
      unfolding dC_F_def
      by auto
    moreover
    have "uncountable_rel(M,{domain(p) . p \<in> A})"
    proof
      interpret M_replacement_lepoll M dC_F
        using lam_replacement_dC_F domain_eq_separation lam_replacement_inj_rel lam_replacement_minimum
        unfolding dC_F_def
      proof(unfold_locales,simp_all)
        fix X b f
        assume "M(X)" "M(b)" "M(f)"
        with 2[of X]
        show "lam_replacement(M, \<lambda>x. \<mu> i. x \<in> if_range_F_else_F(\<lambda>d. {p \<in> X . domain(p) = d}, b, f, i))"
          using lam_replacement_dC_F domain_eq_separation
            mem_F_bound3 countable_lepoll_assms2 repFun_dom_closed
          by (rule_tac lam_Least_assumption_general[where U="\<lambda>_. {domain(x). x\<in>X}"],auto)
      qed (auto)
      have "\<exists>a\<in>A. x = domain(a) \<Longrightarrow> M(dC_F(A,x))" for x
        using \<open>M(A)\<close> transM[OF _ \<open>M(A)\<close>] by (auto)
      moreover
      have "w \<in> A \<and> domain(w) = x \<Longrightarrow> M(x)" for w x
        using transM[OF _ \<open>M(A)\<close>] by auto
      ultimately
      interpret M_cardinal_UN_lepoll _ "dC_F(A)" "{domain(p). p\<in>A}"
        using lam_replacement_dC_F lam_replacement_inj_rel \<open>M(A)\<close>
          lepoll_assumptions domain_eq_separation lam_replacement_minimum
          countable_lepoll_assms2 repFun_dom_closed
          lepoll_assumptions1[OF \<open>M(A)\<close> repFun_dom_closed[OF \<open>M(A)\<close>]]
        apply(unfold_locales)
        by(simp_all del:if_range_F_else_F_def,
            rule_tac lam_Least_assumption_general[where U="\<lambda>_. {domain(x). x\<in>A}"])
          (auto simp del:if_range_F_else_F_def simp add:dC_F_def)
      from \<open>A \<subseteq> Fn(nat, I, 2)\<close>
      have x:"(\<Union>d\<in>{domain(p) . p \<in> A}. {p\<in>A. domain(p) = d}) = A"
        by auto
      moreover
      assume "countable_rel(M,{domain(p) . p \<in> A})"
      moreover
      note \<open>\<And>d. M(d) \<Longrightarrow> countable_rel(M,{p\<in>A. domain(p) = d})\<close>
      moreover from \<open>M(A)\<close>
      have "p\<in>A \<Longrightarrow> M(domain(p))" for p
        by (auto dest: transM)
      ultimately
      have "countable_rel(M,A)"
        using countable_rel_imp_countable_rel_UN
        unfolding dC_F_def
        by auto
      with \<open>\<not> |A|\<^bsup>M\<^esup> \<le> nat\<close> \<open>M(A)\<close>
      show False
        using countable_rel_iff_cardinal_rel_le_nat by simp
    qed
    moreover from \<open>A \<subseteq> Fn(nat, I, 2)\<close> \<open>M(A)\<close>
    have "p \<in> A \<Longrightarrow> Finite(domain(p))" for p
      using lesspoll_rel_nat_is_Finite_rel[of "domain(p)"]
        lesspoll_nat_imp_lesspoll_rel[of "domain(p)"]
        domain_of_fun[of p _ "\<lambda>_. 2"] by (auto dest:transM)
    moreover
    note repFun_dom_closed[OF \<open>M(A)\<close>]
    ultimately
    obtain D where "delta_system(D)" "D \<subseteq> {domain(p) . p \<in> A}" "D \<approx>\<^bsup>M\<^esup> \<aleph>\<^bsub>1\<^esub>\<^bsup>M\<^esup>" "M(D)"
      using delta_system_uncountable_rel[of "{domain(p) . p \<in> A}"] by auto
    then
    have delta:"\<forall>d1\<in>D. \<forall>d2\<in>D. d1 \<noteq> d2 \<longrightarrow> d1 \<inter> d2 = \<Inter>D"
      using delta_system_root_eq_Inter
      by simp
    moreover from \<open>D \<approx>\<^bsup>M\<^esup> \<aleph>\<^bsub>1\<^esub>\<^bsup>M\<^esup>\<close> \<open>M(D)\<close>
    have "uncountable_rel(M,D)"
      using uncountable_rel_iff_subset_eqpoll_rel_Aleph_rel1 by auto
    moreover from this and \<open>D \<subseteq> {domain(p) . p \<in> A}\<close>
    obtain p1 where "p1 \<in> A" "domain(p1) \<in> D"
      using uncountable_rel_not_empty[of D] by blast
    moreover from this and \<open>p1 \<in> A \<Longrightarrow> Finite(domain(p1))\<close>
    have "Finite(domain(p1))"
      using Finite_domain by simp
    moreover
    define r where "r \<equiv> \<Inter>D"
    moreover from \<open>M(D)\<close>
    have "M(r)" "M(r\<times>2)"
      unfolding r_def by simp_all
    ultimately
    have "Finite(r)" using subset_Finite[of "r" "domain(p1)"]
      by auto
    have "countable_rel(M,{restrict(p,r) . p\<in>A})"
    proof -
      note \<open>M(Fn(nat, I, 2))\<close> \<open>M(r)\<close>
      moreover from this
      have "f\<in>Fn(nat, I, 2) \<Longrightarrow> M(restrict(f,r))" for f
        by (blast dest: transM)
      ultimately
      have "f\<in>Fn(nat, I, 2) \<Longrightarrow> restrict(f,r) \<in> Pow_rel(M,r \<times> 2)" for f
        using restrict_subset_Sigma[of f _ "\<lambda>_. 2" r] Pow_rel_char
        by (auto del:FnD dest!:FnD simp: Pi_def) (auto dest:transM)
      with \<open>A \<subseteq> Fn(nat, I, 2)\<close>
      have "{restrict(f,r) . f \<in> A } \<subseteq> Pow_rel(M,r \<times> 2)"
        by fast
      moreover from \<open>M(A)\<close> \<open>M(r)\<close>
      have "M({restrict(f,r) . f \<in> A })"
        using RepFun_closed restrict_strong_replacement transM[OF _ \<open>M(A)\<close>] by auto
      moreover
      note \<open>Finite(r)\<close> \<open>M(r)\<close>
      ultimately
      show ?thesis
        using Finite_Sigma[THEN Finite_Pow_rel, of r "\<lambda>_. 2"]
        by (intro Finite_imp_countable_rel) (auto intro:subset_Finite)
    qed
    moreover from \<open>M(A)\<close> \<open>M(D)\<close>
    have "M({p\<in>A. domain(p) \<in> D})"
      using domain_mem_separation by simp
    have "uncountable_rel(M,{p\<in>A. domain(p) \<in> D})" (is "uncountable_rel(M,?X)")
    proof
      from \<open>D \<subseteq> {domain(p) . p \<in> A}\<close>
      have "(\<lambda>p\<in>?X. domain(p)) \<in> surj(?X, D)"
        using lam_type unfolding surj_def by auto
      moreover from \<open>M(A)\<close> \<open>M(?X)\<close>
      have "M(\<lambda>p\<in>?X. domain(p))"
        using lam_closed[OF domain_replacement \<open>M(?X)\<close>] transM[OF _ \<open>M(?X)\<close>] by simp
      moreover
      note \<open>M(?X)\<close> \<open>M(D)\<close>
      moreover from calculation
      have surjection:"(\<lambda>p\<in>?X. domain(p)) \<in> surj\<^bsup>M\<^esup>(?X, D)"
        using surj_rel_char by simp
      moreover
      assume "countable_rel(M,?X)"
      moreover
      note \<open>uncountable_rel(M,D)\<close>
      ultimately
      show False
        using surj_rel_countable_rel[OF _ surjection] by auto
    qed
    moreover
    have "D = (\<Union>f\<in>Pow_rel(M,r\<times>2) . {y . p\<in>A, restrict(p,r) = f \<and> y=domain(p) \<and> domain(p) \<in> D})"
    proof -
      {
        fix z
        assume "z \<in> D"
        with \<open>M(D)\<close>
        have \<open>M(z)\<close> by (auto dest:transM)
        from \<open>z\<in>D\<close> \<open>D \<subseteq> _\<close> \<open>M(A)\<close>
        obtain p  where "domain(p) = z" "p \<in> A" "M(p)"
          by (auto dest:transM)
        moreover from \<open>A \<subseteq> Fn(nat, I, 2)\<close> \<open>M(z)\<close> and this
        have "p \<in> z \<rightarrow>\<^bsup>M\<^esup> 2"
          using domain_of_fun function_space_rel_char by (auto del:FnD dest!:FnD)
        moreover from this \<open>M(z)\<close>
        have "p \<in> z \<rightarrow> 2"
          using domain_of_fun function_space_rel_char by (auto)
        moreover from this \<open>M(r)\<close>
        have "restrict(p,r) \<subseteq> r \<times> 2"
          using function_restrictI[of p r] fun_is_function[of p z "\<lambda>_. 2"]
            restrict_subset_Sigma[of p z "\<lambda>_. 2" r] function_space_rel_char
          by (auto simp:Pi_def)
        moreover from \<open>M(p)\<close> \<open>M(r)\<close>
        have "M(restrict(p,r))" by simp
        moreover
        note \<open>M(r)\<close>
        ultimately
        have "\<exists>p\<in>A.  restrict(p,r) \<in> Pow_rel(M,r\<times>2) \<and> domain(p) = z"
          using Pow_rel_char by auto
      }
      then
      show ?thesis
        by (intro equalityI) (force)+
    qed
    from \<open>M(D)\<close>\<open>M(r)\<close>
    have "M({y . p\<in>A, restrict(p,r) = f \<and> y=domain(p) \<and> domain(p) \<in> D})" (is "M(?Y(A,f))")
      if "M(f)" "M(A)" for f A
      using drSR_Y_closed[unfolded drSR_Y_def] that
      by simp
    then
    obtain f where "uncountable_rel(M,?Y(A,f))" "M(f)"
    proof -
      have 1:"M(i)"
        if "M(B)" "M(x)"
          "x \<in> {y . x \<in> B, restrict(x, r) = i \<and> y = domain(x) \<and> domain(x) \<in> D}"
        for B x i
        using that \<open>M(r)\<close>
        by (auto dest:transM)
      note \<open>M(r)\<close>
      moreover from this
      have "M(Pow\<^bsup>M\<^esup>(r \<times> 2))" by simp
      moreover
      note \<open>M(A)\<close> \<open>\<And>f A. M(f) \<Longrightarrow> M(A) \<Longrightarrow> M(?Y(A,f))\<close> \<open>M(D)\<close>
      moreover from calculation
      interpret M_replacement_lepoll M "drSR_Y(r,D)"
        using countable_lepoll_assms3 lam_replacement_inj_rel lam_replacement_drSR_Y
          drSR_Y_closed lam_Least_assumption_drSR_Y lam_replacement_minimum
        by (unfold_locales,simp_all add:drSR_Y_def,rule_tac 1,simp_all)
      from calculation
      have "x \<in> Pow\<^bsup>M\<^esup>(r \<times> 2) \<Longrightarrow> M(drSR_Y(r, D, A, x))" for x
        unfolding drSR_Y_def by (auto dest:transM)
      ultimately
      interpret M_cardinal_UN_lepoll _ "?Y(A)" "Pow_rel(M,r\<times>2)"
        using countable_lepoll_assms3 lam_replacement_drSR_Y
          lepoll_assumptions[where S="Pow_rel(M,r\<times>2)", unfolded lepoll_assumptions_defs]
          lam_Least_assumption_drSR_Y[unfolded drSR_Y_def] lam_replacement_minimum
        unfolding drSR_Y_def
        apply unfold_locales
             apply (simp_all add:lam_replacement_inj_rel del: if_range_F_else_F_def,rule_tac 1,simp_all)
        by ((fastforce dest:transM[OF _ \<open>M(A)\<close>])+)
      {
        from \<open>Finite(r)\<close> \<open>M(r)\<close>
        have "countable_rel(M,Pow_rel(M,r\<times>2))"
          using Finite_Sigma[THEN Finite_Pow_rel] Finite_imp_countable_rel
          by simp
        moreover
        assume "M(f) \<Longrightarrow> countable_rel(M,?Y(A,f))" for f
        moreover
        note \<open>D = (\<Union>f\<in>Pow_rel(M,r\<times>2) .?Y(A,f))\<close> \<open>M(r)\<close>
        moreover
        note \<open>uncountable_rel(M,D)\<close>
        ultimately
        have "False"
          using countable_rel_imp_countable_rel_UN by (auto dest: transM)
      }
      with that
      show ?thesis
        by auto
    qed
    moreover from this \<open>M(A)\<close> and \<open>M(f) \<Longrightarrow> M(A) \<Longrightarrow> M(?Y(A,f))\<close>
    have "M(?Y(A,f))"
      by blast
    ultimately
    obtain j where "j \<in> inj_rel(M,nat, ?Y(A,f))" "M(j)"
      using uncountable_rel_iff_nat_lt_cardinal_rel[THEN iffD1, THEN leI,
          THEN cardinal_rel_le_imp_lepoll_rel, THEN lepoll_relD]
      by auto
    with \<open>M(?Y(A,f))\<close>
    have "j`0 \<noteq> j`1" "j`0 \<in> ?Y(A,f)" "j`1 \<in> ?Y(A,f)"
      using inj_is_fun[THEN apply_type, of j nat "?Y(A,f)"]
        inj_rel_char
      unfolding inj_def by auto
    then
    obtain p q where "domain(p) \<noteq> domain(q)" "p \<in> A" "q \<in> A"
      "domain(p) \<in> D" "domain(q) \<in> D"
      "restrict(p,r) = restrict(q,r)" by auto
    moreover from this and delta
    have "domain(p) \<inter> domain(q) = r"
      unfolding r_def by simp
    moreover
    note \<open>A \<subseteq> Fn(nat, I, 2)\<close> Fn_nat_abs[OF \<open>M(I)\<close> nat_into_M[of 2],simplified]
    moreover from calculation
    have "p \<in> Fn\<^bsup>M\<^esup>(nat, I, 2)" "q \<in> Fn\<^bsup>M\<^esup>(nat, I, 2)"
      by auto
    moreover from calculation
    have "p \<union> q \<in> Fn(nat, I, 2)"
      using restrict_eq_imp_compat_rel InfCard_rel_nat
      by simp
    ultimately
    have "\<exists>p\<in>A. \<exists>q\<in>A. p \<noteq> q \<and> compat_in(Fn(nat, I, 2), Fnle(nat, I, 2), p, q)"
      unfolding compat_in_def
      by (rule_tac bexI[of _ p], rule_tac bexI[of _ q]) blast
  }
  moreover from assms
  have "M(Fnle(\<omega>,I,2))"
    by simp
  moreover note \<open>M(Fn(\<omega>,I,2))\<close>
  ultimately
  show ?thesis using def_ccc_rel by (auto simp:absolut antichain_def) fastforce
qed

end \<comment> \<open>\<^locale>\<open>M_add_reals\<close>\<close>

end


(*
 * Copyright 2014, NICTA
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(NICTA_BSD)
 *)

(*
 * Facts about recursive functions with measure parameter.
 * Any recursive functions from AutoCorres are monotonic in the measure,
 * which allows us to use the "measure_call" mechanism for calling them.
 *)
theory MonadMono
imports
  NonDetMonadEx
  "Lib.OptionMonadWP"
begin

(*
 * Call function f by returning all of its possible results.
 * The call succeeds if any measure value succeeds.
 *)
definition "measure_call f \<equiv>
    \<lambda>s. ({(r', s'). \<exists>m. (r', s') \<in> fst (f m s)}, \<forall>m. snd (f m s))"

(*
 * monad_mono gives preconditions for functions so that measure_call will
 * return meaningful results.
 *
 * The preconditions are:
 *
 * - If the measure is increased, the function never returns fewer
 *   results. (Monotonicity condition)
 *
 * - If the function succeeds with some measure, it will not fail with
 *   a larger measure, and will return exactly the same results.
 *
 * The monotonicity condition is technically not needed, but all our
 * functions satisfy it anyway and it makes intermediate proofs easier.
 *)
definition "monad_mono f \<equiv>
     (\<forall>(x :: nat) y s. x < y \<longrightarrow>
         (fst (f x s) \<subseteq> fst (f y s) \<and>
          (\<not> snd (f x s) \<longrightarrow> \<not> snd (f y s) \<and> fst (f x s) = fst (f y s))))"

(* Basic monad_mono lemmas *)
lemma monad_mono_incl: "\<lbrakk> monad_mono f; \<not> snd (f m s) \<rbrakk> \<Longrightarrow> fst (f m' s) \<subseteq> fst (f m s)"
  using less_linear[where x = m and y = m']
  by (auto simp: monad_mono_def)

(* wp rules for function calls *)
lemma call_all_valid [wp]:
    "\<lbrakk> \<forall> m. valid P (x m) Q; monad_mono x \<rbrakk> \<Longrightarrow> valid P (measure_call x) Q"
  apply (clarsimp simp: valid_def measure_call_def monad_mono_def)
  by blast

lemma call_all_validNF [wp]:
    "\<lbrakk>  validNF P (x m) Q; monad_mono x \<rbrakk> \<Longrightarrow> validNF P (measure_call x) Q"
  apply (clarsimp simp: measure_call_def validNF_def valid_def no_fail_def)
  apply (metis in_mono split_conv monad_mono_incl)
  done

(* Alternative definition of monad_mono, suitable for induction *)
definition "monad_mono_step f m \<equiv>
  (\<forall>s. fst (f m s) \<subseteq> fst (f (Suc m) s) \<and>
       (\<not> snd (f m s) \<longrightarrow> \<not> snd (f (Suc m) s) \<and> fst (f m s) = fst (f (Suc m) s)))"

lemma monad_mono_alt_def: "monad_mono f = (\<forall>m. monad_mono_step f m)"
  apply (rule iffI)
   apply (fastforce simp: monad_mono_def monad_mono_step_def)
  apply (unfold monad_mono_def monad_mono_step_def)
  apply clarify
  apply (subst (asm) atomize_all[symmetric])+
  proof -
    fix x y :: nat
    fix s
    assume suc: "\<And>m s. fst (f m s) \<subseteq> fst (f (Suc m) s) \<and>
              (\<not> snd (f m s) \<longrightarrow> \<not> snd (f (Suc m) s) \<and> fst (f m s) = fst (f (Suc m) s))"
       and less: "x < y"
    thus "fst (f x s) \<subseteq> fst (f y s) \<and>
          (\<not> snd (f x s) \<longrightarrow> \<not> snd (f y s) \<and> fst (f x s) = fst (f y s))"
      apply (induct x)
       apply (induct y)
        apply blast
       apply blast
      (* induct bureaucracy... *)
      proof -
        fix x :: nat
        assume less: "Suc x < y"
        thus "fst (f (Suc x) s) \<subseteq> fst (f y s) \<and>
           (\<not> snd (f (Suc x) s) \<longrightarrow> \<not> snd (f y s) \<and> fst (f (Suc x) s) = fst (f y s))"
          apply (induct y)
           apply blast
          apply (case_tac "Suc x < y")
           using suc apply blast
          apply (case_tac "Suc x = y")
           using suc apply blast
          apply simp
          done
       qed
  qed

lemmas monad_mono_step = iffD2[OF monad_mono_alt_def, rule_format]

lemma monad_mono_step_const: "monad_mono_step (\<lambda>_. f) m"
  by (simp add: monad_mono_step_def)

(* nondet_monad rules *)
lemma monad_mono_step_in_monad:
  "\<lbrakk> monad_mono_step f m; (r', s') \<in> fst (f m s) \<rbrakk> \<Longrightarrow> (r', s') \<in> fst (f (Suc m) s)"
  apply (clarsimp simp: monad_mono_step_def)
  apply blast
  done

lemma monad_mono_step_snd_monad:
  "\<lbrakk> monad_mono_step f m; \<not> snd (f m s) \<rbrakk> \<Longrightarrow> \<not> snd (f (Suc m) s)"
  by (clarsimp simp: monad_mono_step_def)

lemma monad_mono_step_bexI:
  "\<lbrakk> monad_mono_step f m; (r', s') \<in> fst (f m s); P r' s' \<rbrakk> \<Longrightarrow> \<exists>(r', s') \<in> fst (f (Suc m) s). P r' s'"
  apply (drule (1) monad_mono_step_in_monad)
  apply force
  done

lemma monad_mono_stepI [intro]:
  "\<lbrakk> \<And>s r' s'. (r', s') \<in> fst (f m s) \<Longrightarrow> (r', s') \<in> fst (f (Suc m) s);
     \<And>s. \<not> snd (f m s) \<Longrightarrow> \<not> snd (f (Suc m) s);
     \<And>s r' s'. \<lbrakk> \<not> snd (f m s); \<not> snd (f (Suc m) s); (r', s') \<in> fst (f (Suc m) s) \<rbrakk>
                \<Longrightarrow> (r', s') \<in> fst (f m s)
   \<rbrakk> \<Longrightarrow> monad_mono_step f m"
  apply (clarsimp simp: monad_mono_step_def)
  apply fast
  done

lemma monad_mono_step_bind:
  "\<lbrakk> monad_mono_step f m; \<And>x. monad_mono_step (\<lambda>m. g m x) m \<rbrakk>
   \<Longrightarrow> monad_mono_step (\<lambda>m. (f m) >>= (g m)) m"
  apply atomize
  apply rule
    apply (monad_eq)
    apply (metis monad_mono_step_in_monad)
   apply (monad_eq simp: Ball_def)
   apply (metis monad_mono_step_def)
  apply (monad_eq simp: Ball_def)
  apply (unfold monad_mono_step_def)
  apply blast
  done

lemma monad_mono_step_bindE:
  "\<lbrakk> monad_mono_step f m; \<And>x. monad_mono_step (\<lambda>m. g m x) m \<rbrakk>
   \<Longrightarrow> monad_mono_step (\<lambda>m. (f m) >>=E (g m)) m"
  apply (unfold bindE_def)
  apply (rule monad_mono_step_bind)
   apply simp
  apply (monad_eq simp: monad_mono_step_def NonDetMonad.lift_def
      split: sum.splits)
  done

lemma monad_mono_step_liftE:
  "monad_mono_step f m \<Longrightarrow> monad_mono_step (\<lambda>m. liftE (f m)) m"
  apply (unfold liftE_def)
  apply (erule monad_mono_step_bind)
  apply (rule monad_mono_step_const)
  done

lemma monad_mono_step_handleE':
  "\<lbrakk> monad_mono_step f m; \<And>x. monad_mono_step (\<lambda>m. g m x) m \<rbrakk>
   \<Longrightarrow> monad_mono_step (\<lambda>m. f m <handle2> g m) m"
  apply atomize
  apply rule
    apply (monad_eq)
    apply (metis monad_mono_step_in_monad)
   apply (monad_eq simp: Ball_def)
   apply (metis monad_mono_step_def)
  apply (monad_eq simp: Ball_def)
  apply (fastforce simp: monad_mono_step_def)
  done

lemma monad_mono_step_handleE:
  "\<lbrakk> monad_mono_step f m; \<And>x. monad_mono_step (\<lambda>m. g m x) m \<rbrakk>
   \<Longrightarrow> monad_mono_step (\<lambda>m. f m <handle> g m) m"
  by (simp add: handleE_def monad_mono_step_handleE')

lemma monad_mono_step_condition:
  "\<lbrakk> monad_mono_step f m; monad_mono_step g m \<rbrakk>
   \<Longrightarrow> monad_mono_step (\<lambda>m. condition C (f m) (g m)) m"
  apply rule
    apply (monad_eq simp: monad_mono_step_def, blast)+
  done

lemma fst_whileLoop_is_exs_valid:
  "((a, b) \<in> fst (whileLoop C B i s)) = \<lbrace> \<lambda>s'. s' = s \<rbrace> whileLoop C B i \<exists>\<lbrace> \<lambda>rv s. rv = a \<and> s = b \<rbrace>"
  by (clarsimp simp: exs_valid_def Bex_def)

lemma not_snd_whileLoop_is_validNF:
  "(\<not> snd (whileLoop C B i s)) = \<lbrace> \<lambda>s'. s' = s \<rbrace> whileLoop C B i \<lbrace> \<lambda>_ _. True \<rbrace>!"
  by (clarsimp simp: validNF_alt_def)

lemma monad_mono_step_whileLoop:
  assumes body_mono: "\<And>x. monad_mono_step (\<lambda>m. B m x) m"
  shows "monad_mono_step (\<lambda>m. whileLoop C (B m) i) m"
proof -
  {
    fix a b s
    have "(a, b) \<in> fst (whileLoop C (B m) i s) \<Longrightarrow>
             (a, b) \<in> fst (whileLoop C (B (Suc m)) i s)"
      apply (clarsimp simp: fst_whileLoop_is_exs_valid)
      apply (subst (asm) exs_valid_whileLoop_complete [symmetric])
      apply (erule exE | erule conjE)+
      apply (rule_tac T=T and R=R in exs_valid_whileLoop)
         apply clarsimp
        apply (cut_tac x=r in body_mono)
        apply (clarsimp simp: monad_mono_step_def exs_valid_def split_def)
        apply blast
       apply simp
      apply blast
      done
  }
  note A = this

  {
    fix a b s
    have "\<lbrakk> \<not> snd (whileLoop C (B m) i s);
                  (a, b) \<in> fst (whileLoop C (B (Suc m)) i s) \<rbrakk>
              \<Longrightarrow> (a, b) \<in> fst (whileLoop C (B m) i s)"
      apply (clarsimp simp: fst_whileLoop_is_exs_valid)
      apply (subst (asm) exs_valid_whileLoop_complete [symmetric])
      apply (subst (asm) not_snd_whileLoop_complete)
      apply (erule exE | erule conjE)+
      apply (rule_tac T="\<lambda>r s. T r s \<and> I r s" and R=Ra in exs_valid_whileLoop)
         apply simp
        apply (cut_tac x=r in body_mono)
        apply (clarsimp simp: monad_mono_step_def exs_valid_def split_def Bex_def)
        apply metis
       apply simp
      apply (clarsimp simp: exs_valid_def Bex_def)
      done
  }
  note B = this

  {
    fix i s
    have "\<lbrakk>\<not> snd (whileLoop C (B m) i s) \<rbrakk> \<Longrightarrow>
                  \<not> snd (whileLoop C (B (Suc m)) i s)"
      apply (subst (asm) not_snd_whileLoop_complete)
      apply (erule exE | erule conjE)+
      apply (rule_tac I="I" and R=R in not_snd_whileLoop)
        apply clarsimp
       apply (cut_tac x=r in body_mono)
       apply (clarsimp simp: monad_mono_step_def validNF_alt_def)
       apply blast
      apply simp
      done
  }
  note C = this

  show ?thesis
    apply (clarsimp simp: monad_mono_step_def)
    apply (metis prod.exhaust subsetI subset_antisym A B C)
    done
qed

lemma monad_mono_step_whileLoopE:
  "\<lbrakk> \<And>x. monad_mono_step (\<lambda>m. B m x) m \<rbrakk>
   \<Longrightarrow> monad_mono_step (\<lambda>m. whileLoopE C (B m) i) m"
  apply (unfold whileLoopE_def)
  apply (subgoal_tac "\<And>x. monad_mono_step (\<lambda>m. lift (B m) x) m")
  apply (erule monad_mono_step_whileLoop)
  apply (unfold lift_def)
  apply rule
    apply (clarsimp split: prod.splits sum.splits)
    apply (fastforce dest: monad_mono_step_in_monad)
   apply (clarsimp split: prod.splits sum.splits simp: monad_mono_step_def)+
  done

(* measure_call for the option monad. *)
definition "measure_ocall f \<equiv> \<lambda>s. f (SOME m. f m s \<noteq> None) s"

definition "option_monad_mono f \<equiv>
  \<forall>(x :: nat) y s. x < y \<longrightarrow>
    (case f y s of None \<Rightarrow> f x s = None
                 | Some r \<Rightarrow> f x s = None \<or> f x s = Some r)"

lemma option_monad_mono_eq:
  "(\<And>m. f m = gets_the (f' m)) \<Longrightarrow> monad_mono f = option_monad_mono f'"
  apply (clarsimp simp: monad_mono_def option_monad_mono_def gets_the_def
    gets_def get_def assert_opt_def return_def fail_def bind_def' split: option.splits)
  apply (rule iff_allI iff_impI)+
  apply (rule_tac t = "\<forall>r. f' x s = Some r \<longrightarrow> (\<exists>r'. f' y s = Some r') \<and> (\<forall>r'. f' y s = Some r' \<longrightarrow> r = r')"
              and s = "\<forall>r. f' x s = Some r \<longrightarrow> f' y s = Some r" in subst)
   apply (force intro: iff_allI iff_impI)
  apply (rule iffI)
   apply (metis (hide_lams, no_types) option.exhaust)
  apply force
  done

lemma measure_ocall_ovalid [wp]:
    "\<lbrakk> \<forall> m. ovalid P (x m) Q; option_monad_mono x \<rbrakk> \<Longrightarrow> ovalid P (measure_ocall x) Q"
  by (clarsimp simp: ovalid_def measure_ocall_def option_monad_mono_def)

lemma measure_ocall_ovalidNF [wp]:
    "\<lbrakk> ovalidNF P (x m) Q; option_monad_mono x \<rbrakk> \<Longrightarrow> ovalidNF P (measure_ocall x) Q"
  apply (clarsimp simp: measure_ocall_def option_monad_mono_def ovalidNF_def)
  apply (rule_tac a = m in someI2)
   apply simp
  apply (metis (lifting, full_types) linorder_neqE_nat option.distinct(1) option.simps(5))
  done

end


theory task1
  imports testvalid
begin

type_synonym tid = real

datatype status =
  WAIT | READY | RUNNING

datatype entered =
  ezero | eone

datatype estate =
  Sch (pool:"(real \<times> tid) list") (run_now:tid) (run_prior:real)
| Task (status:status) (entered:entered) (task_prior:real)
| None

definition req_ch :: "tid \<Rightarrow> string" where
  "req_ch tid = (
    if tid = 1 then ''reqProcessor1''
    else if tid = 2 then ''reqProcessor2''
    else undefined)"

definition preempt_ch :: "tid \<Rightarrow> string" where
  "preempt_ch tid = (
    if tid = 1 then ''preempt1''
    else if tid = 2 then ''preempt2''
    else undefined)"

definition run_ch :: "tid \<Rightarrow> string" where
  "run_ch tid = (
    if tid = 1 then ''run1''
    else if tid = 2 then ''run2''
    else undefined)"

definition free_ch :: "tid \<Rightarrow> string" where
  "free_ch tid = (
    if tid = 1 then ''free1''
    else if tid = 2 then ''free2''
    else undefined)"

definition exit_ch :: "tid \<Rightarrow> string" where
  "exit_ch tid = (
    if tid = 1 then ''exit1''
    else if tid = 2 then ''exit2''
    else undefined)"

definition T :: char where "T = CHR ''t''"

definition C :: char where "C = CHR ''c''"

definition F :: char where "F = CHR ''F''"

fun ent_assign :: "entered \<Rightarrow> estate \<Rightarrow> state \<Rightarrow> estate" where
"ent_assign n (Task st nt p) s = (Task st n p)"

fun wait_assign :: "estate \<Rightarrow> state \<Rightarrow> estate" where
"wait_assign (Task st nt p) s = (Task WAIT nt p)"

fun ready_assign :: "estate \<Rightarrow> state \<Rightarrow> estate" where
"ready_assign (Task st nt p) s = (Task READY nt p)"

fun run_assign :: "estate \<Rightarrow> state \<Rightarrow> estate" where
"run_assign (Task st nt p) s = (Task RUNNING nt p)"

definition inv_s :: "state \<Rightarrow> bool" where
 "inv_s s = (s T \<le> 0.045 \<and> s C \<le> 0.01)"

definition C_upd :: "entered \<Rightarrow> real \<Rightarrow> real" where
 "C_upd ent c = (if ent = ezero then 0 else c)"

lemma C_upd_simp[simp]:
 "C_upd eone c = c"
  unfolding C_upd_def
  by auto

definition T1 :: "estate proc" where
"T1 = IF (\<lambda>(a,s) . status a = WAIT)
        THEN (Cont (ODE ((\<lambda> _ _ . 0)(T := (\<lambda> _ .1)))) (\<lambda> s. s T < 0.045);T ::= (\<lambda>_. 0); Basic (ent_assign ezero);Basic (ready_assign))
      ELSE
      (IF(\<lambda>(a,s) . status a = READY)
        THEN (Cm ((req_ch 1)[!](\<lambda>(a,s). task_prior a));
             (Interrupt (ODE ((\<lambda> _ _ . 0)(T := (\<lambda> _ .1)))) (\<lambda> s. s T < 0.045) [(run_ch 1[?]F,Basic run_assign)]);
             (IF (\<lambda>(a,s) . status a = READY \<and> s T = 0.045) THEN (EChoice [(exit_ch 1[!](\<lambda>_.0),Basic wait_assign),(run_ch 1[?]F,Basic run_assign)]) ELSE Skip FI))
      ELSE
      (IF(\<lambda>(a,s) . entered a = ezero) THEN
             (C ::= (\<lambda>_ . 0); Basic (ent_assign eone)) ELSE Skip FI;
        (Interrupt (ODE ((\<lambda> _ _ . 0)(T := (\<lambda> _ .1),C := (\<lambda>_ .1)))) (\<lambda> s. s T < 0.045 \<and> s C < 0.01) [(preempt_ch 1[?]F,Basic ready_assign)]);
        IF (\<lambda>(a,s) . status a = RUNNING) THEN EChoice [(free_ch 1[!](\<lambda>_.0),Basic wait_assign),(preempt_ch 1[?]F,Basic wait_assign)] ELSE Skip FI)
      FI) FI"

fun T1_tr:: "nat \<Rightarrow> estate ext_state \<Rightarrow> estate tassn" where
  "T1_tr 0 (Task st ent tp,ss)  = emp\<^sub>t"
| "T1_tr (Suc k) (Task WAIT ent tp,ss) =
   (Wait\<^sub>t (9 / 200 - ss T) (\<lambda>t. EState (Task WAIT ent tp, ss(T:= ss T + t))) ({}, {}) @\<^sub>t T1_tr k (Task READY ezero tp,ss(T:=0)))"
| "T1_tr (Suc k) (Task READY ent tp,ss) = (
             (\<exists>\<^sub>t v tt. \<up>(tt\<ge>0 \<and> tt \<le> 0.045 - ss T) \<and>\<^sub>t Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp @\<^sub>t
                   Waitin\<^sub>t tt (\<lambda>t. EState (Task READY ent tp, ss(T := ss T + t)))
                    (run_ch 1) v ({}, {run_ch 1}) @\<^sub>t
                   T1_tr k (Task RUNNING ent tp,ss(T := ss T + tt, F:=v)))
           \<or>\<^sub>t (Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}) @\<^sub>t
                    (outrdy_assn (Task READY ent tp, ss(T:=0.045)) (exit_ch 1) 0 ({exit_ch 1},{run_ch 1}) @\<^sub>t T1_tr k (Task WAIT ent tp,ss(T:=0.045))
                  \<or>\<^sub>t (\<exists>\<^sub>t v. inrdy_assn (Task READY ent tp, ss(T:=0.045)) (run_ch 1) v ({exit_ch 1},{run_ch 1}) @\<^sub>t T1_tr k (Task RUNNING ent tp,ss(T:=0.045,F:=v))))))"
| "T1_tr (Suc k) (Task RUNNING ent tp,ss) = (
             (\<exists>\<^sub>t v tt. \<up>(tt\<ge>0 \<and> tt \<le> (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) \<and>\<^sub>t Waitin\<^sub>t tt
                           (\<lambda>t. EState
                                 (Task RUNNING eone tp, ss
                                  (T := ss T + t,
                                   C := C_upd ent (ss C) + t)))
                           (preempt_ch 1) v ({}, {preempt_ch 1}) @\<^sub>t
                         T1_tr k (Task READY eone tp,ss
                         (T := ss T + tt,
                          C := C_upd ent (ss C) + tt, F := v)))
            \<or>\<^sub>t (Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             ((Outrdy\<^sub>t ((Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C))))) (free_ch 1) 0 ({free_ch 1},{preempt_ch 1})@\<^sub>t
                T1_tr k (Task WAIT eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))))
     \<or>\<^sub>t (\<exists>\<^sub>t v.(Inrdy\<^sub>t ((Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C))))) (preempt_ch 1) v ({free_ch 1},{preempt_ch 1})@\<^sub>t
                T1_tr k (Task WAIT eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)),F:=v)))))
)
)"

lemma T1_Valid_WAIT:
"\<Turnstile> {\<lambda>s t. s = (Task WAIT ent tp,ss) \<and> inv_s (snd s) \<and> P s t}
   T1
    {\<lambda> s t. s = (Task READY ezero tp,ss(T:=0)) \<and> inv_s (snd s) \<and> (P (Task WAIT ent tp,ss) @\<^sub>t Wait\<^sub>t (9 / 200 - ss T) (\<lambda>t. EState (Task WAIT ent tp, ss(T:= ss T + t))) ({}, {})) t}"
  unfolding T1_def
  apply(rule Valid_strengthen_post)
   prefer 2
   apply(rule Valid_cond_sp)
    apply(rule Valid_seq)
     apply(rule Valid_pre_cases'[where P="\<lambda>(a,s) . s T< 0.045"])
      apply(rule Valid_weaken_pre)
       prefer 2
       apply(rule Valid_strengthen_post[where Q'="\<lambda> s t. s = (Task WAIT ent tp,ss(T:=0.045)) \<and> inv_s (snd s) \<and> (P (Task WAIT ent tp,ss) @\<^sub>t
         Wait\<^sub>t (45 / 10 ^ 3 - ss T) (\<lambda>t. EState (Task WAIT ent tp, ss(T := ss T + t))) ({}, {})) t"])
        prefer 2
        apply(rule Valid_ode_sol_sp[where ss= ss and aa = "Task WAIT ent tp" and d="0.045- ss T" and p="\<lambda> t. ss(T:= ss T+t)" and P = "\<lambda>(a,s) t. inv_s (snd (a, s)) \<and> P (a, s) t"])
     subgoal by auto
     subgoal
       apply auto unfolding state2vec_def has_vderiv_on_def
       apply clarify
       apply (rule has_vector_derivative_projI)
       apply auto
       apply (rule has_vector_derivative_eq_rhs)
        apply (fast intro!: derivative_intros)
       by auto
     subgoal by auto
     subgoal by auto
     subgoal
       apply auto unfolding state2vec_def vec2state_def
       apply (rule c1_implies_local_lipschitz[where f'="(\<lambda>(t,v). Blinfun(\<lambda>(v::vec) . \<chi> x. 0))"])
       apply auto
       unfolding has_derivative_def
       apply auto
        prefer 2
        apply (rule vec_tendstoI)
       subgoal
       proof-
         have b1:"bounded_linear (\<lambda> (v::vec). \<chi> a . 0)"
           apply (rule bounded_linearI')
           using vec_lambda_unique by fastforce+
         then have b2:"blinfun_apply (Blinfun (\<lambda> (v::vec). \<chi> x. 0)) = (\<lambda>v. \<chi> x. 0)"
           apply(rule bounded_linear_Blinfun_apply)
           done
         then have b3:"bounded_linear (blinfun_apply (Blinfun (\<lambda> (v::vec). \<chi> x. 0)))"
           using b1
           by (simp add: blinfun.bounded_linear_right)
         show ?thesis
           by(auto simp add:b2)
       qed
       by (simp add: blinfun.bounded_linear_right)
     subgoal
       unfolding entails_def inv_s_def by (auto simp add:C_def T_def pure_assn_def conj_assn_def)
     subgoal unfolding entails_def by auto
        apply(rule Valid_weaken_pre)
         prefer 2
         apply(rule Valid_strengthen_post)
          prefer 2
          apply(rule Valid_ode_not_sp[where ss= ss and aa = "Task WAIT ent tp" and d="0.045- ss T" and p="\<lambda> t. ss(T:= ss T+t)" and P = "\<lambda>(a,s) t. inv_s (snd (a, s)) \<and> P (a, s) t"])
     subgoal by auto
     subgoal by auto
     subgoal unfolding entails_def inv_s_def by (auto simp add:C_def T_def pure_assn_def conj_assn_def)
     subgoal unfolding entails_def inv_s_def by (auto simp add:C_def T_def)
     apply(rule Valid_seq)
  apply(rule Valid_assign_sp1)
    apply(rule Valid_seq)
     apply(rule Valid_basic_sp1)
    apply simp
    apply(rule Valid_basic_sp1)
  unfolding entails_def
   apply simp
   apply(rule Valid_weaken_pre[where P'="\<lambda> s t. False"])
  unfolding entails_def
    apply auto[1]
   apply(rule Valid_False)
  apply(auto simp add: pure_assn_def conj_assn_def inv_s_def C_def T_def)
  subgoal for ss' tr x
    apply (rule ext) subgoal for v
      apply (cases "v = CHR ''t''")
      subgoal by auto
      subgoal premises pre proof -
        have "(ss'(CHR ''t'' := x)) v = (ss(CHR ''t'' := 9 / 200)) v"
          using pre(2) by auto
        then have "ss' v = ss v"
          using pre(6) by auto
        then show ?thesis
          using pre(6) by auto
      qed
      done
    done
  done

lemma T1_Valid_READY:
"\<Turnstile> {\<lambda>s t. s = (Task READY ent tp,ss) \<and> inv_s (snd s) \<and> P s t}
   T1
    {\<lambda> s tr. (inv_s (snd s) \<and> (\<exists> tt v. tt\<ge>0 \<and> tt \<le> 0.045 - ss T \<and> s = (Task RUNNING ent tp,ss(T:= ss T + tt,F := v)) \<and>
                    ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Waitin\<^sub>t tt (\<lambda>t. EState (Task READY ent tp, ss(T := ss T + t)))
                    (run_ch 1) v ({}, {run_ch 1})) tr))
              \<or> (inv_s (snd s) \<and> s = (Task WAIT ent tp,ss(T:=0.045)) \<and>
                   ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}) @\<^sub>t
                    Outrdy\<^sub>t (Task READY ent tp, ss(T:=0.045)) (exit_ch 1) 0 ({exit_ch 1},{run_ch 1}))
                   tr)
              \<or> (\<exists> v. (inv_s (snd s) \<and> s = (Task RUNNING ent tp,ss(T:=0.045,F:=v)) \<and>
                   ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}) @\<^sub>t
                    Inrdy\<^sub>t (Task READY ent tp, ss(T:=0.045)) (run_ch 1) v ({exit_ch 1},{run_ch 1}))
                   tr))}"
unfolding T1_def
  apply(rule Valid_strengthen_post)
   prefer 2
   apply(rule Valid_cond_sp)
  apply(rule Valid_weaken_pre[where P'="\<lambda> s t. False"])
unfolding entails_def
    apply auto[1]
  apply(rule Valid_False)
  apply(rule Valid_cond_sp)
  prefer 2
apply(rule Valid_weaken_pre[where P'="\<lambda> s t. False"])
unfolding entails_def
    apply auto[1]
  apply(rule Valid_False)
  apply(rule Valid_seq)
  apply(rule Valid_send_sp)
  apply(rule Valid_seq[where
    Q="\<lambda> (a,s) tr. (\<exists> tt v. tt\<ge>0 \<and> tt \<le> 0.045 - ss T \<and> (a,s) = (Task RUNNING ent tp,ss(T:= ss T + tt,F := v)) \<and> inv_s s \<and> (
                   (P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Waitin\<^sub>t tt (\<lambda>t. EState (Task READY ent tp, ss(T := ss T + t)))
                    (run_ch 1) v ({}, {run_ch 1})) tr)
              \<or>  ((a,s) = (Task READY ent tp,ss(T:=0.045)) \<and> inv_s s \<and>
                   ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}))
                   tr)"])
  apply(rule Valid_pre_cases'[where P="(\<lambda>(a,s). s T < 45 / 10 ^ 3)"])
   apply(rule Valid_weaken_pre)
  prefer 2
  apply(rule Valid_strengthen_post)
     prefer 2
     apply(rule Valid_interrupt_in_sol[where ss= ss and d="0.045- ss T" and p="\<lambda> t. ss(T:= ss T + t)" and aa= "Task READY ent tp" and P="\<lambda>(a,s) t. inv_s s \<and> (P (a, s) @\<^sub>t Out\<^sub>t (EState (a, s)) (req_ch 1) tp) t"])
  subgoal by auto
  subgoal
    apply auto unfolding state2vec_def has_vderiv_on_def
    apply clarify
    apply (rule has_vector_derivative_projI)
    apply auto
    apply (rule has_vector_derivative_eq_rhs)
     apply (fast intro!: derivative_intros)
    by auto
  subgoal by auto
  subgoal by auto
  subgoal
    apply auto unfolding state2vec_def vec2state_def
    apply (rule c1_implies_local_lipschitz[where f'="(\<lambda>(t,v). Blinfun(\<lambda>(v::vec) . \<chi> x. 0))"])
       apply auto
    unfolding has_derivative_def
    apply auto
    prefer 2
     apply (rule vec_tendstoI)
    subgoal
    proof-
    have b1:"bounded_linear (\<lambda> (v::vec). \<chi> a . 0)"
      apply (rule bounded_linearI')
      using vec_lambda_unique by fastforce+
    then have b2:"blinfun_apply (Blinfun (\<lambda> (v::vec). \<chi> x. 0)) = (\<lambda>v. \<chi> x. 0)"
      apply(rule bounded_linear_Blinfun_apply)
      done
    then have b3:"bounded_linear (blinfun_apply (Blinfun (\<lambda> (v::vec). \<chi> x. 0)))"
      using b1
      by (simp add: blinfun.bounded_linear_right)
    show ?thesis
      by(auto simp add:b2)
  qed
  by (simp add: blinfun.bounded_linear_right)
     apply auto[1]
     apply(rule Valid_basic_sp1)
    prefer 2
  subgoal unfolding entails_def join_assn_def by auto
     prefer 2
  apply(rule Valid_weaken_pre)
  prefer 2
  apply(rule Valid_strengthen_post)
       prefer 2
       apply(rule Valid_interrupt_in_not[where p = "\<lambda> t. ss(T:= ss T + t)" and ss= ss and aa= "Task READY ent tp" and P="\<lambda>(a,s) t. inv_s s \<and> (P (a, s) @\<^sub>t Out\<^sub>t (EState (a, s)) (req_ch 1) tp) t"])
  subgoal by auto
  apply auto[1]
       apply(rule Valid_basic_sp1)
      prefer 2
  subgoal unfolding entails_def join_assn_def by auto
  subgoal unfolding entails_def inv_s_def pure_assn_def join_assn_def conj_assn_def
    apply (auto simp add: T_def C_def F_def)
    subgoal for v tr1 tr3 tr2
      apply(rule exI[where x = 0])
      apply auto
      apply(rule exI[where x = v])
      apply auto
      apply(rule exI[where x = "tr1@tr2"])
      by auto
    done
  subgoal
    apply(rule entails_disjE)
     apply (auto simp del: fun_upd_apply)
    subgoal
    apply(rule entails_trans[where Q ="(\<lambda>a. case a of
         (a, s) \<Rightarrow>
           \<lambda>tr. (\<exists>tt\<ge>0.
                    tt \<le> 9 / 200 - ss T \<and>
                    a = Task RUNNING ent tp \<and>
                    (\<exists>v. s = ss(T := ss T + tt, F := v) \<and>
                         inv_s s \<and>
                         ((P (Task READY ent tp, ss) @\<^sub>t
                           Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                          Waitin\<^sub>t tt (\<lambda>t. EState (Task READY ent tp, ss(T := ss T + t)))
                           (run_ch 1) v ({}, {run_ch 1}))
                          tr)))"])
      subgoal
        unfolding entails_def C_def T_def F_def inv_s_def pure_assn_def conj_assn_def join_assn_def
        apply (auto simp del: fun_upd_apply)
        subgoal for tt vv tr1 tr2 tr3
          apply(rule exI[where x="tt"])
          apply auto
          apply(rule exI[where x="vv"])
          apply auto
          apply(rule exI[where x="tr1@tr3"])
          by auto
        done
      unfolding entails_def by auto
    subgoal
      apply(rule entails_trans[where Q="\<lambda>a. case a of
         (a, s) \<Rightarrow>
           \<lambda>tr. a = Task READY ent tp \<and>
                s = ss(T := 9 / 200) \<and>
                inv_s s \<and>
                ((P (Task READY ent tp, ss) @\<^sub>t
                  Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                 Wait\<^sub>t (9 / 200 - ss T)
                  (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>))) ({}, {run_ch 1}))
                 tr"])
      unfolding entails_def C_def T_def F_def inv_s_def pure_assn_def conj_assn_def join_assn_def
      by auto
    done
   apply(rule Valid_cond_sp)
  apply simp
  apply(rule Valid_echoice[where R ="\<lambda> s tr.(inv_s (snd s) \<and> s = (Task WAIT ent tp,ss(T:=0.045)) \<and>
                   ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}) @\<^sub>t
                    Outrdy\<^sub>t (Task READY ent tp, ss(T:=0.045)) (exit_ch 1) 0 ({exit_ch 1},{run_ch 1}))
                   tr)
              \<or> (\<exists> v. (inv_s (snd s) \<and> s = (Task RUNNING ent tp,ss(T:=0.045,F:=v)) \<and>
                   ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}) @\<^sub>t
                    Inrdy\<^sub>t (Task READY ent tp, ss(T:=0.045)) (run_ch 1) v ({exit_ch 1},{run_ch 1}))
                   tr))"])
  subgoal for i
    apply(cases i)
    subgoal
      apply auto
      apply(rule exI[where x="\<lambda>s tr.
               inv_s (snd s) \<and>
               s = (Task READY ent tp, ss(T := 9 / 200)) \<and>
               ((P (Task READY ent tp, ss) @\<^sub>t
                 Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                Wait\<^sub>t (9 / 200 - ss T)
                 (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>))) ({}, {run_ch 1}) @\<^sub>t
                Outrdy\<^sub>t (Task READY ent tp, ss(T := 9 / 200)) (exit_ch 1) 0
                 ({exit_ch 1}, {run_ch 1}))
                tr"])
      apply auto
      subgoal
        apply(rule Valid_strengthen_post)
         prefer 2
         apply(rule Valid_basic_sp1)
        unfolding entails_def
        by auto
      subgoal unfolding entails_def
        apply (auto simp add:join_assn_def join_assoc)
        subgoal for tr1a tr2 tr2a
          apply(rule exI[where x="tr1a@tr2a"])
          apply auto
          apply(rule exI[where x="tr2"])
          apply auto
          apply(rule )
          done
        done
      subgoal unfolding entails_def
        apply (auto simp add:join_assn_def join_assoc)
        subgoal for d tr1a tr2 tr2a
          apply(rule exI[where x="tr1a@tr2a"])
          apply auto
          apply(rule exI[where x="tr2"])
          apply auto
          apply rule
          by auto
        done
      done
    subgoal for i'
      apply auto
      apply(rule exI[where x="\<lambda> s tr. (\<exists> v. (inv_s (snd s) \<and> s = (Task READY ent tp,ss(T:=0.045,F:=v)) \<and>
                   ((P (Task READY ent tp, ss) @\<^sub>t
                    Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                   Wait\<^sub>t (9 / 200 - ss T) (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>)))
                    ({}, {run_ch 1}) @\<^sub>t
                    Inrdy\<^sub>t (Task READY ent tp, ss(T:=0.045)) (run_ch 1) v ({exit_ch 1},{run_ch 1}))
                   tr))"])
      apply auto
      subgoal
        apply(rule Valid_strengthen_post)
         prefer 2
         apply(rule Valid_basic_sp1)
        unfolding entails_def
        by auto
      subgoal unfolding entails_def
        apply (auto simp add:inv_s_def F_def T_def C_def join_assn_def join_assoc)
        subgoal for tr1a tr2 tr2a v
          apply(rule exI[where x=v])
          apply auto
          apply(rule exI[where x="tr1a@tr2a"])
          apply auto
          apply(rule exI[where x=tr2])
          apply auto
          apply rule
          done
        done
      subgoal unfolding entails_def
        apply (auto simp add:inv_s_def F_def T_def C_def join_assn_def join_assoc)
        subgoal for d tr1a tr2 tr2a v
          apply(rule exI[where x=v])
          apply auto
          apply(rule exI[where x="tr1a@tr2a"])
          apply auto
          apply(rule exI[where x=tr2])
          apply auto
          apply rule
          by auto
        done
      done
    done
   apply(rule Valid_skip)
  by auto

lemma T1_Valid_RUNNING:
"\<Turnstile> {\<lambda>s t. s = (Task RUNNING ent tp,ss) \<and> inv_s (snd s) \<and> P s t}
   T1
    {\<lambda> s tr. ((inv_s (snd s) \<and> (\<exists> tt v. tt\<ge>0 \<and> tt \<le> (min (0.045 - ss T) (0.01 - C_upd ent (ss C))) \<and>
                          s = (Task READY eone tp,ss
                         (CHR ''t'' := ss CHR ''t'' + tt,
                          CHR ''c'' := C_upd ent (ss CHR ''c'') + tt, F := v)) \<and> (
                    P (Task RUNNING ent tp, ss) @\<^sub>t
                          Waitin\<^sub>t tt
                           (\<lambda>t. EState
                                 (Task RUNNING eone tp, ss
                                  (CHR ''t'' := ss CHR ''t'' + t,
                                   CHR ''c'' := C_upd ent (ss CHR ''c'') + t)))
                           (preempt_ch 1) v ({}, {preempt_ch 1}))
                          tr))
              \<or>  (inv_s (snd s) \<and> s =
          (Task WAIT eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             Outrdy\<^sub>t (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) (free_ch 1) 0 ({free_ch 1},{preempt_ch 1}))
         tr)
             \<or> (\<exists> v. (inv_s (snd s) \<and> s =
          (Task WAIT eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)), F := v)) \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             Inrdy\<^sub>t (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) (preempt_ch 1) v ({free_ch 1},{preempt_ch 1}))
         tr)))}"
  unfolding T1_def
apply(rule Valid_strengthen_post)
   prefer 2
   apply(rule Valid_cond_sp)
  apply(rule Valid_weaken_pre[where P'="\<lambda> s t. False"])
unfolding entails_def
    apply auto[1]
  apply(rule Valid_False)
apply(rule Valid_cond_sp)
  apply(rule Valid_weaken_pre[where P'="\<lambda> s t. False"])
unfolding entails_def
    apply auto[1]
  apply(rule Valid_False)
  apply(rule Valid_seq[where Q="\<lambda> s t. s = (Task RUNNING eone tp, ss(C := C_upd ent (ss C))) \<and> inv_s (snd s) \<and> P (Task RUNNING ent tp, ss) t"])
  apply(rule Valid_strengthen_post)
  prefer 2
   apply(rule Valid_cond_sp)
   apply(rule Valid_seq)
    apply(rule Valid_assign_sp1)
    apply(rule Valid_basic_sp1)
   apply(rule Valid_skip)
  subgoal unfolding entails_def inv_s_def C_upd_def
    apply auto
    using entered.exhaust by blast
   apply(rule Valid_seq[where
    Q="\<lambda> (a,s) tr. (\<exists> tt v. tt\<ge>0 \<and> tt \<le> (min (0.045 - ss T) (0.01 - C_upd ent (ss C))) \<and>
                          (a,s) = (Task READY eone tp,ss
                         (CHR ''t'' := ss CHR ''t'' + tt,
                          CHR ''c'' := C_upd ent (ss CHR ''c'') + tt, F := v)) \<and> inv_s s \<and> (
                    P (Task RUNNING ent tp, ss) @\<^sub>t
                          Waitin\<^sub>t tt
                           (\<lambda>t. EState
                                 (Task RUNNING eone tp, ss
                                  (CHR ''t'' := ss CHR ''t'' + t,
                                   CHR ''c'' := C_upd ent (ss CHR ''c'') + t)))
                           (preempt_ch 1) v ({}, {preempt_ch 1}))
                          tr)
              \<or>  ((a, s) =
          (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) \<and> inv_s s \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}))
         tr)"])
 apply(rule Valid_pre_cases'[where P="(\<lambda>(a,s). s T < 45 / 10 ^ 3 \<and> s C < 1 / 10\<^sup>2)"])
   apply(rule Valid_weaken_pre)
  prefer 2
  apply(rule Valid_strengthen_post)
     prefer 2
     apply(rule Valid_interrupt_in_sol[where ss= "ss(C := C_upd ent (ss C))" and d="min (0.045 - ss T) (0.01 - C_upd ent (ss C))" and p="\<lambda> t. ss(T:= ss T + t, C:= C_upd ent (ss C) + t)" and aa= "Task RUNNING eone tp" and P="\<lambda>(a,s) t. inv_s s \<and> P (Task RUNNING ent tp, ss)  t"])
  subgoal apply auto unfolding T_def C_def by auto
  subgoal
    apply auto unfolding state2vec_def has_vderiv_on_def
    apply clarify
    apply (rule has_vector_derivative_projI)
    apply auto
    unfolding T_def C_def
    apply auto
    apply (rule has_vector_derivative_eq_rhs)
      apply (fast intro!: derivative_intros)
     apply auto
      apply (rule has_vector_derivative_eq_rhs)
      apply (fast intro!: derivative_intros)
    by auto
  subgoal by auto
  subgoal unfolding T_def C_def
     apply auto
    apply(cases "(9 / 200 - ss CHR ''t'') \<le> (1 / 100 - C_upd ent (ss CHR ''c''))")
    by auto
  subgoal
    apply auto unfolding state2vec_def vec2state_def
    apply (rule c1_implies_local_lipschitz[where f'="(\<lambda>(t,v). Blinfun(\<lambda>(v::vec) . \<chi> x. 0))"])
       apply auto
    unfolding has_derivative_def
    apply auto
    prefer 2
     apply (rule vec_tendstoI)
    subgoal
    proof-
    have b1:"bounded_linear (\<lambda> (v::vec). \<chi> a . 0)"
      apply (rule bounded_linearI')
      using vec_lambda_unique by fastforce+
    then have b2:"blinfun_apply (Blinfun (\<lambda> (v::vec). \<chi> x. 0)) = (\<lambda>v. \<chi> x. 0)"
      apply(rule bounded_linear_Blinfun_apply)
      done
    then have b3:"bounded_linear (blinfun_apply (Blinfun (\<lambda> (v::vec). \<chi> x. 0)))"
      using b1
      by (simp add: blinfun.bounded_linear_right)
    show ?thesis
      by(auto simp add:b2)
    qed
    by (simp add: blinfun.bounded_linear_right)
  apply clarify[1]
       apply (simp add: T_def C_def)[1]
       apply(rule Valid_basic_sp1)
      prefer 2
  subgoal unfolding entails_def
    by auto
     prefer 2
     apply(rule Valid_weaken_pre)
  prefer 2
     apply(rule Valid_strengthen_post)
       prefer 2
       apply(rule Valid_interrupt_in_not[where ss= "ss(C := C_upd ent (ss C))" and p="\<lambda> t. ss(T:= ss T + t, C:= C_upd ent (ss C) + t)" and aa= "Task RUNNING eone tp" and P="\<lambda>(a,s) t. inv_s s \<and> P (Task RUNNING ent tp, ss)  t"])
  subgoal by auto
  unfolding T_def C_def
  apply auto[1]
       apply(rule Valid_basic_sp1)
      prefer 2
  subgoal unfolding entails_def by auto
  subgoal
    unfolding entails_def
    apply (rule allI)+
    apply(rule impI)
    subgoal for s tr
      apply(cases s)
      subgoal for a sss
        apply simp
        apply(erule disjE)
        subgoal apply(rule disjI1)
          apply(rule exI[where x=0])
          apply clarify
          apply(rule conjI) subgoal by auto
          apply(rule conjI) subgoal unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def by auto
          apply(rule conjI) subgoal unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def by auto
          subgoal for v
            apply simp
            apply(rule exI[where x=v])
            unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def F_def by auto
          done
        subgoal apply(rule disjI2)
          apply simp
          apply(rule conjI) subgoal unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def F_def by auto
          apply(rule conjI) subgoal unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def F_def by auto
          unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def F_def
          apply(subgoal_tac"(min (9 / 200 - ss CHR ''t'') (1 / 100 - C_upd ent (ss CHR ''c''))) = 0")
          subgoal by (auto simp add: emp_assn_def)
          by auto
        done
      done
    done
  subgoal
    unfolding entails_def
    apply (rule allI)+
    apply(rule impI)
    subgoal for s tr
      apply(cases s)
      subgoal for a sss
        apply simp
        apply(erule disjE)
        subgoal apply(rule disjI1)
          apply auto
          subgoal for tt vv
            apply(rule exI[where x=tt])
            apply auto
            apply(rule exI[where x=vv])
            apply auto
            unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def F_def
            by auto
          done
        subgoal apply(rule disjI2)
          unfolding pure_assn_def join_assn_def conj_assn_def inv_s_def T_def C_def F_def
          apply auto
          subgoal
           apply(cases "(9 / 200 - ss CHR ''t'') \<le>(1 / 100 - C_upd ent (ss CHR ''c''))")
            by auto
          subgoal
           apply(cases "(9 / 200 - ss CHR ''t'') \<le>(1 / 100 - C_upd ent (ss CHR ''c''))")
            by auto
          done
        done
      done
    done
   apply(rule Valid_cond_sp)
    apply simp
    apply(rule Valid_echoice[where R="\<lambda> s tr.(inv_s (snd s) \<and> s =
          (Task WAIT eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             Outrdy\<^sub>t (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) (free_ch 1) 0 ({free_ch 1},{preempt_ch 1}))
         tr)
             \<or> (\<exists> v. (inv_s (snd s) \<and> s =
          (Task WAIT eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)), F := v)) \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             Inrdy\<^sub>t (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) (preempt_ch 1) v ({free_ch 1},{preempt_ch 1}))
         tr))"])
  subgoal for i
    apply(cases i)
    subgoal
      apply simp
      apply(rule exI[where x = "\<lambda> s tr.(inv_s (snd s) \<and> s =
          (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             Outrdy\<^sub>t (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) (free_ch 1) 0 ({free_ch 1},{preempt_ch 1}))
         tr)"])
      apply(rule conjI)
      subgoal
        apply(rule Valid_strengthen_post)
         prefer 2
         apply(rule Valid_basic_sp1)
        unfolding entails_def
        by auto
      subgoal unfolding entails_def
        apply (auto simp add:T_def C_def join_assn_def)
        subgoal for tr1 tr2
          apply(rule exI[where x= tr1])
          apply auto
          apply(rule exI[where x= tr2])
          apply auto
          apply rule
          done
        subgoal for d tr1 tr2
          apply(rule exI[where x= tr1])
          apply auto
          apply(rule exI[where x= tr2])
          apply auto
          apply rule
          by auto
        done
      done
    subgoal for i'
      apply simp
      apply(rule exI[where x="\<lambda> s tr.(\<exists> v. (inv_s (snd s) \<and> s =
          (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)), F := v)) \<and>
                   ((P (Task RUNNING ent tp, ss)) @\<^sub>t
         Wait\<^sub>t (min (0.045 - ss T) (0.01 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState
                (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>)))
          ({}, {preempt_ch 1}) @\<^sub>t
             Inrdy\<^sub>t (Task RUNNING eone tp, ss
         (T := ss T + min (0.045 - ss T) (0.01 - C_upd ent (ss C)),
          C := C_upd ent (ss C) +
               min (0.045 - ss T) (0.01 - C_upd ent (ss C)))) (preempt_ch 1) v ({free_ch 1},{preempt_ch 1}))
         tr))"])
      apply(rule conjI)
      subgoal
        apply(rule Valid_ex_pre)
        subgoal for v
          apply(rule Valid_strengthen_post)
         prefer 2
         apply(rule Valid_basic_sp1)
        unfolding entails_def
        by auto
      done
    subgoal unfolding entails_def
      apply (auto simp add:T_def C_def F_def join_assn_def inv_s_def)
      subgoal for tr1 tr2 v
        apply(rule exI[where x= v])
        apply auto
        apply(rule exI[where x= tr1])
        apply auto
        apply(rule exI[where x= tr2])
        apply auto
        apply rule
        done
      subgoal for d tr1 tr2 v
        apply(rule exI[where x= v])
        apply auto
        apply(rule exI[where x= tr1])
        apply auto
        apply(rule exI[where x= tr2])
        apply auto
        apply rule
        by auto
      done
    done
  done
  apply(rule Valid_skip)
  apply(rule allI)+
  apply(rule impI)
  apply(erule disjE)
  subgoal by auto
  apply(erule disjE)
  subgoal by auto
  apply(erule disjE)
  subgoal for s tr
    by (auto simp add:T_def C_def )
  subgoal for s tr
    by auto
  done

fun RepN :: "nat \<Rightarrow> 'a proc \<Rightarrow> 'a proc" where
  "RepN 0 c = Skip"
| "RepN (Suc n) c = c; RepN n c"

lemma big_step_rep:
  "big_step (Rep c) s1 tr1 s2 \<longleftrightarrow> (\<exists>n. big_step (RepN n c) s1 tr1 s2)"
proof -
  have "big_step p s1 tr1 s2 \<Longrightarrow> p = Rep c \<Longrightarrow> \<exists>n. big_step (RepN n c) s1 tr1 s2" for p s1 tr1 s2
    apply (induction rule: big_step.induct, auto)
     apply (rule exI[where x=0])
    apply simp apply (rule skipB)
    subgoal for a b tr1 aa ba tr2 ab bb n
      apply (rule exI[where x="Suc n"])
      apply simp apply (rule seqB) by auto
    done
  moreover have "\<And>s1 tr1 s2. big_step (RepN n c) s1 tr1 s2 \<Longrightarrow> big_step (Rep c) s1 tr1 s2" for n
    apply (induction n)
     apply simp apply (elim skipE) apply (auto intro: RepetitionB1)[1]
    apply simp apply (elim seqE) apply (auto intro: RepetitionB2)
    using RepetitionB2 by blast
  ultimately show ?thesis
    by blast
    qed

lemma Valid_rep':
  assumes"\<And>n P . \<Turnstile> {\<lambda>s t. s = s0 \<and> f s \<and> P t}
                      RepN n c
                 {\<lambda>s t. f s \<and> (P @\<^sub>t (Q n s0)) t}"
  shows "\<Turnstile> {\<lambda>s t. s = s0 \<and> f s \<and> P t}
                      Rep c
            {\<lambda>s t. f s \<and> (\<exists>n. (P @\<^sub>t (Q n s0)) t)}"
  using assms unfolding Valid_def big_step_rep
  by blast

lemma Valid_rep'':
  assumes"\<And>n P . \<Turnstile> {\<lambda>s t. s = s0 \<and> P t}
                      RepN n c
                 {\<lambda>s t. (P @\<^sub>t (Q n s0)) t}"
  shows "\<Turnstile> {\<lambda>s t. s = s0 \<and> P t}
                      Rep c
            {\<lambda>s t. (\<exists>n. (P @\<^sub>t (Q n s0)) t)}"
  using assms unfolding Valid_def big_step_rep
  by blast

lemma Valid_T1_rep:
  "\<Turnstile> {\<lambda>s t. s = (Task st ent tp,ss) \<and> inv_s (snd s) \<and> emp\<^sub>t t}
                      Rep T1
      {\<lambda>s t. inv_s (snd s) \<and> (\<exists>n. (emp\<^sub>t @\<^sub>t T1_tr n (Task st ent tp,ss)) t)}"
  apply(rule Valid_rep')
  subgoal for n p
    apply(induction n arbitrary:p st ent tp ss)
    subgoal for p
      apply auto
      apply(rule Valid_strengthen_post)
       prefer 2
       apply(rule Valid_skip)
      unfolding entails_def by auto
    subgoal premises pre for n p st ent tp ss
      apply auto
      apply(cases st)
      subgoal
        apply simp
        apply(rule Valid_seq)
         apply(rule T1_Valid_WAIT)
        apply(rule Valid_strengthen_post)
         prefer 2
         apply(rule pre)
        unfolding entails_def by (auto simp add:join_assoc)
      subgoal
        apply simp
        apply(rule Valid_seq)
         apply(rule T1_Valid_READY)
        apply(rule Valid_pre_or)
        subgoal
          thm pre
          apply auto
          apply(rule Valid_weaken_pre[where P' = "\<lambda>s tr. \<exists>tt v . s = (Task RUNNING ent tp, ss(T := ss T + tt, F := v)) \<and> inv_s (snd s) \<and>
               (((\<up>(0 \<le> tt \<and> tt \<le> 9 / 200 - ss T) \<and>\<^sub>t p @\<^sub>t Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                         Waitin\<^sub>t tt (\<lambda>t. EState (Task READY ent tp, ss(T := ss T + t)))
                          (run_ch 1) v ({}, {run_ch 1}))
                         tr)"])
          subgoal unfolding entails_def
            by(auto simp add: pure_assn_def conj_assn_def)
          apply(rule Valid_ex_pre)+
          apply(rule Valid_strengthen_post)
           prefer 2
           apply(rule pre)
          unfolding entails_def
          apply (auto simp add: join_disj_assn)
          unfolding disj_assn_def
          apply(rule disjI1)
          apply(auto simp add: ex_assn_def pure_assn_def conj_assn_def join_assn_def)
          subgoal for tt v b tr2 tr1b tr2a tr2b
            apply(rule exI[where x="tr1b"])
            apply auto
            apply(rule exI[where x=v])
            apply(rule exI[where x=tt])
            by auto
          done
        apply(rule Valid_pre_or)
        subgoal
        apply(rule Valid_weaken_pre[where P'="\<lambda>s tr.
                s = (Task WAIT ent tp, ss(T := 45 / 10 ^ 3)) \<and> inv_s (snd s) \<and>
               ((p @\<^sub>t Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                Wait\<^sub>t (9 / 200 - ss T)
                 (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>))) ({}, {run_ch 1}) @\<^sub>t
                Outrdy\<^sub>t ((Task READY ent tp, ss(T := 45 / 10 ^ 3))) (exit_ch 1) 0 ({exit_ch 1},{run_ch 1}))
                tr"])
        subgoal unfolding entails_def by auto
        apply(rule Valid_strengthen_post)
           prefer 2
           apply(rule pre)
          unfolding entails_def
          apply (auto simp add: join_disj_assn)
          unfolding disj_assn_def
          apply(rule disjI2)
          by(auto simp add: join_assoc)
        subgoal
          apply(rule Valid_ex_pre)
          subgoal for v
          apply(rule Valid_weaken_pre[where P'="\<lambda>s tr.
                s = (Task RUNNING ent tp, ss(T := 45 / 10 ^ 3,F:=v)) \<and> inv_s (snd s) \<and>
               ((p @\<^sub>t Out\<^sub>t (EState (Task READY ent tp, ss)) (req_ch 1) tp) @\<^sub>t
                Wait\<^sub>t (9 / 200 - ss T)
                 (\<lambda>\<tau>. EState (Task READY ent tp, ss(T := ss T + \<tau>))) ({}, {run_ch 1}) @\<^sub>t
                Inrdy\<^sub>t ((Task READY ent tp, ss(T := 45 / 10 ^ 3))) (run_ch 1) v ({exit_ch 1},{run_ch 1}))
                tr"])
        subgoal unfolding entails_def by auto
        apply(rule Valid_strengthen_post)
           prefer 2
         apply(rule pre)
          unfolding entails_def
          apply (auto simp add: join_disj_assn ex_assn_def)
          unfolding disj_assn_def
          apply(rule disjI2)+
          apply (auto simp add: join_assoc join_assn_def)
          subgoal for b tr2 tr1b tr2b tr1c tr2c
            apply(rule exI[where x= tr1b])
            apply auto
            apply(rule exI[where x= tr2b])
            apply auto
            apply(rule exI[where x= tr1c])
            apply auto
            done
          done
        done
      done
        subgoal
          apply simp
          apply(rule Valid_seq)
           apply(rule T1_Valid_RUNNING)
          apply(rule Valid_pre_or)
        subgoal
          thm pre
          apply auto
          apply(rule Valid_weaken_pre[where P' = "\<lambda>s tr. \<exists>tt v . s = (Task READY eone tp, ss
                         (CHR ''t'' := ss CHR ''t'' + tt,CHR ''c'' := C_upd ent (ss CHR ''c'') + tt, F := v)) \<and> inv_s (snd s) \<and>
               ((\<up>(0 \<le> tt \<and> tt \<le> 9 / 200 - ss T \<and> tt \<le> 1 / 100 - C_upd ent (ss C))
                       \<and>\<^sub>t p @\<^sub>t Waitin\<^sub>t tt
                          (\<lambda>t. EState
                                (Task RUNNING eone tp, ss
                                 (CHR ''t'' := ss CHR ''t'' + t,
                                  CHR ''c'' := C_upd ent (ss CHR ''c'') + t)))
                          (preempt_ch 1) v ({}, {preempt_ch 1}))
                         tr)"])
          subgoal unfolding entails_def
            by(auto simp add: pure_assn_def conj_assn_def)
          apply(rule Valid_ex_pre)+
          apply(rule Valid_strengthen_post)
           prefer 2
           apply(rule pre)
          unfolding entails_def
          apply (auto simp add: join_disj_assn)
          unfolding disj_assn_def
          apply(rule disjI1)
          apply(auto simp add: ex_assn_def pure_assn_def conj_assn_def join_assn_def T_def C_def)
          subgoal for tt v b tr1a tr2 tr2a
            apply(rule exI[where x="tr1a"])
            by auto
          done
        apply(rule Valid_pre_or)
        subgoal
        apply(rule Valid_weaken_pre[where P'="\<lambda>s tr.
                s = (Task WAIT eone tp, ss
                (T := ss T + min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)),
                 C := C_upd ent (ss C) +
                      min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)))) \<and> inv_s (snd s) \<and>
               ((p @\<^sub>t Wait\<^sub>t (min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>))) ({}, {preempt_ch 1}) @\<^sub>t
         Outrdy\<^sub>t ((Task RUNNING eone tp, ss(T := ss T + min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)),
              C := C_upd ent (ss C) + min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)))))(free_ch 1) 0 ({free_ch 1}, {preempt_ch 1}))
                tr)"])
        subgoal unfolding entails_def by auto
        apply(rule Valid_strengthen_post)
           prefer 2
           apply(rule pre)
          unfolding entails_def
          apply (auto simp add: join_disj_assn)
          unfolding disj_assn_def
          apply(rule disjI2)
          by(auto simp add: join_assoc)
        subgoal
          apply(rule Valid_ex_pre)
          subgoal for v
            apply(rule Valid_weaken_pre[where P'="\<lambda>s tr.
                s = (Task WAIT eone tp, ss
                (T := ss T + min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)),
                 C := C_upd ent (ss C) +
                      min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)),F:=v)) \<and> inv_s (snd s) \<and>
               ((p @\<^sub>t Wait\<^sub>t (min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)))
          (\<lambda>\<tau>. EState (Task RUNNING eone tp, ss(T := ss T + \<tau>, C := C_upd ent (ss C) + \<tau>))) ({}, {preempt_ch 1}) @\<^sub>t
         Inrdy\<^sub>t ((Task RUNNING eone tp, ss(T := ss T + min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)),
              C := C_upd ent (ss C) + min (45 / 10 ^ 3 - ss T) (1 / 10\<^sup>2 - C_upd ent (ss C)))))(preempt_ch 1) v ({free_ch 1}, {preempt_ch 1}))
                tr)"])
        subgoal unfolding entails_def by auto
        apply(rule Valid_strengthen_post)
           prefer 2
           apply(rule pre)
          unfolding entails_def
          apply (auto simp add: join_disj_assn)
          unfolding disj_assn_def
          apply(rule disjI2)
          apply(rule disjI2)
          apply(auto simp add: join_assoc ex_assn_def join_assn_def)
          subgoal for b tr1a tr2 tr1b tr2b
            apply(rule exI[where x = tr1a])
            apply auto
            apply(rule exI[where x = tr1b])
            by auto
        done
      done
    done
  done
  done
  done

end